Issues

ZF-3390: Inheritage of roles: rules are checked by parent roles

Issue Type: Bug Created: 2008-06-04T14:13:27.000+0000 Last Updated: 2009-08-14T14:33:08.000+0000 Status: Resolved Fix version(s): - 1.9.1 (11/Aug/09)

Reporter: Mathias Schreck (lo1tuma) Assignee: Ralph Schindler (ralph) Tags: - Zend_Acl

Related issues: - ZF-1722

Attachments:

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

<pre class="highlight">
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:

<pre class="highlight">
$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.

<pre class="highlight">
$this->allow('guest', 'video', 'watch', new VideoWatchAssertion());
$this->allow('member', 'video', 'watch', new VideoWatchAssertion());
$this->allow('member');

Comments

Posted by Marc Jakubowski (octavian) on 2008-07-01T09:17:21.000+0000

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.

Posted by Mathias Schreck (lo1tuma) on 2008-07-09T05:22:19.000+0000

You are right, your solution uses the correct class. But I have to work with the current instance that the assertion can handle the object specific properties.

Posted by Wil Sinclair (wil) on 2009-01-14T13:31:39.000+0000

Assigning to Ralph to get closure on this issues.

Posted by Ralph Schindler (ralph) on 2009-07-30T18:48:32.000+0000

There is a fix in place for ZF-1721 and ZF-1722 which I think will fix this issues, please test r17317 in trunk.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts