Как определить правила при ролевом доступе к контенту создаваемого сайта - vorst.ru

Правила


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

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

Правила

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

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

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

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

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

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

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

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


Is it your post?

Для подобных проверок существуют правила. Это классы, унаследованные от абстрактного класса yii\rbac\Rule с единственным методом execute.

Для определения авторства статьи метод определяется следующим образом:

  public function execute($user_id, $item, $params)
  {
    return isset($params['post']) 
      ? $params['post']->author_id == $user_id
      : false;
  }

Первый параметр всегда ID текущего пользователя. Третий - то, что передается при вызове метода can.

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

То есть мы передаем в правило модель статьи и проверка авторства становится очевидной.

Is it a comment for one of your posts?

Когда кто-либо пытается ответить на комментарий, проверяется разрешение replyOwnComment.

if (!\Yii::$app->user->can('replyComment', ['comment' => $comment]))

которое связано правилом OwnCommentRule со следующим методом execute:

  public function execute($user_id, $item, $params)
  {
    return isset($params['comment']) 
      ? in_array($params['comment']->post_id, $params['comment']->getUserPosts($user_id))
      : false;
  }

В методе проверяется, относится ли текущий пост к списку созданных данным Автором постов. Метод getUserPosts модели выбирает ID всех постов, созданных текущим пользователем.

  public function getUserPosts($user_id)
  {
    $a = [];
    foreach(Post::find()
      ->select(['id'])
      ->where(['author_id' => $user_id])
      ->all() as $post)
      $a[] = $post->id;
      return $a;
  }

Одно разрешение, несколько правил

В методе execute, как правило, делается проверка принадлежности к модели.

  return isset($params['model'])
    ? // checking
    : falsе

Дело в том, что если определены общие разрешения, как например update, то правило будет вызываться для разных моделей и нужно быть уверенным, что проверка выполняется для "правильной" модели. Таким образом на одно разрешение, например на то же update, может быть "повешено" несколько правил. Как и было сделано в предыдущей статье.

Остальные правила упомянутые в предыдущей статье определяются аналогично. После их добавления можно вызывать php yii rbac/init.

Заключение

RBAC это вещь простая и существенно упрощающая решение проблем распределения прав при создании сайта. Вся логика определяется в одном файле RbacController.php и легко контролируется. Вариант ролей и разрешений для работы с блогом можно посмотреть в модуле sergmoro1/yii2-blog-tools.

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

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