Да, это так, но есть одно "но", пытаюсь автоматизировать проверку правил, из замечательного проекта
https://github.com/trntv/yii2-starter-kit взят GlobalAccessBehavior, который задает глобально права доступы на экшины.
Вот как это выглядит
Есть консольная команда, которая пробегается по всем модулям админки, собирает контроллеры и все экшины, так же пробегается по контроллерам внутри админки и делает то же самое.
правила составляются следующим образом
backend___
Далее это все привязывается к роли.
Все работает отлично, но когда возникает ситуация, когда конкретному пользователю (а их может быть и десяток) нужно отключить определенный контроллер или даже экшн, то в случае с использованием permission, его не понимает AccessControl, так как доступ задать можно для роли.
В случае использования permission, подобную проверку проводить нужно в методе контроллера beforeAction
public function beforeAction() {
$permission = 'backend_' . Yii::$app->controller->module->id . '_' . Yii::$app->controller->id . '_' . Yii::$app->controller->action->id;
if (!Yii::$app->user->can($permission)) {
throw new yii\web\ForbiddenHttpException;
}
}
В таком случае, это необходимо реализовывать в базовом контроллере.
Еще есть вариант все же заставить понимать AccessRule permission а не только роли, немного его переопределив
<?php
namespace common\behaviors;
use yii\base\Action;
use yii\filters\AccessRule;
use yii\helpers\Inflector;
/**
* @class AccessRuleCustom
*
* @package common\behaviors
* @author Sergey Doniy <doniysa@gmail.com>
*/
class AccessRuleCustom extends AccessRule
{
public $checkPermissions = true;
public $prefix = 'backend_';
public function allows($action, $user, $request)
{
return parent::allows($action, $user, $request) || $this->hasPermission($action);
}
protected function hasPermission(Action $action) {
if (!$this->checkPermissions)
return false;
$permission = $this->prefix . $action->controller->module->id . '_' . $action->controller->id . '_' . Inflector::id2camel($action->id);
return \Yii::$app->user->can($permission);
}
}
Во втором варианте все работает, во всяком случае permission проходят, и все ок. Остановился в конечном счете на этом варианте - у пользователя всего одна роль, к которой привязываются дефолтные пермишины, а отдельные привязываются непосредственно к пользователю.
Для того, чтобы не хардкодить с языками и ролями по ним, отдельно создал две таблицы
auth_assignment_language_item
которая хранит перечень языков - т.е. по сути permission для языка
и таблицу
auth_assignment_language
Которая в свою очередь хранит привязку отдельного пользователя к языку
и таблицу auth_assignment_language_child
Для привязки роли к языку
Расширен функционал RBAC для управления еще и языками (так как rbac храню в БД, то расширен DbManager)
В отдельные таблицы вынес для того, чтобы логика данных была прозрачна, что позволило достаточно быстро накидать gui-интерфейс для управления правами на конкретный язык.
Это я описал свою реализацию поднятой темы.
Но все равно не уверен, что нет более лучших подходов для реализации.
Интересно будет почитать, кто как решал подобные задачи и какими методами - сразу уточню - система пишется не под один проект, это внутренняя CMS компании и hot-фиксы и пинание системы под конкретный случай усложнит разработку следующих проектов, поэтому приходится по максимуму (насколько позволяет время) делать ее гибкой и расширяемой для большинства задач, которые перед разработчиками ставятся.