/**
  * 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;
 }
Example #2
0
 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");
     }
 }
Example #3
0
 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(
 }
Example #4
0
 /**
  * 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;
         }
     }
 }
Example #5
0
 /**
  * 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');
     }
 }
Example #6
0
 /**
  * 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";
     }
 }
Example #7
0
 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));
 }