/** * Retrieves roles for the user */ public function getRoles() { if (!isset($this->_roles)) { $this->_roles = Roles::getUserRoles($this->getId()); } return $this->_roles; }
/** * Getter for {@link fieldPermissions} * @return type */ public function getFieldPermissions() { $class = get_class($this); if (!isset(self::$_fieldPermissions[$class])) { $roles = Roles::getUserRoles(Yii::app()->getSuId()); if (!$this->isExemptFromFieldLevelPermissions) { $permRecords = Yii::app()->db->createCommand()->select("f.fieldName,MAX(rtp.permission),f.readOnly")->from(RoleToPermission::model()->tableName() . ' rtp')->join(Fields::model()->tableName() . ' f', 'rtp.fieldId=f.id ' . 'AND rtp.roleId IN ' . AuxLib::arrToStrList($roles) . ' ' . 'AND f.modelName=:class', array(':class' => $class))->group('f.fieldName')->queryAll(false); } else { $permRecords = Yii::app()->db->createCommand()->select("fieldName,CAST(2 AS UNSIGNED INTEGER),readOnly")->from(Fields::model()->tableName() . ' f')->where('modelName=:class', array(':class' => $class))->queryAll(false); } $fieldPerms = array(); foreach ($permRecords as $record) { // If the permissions of the user on the field are "2" (write), // subtract the readOnly field $fieldPerms[$record[0]] = $record[1] - (int) ((int) $record[1] === 2 ? $record[2] : 0); } self::$_fieldPermissions[$class] = $fieldPerms; } return self::$_fieldPermissions[$class]; }
/** * Ensure that upon deletion of roleToUser records, roles update immediately * (do not use an outdated cache entry) */ public function testGetUserRoles() { $userId = $this->user['testUser']['id']; $userRoles = Roles::getUserRoles($userId); // Assert that user has roles $this->assertTrue(sizeof($userRoles) > 0); // Specifically, these (user groups only): $this->assertEquals(array(1, 2), $userRoles); // Test group-inherited user roles; fixture entry "testUser5" is a // member of a group: $userRoles = Roles::getUserRoles($this->user['testUser5']['id']); $this->assertEquals(array(3), $userRoles); // Iterate over and remove records explicitly to raise the afterDelete event $records = RoleToUser::model()->findAllByAttributes(array('userId' => $userId, 'type' => 'user')); foreach ($records as $record) { $record->delete(); } $userRoles = Roles::getUserRoles($userId); // assert that user has no roles $this->assertTrue(sizeof($userRoles) === 0); }
/** * Access check function. * * Checks access and attempts to speed up all future access checks using * caching and storage of the variable within {@link _access}. * * Note, only if parameters are empty will permissions caching or storage * in {@link _access} be effective, because parameters (i.e. the assignment * of a record based on the value of its assignedTo field) are expected to * vary. For example, in record-specific permission items checked for * multiple records. That is why $params be empty for any shortcuts to be * taken. * * @param string $itemName Name of the auth item for which access is being checked * @param integer $userId ID of the user for which to check access * @param array $params Parameters to pass to business rules * @return boolean */ public function checkAccess($itemName, $userId, $params = array()) { if (!isset($params['userId'])) { $params['userId'] = $userId; } if (!isset($this->_access)) { $this->_access = array(); } if (isset($this->_access[$userId][$itemName]) && !empty($this->_access[$userId][$itemName])) { $checkParams = $this->getCacheParams($params); if ($checkParams !== false) { $checkParams = json_encode($checkParams); // Shortcut 1: return data stored in the component's property if (isset($this->_access[$userId][$itemName][$checkParams])) { return $this->_access[$userId][$itemName][$checkParams]; } } } else { if ($this->caching) { // Shortcut 2: load the auth cache data and return if a result was found if (!isset($this->_access[$userId])) { $this->_access[$userId] = Yii::app()->authCache->loadAuthCache($userId); } if (isset($this->_access[$userId][$itemName]) && !empty($this->_access[$userId][$itemName])) { $checkParams = $this->getCacheParams($params); if ($checkParams !== false) { $checkParams = json_encode($checkParams); if (isset($this->_access[$userId][$itemName][$checkParams])) { return $this->_access[$userId][$itemName][$checkParams]; } } } } } if (!isset($this->_access[$userId])) { $this->_access[$userId] = array(); } if (!isset($this->_access[$userId][$itemName])) { $this->_access[$userId][$itemName] = array(); } // Get assignments via roles. // // In X2Engine's system, x2_auth_assignment doesn't refer to users, but // to roles. Hence, the ID of each role is sent to // parent::getAuthAssignments rather than a user ID, which would be // meaningless in light of how x2_auth_assignment stores roles. if (isset($this->_assignments[$userId])) { $assignments = $this->_assignments[$userId]; } else { $roles = Roles::getUserRoles($userId); $assignments = array(); foreach ($roles as $roleId) { $assignments = array_merge($assignments, parent::getAuthAssignments($roleId)); } $this->_assignments[$userId] = $assignments; } // Prepare the username for the session-agnostic permissions check: if (!isset($this->_usernames[$userId])) { if ($userId == Yii::app()->getSuId()) { $user = Yii::app()->getSuModel(); } else { $user = User::model()->findByPk($userId); } if ($user instanceof User) { $this->_usernames[$userId] = $user->username; } else { $this->_usernames[$userId] = 'Guest'; } } // Get whether the user has access: $hasAccess = parent::checkAccessRecursive($itemName, $userId, $params, $assignments); // Store locally. $cacheParams = $this->getCacheParams($params); if ($cacheParams !== false) { $this->_access[$userId][$itemName][json_encode($cacheParams)] = $hasAccess; // Cache if ($this->caching) { Yii::app()->authCache->addResult($userId, $itemName, $hasAccess, $cacheParams); } } return $hasAccess; }
/** * Adds parameters that are used to determine user access * @param type $userId */ private function setUserAccessParameters($userId) { $this->owner->params->groups = Groups::getUserGroups($userId); $this->owner->params->roles = Roles::getUserRoles($userId); $this->owner->params->isAdmin = $userId !== null ? $this->owner->authManager->checkAccess('AdminIndex', $userId) : false; }
/** * Returns the timeout of the current user. * * Selects and returns the maximum timeout between the timeouts of the * current user's roles and the default timeout. * @return Integer Maximum timeout value */ public static function getUserTimeout($userId, $cache = true) { $cacheVar = 'user_roles_timeout' . $userId; if ($cache === true && ($timeout = Yii::app()->cache->get($cacheVar)) !== false) { return $timeout; } $userRoles = Roles::getUserRoles($userId); $availableTimeouts = array(); foreach ($userRoles as $role) { $timeout = Yii::app()->db->createCommand()->select('timeout')->from('x2_roles')->where('id=:role', array(':role' => $role))->queryScalar(); if (!is_null($timeout)) { $availableTimeouts[] = (int) $timeout; } } $availableTimeouts[] = Yii::app()->settings->timeout; $timeout = max($availableTimeouts); if ($cache === true) { Yii::app()->cache->set($cacheVar, $timeout, 259200); } return $timeout; }
/** * Checks credentials for API access * * @param CFilterChain $filterChain */ public function filterAuthenticate($filterChain) { $haveCred = false; $this->log("Checking user record."); if (Yii::app()->request->requestType == 'POST') { $haveCred = isset($_POST['userKey']) && isset($_POST['user']); $params = $_POST; } else { $haveCred = isset($_GET['userKey']) && isset($_GET['user']); $params = $_GET; } if ($haveCred) { $this->user = User::model()->findByAttributes(array('username' => $params['user'], 'userKey' => $params['userKey'])); if ((bool) $this->user) { Yii::app()->suModel = $this->user; if (!empty($this->user->userKey)) { Yii::app()->params->groups = Groups::getUserGroups($this->user->id); Yii::app()->params->roles = Roles::getUserRoles($this->user->id); // Determine if the API user is admin (so that Yii::app()->params->isAdmin gets set properly): $roles = RoleToUser::model()->findAllByAttributes(array('userId' => $this->user->id)); $access = false; $auth = Yii::app()->authManager; foreach ($roles as $role) { $access = $access || $auth->checkAccess('AdminIndex', $role->roleId); } if ($access) { Yii::app()->params->isAdmin = true; } $filterChain->run(); } else { $this->_sendResponse(403, "User \"{$this->user->username}\" cannot use API; userKey not set."); } } else { $this->log("Authentication failed; invalid user credentials; IP = {$_SERVER['REMOTE_ADDR']}; get or post params = " . CJSON::encode($params) . ''); $this->_sendResponse(401, "Invalid user credentials."); } } else { $this->log('No user credentials provided; IP = ' . $_SERVER['REMOTE_ADDR']); $this->_sendResponse(401, "No user credentials provided."); } }