public function testGetUserTimeout() { $this->assertTrue(Yii::app()->cache->flush()); $defaultTimeout = 60; Yii::app()->settings->timeout = $defaultTimeout; // admin's timeout should be the big one based on role $this->assertEquals($this->role('longTimeout')->timeout, Roles::getUserTimeout($this->user('admin')->id, false)); // testuser's timeout should also be the big one, and not the "Peon" // role's timeout length $this->assertEquals($this->role('longTimeout')->timeout, Roles::getUserTimeout($this->user('testUser')->id, false)); // testuser2's timeout should be the "Peon" role's timeout length // because that user has that role, and that role has a timeout longer // than the default timeout $this->assertEquals($this->role('shortTimeout')->timeout, Roles::getUserTimeout($this->user('testUser2')->id, false)); // testuser3 should have no role. Here, let's ensure that in case the // fixtures have been modified otherwise RoleToUser::model()->deleteAllByAttributes(array('userId' => $this->user('testUser3')->id)); $this->assertEquals($defaultTimeout, Roles::getUserTimeout($this->user('testUser3')->id, false)); }
/** * 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))); }
/** * 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, * ); */ } }