/** * Displays the login page * @param object $formModel * @param bool $isMobile Whether this was called from mobile site controller */ public function login(LoginForm $model, $isMobile = false) { $model->attributes = $_POST['LoginForm']; // get user input data Session::cleanUpSessions(); $ip = $this->owner->getRealIp(); $userModel = $model->getUser(); $isRealUser = $userModel instanceof User; $effectiveUsername = $isRealUser ? $userModel->username : $model->username; $isActiveUser = $isRealUser && $userModel->status == User::STATUS_ACTIVE; /* increment count on every session with this user/IP, to prevent brute force attacks using session_id spoofing or whatever */ Yii::app()->db->createCommand('UPDATE x2_sessions SET status=status-1,lastUpdated=:time WHERE user=:name AND CAST(IP AS CHAR)=:ip AND status BETWEEN -2 AND 0')->bindValues(array(':time' => time(), ':name' => $effectiveUsername, ':ip' => $ip))->execute(); $activeUser = Yii::app()->db->createCommand()->select('username')->from('x2_users')->where('username=:name AND status=1', array(':name' => $model->username))->limit(1)->queryScalar(); // get the correctly capitalized username if (isset($_SESSION['sessionId'])) { $sessionId = $_SESSION['sessionId']; } else { $sessionId = $_SESSION['sessionId'] = session_id(); } $session = X2Model::model('Session')->findByPk($sessionId); /* get the number of failed login attempts from this IP within timeout interval. If the number of login attempts exceeds maximum, display captcha */ $badAttemptsRefreshTimeout = 900; $maxFailedLoginAttemptsPerIP = 100; $maxLoginsBeforeCaptcha = 5; $this->pruneTimedOutBans($badAttemptsRefreshTimeout); $failedLoginRecord = FailedLogins::model()->findActiveByIp($ip); $badAttemptsWithThisIp = $failedLoginRecord ? $failedLoginRecord->attempts : 0; if ($badAttemptsWithThisIp >= $maxFailedLoginAttemptsPerIP) { $this->recordFailedLogin($ip); throw new CHttpException(403, Yii::t('app', 'You are not authorized to use this application')); } // if this client has already tried to log in, increment their attempt count if ($session === null) { $session = new Session(); $session->id = $sessionId; $session->user = $model->getSessionUserName(); $session->lastUpdated = time(); $session->status = 0; $session->IP = $ip; } else { $session->lastUpdated = time(); $session->user = $model->getSessionUserName(); } if ($isActiveUser === false) { $model->verifyCode = ''; // clear captcha code $model->validate(); // validate captcha if it's being used $this->recordFailedLogin($ip); $session->save(); if ($badAttemptsWithThisIp + 1 >= $maxFailedLoginAttemptsPerIP) { throw new CHttpException(403, Yii::t('app', 'You are not authorized to use this application')); } else { if ($badAttemptsWithThisIp >= $maxLoginsBeforeCaptcha - 1) { $model->useCaptcha = true; $model->setScenario('loginWithCaptcha'); $session->status = -2; } } } else { if ($model->validate() && $model->login()) { // user successfully logged in if ($model->rememberMe) { foreach (array('username', 'rememberMe') as $attr) { // Expires in 30 days AuxLib::setCookie(CHtml::resolveName($model, $attr), $model->{$attr}, 2592000); } } else { foreach (array('username', 'rememberMe') as $attr) { // Remove the cookie if they unchecked the box AuxLib::clearCookie(CHtml::resolveName($model, $attr)); } } // We're not using the isAdmin parameter of the application // here because isAdmin in this context hasn't been set yet. $isAdmin = Yii::app()->user->checkAccess('AdminIndex'); if ($isAdmin && !$isMobile) { $this->owner->attachBehavior('updaterBehavior', new UpdaterBehavior()); $this->owner->checkUpdates(); // check for updates if admin } else { Yii::app()->session['versionCheck'] = true; } // ...or don't $session->status = 1; $session->save(); SessionLog::logSession($model->username, $sessionId, 'login'); $_SESSION['playLoginSound'] = true; if (YII_UNIT_TESTING && defined('X2_DEBUG_EMAIL') && X2_DEBUG_EMAIL) { Yii::app()->session['debugEmailWarning'] = 1; } // if ( isset($_POST['themeName']) ) { // $profile = X2Model::model('Profile')->findByPk(Yii::app()->user->id); // $profile->theme = array_merge( // $profile->theme, // ThemeGenerator::loadDefault( $_POST['themeName']) // ); // $profile->save(); // } LoginThemeHelper::login(); if ($isMobile) { $this->owner->redirect($this->owner->createUrl('/mobile/home')); } else { if (Yii::app()->user->returnUrl == '/site/index') { $this->owner->redirect(array('/site/index')); } else { // after login, redirect to wherever $this->owner->redirect(Yii::app()->user->returnUrl); } } } else { // login failed $model->verifyCode = ''; // clear captcha code $this->recordFailedLogin($ip); $session->save(); if ($badAttemptsWithThisIp + 1 >= $maxFailedLoginAttemptsPerIP) { throw new CHttpException(403, Yii::t('app', 'You are not authorized to use this application')); } else { if ($badAttemptsWithThisIp >= $maxLoginsBeforeCaptcha - 1) { $model->useCaptcha = true; $model->setScenario('loginWithCaptcha'); $session->status = -2; } } } } $model->rememberMe = false; }
public function testCleanUpSessions() { Yii::app()->cache->flush(); // Prepare expected data: $sessionCounts = array('session1' => 1, 'session2' => 1, 'session3' => 0); foreach (array_keys($sessionCounts) as $alias) { $sessionIds[$alias] = $this->session($alias)->id; } $defaultTimeout = 60; Yii::app()->settings->timeout = $defaultTimeout; Session::cleanUpSessions(); // Session 1 shoud still be there // Sessions 2 and 3 should be gone foreach ($sessionCounts as $alias => $count) { $this->assertEquals((int) $count, Session::model()->countByAttributes(array('id' => $sessionIds[$alias])), "{$alias} did not get deleted"); } }
public function run() { Session::cleanUpSessions(); // $criteria = new CDbCriteria(array('condition'=>'','distinct'=>true) // $sessions = Session::model()->findAll($criteria); // $str = ""; // foreach($sessions as $session) { // if(time()-$session->lastUpdated<(15*60)) { // $str.=$session->user.", "; // } // } // if($str!="") { // $str=substr($str,0,-2); // } $onlineUsers = User::getUserLinks(Session::getOnlineUsers()); $this->render('onlineUsers', array('users' => $onlineUsers)); //array( }
/** * Obtains lead routing rules. * @param type $data * @return type */ public function getRoutingRules($data) { $admin =& Yii::app()->settings; $online = $admin->onlineOnly; Session::cleanUpSessions(); $sessions = Session::getOnlineUsers(); $criteria = new CDbCriteria(); $criteria->order = "priority ASC"; $rules = X2Model::model('LeadRouting')->findAll($criteria); foreach ($rules as $rule) { $arr = LeadRouting::parseCriteria($rule->criteria); $flagArr = array(); foreach ($arr as $criteria) { if (isset($data[$criteria['field']])) { $val = $data[$criteria['field']]; $operator = $criteria['comparison']; $target = $criteria['value']; if ($operator != 'contains') { switch ($operator) { case '>': $flag = $val >= $target; break; case '<': $flag = $val <= $target; break; case '=': $flag = $val == $target; break; case '!=': $flag = $val != $target; break; default: $flag = false; } } else { $flag = preg_match("/{$target}/i", $val) != 0; } $flagArr[] = $flag; } } if (!in_array(false, $flagArr) && count($flagArr) > 0) { $users = $rule->users; $users = explode(", ", $users); if (is_null($rule->groupType)) { if ($online == 1) { $users = array_intersect($users, $sessions); } } else { $groups = $rule->users; $groups = explode(", ", $groups); $users = array(); foreach ($groups as $group) { if ($rule->groupType == self::WITHIN_GROUPS) { $links = GroupToUser::model()->findAllByAttributes(array('groupId' => $group)); foreach ($links as $link) { $usernames[] = User::model()->findByPk($link->userId)->username; } } else { // $rule->groupType == self::BETWEEN_GROUPS $users[] = $group; } } if ($online == 1 && $rule->groupType == self::WITHIN_GROUPS) { foreach ($usernames as $user) { if (in_array($user, $sessions)) { $users[] = $user; } } } elseif ($rule->groupType == self::WITHIN_GROUPS) { $users = $usernames; } } if ($rule->groupType == self::WITHIN_GROUPS) { $users = array_values(array_intersect(Profile::model()->getUsernamesOfAvailableUsers(), $users)); } $users[] = $rule->rrId; $rule->rrId++; $rule->save(); return $users; } } }
/** * Log in using a Google account. */ public function actionGoogleLogin() { $this->layout = '//layouts/login'; $model = new LoginForm(); $model->useCaptcha = false; // echo var_dump(Session::getOnlineUsers()); if (Yii::app()->user->isInitialized && !Yii::app()->user->isGuest) { $this->redirect(Yii::app()->homeUrl); return; } require_once 'protected/components/GoogleAuthenticator.php'; $auth = new GoogleAuthenticator(); if (Yii::app()->settings->googleIntegration && ($token = $auth->getAccessToken())) { try { $user = $auth->getUserInfo($token); $email = filter_var($user->email, FILTER_SANITIZE_EMAIL); $profileRecord = X2Model::model('Profile')->findByAttributes(array('googleId' => $email)); if (!isset($profileRecord)) { $userRecord = X2Model::model('User')->findByAttributes(array('emailAddress' => $email)); $profileRecord = X2Model::model('Profile')->findByAttributes(array(), "emailAddress=:email OR googleId=:email", array(':email' => $email)); } if (isset($userRecord) || isset($profileRecord)) { if (!isset($profileRecord)) { $profileRecord = X2Model::model('Profile')->findByPk($userRecord->id); } $auth->storeCredentials($profileRecord->id, $_SESSION['access_token']); } if (isset($userRecord) || isset($profileRecord)) { if (!isset($userRecord)) { $userRecord = User::model()->findByPk($profileRecord->id); } $username = $userRecord->username; $password = $userRecord->password; $model->username = $username; $model->password = $password; if ($model->login(true)) { $ip = $this->getRealIp(); Session::cleanUpSessions(); if (isset($_SESSION['sessionId'])) { $sessionId = $_SESSION['sessionId']; } else { $sessionId = $_SESSION['sessionId'] = session_id(); } $session = X2Model::model('Session')->findByPk($sessionId); // if this client has already tried to log in, increment their attempt count if ($session === null) { $session = new Session(); $session->id = $sessionId; $session->user = $model->getSessionUsername(); $session->lastUpdated = time(); $session->status = 1; $session->IP = $ip; } else { $session->lastUpdated = time(); } // x2base::cleanUpSessions(); // $session = X2Model::model('Session')->findByAttributes(array('user'=>$userRecord->username,'IP'=>$ip)); // if(isset($session)) { // $session->lastUpdated = time(); // } else { // $session = new Session; // $session->user = $model->username; // $session->lastUpdated = time(); // $session->status = 1; // $session->IP = $ip; // } $session->save(); SessionLog::logSession($userRecord->username, $sessionId, 'googleLogin'); $userRecord->login = time(); $userRecord->save(); Yii::app()->session['versionCheck'] = true; Yii::app()->session['loginTime'] = time(); $session->status = 1; if (Yii::app()->user->returnUrl == 'site/index') { $this->redirect(array('/site/index')); } else { $this->redirect(Yii::app()->user->returnUrl); } } } else { $this->render('googleLogin', array('failure' => 'email', 'email' => $email)); } } catch (Google_AuthException $e) { $auth->flushCredentials(); $auth->setErrors($e->getMessage()); $this->render('googleLogin', array('failure' => $auth->getErrors())); } catch (NoUserIdException $e) { $auth->flushCredentials(); $auth->setErrors($e->getMessage()); $this->render('googleLogin', array('failure' => $auth->getErrors())); } } else { $this->render('googleLogin'); } }
/** * Picks the next assignee in a round-robin manner. * * Users get a chance to be picked in this manner only if online. In the * round-robin distribution of leads, the last person who was picked for * a lead assignment is stored using {@link updateRoundRobin()}. If no * one is online, the lead will be assigned to "Anyone". * @return mixed */ public function roundRobin() { $admin =& Yii::app()->settings; $online = $admin->serviceOnlineOnly; Session::cleanUpSessions(); $usernames = array(); $sessions = Session::getOnlineUsers(); $users = X2Model::model('User')->findAll(); foreach ($users as $userRecord) { //exclude admin from candidates if ($userRecord->username != 'admin' && $userRecord->username != 'api') { $usernames[] = $userRecord->username; } } if ($online == 1) { $userList = array(); foreach ($usernames as $user) { if (in_array($user, $sessions)) { $userList[] = $user; } } } else { $userList = $usernames; } $srrId = $this->getRoundRobin(); if (count($userList) > 0) { $i = $srrId % count($userList); $this->updateRoundRobin(); return $userList[$i]; } else { return "Anyone"; } }
public function actionOnline() { Session::cleanUpSessions(); $sessions = Session::model()->findAll(); $usernames = array(); $users = array(); foreach ($sessions as $session) { $usernames[] = $session->user; } $usernames = array_unique($usernames); foreach ($usernames as $username) { $user = User::model()->findByAttributes(array('username' => $username)); $users[] = $user->firstName . " " . $user->lastName; } sort($users); $this->render('online', array('users' => $users)); }