vorst.ru - Как определить роли и задать разрешения, RBAC
Статьи из рубрики rbac

Правила

rbac - выполнять действие или нет

В предыдущей статье были определены две роли - Админ и Автор, как в обычном блоге. А обычно блог используется при создании любого сайта. Для ролей Админ и Автор были определены разрешения.

Если вы Админ, то у вас есть общее разрешение create. Оно дает право добавлять данные к любым моделям. Если вы Автор, то такое разрешение давать не стоит. Автор не может, например, добавить новую рубрику.

Если нельзя дать общее разрешение, то нужно создать и выдать частное разрешение. Чтобы позволить Автору добавлять статьи, нужно создать разрешение createPost. Оно должно проверяться следующим, в случае неудачи при проверке разрешения create.

$auth->addChild($createPost, $create);

Чтобы Админ мог добавить статью, нужно, чтобы он имел разрешение на все, на что имеет разрешение Автор.

$auth->addChild($admin, $author);

Все отлично и логично. Четкая иерархия разрешений и ролей. Но, например, вы Автор и пытаетесь редактировать чужую статью. Действие не желательное. Как проверить, что статья не ваша? Или как проверить, что этот комментарий не к вашей статье и вам не стоит на него отвечать?


Разрешения

rbac - разрешения на доступ, роли для групп пользователей

Разработка бекенда сайта часто подразумевает ограничение прав при редактировании контента. Ролевая модель имеет иерархию. Сначала прав не много, потом чуть больше, наконец доступно все. Права (или разрешения) - это константы, которые связаны с конкретной ролью. Если за ролью закреплено разрешение, то действие может быть выполнено.

Проверяется разрешение просто, например:

if(Yii::$app->user->can('update', ['model' => $model])) {
  // code for model updating
}

То есть может быть выполнен некий код, если за ролью текущего Пользователя закреплено разрешение update. Если представить, что с каждой ролью связан массив текстовых констант - "create", "update" и прочее, то правило проверки становится очевидным.

Но при такой организации данных нельзя учесть иерархию разрешений. Нужна древовидная структура. Строится такое дерево с помощью менеджера авторизации.

Определим те разрешения, что были упомянуты в предыдущей статье.


Настройка RBAC

rbac - подключение ролевого доступа

В большом количестве задач необходимо в backend-части приложения разрешать одним группам пользователей выполнять только определенные действия. Другим может быть разрешено чуть больше. И так далее, до админа.

Именно распределение прав для групп пользователей и будет рассмотрено в паре-тройке статей. В качестве примера будет использоваться всего две роли.



Поиск



Разрешения

rbac - разрешения на доступ, роли для групп пользователей

Разработка бекенда сайта часто подразумевает ограничение прав при редактировании контента. Ролевая модель имеет иерархию. Сначала прав не много, потом чуть больше, наконец доступно все. Права (или разрешения) - это константы, которые связаны с конкретной ролью. Если за ролью закреплено разрешение, то действие может быть выполнено.

Проверяется разрешение просто, например:

if(Yii::$app->user->can('update', ['model' => $model])) {
  // code for model updating
}

То есть может быть выполнен некий код, если за ролью текущего Пользователя закреплено разрешение update. Если представить, что с каждой ролью связан массив текстовых констант - "create", "update" и прочее, то правило проверки становится очевидным.

Но при такой организации данных нельзя учесть иерархию разрешений. Нужна древовидная структура. Строится такое дерево с помощью менеджера авторизации.

Определим те разрешения, что были упомянуты в предыдущей статье.


    Поделиться

Permissions

Для basic шаблона разрешения определяются в файле /commands/RbacConrollers.php, а для advanced в /console/controllers/RbacController.php. Сначала общие разрешения, используемые для всего приложения.

<?php
namespace console\controllers;
use Yii;
use yii\console\Controller;
class RbacController extends Controller
{
  public function actionInit()
  {
    $auth = Yii::$app->authManager;
    // delete previous /console/rbac/items.php, /console/rbac/rules.php
    $auth->removeAll();
    // Create permissions
    // Create simple, based on action{$NAME} permissions
    $index  = $auth->createPermission('index');
    $create = $auth->createPermission('create');
    $update = $auth->createPermission('update');
    $delete = $auth->createPermission('delete');
    $auth->add($index);
    $auth->add($create);
    $auth->add($update);
    $auth->add($delete);

Просмотр в блоге нужен только для статей. Поэтому это разрешение определяется отдельно.

    // Post
    $viewPost = $auth->createPermission('viewPost');
    $createPost = $auth->createPermission('createPost');
    $changePostStatus = $auth->createPermission('changePostStatus');
    $auth->add($viewPost);
    $auth->add($createPost);
    $auth->add($changePostStatus);
    $auth->addChild($createPost, $create);

Статус статьи ("Черновик", "Опубликовано", "Архив") может менять только Админ. То есть, Автор может набрать статью, но "выпустить" ее может только Редактор-Админ. Разрешение changePostStatus будет использовано в форме редактирования статьи.

Общее разрешение create будет выдано только Админу, поэтому необходимо отдельное разрешение createPost.

Теперь добавим правило, по которому можно определить, что пользователь является автором статьи. Определение правила будет приведено позже.

    // Rule- Post Author
    $postAuthor = new console\rbac\PostAuthorRule();
    $auth->add($postAuthor);
    $updateOwnPost = $auth->createPermission('updateOwnPost');
    $updateOwnPost->ruleName = $postAuthor->name;
    $auth->add($updateOwnPost);
    $auth->addChild($updateOwnPost, $update);

Сейчас важно только установить взаимосвязь между правилом и разрешением. Когда в коде будет вызвана проверка:

$model = $this->findModel($id); 
if(Yii::$app->user->can('update', ['model' => $model])) {

сначала будет проверено, разрешение update. Если вы не Админ, то вернется отказ. Тогда будет проверено разрешение updateOwnPost. Для этого, будет вызван метод execute класса /console/rbac/PostAuthorRule.php.

Комментарии добавляются только во frontend, поэтому на них можно только отвечать.

    // Comment
    $replyComment = $auth->createPermission('replyComment');
    $auth->add($replyComment);

Автор может отвечать только на комментарии к своим статьям. Добавим соответствующее правило.

    // Rule - Comments Only For Own Posts
    $ownComment = console\rbac\new OwnCommentRule();
    $auth->add($ownComment);
    $replyOwnComment = $auth->createPermission('replyOwnComment');
    $replyOwnComment->ruleName = $ownComment->name;
    $auth->add($replyOwnComment);
    $auth->addChild($replyOwnComment, $replyComment);

Кроме того, Автор может редактировать только собственный комментарий.

    // Rule - Own Answers For Comments
    $ownAnswer = new console\rbac\OwnAnswerRule();
    $auth->add($ownAnswer);
    $updateOwnAnswer = $auth->createPermission('updateOwnAnswer');
    $updateOwnAnswer->ruleName = $ownAnswer->name;
    $auth->add($updateOwnAnswer);
    $auth->addChild($updateOwnAnswer, $update);

Последний вызов addChild кажется немного странным - как же это, опять связываем правило с разрешением, причем собираемся проверять одно и то же разрешение для разных моделей? Ответ будет. Чуть позже.

Остались профили Юзеров. Админ, естественно, видит всех. Авторы, только себя.

    // User
    // Rule - Own Answers For Comments
    $ownProfile = console\rbac\new OwnProfileRule();
    $auth->add($ownProfile);
    $updateOwnProfile = $auth->createPermission('updateOwnProfile');
    $updateOwnProfile->ruleName = $ownProfile->name;
    $auth->add($updateOwnProfile);
    $auth->addChild($updateOwnProfile, $update);

- Опять прикрепили правило все к тому же разрешению update?

- Да!

Но об этом, опять, чуть позже.

Roles

Определим роли и закрепим за ними разрешения. С каждой ролью свяжем правило, по которому Пользователь будет следовать той или иной роли.

    // Role
    // Rule - User Group
    $group = new console\rbac\UserGroupRule();
    $auth->add($group);
    $author = $auth->createRole('author');
    $author->ruleName  = $group->name;
    $auth->add($author);
    $admin = $auth->createRole('admin');
    $admin->ruleName  = $group->name;
    $auth->add($admin);
    // Author
    $auth->addChild($author, $index);
    $auth->addChild($author, $createPost);
    $auth->addChild($author, $viewPost);
    $auth->addChild($author, $updateOwnPost);
    $auth->addChild($author, $replyOwnComment);
    $auth->addChild($author, $updateOwnAnswer);
    $auth->addChild($author, $updateOwnProfile);
    // Admin
    $auth->addChild($admin, $replyComment);
    $auth->addChild($admin, $changePostStatus);
    $auth->addChild($admin, $create);
    $auth->addChild($admin, $update);
    $auth->addChild($admin, $delete);
    // Admin can all that can Author
    $auth->addChild($admin, $author);
  }

Заключение

Кажется, пора уже выполнить php yii rbac/init, но "нет". Нужно еще определить все упомянутые правила. А о них в следующей статье.

Оставить комментарий

Только авторизованные пользователи могут оставлять комментарии. Пожалуйста авторизуйтесь или пройдите регистрацию.