У меня в системе есть заказы, и есть роль менеджера и работника. Работник имеет доступ к деталям только своего заказа (то есть, внесенного им в систему), менеджер имеет доступ ко всем заказам.
Делал по аналогии с руководством - менеджер есть родителем для работника, а так же два пермишшна - для менеджера manage_products и для работника manage_own_orders.
При этом, у manage_own_orders есть правило, которое проверяет автора заказа.
Унаследовал manage_products от manage_own_orders (насколько я понял, более общее правило является потомком более узкого).
По факту, это по схеме из руководства:
При этом, правило проверки на свой заказ даже не запускается (проверял дебаггером), и работник не имеет доступа к деталям своего заказа.
Полный листинг консольных команд инициализации схемы:
Код: Выделить всё
<?php
namespace app\commands;
use yii\console\Controller;
use app\models\User;
use Yii;
class RbacController extends Controller
{
public function actionInit()
{
$this->_initRoles();
$this->_initPermissions();
}
public function actionSaveUserRoles()
{
...
}
/**
* Инициализация ролей
*/
private function _initRoles()
{
$auth = Yii::$app->authManager;
$auth->removeAllRoles();
$admin = $auth->createRole(User::ROLE_ADMIN);
$manager = $auth->createRole(User::ROLE_MANAGER);
$staff = $auth->createRole(User::ROLE_STAFF);
$auth->add($admin);
$auth->add($manager);
$auth->add($staff);
$auth->addChild($manager, $staff);
$auth->addChild($admin, $manager);
}
/**
* Инициализация разрешений
*/
private function _initPermissions()
{
$auth = Yii::$app->authManager;
$auth->removeAllPermissions();
$auth->removeAllRules();
$manageProduct = $auth->createPermission('manage_products');
$auth->add($manageProduct);
$auth->addChild($auth->getRole(User::ROLE_MANAGER), $manageProduct);
$manageOrder = $auth->createPermission('manage_orders');
$auth->add($manageOrder);
$auth->addChild($auth->getRole(User::ROLE_MANAGER), $manageOrder);
$rule = new \app\rbac\IsOrderAuthorRule();
$auth->add($rule);
$manageOwnOrder = $auth->createPermission('manage_own_orders');
$manageOwnOrder->ruleName = $rule->name;
$auth->add($manageOwnOrder);
$auth->addChild($manageOwnOrder, $manageOrder);
$auth->addChild($auth->getRole(User::ROLE_STAFF), $manageOwnOrder);
}
}
Код: Выделить всё
<?php
namespace app\rbac;
use yii\rbac\Rule;
class IsOrderAuthorRule extends Rule
{
public $name = 'isOrderAuthor';
/**
* @param string|int $user the user ID.
* @param Item $item the role or permission that this rule is associated width.
* @param array $params parameters passed to ManagerInterface::checkAccess().
* @return bool a value indicating whether the rule permits the role or permission it is associated with.
*/
public function execute($user, $item, $params)
{
return isset($params['order']) ? $params['order']->created_by == $user : false;
}
}
Код: Выделить всё
if (!Yii::$app->user->can('manage_products', ['order' => $model])) {
throw new \yii\web\ForbiddenHttpException();
}
Если же юзер - работник, то сначала проверяется это разрешение, у работника его нет, затем должно проверятся разрешение manage_own_orders, так как оно является родителем предыдущего. А у него должно проверятся правило.
Но. почему-то, так не происходит. Где тут ошибка? Спасибо.
Кеш и папку runtime чистил.