1<?php 2use LimeSurvey\PluginManager\PluginEvent; 3/* 4* LimeSurvey 5* Copyright (C) 2007-2013 The LimeSurvey Project Team / Carsten Schmitz 6* All rights reserved. 7* License: GNU/GPL License v2 or later, see LICENSE.php 8* LimeSurvey is free software. This version may have been modified pursuant 9* to the GNU General Public License, and as distributed it includes or 10* is derivative of works licensed under the GNU General Public License or 11* other free or open source software licenses. 12* See COPYRIGHT.php for copyright notices and details. 13* 14*/ 15 16/** 17 * For 2.06 most of the functionality in this class will be moved to the LSWebUser class. 18 * To not delay release of 2.05 this class was kept the way it is now. 19 * 20 * @@TODO Move to LSWebUser and change documentation / workflow for authentication plugins 21 */ 22class LSUserIdentity extends CUserIdentity 23{ 24 25 const ERROR_IP_LOCKED_OUT = 98; 26 const ERROR_UNKNOWN_HANDLER = 99; 27 28 protected $config = array(); 29 30 /** 31 * The userid 32 * 33 * @var int 34 */ 35 public $id = null; 36 37 /** 38 * A User::model() object 39 * 40 * @var User 41 */ 42 public $user; 43 44 /** 45 * This is the name of the plugin to handle authentication 46 * default handler is used for remote control 47 * 48 * @var string 49 */ 50 public $plugin = 'Authdb'; 51 52 public function authenticate() 53 { 54 // First initialize the result, we can later retieve it to get the exact error code/message 55 $result = new LSAuthResult(self::ERROR_NONE); 56 57 // Check if the ip is locked out 58 if (FailedLoginAttempt::model()->isLockedOut()) { 59 $message = sprintf(gT('You have exceeded the number of maximum login attempts. Please wait %d minutes before trying again.'), App()->getConfig('timeOutTime') / 60); 60 $result->setError(self::ERROR_IP_LOCKED_OUT, $message); 61 } 62 63 // If still ok, continue 64 if ($result->isValid()) { 65 if (is_null($this->plugin)) { 66 $result->setError(self::ERROR_UNKNOWN_HANDLER); 67 } else { 68 // Delegate actual authentication to plugin 69 // one_time_password is to be handled properly when writing a Plugin with this event 70 $authEvent = new PluginEvent('newUserSession', $this); // TODO: rename the plugin function authenticate() 71 $authEvent->set('identity', $this); 72 App()->getPluginManager()->dispatchEvent($authEvent); 73 $pluginResult = $authEvent->get('result'); 74 if ($pluginResult instanceof LSAuthResult) { 75 $result = $pluginResult; 76 } else { 77 $result->setError(self::ERROR_UNKNOWN_IDENTITY); 78 } 79 } 80 } 81 82 if ($result->isValid()) { 83 // Perform postlogin 84 regenerateCSRFToken(); 85 $this->postLogin(); 86 // Reset counter after successful login 87 FailedLoginAttempt::model()->deleteAttempts(); 88 } else { 89 // Log a failed attempt 90 FailedLoginAttempt::model()->addAttempt(); 91 regenerateCSRFToken(); 92 App()->session->regenerateID(); // Handled on login by Yii 93 } 94 95 $this->errorCode = $result->getCode(); 96 $this->errorMessage = $result->getMessage(); 97 98 return $result->isValid(); 99 } 100 101 public function getConfig() 102 { 103 return $this->config; 104 } 105 106 /** 107 * Returns the current user's ID 108 * 109 * @access public 110 * @return int 111 */ 112 public function getId() 113 { 114 return $this->id; 115 } 116 117 /** 118 * Returns the active user's record 119 * 120 * @access public 121 * @return User 122 */ 123 public function getUser() 124 { 125 return $this->user; 126 } 127 128 protected function postLogin() 129 { 130 $user = $this->getUser(); 131 App()->user->login($this); 132 133 // Check for default password 134 if ($this->password === 'password') { 135 $not = new UniqueNotification(array( 136 'user_id' => App()->user->id, 137 'importance' => Notification::HIGH_IMPORTANCE, 138 'title' => 'Password warning', 139 'message' => '<span class="fa fa-exclamation-circle text-warning"></span> '. 140 gT("Warning: You are still using the default password ('password'). Please change your password and re-login again.") 141 )); 142 $not->save(); 143 } 144 145 if ((int) App()->request->getPost('width', '1220') < 1220) { 146// Should be 1280 but allow 60 lenience pixels for browser frame and scrollbar 147 Yii::app()->setFlashMessage(gT("Your browser screen size is too small to use the administration properly. The minimum size required is 1280*1024 px."), 'error'); 148 } 149 150 // Do session setup 151 Yii::app()->session['loginID'] = (int) $user->uid; 152 Yii::app()->session['user'] = $user->users_name; 153 Yii::app()->session['full_name'] = $user->full_name; 154 Yii::app()->session['htmleditormode'] = $user->htmleditormode; 155 Yii::app()->session['templateeditormode'] = $user->templateeditormode; 156 Yii::app()->session['questionselectormode'] = $user->questionselectormode; 157 Yii::app()->session['dateformat'] = $user->dateformat; 158 Yii::app()->session['session_hash'] = hash('sha256', getGlobalSetting('SessionName').$user->users_name.$user->uid); 159 160 // Perform language settings 161 if (App()->request->getPost('loginlang', 'default') != 'default') { 162 $user->lang = sanitize_languagecode(App()->request->getPost('loginlang')); 163 $user->save(); 164 $sLanguage = $user->lang; 165 } else if ($user->lang == 'auto' || $user->lang == '') { 166 $sLanguage = getBrowserLanguage(); 167 } else { 168 $sLanguage = $user->lang; 169 } 170 171 Yii::app()->session['adminlang'] = $sLanguage; 172 App()->setLanguage($sLanguage); 173 174 // Read all plugin config files if superadmin logged in 175 if (Permission::model()->hasGlobalPermission('superadmin')) { 176 $pm = Yii::app()->getPluginManager(); 177 $pm->readConfigFiles(); 178 } 179 } 180 181 public function setPlugin($name) 182 { 183 $this->plugin = $name; 184 } 185 186 public function setConfig($config) 187 { 188 $this->config = $config; 189 } 190} 191