Нужно создать 2 разрешения:
1) updateOwnPost - для автора, в нём должно быть правило, которое проверяет автора статьи.
2) updatePost - для администратора, здесь никаких правил нет.
Создаем правило:
use yii\rbac\Item;
use yii\rbac\Rule;
Код: Выделить всё
class IsAuthorRule extends Rule
{
public $name = 'isAuthor';
/** default generated */
public function execute($user, $item, $params)
{
return isset($params['authorId']) ? $params['authorId'] == $user : false;
}
}
Далее, в контроллере RBAC пишем:
Код: Выделить всё
// создаем разрешение updateOwnPost, к которому включаем правило isAuthor, и updatePost:
$isAuthorRule = new IsAuthorRule;
$authManager->add($isAuthorRule);
$updateOwnPost = $authManager->createPermission('updateOwnPost');
$updateOwnPost->description = 'Изменение объекта где создатель как текущий автор указан'; //TODO change Yodd style
$updateOwnPost->ruleName = $isAuthorRule->name;
$authManager->add($updateOwnPost);
$updatePost = $authManager->createPermission('updateAnyPosts');
$updatePost->description = 'Изменение любого объекта';
$authManager->add($updatePost);
// Указываем, что $updatePost является частным случаем $updateOwnPost
$authManager->addChild($updateOwnPost, $updatePost);
// Теперь создаем роли:
$user = $authManager->createRole('author');
$user->name = 'author';
$user->description = 'Автор статей';
$admin = $authManager->createRole('admin');
$admin->name = 'admin';
$admin->description = 'Администратор';
$authManager->add($admin);
// Назначаем права пользователям
$authManager->addChild($user, $updateOwnPost);
$authManager->addChild($admin, $updatePost);
// Указываем, что администратор может всё что и пользователь:
$authManager->addChild($admin, $user);
Второй этап - проверка разрешений. Делаем проверку в экшине контроллера:
Код: Выделить всё
public function actionUpdate($id)
{
$model = $this->findModel($id);
if (!Yii::$app->user->can('updateAnyPosts', ['authorId' => $model->author_id])) {
throw new ForbiddenHttpException(Yii::t('error',
'You are not authorized to change the current record. You probably not an own'));
}
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
}
Если авторизоваться под Автором то произойдет следующее:
- проверяется, есть ли у Автора разрешение 'updateAnyPosts' - если есть, то продолжится выполнения функции, если нет - следующий шаг;
- проверяется, есть ли у Автора разрешение 'updateOwnPost' - если есть и правило 'isAuthor' возвращает true, то продолжится выполнения функции, если нет - throw exception