Details
Description
Hi,
I think there is a problem of inheritage of roles. If an inhertited role is checked by isAllowed(), the rules are checked on an instance (Zend_Acl_Role) of the parent and not on the instance of the current role.
Example:
ACL definitions
class TestAcl extends Zend_Acl { public function __construct() { $this->add(new Zend_Acl_Resource('video')); $this->addRole(new Zend_Acl_Role('guest')); $this->addRole(new Zend_Acl_Role('member'), 'guest'); $this->allow('guest', 'video', 'watch', new VideoWatchAssertion()); $this->allow('member'); } } class Video implements Zend_Acl_Resource_Interface { public $property; public function __construct($p) { $this->property = 0; if($p) { $this->property = 1; } } public function getResourceId() { return 'video'; } } class User implements Zend_Acl_Role_Interface { public $property; private $roleId; public function __construct($role, $p) { $this->roleId = $role; $this->property = 0; if($p) { $this->property = 1; } } public function getRoleId() { return $this->roleId; } } class VideoWatchAssertion implements Zend_Acl_Assert_Interface { public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $user=null, Zend_Acl_Resource_Interface $video=null, $privilege=null) { if($video->property == 1) { if($user->property != 1) { return false; } } return true; } }
Check for access:
$acl = new TestAcl(); $user = new User('member', true); $video = new Video(true); $result = $acl->isAllowed($user, $video, 'watch');
The assertion is called by an instance of Zend_Acl_Role (roleId = guest) and not by an instance of User; but the check of the User instance for access to object specific properties/methods would be absolutly necessary.
It would be very helpful if the rules of the parent role is checked by the instance of the current role.
Of course it is possible to bypass this problem by defining the rules for each single role, but it is not very nice.
$this->allow('guest', 'video', 'watch', new VideoWatchAssertion()); $this->allow('member', 'video', 'watch', new VideoWatchAssertion()); $this->allow('member');
Issue Links
| This issue duplicates: | ||||
| ZF-1722 | Zend_Acl assertions broken when inheritance is required (ie DepthFirstSearch) |
|
|
|
In your TestAcl::__construct() you assigned standard Zend_Acl_Role and Zend_Acl_Resource objects so objects of these types are stored.
Why don´t you pass the User and Video objects?
$result = $acl->isAllowed($user, $video, 'watch')
only extracts the IDs of your custom objects and looks in the registry for existing objects with that IDs, and then of course the standard ones will be found and used for the assertions.