yupe/yupe — pull request #1544 by DarkCs (2014-07-09 20:39:37+00:00)
Title: RBAC модуль

**Небольшое вступление**
В качестве роли администратора выступает роль «admin», создаваемая во время установки модуля. Она так же назначается всем пользователям, которые были администраторами до установки модуля.
Поэтому нельзя выбирать модуль для установки на этапе установки юпи, потому что пользователь создается после установки модулей (может быть стоит предусмотреть возможность отключения выбора модуля на этапе установки).

**Описание изменений, которые вносит данный пулл реквест в систему**
* ModuleManager - добавлены функции для скрытия меню, чтобы подстраивать меню соответствующе роли пользователя.
* WebModule - функция getAuthItems() - возвращает дерево ролей, задач и правил для модуля, для получения предопределенных правил.
* BackController - включается фильтр accessControll, если включен модуль rbac, чтобы собственно фильтровать доступ.
* yupe/controllers/BackendController - добавлены accessRules и страница вывода ошибок, для того, чтобы 403 ошибки показывались внутри админки.
* YBackAccessControl - переделан, чтобы учитывать модуль rbac.
* YAdminPanel - убрана проверка на суперюзера, потому что меню надо показывать всем, а видимость его и так отфильтруется.

**Использование**
Модуль, который хочет разграничивать права к своим действиям, должен позаботиться о назначении прав доступа в своих контроллерах с помощью переопределения функции getAccessRules, например, для модуля news это может выглядеть так:

```php
public function accessRules()
{
return array(
array('allow', 'roles' => array('admin'),),
array('allow', 'actions' => array('create'), 'roles' => array('News.NewsBackend.Create'),),
array('allow', 'actions' => array('delete'), 'roles' => array('News.NewsBackend.Delete'),),
array('allow', 'actions' => array('update'), 'roles' => array('News.NewsBackend.Update'),),
array('allow', 'actions' => array('inline'), 'roles' => array('News.NewsBackend.Update'),),
array('allow', 'actions' => array('index'), 'roles' => array('News.NewsBackend.Index'),),
array('allow', 'actions' => array('view'), 'roles' => array('News.NewsBackend.View'),),
array('deny',),
);
}
```
Первым правилом «array('allow', 'roles' => array('admin'),),» разрешаем полный доступ для стандартной роли «admin», последним запрещаем все. Между разрешаем определенные действия для операций, тут нужно определять именно операции. Я рекомендую их называть согласно соответствующему полному роуту до экшена, оно всегда будет уникально и понятно за что оно отвечает, и именно по нему происходит фильтрация видимости, если таковая не обозначена вручную. Например, для роута news/newsBackend/create будет ссылка проверена по правилу News.NewsBackend.Create.
Далее в модуле переопределяя функцию getAuthItems() мы задаем дерево ролей/задач/операций (стандартно для yii типы: role -> 2, task -> 1, operation -> 0). Для модуля news это может выглядеть так:

```php
public function getAuthItems()
{
return array(
array('type' => 1, 'name' => 'News.NewsBackend.Management', 'description' => 'Управление новостями',
'items' => array(
array('type' => 0, 'name' => 'News.NewsBackend.Index', 'description' => 'Просмотр списка новостей',),
array('type' => 0, 'name' => 'News.NewsBackend.Create', 'description' => 'Создание новости',),
array('type' => 0, 'name' => 'News.NewsBackend.Update', 'description' => 'Редактирование новости',),
array('type' => 0, 'name' => 'News.NewsBackend.View', 'description' => 'Просмотр новости',),
array('type' => 0, 'name' => 'News.NewsBackend.Delete', 'description' => 'Удаление новости',),
),
),
);
}
```
Тут мы определили задачу «Управление новостями», которой назначили операции из контроллера newsBackend.

Модуль импортирует правила из остальных модулей в ручном режиме:
![](http://i.imgur.com/MqojV4N.png)
Наверняка в будущем можно привязаться как-то к событиям активации модулей или чему-то подобному, но пока так.
После импорта правил, можно будет назначить их пользователям, или комбинировать в другие задачи и роли.
![](http://i.imgur.com/CKXkxxs.png)

Баги.
Модуль не удаляется штатными средствами - миграции вызываются в порядке их установки, а не наоборот, нарушая целостность связей. Возможно, стоит разобраться с мигратором.