ModuleRbac
Package | application.modules.rbac |
---|---|
Inheritance | class ModuleRbac » ModuleORM » Module » LsObject |
Since | 2.0 |
Source Code | /application/classes/modules/rbac/Rbac.class.php |
// для текущего пользователя $this->Rbac_IsAllow('topic_create'); // для конкретного пользователя с параметрами $this->Rbac_IsAllowUser($oUser,'topic_update',array('topic'=>$oTopic)); // для плагина 'article', указывается код плагина $this->Rbac_IsAllow('article_create','article'); // для плагина, где $this - любой текущий объект плагина (кроме Inherit классов) $this->Rbac_IsAllow('article_create',$this); // для плагина с параметрами $this->Rbac_IsAllow('article_update',$this,array('article'=>$oArticle));
Protected Properties
Property | Type | Description | Defined By |
---|---|---|---|
_aBehaviors | Список поведений в виде готовых объектов, формируется автоматически | LsObject | |
aBehaviors | array | Список поведений | LsObject |
aPermissionCache | array | Внутренний кеш всех используемых разрешений | ModuleRbac |
aRoleCache | array | Внутренний кеш всех ролей | ModuleRbac |
aRulePermissionCache | array | Внутренний кеш разрешений для ролей | ModuleRbac |
aUserRoleCache | array | Внутренний кеш ролей пользователя | ModuleRbac |
bIsInit | bool | Указывает на то, была ли проведенна инициализация модуля | Module |
oMapper | ModuleRbac_MapperRbac | Объект маппера | ModuleRbac |
oMapperORM | MapperORM | Объект маппера ORM | ModuleORM |
sMessageLast | null|string | Хранит последнее сообщение о неудачной проверке прав | ModuleRbac |
Public Methods
Method | Description | Defined By |
---|---|---|
AddBehaviorHook() | Добавляет хук поведения | LsObject |
AddRoleToUser() | Добавляет роль к пользователю | ModuleRbac |
AttachBehavior() | Присоединяет поведение к объекту | LsObject |
CreatePermissions() | Создает разрешений для управления правами | ModuleRbac |
DeleteItemsByFilter() | Удаляет сущности по фильтру | ModuleORM |
DetachBehavior() | Отсоединяет поведение от объекта | LsObject |
GetAggregateFunctionByFilter() | Получить значение агрегирующей функции | ModuleORM |
GetBehavior() | Возвращает объект поведения по его имени | LsObject |
GetBehaviors() | Возвращает все объекты поведения | LsObject |
GetByFilter() | Получить сущность по фильтру | ModuleORM |
GetCountItemsByFilter() | Получить количество сущностей по фильтру | ModuleORM |
GetCountItemsByJoinEntity() | ModuleORM | |
GetCountUsersByRole() | Возвращает количество пользователей у роли | ModuleRbac |
GetItemsByArray() | Возвращает список сущностей по фильтру | ModuleORM |
GetItemsByFilter() | Получить список сущностей по фильтру | ModuleORM |
GetItemsByJoinEntity() | ModuleORM | |
GetMsgLast() | Возвращает последнее сообщение о неудачной проверке прав | ModuleRbac |
GetRolesByUser() | Возвращает список ролей пользователя | ModuleRbac |
Init() | Инициализация модуля | ModuleRbac |
IsAllow() | Проверяет разрешение для текущего авторизованного пользователя | ModuleRbac |
IsAllowUser() | Проверяет разрешение для конкретного пользователя | ModuleRbac |
LoadTree() | Для сущностей со связью RELATION_TYPE_TREE возвращает список сущностей в виде дерева | ModuleORM |
RemoveBehaviorHook() | Удаляет хук поведения | LsObject |
RemovePermissions() | Удаляет разрешения - группы, роли, разрешения | ModuleRbac |
ReturnActionError() | Алиас для перенаправления экшена на страницу ошибки с сообщением | ModuleRbac |
RunBehaviorHook() | Запускает хук поведения на выполнение | LsObject |
SetInit() | Помечает модуль как инициализированный | Module |
Shutdown() | Метод срабатывает при завершении работы ядра | Module |
__call() | Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля. | ModuleORM |
__clone() | Блокируем копирование/клонирование объекта | Module |
__construct() | Конструктор, запускается автоматически при создании объекта | LsObject |
__get() | Обработка доступа к объекты поведения | LsObject |
buildTree() | Построение дерева | ModuleORM |
isInit() | Возвращает значение флага инициализации модуля | Module |
Protected Methods
Method | Description | Defined By |
---|---|---|
CheckPermissionByRole() | Проверяет наличие разрешения у конкретной роли, учитывается наследование ролей | ModuleRbac |
IsAllowUserFull() | Проверяет разрешение для конкретного пользователя | ModuleRbac |
LoadPermissions() | Загружает в кеш разрешения | ModuleRbac |
LoadRoleAndPermissions() | Выполняет загрузку в кеш ролей и разрешений | ModuleRbac |
LoadRoles() | Загружает в кеш роли | ModuleRbac |
PrepareBehaviors() | Инициализация поведений | LsObject |
_AddEntity() | Добавление сущности в БД | ModuleORM |
_DeleteEntity() | Удаление сущности из БД | ModuleORM |
_GetAncestorsOfEntity() | Для сущности со связью RELATION_TYPE_TREE возвращает список всех предков | ModuleORM |
_GetChildrenOfEntity() | Для сущности со связью RELATION_TYPE_TREE возвращает список прямых потомков | ModuleORM |
_GetDescendantsOfEntity() | Для сущности со связью RELATION_TYPE_TREE возвращает список всех потомков | ModuleORM |
_GetParentOfEntity() | Для сущности со связью RELATION_TYPE_TREE возвращает предка | ModuleORM |
_LoadMapperORM() | Загрузка маппера ORM | ModuleORM |
_NormalizeEntityRootName() | Приводит название сущности к единому формату полного имени класса | ModuleORM |
_ReloadEntity() | Обновляет данные сущности из БД | ModuleORM |
_SaveEntity() | Сохранение сущности в БД | ModuleORM |
_ShowColumnsFrom() | Список полей сущности | ModuleORM |
_ShowPrimaryIndexFrom() | Primary индекс сущности | ModuleORM |
_UpdateEntity() | Обновление сущности в БД | ModuleORM |
_deleteManyToManyRelation() | Выполняет удаление всех связей many_to_many сущности | ModuleORM |
_setIndexesFromField() | Returns assotiative array, indexed by PRIMARY KEY or another field. | ModuleORM |
_setIndexesGroupField() | Возвращает сгруппированный массив по нужному полю | ModuleORM |
_setIndexesGroupJoinField() | Возвращает сгруппированный массив по нужному полю из данных таблицы связей | ModuleORM |
_updateManyToManyRelation() | Выполняет обновление связи many_to_many у сущности | ModuleORM |
Property Details
Внутренний кеш всех используемых разрешений
Внутренний кеш всех ролей
Внутренний кеш разрешений для ролей
Внутренний кеш ролей пользователя
Объект маппера
Хранит последнее сообщение о неудачной проверке прав
Method Details
public bool|Entity AddRoleToUser(ModuleRbac_EntityRole|string $oRole, int|ModuleUser_EntityUser $iUserId)
| ||
$oRole | ModuleRbac_EntityRole|string | Объект роли или код роли |
$iUserId | int|ModuleUser_EntityUser | Объект пользователя или его ID |
{return} | bool|Entity |
public function AddRoleToUser($oRole, $iUserId)
{
if (is_string($oRole)) {
$oRole = $this->GetRoleByCode($oRole);
}
if (is_object($iUserId)) {
$iUserId = $iUserId->getId();
}
if (!$oRole or !$iUserId) {
return false;
}
if (!($oRoleUser = $this->Rbac_GetRoleUserByFilter(array(
'role_id' => $oRole->getId(),
'user_id' => $iUserId
)))
) {
/**
* Добавляем
*/
$oRoleUser = Engine::GetEntity('ModuleRbac_EntityRoleUser');
$oRoleUser->setRoleId($oRole->getId());
$oRoleUser->setUserId($iUserId);
$oRoleUser->Add();
}
return $oRoleUser;
}
Добавляет роль к пользователю
protected bool CheckPermissionByRole(ModuleRbac_EntityRole $oRole, string $sPermissionCode, string $sPlugin='')
| ||
$oRole | ModuleRbac_EntityRole | Объект роли |
$sPermissionCode | string | Код разрешения |
$sPlugin | string | Код плагина или пустая строка (разрешения ядра) |
{return} | bool |
protected function CheckPermissionByRole($oRole, $sPermissionCode, $sPlugin = '')
{
/**
* Проверяем наличие пермишена в текущей роли
*/
if (isset($this->aRulePermissionCache[$oRole->getId()][$sPlugin])) {
if (in_array($sPermissionCode, $this->aRulePermissionCache[$oRole->getId()][$sPlugin])) {
return true;
}
}
/**
* Смотрим родительскую роль
*/
if ($oRole->getPid() and isset($this->aRoleCache[$oRole->getPid()])) {
return $this->CheckPermissionByRole($this->aRoleCache[$oRole->getPid()], $sPermissionCode, $sPlugin);
}
return false;
}
Проверяет наличие разрешения у конкретной роли, учитывается наследование ролей
public bool CreatePermissions(array $aData, mixed $sPlugin=NULL)
| ||
$aData | array | Набор данных |
$sPlugin | mixed | Плагин, можно указать код плагина, название класса или объект |
{return} | bool |
public function CreatePermissions($aData, $sPlugin = null)
{
$sPlugin = $sPlugin ? Plugin::GetPluginCode($sPlugin) : '';
/**
* Создаем группы
*/
if (isset($aData['groups'])) {
foreach ($aData['groups'] as $aGroup) {
$sCode = $aGroup[0];
$sTitle = isset($aGroup[1]) ? $aGroup[1] : $sCode;
if (!$this->GetGroupByCode($sCode)) {
$oGroup = Engine::GetEntity('ModuleRbac_EntityGroup');
$oGroup->setCode($sCode);
$oGroup->setTitle($sTitle);
if ($oGroup->_Validate()) {
$oGroup->setTitle(htmlspecialchars($oGroup->getTitle()));
$oGroup->Add();
}
}
}
}
/**
* Создаем роли
*/
if (isset($aData['roles'])) {
foreach ($aData['roles'] as $aRole) {
$sCode = $aRole[0];
$sTitle = isset($aRole[1]) ? $aRole[1] : $sCode;
if (!$this->GetRoleByCode($sCode)) {
$oRole = Engine::GetEntity('ModuleRbac_EntityRole');
$oRole->setCode($sCode);
$oRole->setTitle($sTitle);
if ($oRole->_Validate()) {
$oRole->setTitle(htmlspecialchars($oRole->getTitle()));
$oRole->Add();
}
}
}
}
/**
* Создаем разрешения
*/
if (isset($aData['permissions'])) {
foreach ($aData['permissions'] as $aPermission) {
$sCode = $aPermission[0];
$sTitle = isset($aPermission[1]) ? $aPermission[1] : $sCode;
$aFilter = array(
'code' => $sCode
);
if ($sPlugin) {
$aFilter['plugin'] = $sPlugin;
}
if (!$this->GetPermissionByFilter($aFilter)) {
$oPermission = Engine::GetEntity('ModuleRbac_EntityPermission');
$oPermission->setCode($sCode);
$oPermission->setTitle($sTitle);
$oPermission->setPlugin($sPlugin);
$oPermission->setMsgError(isset($aPermission['msg_error']) ? $aPermission['msg_error'] : '');
if (isset($aPermission['group']) and $oGroup = $this->GetGroupByCode($aPermission['group'])) {
$oPermission->setGroupId($oGroup->getId());
}
if ($oPermission->_Validate()) {
$oPermission->setTitle(htmlspecialchars($oPermission->getTitle()));
$oPermission->setMsgError(htmlspecialchars($oPermission->getMsgError()));
if ($oPermission->Add()) {
/**
* Создаем связь с ролями
*/
if (isset($aPermission['roles'])) {
$aRoles = is_array($aPermission['roles']) ? $aPermission['roles'] : array($aPermission['roles']);
foreach ($aRoles as $sRoleCode) {
if ($oRole = $this->GetRoleByCode($sRoleCode)) {
$oRolePermission = Engine::GetEntity('ModuleRbac_EntityRolePermission');
$oRolePermission->setRoleId($oRole->getId());
$oRolePermission->setPermissionId($oPermission->getId());
$oRolePermission->Add();
}
}
}
}
}
}
}
}
return true;
}
Создает разрешений для управления правами В качестве основного параметра передается массив с данными, массив имеет тип корневых ключа: groups, roles и permissions.
$aData=array( 'groups' => array( array('article','Статьи'), ), 'roles' => array( array('article_moderator','Модератор статей'), ), 'permissions' => array( array('view','Просмотр статьи','msg_error'=>'У вас нет прав на просмотр статьи','group'=>'article','roles'=>array('guest','user')), array('create','Создание статей','msg_error'=>'У вас нет прав на создание статьи','group'=>'article','roles'=>'user'), array('update_all','Правка всех статей','msg_error'=>'У вас нет прав на редактирование статьи','group'=>'article','roles'=>'article_moderator'), ), );
public int GetCountUsersByRole(ModuleRbac_EntityRole|int $oRole)
| ||
$oRole | ModuleRbac_EntityRole|int | |
{return} | int |
public function GetCountUsersByRole($oRole)
{
if (!$oRole) {
return 0;
}
if (is_object($oRole)) {
$iRoleId = $oRole->getId();
} else {
$iRoleId = $oRole;
}
return $this->GetCountItemsByFilter(array('role_id' => $iRoleId), 'ModuleRbac_EntityRoleUser');
}
Возвращает количество пользователей у роли
public null|string GetMsgLast()
| ||
{return} | null|string |
public function GetMsgLast()
{
return $this->sMessageLast;
}
Возвращает последнее сообщение о неудачной проверке прав
public array GetRolesByUser(ModuleUser_EntityUser|int $oUser, bool $bActiveOnly=true)
| ||
$oUser | ModuleUser_EntityUser|int | |
$bActiveOnly | bool | Учитывать только активные роли |
{return} | array |
public function GetRolesByUser($oUser, $bActiveOnly = true)
{
if (!$oUser) {
return array();
}
if (is_object($oUser)) {
$iUserId = $oUser->getId();
} else {
$iUserId = $oUser;
}
/**
* Сначала получаем все связи
*/
$aRoleUserItems = $this->GetRoleUserItemsByFilter(array('user_id' => $iUserId, '#index-from' => 'role_id'));
$aRoleIds = array_keys($aRoleUserItems);
/**
* Теперь получаем список ролей
*/
if ($aRoleIds) {
$aFilter = array('id in' => $aRoleIds);
if ($bActiveOnly) {
$aFilter['state'] = self::ROLE_STATE_ACTIVE;
}
return $this->GetRoleItemsByFilter($aFilter);
}
return array();
}
Возвращает список ролей пользователя На самом деле этот метод можно было бы заменить на $oUser->getRolesActive(), если бы сущность User была ORM
public void Init()
|
public function Init()
{
parent::Init();
$this->oMapper = Engine::GetMapper(__CLASS__);
}
Инициализация модуля
public bool IsAllow(string $sPermissionCode, mixed $aParamsOrPlugin=array (
), mixed $sPluginOrParams=NULL)
| ||
$sPermissionCode | string | Код разрешения |
$aParamsOrPlugin | mixed | Параметры или плагин |
$sPluginOrParams | mixed | Плагин или параметры |
{return} | bool |
public function IsAllow($sPermissionCode, $aParamsOrPlugin = array(), $sPluginOrParams = null)
{
return $this->IsAllowUser($this->User_GetUserCurrent(), $sPermissionCode, $aParamsOrPlugin, $sPluginOrParams);
}
Проверяет разрешение для текущего авторизованного пользователя
public bool IsAllowUser(ModuleUser_EntityUser $oUser, string $sPermissionCode, mixed $aParamsOrPlugin=array (
), mixed $sPluginOrParams=NULL)
| ||
$oUser | ModuleUser_EntityUser | Пользователь |
$sPermissionCode | string | Код разрешения |
$aParamsOrPlugin | mixed | Параметры или плагин |
$sPluginOrParams | mixed | Плагин или параметры |
{return} | bool |
public function IsAllowUser($oUser, $sPermissionCode, $aParamsOrPlugin = array(), $sPluginOrParams = null)
{
$aParams = array();
$sPlugin = null;
if (!is_array($sPluginOrParams)) {
$sPlugin = $sPluginOrParams;
} else {
$aParams = $sPluginOrParams;
}
if (is_array($aParamsOrPlugin)) {
$aParams = $aParamsOrPlugin;
} else {
$sPlugin = $aParamsOrPlugin;
}
return $this->IsAllowUserFull($oUser, $sPermissionCode, $aParams, $sPlugin);
}
Проверяет разрешение для конкретного пользователя
protected bool IsAllowUserFull(ModuleUser_EntityUser $oUser, string $sPermissionCode, array $aParams=array (
), mixed $sPlugin=NULL)
| ||
$oUser | ModuleUser_EntityUser | Пользователь |
$sPermissionCode | string | Код разрешения |
$aParams | array | Параметры |
$sPlugin | mixed | Плагин, можно указать код плагина, название класса или объект |
{return} | bool |
protected function IsAllowUserFull($oUser, $sPermissionCode, $aParams = array(), $sPlugin = null)
{
if (!$sPermissionCode) {
return false;
}
$sPlugin = $sPlugin ? Plugin::GetPluginCode($sPlugin) : '';
/**
* Загружаем все роли и пермишены
*/
$this->LoadRoleAndPermissions();
$sUserId = self::ROLE_CODE_GUEST;
if ($oUser) {
$sUserId = $oUser->getId();
}
/**
* Смотрим роли в кеше
*/
if (!isset($this->aUserRoleCache[$sUserId])) {
if ($sUserId == self::ROLE_CODE_GUEST) {
$aRoles = $this->GetRoleByCodeAndState(self::ROLE_CODE_GUEST, self::ROLE_STATE_ACTIVE);
$aRoles = $aRoles ? array($aRoles) : array();
} else {
$aRoles = $this->GetRolesByUser($oUser);
}
$this->aUserRoleCache[$sUserId] = $aRoles;
} else {
$aRoles = $this->aUserRoleCache[$sUserId];
}
/**
* Получаем пермишены для ролей
*/
$sPermissionCode = func_underscore($sPermissionCode);
$mResult = false;
foreach ($aRoles as $oRole) {
/**
* У роли есть необходимый пермишен, то проверим на возможную кастомную обработку с параметрами
*/
if ($this->CheckPermissionByRole($oRole, $sPermissionCode, $sPlugin)) {
/**
* Проверяем на передачу коллбека
*/
if (isset($aParams['callback']) and is_callable($aParams['callback'])) {
$mResult = call_user_func($aParams['callback'], $oUser, $aParams);
} else {
/**
* Для плагинов: CheckCustomPluginArticleCreate
* Для ядра: CheckCustomCreate
*/
$sAdd = $sPlugin ? ('Plugin' . func_camelize($sPlugin)) : '';
$sMethod = 'CheckCustom' . $sAdd . func_camelize($sPermissionCode);
if (method_exists($this, $sMethod)) {
$mResult = call_user_func(array($this, $sMethod), $oUser, $aParams);
} else {
return true;
}
}
break;
}
}
/**
* Дефолтное сообщение об ошибке
*/
$sMsg = 'У вас нет прав на "' . $sPermissionCode . '"';
/**
* Проверяем результат кастомной обработки
*/
if ($mResult === true) {
return true;
} elseif (is_string($mResult)) {
/**
* Вернули кастомное сообщение об ошибке
*/
$sMsg = $mResult;
} else {
/**
* Формируем сообщение об ошибке
*/
if (isset($this->aPermissionCache[$sPlugin][$sPermissionCode])) {
$aPerm = $this->aPermissionCache[$sPlugin][$sPermissionCode];
if ($aPerm['msg_error']) {
$sMsg = $this->Lang_Get($aPerm['msg_error']);
} else {
$sMsg = 'У вас нет прав на "' . ($aPerm['title'] ? $aPerm['title'] : $aPerm['code']) . '"';
}
}
}
$this->sMessageLast = $sMsg;
return false;
}
Проверяет разрешение для конкретного пользователя
protected void LoadPermissions()
|
protected function LoadPermissions()
{
if ($this->aRulePermissionCache) {
return;
}
$aResult = $this->oMapper->GetRoleWithPermissions();
foreach ($aResult as $aRow) {
$this->aRulePermissionCache[$aRow['role_id']][$aRow['plugin']][] = $aRow['code'];
$this->aPermissionCache[$aRow['plugin']][$aRow['code']] = $aRow;
}
}
Загружает в кеш разрешения
protected void LoadRoleAndPermissions()
|
protected function LoadRoleAndPermissions()
{
/**
* Роли
*/
$this->LoadRoles();
/**
* Пермишены
*/
$this->LoadPermissions();
}
Выполняет загрузку в кеш ролей и разрешений
protected void LoadRoles()
|
protected function LoadRoles()
{
if ($this->aRoleCache) {
return;
}
$aRoles = $this->GetRoleItemsByState(self::ROLE_STATE_ACTIVE);
foreach ($aRoles as $oRole) {
$this->aRoleCache[$oRole->getId()] = $oRole;
}
}
Загружает в кеш роли
public void RemovePermissions(array $aData, mixed $sPlugin)
| ||
$aData | array | Данные для удаления |
$sPlugin | mixed | Плагин, можно указать код плагина, название класса или объект |
public function RemovePermissions($aData, $sPlugin)
{
if (isset($aData['groups'])) {
$aGroups = is_array($aData['groups']) ? $aData['groups'] : array($aData['groups']);
foreach ($aGroups as $sGroupCode) {
if ($oGroup = $this->GetGroupByCode($sGroupCode)) {
$oGroup->Delete();
}
}
}
if (isset($aData['roles'])) {
$aRoles = is_array($aData['roles']) ? $aData['roles'] : array($aData['roles']);
foreach ($aRoles as $sRoleCode) {
if ($oRole = $this->GetRoleByCode($sRoleCode)) {
$oRole->Delete();
}
}
}
/**
* Удаляем разрешения
*/
$sPlugin = $sPlugin ? Plugin::GetPluginCode($sPlugin) : '';
if ($sPlugin and $aPermissions = $this->GetPermissionItemsByPlugin($sPlugin)) {
foreach ($aPermissions as $oPermission) {
$oPermission->Delete();
}
}
}
Удаляет разрешения - группы, роли, разрешения
$aData=array( 'groups' => array('article'), 'roles' => array('article_moderator'), );
public string ReturnActionError(bool $bFromAdmin=false)
| ||
$bFromAdmin | bool | Необходимо указать true, если метод вызывается из стандартной админки |
{return} | string |
public function ReturnActionError($bFromAdmin = false)
{
if ($bFromAdmin) {
$this->Message_AddErrorSingle($this->GetMsgLast());
return Router::Action('admin', 'error');
} else {
return Router::ActionError($this->GetMsgLast());
}
}
Алиас для перенаправления экшена на страницу ошибки с сообщением