У меня простой ACL настраивается в acl.global.php
следующим образом:
return [ 'acl' => [ 'roles' => [ 'guest' => null, 'member' => 'guest', 'admin' => 'member' ], 'resources' => [ 'allow' => [ 'Application\Controller\Index' => ['all' => 'member'], 'Application\Controller\Error' => ['all' => 'member'], 'Item\Controller\Process' => [ 'index' => 'member', 'create' => 'member', 'showItem' => 'member', // website.tld/item/:id 'showList' => 'member' // website.tld/list-items ] ] ], ] ];
Парсер выполняет итерацию через конфигурацию и генерирует из элементов массива обращения к Zend\Permissions\Acl#allow(...)
как $this->allow($role, $controller, $action);
,
Теперь мне нужно дополнительно ограничить доступ пользователей к единому виду mydomain.tld/item/:id
( mydomain.tld/item/:id
). Пользователь должен получить доступ только в том случае, если его id
равен item.user_id
(означает: пользователь является автором / владельцем).
Как я вижу, для реализации этого требования необходимо расширить конфигурацию
'Item\Controller\Process' => [ 'index' => 'member', 'create' => 'member', 'showItem' => [ 'role' => 'member', 'assertion' => 'UserIsOwner' ] 'showList' => 'member' ]
и ввести Assertion
в Zend\Permissions\Acl#allow(...)
: $this->allow($role, $controller, $action, $assertion);
,
namespace Authorization\Acl\Assertion; use ... class UserIsOwner implements AssertionInterface { protected $userId; // To inject the $userId can be the job of the factory. public function __construct(int $userId) { $this->userId = $userId; } public function assert(Acl $acl, RoleInterface $role = null, ResourceInterface $resource = null, $privilege = null) { return return $this->userId === ???; } }
Но теперь я понятия не имею, как это утверждение должно получить item.user_id
. Пример в документе не имеет этой проблемы, поскольку он имеет активы против $_SERVER['REMOTE_ADDR']
.
Я могу ввести ItemService
чтобы узнать item.user_id
:
public function assert(Acl $acl, RoleInterface $role = null, ResourceInterface $resource = null, $privilege = null) { return $this->isUserOwner(); } protected function isUserOwner() { $itemId = ???; $item = $this->itemService->findOne($itemId); $itemOwnerId = $item->getUser()->getId(); return $this->userId == $itemOwnerId; }
Хотя тогда мне все еще нужны внешние данные – текущий item.id
В каком месте могут / должны быть введены данные переменной item (в этом случае item.user_id
или item.user_id
) для утверждения?