/**
  * 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
 /**
  * An AJAX called function which will return HTML containing a full history
  * of a particular session, from login to logout.
  * @param $id The ID of the session
  */
 public function actionViewSessionHistory($id)
 {
     $sessions = X2Model::model('SessionLog')->findAllByAttributes(array('sessionId' => $id));
     $firstTimestamp = 0;
     $lastTimestamp = 0;
     $str = "<table class='items'><thead><tr><th>User</th><th>Status</th><th>Timestamp</th></tr></thead>";
     foreach ($sessions as $session) {
         $str .= "<tr>";
         $str .= "<td>" . User::getUserLinks($session->user) . "</td>";
         $str .= "<td>" . SessionLog::parseStatus($session->status) . "</td>";
         $str .= "<td>" . Formatter::formatCompleteDate($session->timestamp) . "</td>";
         $str .= "</tr>";
     }
     $str .= "</table>";
     echo $str;
 }
 /**
  * Load dynamic app configuration.
  *
  * Per the onBeginRequest key in the array returned by {@link events()},
  * this method will be called when the request has begun. It allows for
  * many extra configuration tasks to be run on a per-request basis
  * without having to extend {@link Yii} and override its methods.
  */
 public function beginRequest()
 {
     // About the "noSession" property/variable:
     //
     // This variable, if true, indicates that the application is running in
     // the context of either an API call or a console command, in which case
     // there would not be the typical authenticated user and session
     // variables one would need in a web request
     //
     // It's necessary because originally this method was written with
     // absolutely no regard for compatibility with the API or Yii console,
     // and thus certain lines of code that make references to the usual web
     // environment with cookie-based authentication (which would fail in
     // those cases) needed to be kept inside of conditional statements that
     // are skipped over if in the console/API.
     $this->owner->params->noSession = $this->owner->params->noSession || strpos($this->owner->request->getPathInfo(), 'api/') === 0 || strpos($this->owner->request->getPathInfo(), 'api2/') === 0;
     $noSession = $this->owner->params->noSession;
     if (!$noSession) {
         if ($this->owner->request->getPathInfo() == 'notifications/get') {
             // skip all the loading if this is a chat/notification update
             Yii::import('application.components.util.AuxLib');
             Yii::import('application.models.Roles');
             Yii::import('application.components.X2AuthManager');
             Yii::import('application.components.X2Html');
             Yii::import('application.components.X2WebUser');
             Yii::import('application.components.sortableWidget.*');
             Yii::import('application.components.sortableWidget.profileWidgets.*');
             Yii::import('application.components.sortableWidget.recordViewWidgets.*');
             Yii::import('application.components.X2Settings.*');
             Yii::import('application.components.X2MessageSource');
             Yii::import('application.components.Formatter');
             Yii::import('application.components.X2Html');
             Yii::import('application.components.JSONEmbeddedModelFieldsBehavior');
             Yii::import('application.components.TransformedFieldStorageBehavior');
             Yii::import('application.components.EncryptedFieldsBehavior');
             Yii::import('application.components.permissions.*');
             Yii::import('application.models.Modules');
             if (!$this->owner->user->getIsGuest()) {
                 $profData = $this->owner->db->createCommand()->select('timeZone, language')->from('x2_profile')->where('id=' . $this->owner->user->getId())->queryRow();
             }
             // set the timezone to the admin's
             if (isset($profData)) {
                 if (isset($profData['timeZone'])) {
                     $timezone = $profData['timeZone'];
                 }
                 if (isset($profData['language'])) {
                     $language = $profData['language'];
                 } else {
                 }
             }
             if (!isset($timezone)) {
                 $timezone = 'UTC';
             }
             if (!isset($language)) {
                 $language = 'en';
             }
             date_default_timezone_set($timezone);
             $this->owner->language = $language;
             Yii::import('application.models.X2Model');
             Yii::import('application.models.Dropdowns');
             Yii::import('application.models.Admin');
             $this->cryptInit();
             // Yii::import('application.models.*');
             // foreach(scandir('protected/modules') as $module){
             // if(file_exists('protected/modules/'.$module.'/register.php'))
             // Yii::import('application.modules.'.$module.'.models.*');
             // }
             return;
         }
     } else {
         Yii::import('application.models.Profile');
         Yii::import('application.components.sortableWidget.*');
         Yii::import('application.components.X2Settings.*');
         Yii::import('application.components.TransformedFieldStorageBehavior');
         // Set time zone based on the default value
         date_default_timezone_set(Profile::model()->tableSchema->getColumn('timeZone')->defaultValue);
     }
     $this->importDirectories();
     $this->cryptInit();
     if (YII_DEBUG) {
         $this->owner->params->timer = new TimerUtil();
     }
     $this->owner->messages->onMissingTranslation = array(new TranslationLogger(), 'log');
     // Set profile
     //
     // Get the Administrator's and the current user's profile.
     $adminProf = Profile::model()->findByPk(1);
     $this->owner->params->adminProfile = $adminProf;
     if (!$noSession) {
         // Typical web session:
         $notGuest = !$this->owner->user->getIsGuest();
         if ($notGuest) {
             $this->owner->params->profile = X2Model::model('Profile')->findByAttributes(array('username' => $this->owner->user->getName()));
             $this->setSuModel($this->owner->params->profile->user);
         } else {
             $this->owner->params->profile = Profile::model()->getGuestProfile();
         }
     } else {
         // Use the admin profile as the user profile.
         //
         // If a different profile is desired in an API call or console
         // command, a different profile should be loaded.
         //
         // Using "admin" as the default profile should not affect
         // permissions (that's what the "suModel" property is for). It is
         // merely to account for cases where there is a reference to the
         // "profile" property of some model or component class that would
         // break the application outside the scope of a web request with a
         // session and cookie-based authentication.
         $notGuest = false;
         $this->owner->params->profile = $adminProf;
         $userModel = $this->owner->params->profile->user;
         $this->setSuModel($userModel instanceof User ? $userModel : User::model()->findByPk(1));
     }
     // Set session variables
     if (!$noSession) {
         $sessionId = isset($_SESSION['sessionId']) ? $_SESSION['sessionId'] : session_id();
         $session = X2Model::model('Session')->findByPk($sessionId);
         if (!empty($this->owner->params->profile)) {
             $_SESSION['fullscreen'] = $this->owner->params->profile->fullscreen;
         }
         if (!($this->owner->request->getPathInfo() == 'site/getEvents')) {
             if ($notGuest) {
                 $this->owner->user->setReturnUrl($this->owner->request->requestUri);
                 if ($session != null) {
                     $timeout = Roles::getUserTimeout($this->owner->user->getId());
                     if ($session->lastUpdated + $timeout < time()) {
                         SessionLog::logSession($this->owner->user->getName(), $sessionId, 'activeTimeout');
                         $session->delete();
                         $this->owner->user->logout(false);
                         $this->_suModel = null;
                         $this->_suID = null;
                         $this->setUserAccessParameters(null);
                     } else {
                         // Print a warning message
                         if ($this->owner->session['debugEmailWarning']) {
                             $this->owner->session['debugEmailWarning'] = 0;
                             $this->owner->user->setFlash('admin.debugEmailMode', Yii::t('app', 'Note, email debugging mode ' . 'is enabled. Emails will not ' . 'actually be delivered.'));
                         }
                         $session->lastUpdated = time();
                         $session->update(array('lastUpdated'));
                         $this->owner->params->sessionStatus = $session->status;
                     }
                 } else {
                     $this->owner->user->logout(false);
                 }
             } else {
                 // Guest
                 $this->setUserAccessParameters(null);
             }
         }
     }
     // Configure logos
     if (!($logo = $this->owner->cache['x2Power'])) {
         $logo = 'data:image/png;base64,' . base64_encode(file_get_contents(implode(DIRECTORY_SEPARATOR, array(Yii::app()->basePath, '..', 'images', 'powered_by_x2engine.png'))));
         $this->owner->cache['x2Power'] = $logo;
     }
     $this->owner->params->x2Power = $logo;
     $logo = Media::model()->findByAttributes(array('associationId' => 1, 'associationType' => 'logo'));
     if (isset($logo)) {
         $this->owner->params->logo = $logo->fileName;
     }
     // Set currency and load currency symbols
     $this->owner->params->currency = $this->settings->currency;
     $locale = $this->owner->locale;
     $curSyms = array();
     foreach ($this->owner->params->supportedCurrencies as $curCode) {
         $curSyms[$curCode] = $locale->getCurrencySymbol($curCode);
     }
     $this->owner->params->supportedCurrencySymbols = $curSyms;
     // Code to symbol
     // Set language
     if (!empty($this->owner->params->profile->language)) {
         $this->owner->language = $this->owner->params->profile->language;
     } else {
         if (isset($adminProf)) {
             $this->owner->language = $adminProf->language;
         }
     }
     // Set timezone
     if (!empty($this->owner->params->profile->timeZone)) {
         date_default_timezone_set($this->owner->params->profile->timeZone);
     } elseif (!empty($adminProf->timeZone)) {
         date_default_timezone_set($adminProf->timeZone);
     } else {
         date_default_timezone_set('UTC');
     }
     setlocale(LC_ALL, 'en_US.UTF-8');
     // Set base path and theme path globals for JS (web UI only)
     if (!$noSession) {
         $this->checkForMobileDevice();
         $this->checkResponsiveLayout();
         if ($notGuest) {
             $profile = $this->owner->params->profile;
             if (isset($profile)) {
                 $yiiString = $this->getJSGlobalsSetupScript($profile);
             } else {
                 $yiiString = $this->getJSGlobalsSetupScript();
             }
             if (!$this->owner->request->isAjaxRequest) {
                 Yii::app()->clientScript->registerScript(sprintf('%x', crc32(Yii::app()->name)), base64_decode('dmFyIF8weDFhNzk9WyJceDc1XHg2RVx4NjRceDY1XHg2Nlx4NjlceDZFXHg2NVx4NjQiLCJceDZDXHg2R' . 'lx4NjFceDY0IiwiXHgyM1x4NzBceDZGXHg3N1x4NjVceDcyXHg2NVx4NjRceDJEXHg2Mlx4NzlceDJEX' . 'Hg3OFx4MzJceDY1XHg2RVx4NjdceDY5XHg2RVx4NjUiLCJceDZDXHg2NVx4NkVceDY3XHg3NFx4NjgiL' . 'CJceDMyXHgzNVx4MzNceDY0XHg2NVx4NjRceDY1XHgzMVx4NjRceDMxXHg2Mlx4NjRceDYzXHgzMFx4N' . 'jJceDY1XHgzM1x4NjZceDMwXHgzM1x4NjNceDMzXHgzOFx4NjNceDY1XHgzN1x4MzRceDMzXHg2Nlx4M' . 'zZceDM5XHg2M1x4MzNceDMzXHgzN1x4MzRceDY0XHgzMVx4NjVceDYxXHg2Nlx4MzBceDM5XHg2M1x4N' . 'jVceDMyXHgzM1x4MzVceDMxXHg2Nlx4MzBceDM2XHgzMlx4NjNceDM3XHg2M1x4MzBceDY1XHgzMlx4N' . 'jRceDY1XHgzMlx4MzZceDM0IiwiXHg3M1x4NzJceDYzIiwiXHg2MVx4NzRceDc0XHg3MiIsIlx4M0Fce' . 'Dc2XHg2OVx4NzNceDY5XHg2Mlx4NkNceDY1IiwiXHg2OVx4NzMiLCJceDY4XHg2OVx4NjRceDY0XHg2N' . 'Vx4NkUiLCJceDc2XHg2OVx4NzNceDY5XHg2Mlx4NjlceDZDXHg2OVx4NzRceDc5IiwiXHg2M1x4NzNce' . 'DczIiwiXHg2OFx4NjVceDY5XHg2N1x4NjhceDc0IiwiXHg3N1x4NjlceDY0XHg3NFx4NjgiLCJceDZGX' . 'Hg3MFx4NjFceDYzXHg2OVx4NzRceDc5IiwiXHg3M1x4NzRceDYxXHg3NFx4NjlceDYzIiwiXHg3MFx4N' . 'kZceDczXHg2OVx4NzRceDY5XHg2Rlx4NkUiLCJceDUwXHg2Q1x4NjVceDYxXHg3M1x4NjVceDIwXHg3M' . 'Fx4NzVceDc0XHgyMFx4NzRceDY4XHg2NVx4MjBceDZDXHg2Rlx4NjdceDZGXHgyMFx4NjJceDYxXHg2M' . '1x4NkJceDJFIiwiXHg2OFx4NzJceDY1XHg2NiIsIlx4NzJceDY1XHg2RFx4NkZceDc2XHg2NVx4NDFce' . 'Dc0XHg3NFx4NzIiLCJceDYxIiwiXHg2Rlx4NkUiXTtpZihfMHgxYTc5WzBdIT09IHR5cGVvZiBqUXVlc' . 'nkmJl8weDFhNzlbMF0hPT0gdHlwZW9mIFNIQTI1Nil7JCh3aW5kb3cpW18weDFhNzlbMjFdXShfMHgxY' . 'Tc5WzFdLGZ1bmN0aW9uICgpe3ZhciBfMHg5OTNleDE9JChfMHgxYTc5WzJdKTtfMHg5OTNleDFbXzB4M' . 'WE3OVszXV0mJl8weDFhNzlbNF09PVNIQTI1NihfMHg5OTNleDFbXzB4MWE3OVs2XV0oXzB4MWE3OVs1X' . 'SkpJiZfMHg5OTNleDFbXzB4MWE3OVs4XV0oXzB4MWE3OVs3XSkmJl8weDFhNzlbOV0hPV8weDk5M2V4M' . 'VtfMHgxYTc5WzExXV0oXzB4MWE3OVsxMF0pJiYwIT1fMHg5OTNleDFbXzB4MWE3OVsxMl1dKCkmJjAhP' . 'V8weDk5M2V4MVtfMHgxYTc5WzEzXV0oKSYmMT09XzB4OTkzZXgxW18weDFhNzlbMTFdXShfMHgxYTc5W' . 'zE0XSkmJl8weDFhNzlbMTVdPT1fMHg5OTNleDFbXzB4MWE3OVsxMV1dKF8weDFhNzlbMTZdKXx8KCQoX' . 'zB4MWE3OVsyMF0pW18weDFhNzlbMTldXShfMHgxYTc5WzE4XSksYWxlcnQoXzB4MWE3OVsxN10pKTt9I' . 'Ck7fQo='));
             }
         } else {
             $yiiString = $this->getJSGlobalsSetupScript();
         }
         $this->owner->clientScript->registerScript('setParams', $yiiString, CClientScript::POS_HEAD);
         $cs = $this->owner->clientScript;
         $baseUrl = $this->owner->request->baseUrl;
         $jsVersion = '?' . $this->owner->params->buildDate;
         /**
          * To be restored when JavaScript minification is added to the build process:
          * $cs->scriptMap=array(
          * 'backgroundImage.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * 'json2.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * 'layout.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * 'media.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * 'modernizr.custom.66175.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * 'publisher.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * //'relationships.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * 'tags.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * 'translator.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * 'widgets.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * 'x2forms.js'=>$baseUrl.'/js/all.min.js'.$jsVersion,
          * ); */
     }
 }
Example #4
0
 /**
  * Clear session records which have timed out. Log the timeout.
  */
 public static function cleanUpSessions()
 {
     // Only select users with active sessions to clear out, in case there are
     // dozens of inactive users, to make things more efficient:
     $users = Yii::app()->db->createCommand()->select('x2_users.id,x2_users.username')->from('x2_users')->rightJoin('x2_sessions', 'x2_sessions.user = x2_users.username')->where('x2_users.username IS NOT NULL AND x2_users.username != ""')->queryAll();
     foreach ($users as $user) {
         $timeout = Roles::getUserTimeout($user['id']);
         $sessions = X2Model::model('Session')->findAllByAttributes(array('user' => $user['username']), 'lastUpdated < :cutoff', array(':cutoff' => time() - $timeout));
         foreach ($sessions as $session) {
             SessionLog::logSession($session->user, $session->id, 'passiveTimeout');
             $session->delete();
         }
     }
     // check timeout on sessions not corresponding to any existing user
     $defaultTimeout = 900;
     self::model()->deleteAll(array('condition' => 'lastUpdated < :cutoff and 
                 user not in (select distinct (username) from x2_users)', 'params' => array(':cutoff' => time() - $defaultTimeout)));
 }
Example #5
0
 public function actionToggleVisibility()
 {
     $id = $_SESSION['sessionId'];
     $session = Session::model()->findByAttributes(array('id' => $id));
     if (isset($session)) {
         if ($session->status < 0) {
             $session->status = 0;
         }
         $session->status = !$session->status;
         $session->save();
         SessionLog::logSession(Yii::app()->user->getName(), $id, $session->status ? "visible" : "invisible");
     }
     $this->redirect($_GET['redirect']);
 }
 public function actionPushSessionLogEnd()
 {
     $student_id = Yii::app()->request->getPost("student_id", NULL);
     $session_id = Yii::app()->request->getPost("session_id", NULL);
     $session_end_time = Yii::app()->request->getPost("session_end_time", NULL);
     $session = SessionLog::model()->find('student_id=:student_id AND session_id=:session_id', array(':student_id' => $student_id, ':session_id' => $session_id));
     if ($session) {
         $session->session_end_time = $session_end_time;
         if (!$session->save()) {
             $this->renderJSON($session->getErrors());
         } else {
             $this->renderJSON(array('status' => 1, 'message' => 'Successfully saved!'));
         }
     } else {
         $this->renderJSON(array('status' => 0, 'message' => 'Given Questionnaire could not be found!'));
     }
 }
Example #7
0
 public static function logSession($user, $sessionId, $status)
 {
     $sessionLog = Yii::app()->db->createCommand()->select('sessionLog')->from('x2_admin')->where('id=1')->queryScalar();
     if ($sessionLog) {
         $model = new SessionLog();
         $model->user = $user;
         $model->sessionId = $sessionId;
         $model->status = $status;
         $model->timestamp = time();
         $model->save();
     }
 }
Example #8
0
 /**
  * Logs out the current user and redirect to homepage.
  */
 public function actionLogout()
 {
     $user = User::model()->findByPk(Yii::app()->user->getId());
     if (isset($user)) {
         $user->lastLogin = time();
         $user->save();
         if (isset($_SESSION['sessionId'])) {
             SessionLog::logSession($user->username, $_SESSION['sessionId'], 'logout');
             X2Model::model('Session')->deleteByPk($_SESSION['sessionId']);
         } else {
             X2Model::model('Session')->deleteAllByAttributes(array('IP' => $this->getRealIp()));
         }
     }
     if (isset($_SESSION['access_token'])) {
         unset($_SESSION['access_token']);
     }
     $this->redirect($this->createAbsoluteUrl('login'));
 }
 protected function getSessionLogs($student_id)
 {
     $session_logs = SessionLog::model()->findAll('student_id=:student_id AND (session_end_time!=NULL or session_end_time!="")', array(':student_id' => $student_id));
     return $session_logs;
 }