Index: branches/5.1.x/core/units/helpers/user_helper.php =================================================================== diff -u -N -r14198 -r14241 --- branches/5.1.x/core/units/helpers/user_helper.php (.../user_helper.php) (revision 14198) +++ branches/5.1.x/core/units/helpers/user_helper.php (.../user_helper.php) (revision 14241) @@ -1,444 +1,444 @@ -event)) { - $this->event = new kEvent('u:OnLogin'); - } - - if (!$password && !$remember_login_cookie) { - return LOGIN_RESULT_INVALID_PASSWORD; - } - - $object =& $this->getUserObject(); - - // process "Save Username" checkbox - if ($this->Application->isAdmin) { - $save_username = $this->Application->GetVar('cb_save_username') ? $username : ''; - $this->Application->Session->SetCookie('save_username', $save_username, strtotime('+1 year')); - - // cookie will be set on next refresh, but refresh won't occur if - // login error present, so duplicate cookie in kHTTPQuery - $this->Application->SetVar('save_username', $save_username); - } - - // logging in "root" (admin only) - $super_admin = ($username == 'super-root') && $this->verifySuperAdmin(); - if ($this->Application->isAdmin && ($username == 'root') || ($super_admin && $username == 'super-root')) { - $root_password = $this->Application->ConfigValue('RootPass'); - $password_formatter =& $this->Application->recallObject('kPasswordFormatter'); - - if ($root_password != $password_formatter->EncryptPassword($password, 'b38')) { - return LOGIN_RESULT_INVALID_PASSWORD; - } - - $user_id = USER_ROOT; - $object->Clear($user_id); - $object->SetDBField('Login', 'root'); - - if (!$dry_run) { - $this->loginUserById($user_id, $remember_login_cookie); - - if ($super_admin) { - $this->Application->StoreVar('super_admin', 1); - } - - // reset counters - $this->Application->resetCounters('UserSession'); - - $this->_processLoginRedirect('root', $password); - $this->_processInterfaceLanguage(); - } - - return LOGIN_RESULT_OK; - } - - $user_id = $this->getUserId($username, $password, $remember_login_cookie); - - if ($user_id) { - $object->Load($user_id); - - if (!$this->checkBanRules($object)) { - return LOGIN_RESULT_BANNED; - } - - if ($object->GetDBField('Status') == STATUS_ACTIVE) { - if ( !$this->checkLoginPermission() ) { - return LOGIN_RESULT_NO_PERMISSION; - } - - if (!$dry_run) { - $this->loginUserById($user_id, $remember_login_cookie); - - if ($remeber_login) { - // remember username & password when "Remember Login" checkbox us checked (when user is using login form on Front-End) - $remember_login_cookie = $username . '|' . md5($password); - $this->Application->Session->SetCookie('remember_login', $remember_login_cookie, strtotime('+1 month')); - } - - if (!$remember_login_cookie) { - // reset counters - $this->Application->resetCounters('UserSession'); - - $this->_processLoginRedirect($username, $password); - $this->_processInterfaceLanguage(); - } - } - - return LOGIN_RESULT_OK; - } - else { - $pending_template = $this->Application->GetVar('pending_disabled_template'); - - if ($pending_template !== false && !$dry_run) { - // when user found, but it's not yet approved redirect hit to notification template - $this->event->redirect = $pending_template; - } - else { - // when no notification template given return an error - return LOGIN_RESULT_INVALID_PASSWORD; - } - } - } - - if (!$dry_run) { - $this->event->SetRedirectParam('pass', 'all'); -// $this->event->SetRedirectParam('pass_category', 1); // to test - } - - return LOGIN_RESULT_INVALID_PASSWORD; - } - - /** - * Login username by it's PortalUserId - * - * @param int $user_id - * @param bool $remember_login_cookie - */ - function loginUserById($user_id, $remember_login_cookie = false) - { - $object =& $this->getUserObject(); - - $this->Application->StoreVar('user_id', $user_id); - $this->Application->SetVar('u.current_id', $user_id); - $this->Application->Session->SetField('PortalUserId', $user_id); - - if ($user_id != USER_ROOT) { - $groups = $this->Application->RecallVar('UserGroups'); - $this->Application->Session->SetField('GroupId', reset( explode(',', $groups) )); - $this->Application->Session->SetField('GroupList', $groups); - } - - $this->Application->LoadPersistentVars(); - - if (!$remember_login_cookie) { - // don't change last login time when auto-login is used - $this_login = (int)$this->Application->RecallPersistentVar('ThisLogin'); - $this->Application->StorePersistentVar('LastLogin', $this_login); - $this->Application->StorePersistentVar('ThisLogin', adodb_mktime()); - } - - $this->Application->HandleEvent($dummy, 'u:OnAfterLogin'); - } - - /** - * Checks login permission - * - * @return bool - */ - function checkLoginPermission() - { - $object =& $this->getUserObject(); - - $groups = $object->getMembershipGroups(true); - if (!$groups) { - $groups = Array(); - } - - // store groups, because kApplication::CheckPermission will use them! - array_push($groups, $this->Application->ConfigValue('User_LoggedInGroup') ); - $this->Application->StoreVar( 'UserGroups', implode(',', $groups), true ); // true for optional - - return $this->Application->CheckPermission($this->Application->isAdmin ? 'ADMIN' : 'LOGIN', 1); - } - - /** - * Performs user logout - * - */ - function logoutUser() - { - if (!isset($this->event)) { - $this->event = new kEvent('u:OnLogout'); - } - - $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); - $sync_manager->performAction('LogoutUser'); - - $this->Application->HandleEvent($dummy, 'u:OnBeforeLogout'); - - $user_id = USER_GUEST; - $this->Application->SetVar('u.current_id', $user_id); - $object =& $this->Application->recallObject('u.current', null, Array('skip_autoload' => true)); - $object->Load($user_id); - - $this->Application->DestroySession(); - - $this->Application->StoreVar('user_id', $user_id, true); - $this->Application->Session->SetField('PortalUserId', $user_id); - - $group_list = $this->Application->ConfigValue('User_GuestGroup') . ',' . $this->Application->ConfigValue('User_LoggedInGroup'); - $this->Application->StoreVar('UserGroups', $group_list, true); - $this->Application->Session->SetField('GroupList', $group_list); - - if ($this->Application->ConfigValue('UseJSRedirect')) { - $this->event->SetRedirectParam('js_redirect', 1); - } - - $this->Application->resetCounters('UserSession'); - $this->Application->Session->SetCookie('remember_login', '', strtotime('-1 hour')); - - $this->event->SetRedirectParam('pass', 'all'); - } - - /** - * Returns user id based on given criteria - * - * @param string $username - * @param string $password - * @param string $remember_login_cookie - * @return int - */ - function getUserId($username, $password, $remember_login_cookie) - { - $password = md5($password); - - if ($remember_login_cookie) { - list ($username, $password) = explode('|', $remember_login_cookie); // 0 - username, 1 - md5(password) - } - - $sql = 'SELECT PortalUserId - FROM ' . TABLE_PREFIX . 'PortalUser - WHERE (Email = %1$s OR Login = %1$s) AND (Password = %2$s)'; - return $this->Conn->GetOne( sprintf($sql, $this->Conn->qstr($username), $this->Conn->qstr($password) ) ); - } - - /** - * Process all required data and redirect logged-in user - * - * @param string $username - * @param string $password - */ - function _processLoginRedirect($username, $password) - { - // set next template - $next_template = $this->Application->GetVar('next_template'); - - if ($next_template) { - $this->event->redirect = $next_template; - } - - // process IIS redirect - if ($this->Application->ConfigValue('UseJSRedirect')) { - $this->event->SetRedirectParam('js_redirect', 1); - } - - // syncronize login - $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); - $sync_manager->performAction('LoginUser', $username, $password); - } - - /** - * Sets correct interface language after sucessful login, based on user settings - * - * @param kEvent $event - */ - function _processInterfaceLanguage() - { - if (!$this->Application->isAdmin) { - return ; - } - - $is_root = $this->Application->RecallVar('user_id') == USER_ROOT; - - $object =& $this->getUserObject(); - - $user_language_id = $is_root ? $this->Application->RecallPersistentVar('AdminLanguage') : $object->GetDBField('AdminLanguage'); - - $sql = 'SELECT LanguageId, IF(LanguageId = ' . (int)$user_language_id . ', 2, AdminInterfaceLang) AS SortKey - FROM ' . TABLE_PREFIX . 'Language - WHERE Enabled = 1 - HAVING SortKey <> 0 - ORDER BY SortKey DESC'; - $language_info = $this->Conn->GetRow($sql); - $language_id = $language_info && $language_info['LanguageId'] ? $language_info['LanguageId'] : $user_language_id; - - if ($user_language_id != $language_id) { - // first admin login OR language was delelted or disabled - if ($is_root) { - $this->Application->StorePersistentVar('AdminLanguage', $language_id); - } - else { - $object->SetDBField('AdminLanguage', $language_id); - $object->Update(); - } - } - - $this->event->SetRedirectParam('m_lang', $language_id); // data - $this->Application->Session->SetField('Language', $language_id); // interface - } - - /** - * Checks that user is allowed to use super admin mode - * - * @return bool - */ - function verifySuperAdmin() - { - $sa_mode = ipMatch(defined('SA_IP') ? SA_IP : ''); - return $sa_mode || $this->Application->isDebugMode(); - } - - /** - * Returns user object, used during login processings - * - * @return UsersItem - */ - function &getUserObject() - { - $prefix_special = $this->Application->isAdmin ? 'u.current' : 'u'; // "u" used on front not to change theme - $object =& $this->Application->recallObject($prefix_special, null, Array('skip_autoload' => true)); - - return $object; - } - - /** - * Checks, if given user fields matches at least one of defined ban rules - * - * @param kDBItem $object - * @return bool - */ - function checkBanRules(&$object) - { - $table = $this->Application->getUnitOption('ban-rule', 'TableName'); - - if (!$this->Conn->TableFound($table)) { - // when ban table not found -> assume user is ok by default - return true; - } - - $sql = 'SELECT * - FROM ' . $table . ' - WHERE ItemType = 6 AND Status = ' . STATUS_ACTIVE . ' - ORDER BY Priority DESC'; - $rules = $this->Conn->Query($sql); - - $found = false; - - foreach ($rules as $rule) { - $field = $rule['ItemField']; - $this_value = mb_strtolower( $object->GetDBField($field) ); - $test_value = mb_strtolower( $rule['ItemValue'] ); - - switch ( $rule['ItemVerb'] ) { - case 1: // is - if ($this_value == $test_value) { - $found = true; - } - break; - - case 2: // is not - if ($this_value != $test_value) { - $found = true; - } - break; - - case 3: // contains - if ( strstr($this_value, $test_value) ) { - $found = true; - } - break; - - case 4: // not contains - if ( !strstr($this_value, $test_value) ) { - $found = true; - } - break; - - case 7: // exists - if ( strlen($this_value) > 0 ) { - $found = true; - } - break; - - case 8: // unique - if ( $this->_checkValueExist($field, $this_value) ) { - $found = true; - } - break; - } - - if ( $found ) { - // check ban rules, until one of them matches - - if ( $rule['RuleType'] ) { - // invert rule type - $found = false; - } - - break; - } - } - - return !$found; - } - - /** - * Checks if value is unique in Users table against the specified field - * - * @param string $field - * @param string $value - * @return string - */ - function _checkValueExist($field, $value) - { - $sql = 'SELECT * - FROM ' . $this->Application->getUnitOption('u', 'TableName') . ' - WHERE '. $field .' = ' . $this->Conn->qstr($value); - - return $this->Conn->GetOne($sql); - } - } +event)) { + $this->event = new kEvent('u:OnLogin'); + } + + if (!$password && !$remember_login_cookie) { + return LOGIN_RESULT_INVALID_PASSWORD; + } + + $object =& $this->getUserObject(); + + // process "Save Username" checkbox + if ($this->Application->isAdmin) { + $save_username = $this->Application->GetVar('cb_save_username') ? $username : ''; + $this->Application->Session->SetCookie('save_username', $save_username, strtotime('+1 year')); + + // cookie will be set on next refresh, but refresh won't occur if + // login error present, so duplicate cookie in kHTTPQuery + $this->Application->SetVar('save_username', $save_username); + } + + // logging in "root" (admin only) + $super_admin = ($username == 'super-root') && $this->verifySuperAdmin(); + if ($this->Application->isAdmin && ($username == 'root') || ($super_admin && $username == 'super-root')) { + $root_password = $this->Application->ConfigValue('RootPass'); + $password_formatter =& $this->Application->recallObject('kPasswordFormatter'); + + if ($root_password != $password_formatter->EncryptPassword($password, 'b38')) { + return LOGIN_RESULT_INVALID_PASSWORD; + } + + $user_id = USER_ROOT; + $object->Clear($user_id); + $object->SetDBField('Login', 'root'); + + if (!$dry_run) { + $this->loginUserById($user_id, $remember_login_cookie); + + if ($super_admin) { + $this->Application->StoreVar('super_admin', 1); + } + + // reset counters + $this->Application->resetCounters('UserSession'); + + $this->_processLoginRedirect('root', $password); + $this->_processInterfaceLanguage(); + } + + return LOGIN_RESULT_OK; + } + + $user_id = $this->getUserId($username, $password, $remember_login_cookie); + + if ($user_id) { + $object->Load($user_id); + + if (!$this->checkBanRules($object)) { + return LOGIN_RESULT_BANNED; + } + + if ($object->GetDBField('Status') == STATUS_ACTIVE) { + if ( !$this->checkLoginPermission() ) { + return LOGIN_RESULT_NO_PERMISSION; + } + + if (!$dry_run) { + $this->loginUserById($user_id, $remember_login_cookie); + + if ($remeber_login) { + // remember username & password when "Remember Login" checkbox us checked (when user is using login form on Front-End) + $remember_login_cookie = $username . '|' . md5($password); + $this->Application->Session->SetCookie('remember_login', $remember_login_cookie, strtotime('+1 month')); + } + + if (!$remember_login_cookie) { + // reset counters + $this->Application->resetCounters('UserSession'); + + $this->_processLoginRedirect($username, $password); + $this->_processInterfaceLanguage(); + } + } + + return LOGIN_RESULT_OK; + } + else { + $pending_template = $this->Application->GetVar('pending_disabled_template'); + + if ($pending_template !== false && !$dry_run) { + // when user found, but it's not yet approved redirect hit to notification template + $this->event->redirect = $pending_template; + } + else { + // when no notification template given return an error + return LOGIN_RESULT_INVALID_PASSWORD; + } + } + } + + if (!$dry_run) { + $this->event->SetRedirectParam('pass', 'all'); +// $this->event->SetRedirectParam('pass_category', 1); // to test + } + + return LOGIN_RESULT_INVALID_PASSWORD; + } + + /** + * Login username by it's PortalUserId + * + * @param int $user_id + * @param bool $remember_login_cookie + */ + function loginUserById($user_id, $remember_login_cookie = false) + { + $object =& $this->getUserObject(); + + $this->Application->StoreVar('user_id', $user_id); + $this->Application->SetVar('u.current_id', $user_id); + $this->Application->Session->SetField('PortalUserId', $user_id); + + if ($user_id != USER_ROOT) { + $groups = $this->Application->RecallVar('UserGroups'); + $this->Application->Session->SetField('GroupId', reset( explode(',', $groups) )); + $this->Application->Session->SetField('GroupList', $groups); + } + + $this->Application->LoadPersistentVars(); + + if (!$remember_login_cookie) { + // don't change last login time when auto-login is used + $this_login = (int)$this->Application->RecallPersistentVar('ThisLogin'); + $this->Application->StorePersistentVar('LastLogin', $this_login); + $this->Application->StorePersistentVar('ThisLogin', adodb_mktime()); + } + + $this->Application->HandleEvent($dummy, 'u:OnAfterLogin'); + } + + /** + * Checks login permission + * + * @return bool + */ + function checkLoginPermission() + { + $object =& $this->getUserObject(); + + $groups = $object->getMembershipGroups(true); + if (!$groups) { + $groups = Array(); + } + + // store groups, because kApplication::CheckPermission will use them! + array_push($groups, $this->Application->ConfigValue('User_LoggedInGroup') ); + $this->Application->StoreVar( 'UserGroups', implode(',', $groups), true ); // true for optional + + return $this->Application->CheckPermission($this->Application->isAdmin ? 'ADMIN' : 'LOGIN', 1); + } + + /** + * Performs user logout + * + */ + function logoutUser() + { + if (!isset($this->event)) { + $this->event = new kEvent('u:OnLogout'); + } + + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager->performAction('LogoutUser'); + + $this->Application->HandleEvent($dummy, 'u:OnBeforeLogout'); + + $user_id = USER_GUEST; + $this->Application->SetVar('u.current_id', $user_id); + $object =& $this->Application->recallObject('u.current', null, Array('skip_autoload' => true)); + $object->Load($user_id); + + $this->Application->DestroySession(); + + $this->Application->StoreVar('user_id', $user_id, true); + $this->Application->Session->SetField('PortalUserId', $user_id); + + $group_list = $this->Application->ConfigValue('User_GuestGroup') . ',' . $this->Application->ConfigValue('User_LoggedInGroup'); + $this->Application->StoreVar('UserGroups', $group_list, true); + $this->Application->Session->SetField('GroupList', $group_list); + + if ($this->Application->ConfigValue('UseJSRedirect')) { + $this->event->SetRedirectParam('js_redirect', 1); + } + + $this->Application->resetCounters('UserSession'); + $this->Application->Session->SetCookie('remember_login', '', strtotime('-1 hour')); + + $this->event->SetRedirectParam('pass', 'all'); + } + + /** + * Returns user id based on given criteria + * + * @param string $username + * @param string $password + * @param string $remember_login_cookie + * @return int + */ + function getUserId($username, $password, $remember_login_cookie) + { + $password = md5($password); + + if ($remember_login_cookie) { + list ($username, $password) = explode('|', $remember_login_cookie); // 0 - username, 1 - md5(password) + } + + $sql = 'SELECT PortalUserId + FROM ' . TABLE_PREFIX . 'PortalUser + WHERE (Email = %1$s OR Login = %1$s) AND (Password = %2$s)'; + return $this->Conn->GetOne( sprintf($sql, $this->Conn->qstr($username), $this->Conn->qstr($password) ) ); + } + + /** + * Process all required data and redirect logged-in user + * + * @param string $username + * @param string $password + */ + function _processLoginRedirect($username, $password) + { + // set next template + $next_template = $this->Application->GetVar('next_template'); + + if ($next_template) { + $this->event->redirect = $next_template; + } + + // process IIS redirect + if ($this->Application->ConfigValue('UseJSRedirect')) { + $this->event->SetRedirectParam('js_redirect', 1); + } + + // syncronize login + $sync_manager =& $this->Application->recallObjectP('UsersSyncronizeManager', null, Array(), 'InPortalSyncronize'); + $sync_manager->performAction('LoginUser', $username, $password); + } + + /** + * Sets correct interface language after sucessful login, based on user settings + * + * @param kEvent $event + */ + function _processInterfaceLanguage() + { + if (!$this->Application->isAdmin) { + return ; + } + + $is_root = $this->Application->RecallVar('user_id') == USER_ROOT; + + $object =& $this->getUserObject(); + + $user_language_id = $is_root ? $this->Application->RecallPersistentVar('AdminLanguage') : $object->GetDBField('AdminLanguage'); + + $sql = 'SELECT LanguageId, IF(LanguageId = ' . (int)$user_language_id . ', 2, AdminInterfaceLang) AS SortKey + FROM ' . TABLE_PREFIX . 'Language + WHERE Enabled = 1 + HAVING SortKey <> 0 + ORDER BY SortKey DESC'; + $language_info = $this->Conn->GetRow($sql); + $language_id = $language_info && $language_info['LanguageId'] ? $language_info['LanguageId'] : $user_language_id; + + if ($user_language_id != $language_id) { + // first admin login OR language was delelted or disabled + if ($is_root) { + $this->Application->StorePersistentVar('AdminLanguage', $language_id); + } + else { + $object->SetDBField('AdminLanguage', $language_id); + $object->Update(); + } + } + + $this->event->SetRedirectParam('m_lang', $language_id); // data + $this->Application->Session->SetField('Language', $language_id); // interface + } + + /** + * Checks that user is allowed to use super admin mode + * + * @return bool + */ + function verifySuperAdmin() + { + $sa_mode = ipMatch(defined('SA_IP') ? SA_IP : ''); + return $sa_mode || $this->Application->isDebugMode(); + } + + /** + * Returns user object, used during login processings + * + * @return UsersItem + */ + function &getUserObject() + { + $prefix_special = $this->Application->isAdmin ? 'u.current' : 'u'; // "u" used on front not to change theme + $object =& $this->Application->recallObject($prefix_special, null, Array('skip_autoload' => true)); + + return $object; + } + + /** + * Checks, if given user fields matches at least one of defined ban rules + * + * @param kDBItem $object + * @return bool + */ + function checkBanRules(&$object) + { + $table = $this->Application->getUnitOption('ban-rule', 'TableName'); + + if (!$this->Conn->TableFound($table)) { + // when ban table not found -> assume user is ok by default + return true; + } + + $sql = 'SELECT * + FROM ' . $table . ' + WHERE ItemType = 6 AND Status = ' . STATUS_ACTIVE . ' + ORDER BY Priority DESC'; + $rules = $this->Conn->Query($sql); + + $found = false; + + foreach ($rules as $rule) { + $field = $rule['ItemField']; + $this_value = mb_strtolower( $object->GetDBField($field) ); + $test_value = mb_strtolower( $rule['ItemValue'] ); + + switch ( $rule['ItemVerb'] ) { + case 1: // is + if ($this_value == $test_value) { + $found = true; + } + break; + + case 2: // is not + if ($this_value != $test_value) { + $found = true; + } + break; + + case 3: // contains + if ( strstr($this_value, $test_value) ) { + $found = true; + } + break; + + case 4: // not contains + if ( !strstr($this_value, $test_value) ) { + $found = true; + } + break; + + case 7: // exists + if ( strlen($this_value) > 0 ) { + $found = true; + } + break; + + case 8: // unique + if ( $this->_checkValueExist($field, $this_value) ) { + $found = true; + } + break; + } + + if ( $found ) { + // check ban rules, until one of them matches + + if ( $rule['RuleType'] ) { + // invert rule type + $found = false; + } + + break; + } + } + + return !$found; + } + + /** + * Checks if value is unique in Users table against the specified field + * + * @param string $field + * @param string $value + * @return string + */ + function _checkValueExist($field, $value) + { + $sql = 'SELECT * + FROM ' . $this->Application->getUnitOption('u', 'TableName') . ' + WHERE '. $field .' = ' . $this->Conn->qstr($value); + + return $this->Conn->GetOne($sql); + } + }