ZF-7838: Null privilege tests incorrectly when explicit privileges are defined
Description
Assuming the following ACL
{{$acl=new Zend_Acl();}} {{$acl->add(new Zend_Acl_Resource('files'));}} {{$acl->addRole(new Zend_Acl_Role('user'));}}
{{$acl->allow('user', 'files');}} {{$acl->deny('user', 'files', 'create');}}
Then
{{isAllowed('user','files'); // returns false but should true because access was given to the entire resource and only revoked for the 'create' privilege.}}
Could not find a suitable workaround other than never checking the default access but explicitly checking each privilege. The trouble with that is that undefined default privileges will correctly reflect the explicit definition of the null privilege for the resource. However the as reported here the null privilege reports wrong if a specific privilege is denied.
Hope this makes sense.
Comments
Posted by Ralph Schindler (ralph) on 2009-09-15T06:35:32.000+0000
Interesting, I'll have to dig around, I am not sure if this is a bug or not. Either way, the bigger question is if fixing this would cause a backwards-incompatibility for people consuming Zend_Acl.
Put another way:
Posted by Ralph Schindler (ralph) on 2009-09-15T06:54:30.000+0000
Consider this code in addendum to the above:
By giving carte blanche access (no privilege), a user has full power over all privileges possible, thus it returns true. When you add a denied privilege to the tree, the user by definition can no longer have carte blanche access, thus when you ask if they have such access, it returns false, which is the correct behavior.
Posted by Juergen Schreck (mirage) on 2009-09-15T08:51:20.000+0000
Ralph,
Thanks for looking into and explaining it. I don't agree with the logic as it works different than card blanche overrides for resources and roles alongside their support for inheritance. I.E. setting specific [card blanche] access lower in the inheritance tree doesn't alter the upstream [card blanche] definitions the same way.
So, following my logic would be more consistent across the board. Frankly, I have to assume backward compatibility would not be a problem, because apparently no-one has come across this yet. :-)
If it needs to stay as it is now, it would definitely be most useful for that to be explained in the reference guide.
Aside from that, I also want to point out that card-blanche privilege access does not work consistently when checking for non-existent privileges. My gut instinct tells me that non-existent privileges should be denied as they don't exist from the ACL's point of view and thus, can't be tested. Another case could be made for it to reflect the current state of the card blanche access. Currently it doesn't operate like either of the above:
// give card-blanche access $acl->allow('some-role', 'some-resource'); // deny for a very specific priv, thus breaking carte blanche access $acl->deny('some-role', 'some-resource', 'some-privilege'); // check card blanche access echo ($acl->isAllowed('some-role','some-resource') ? 'true' : 'false') . PHP_EOL; // returns false // check against a non-existing privilege echo ($acl->isAllowed('some-role','some-resource', 'non-existent-privilige') ? 'true' : 'false') . PHP_EOL; // returns true even though card blanche is false - NOT GOODCompared to reversing the acl
// deny card-blanche access $acl->deny('some-role', 'some-resource'); // allow for a very specific priv, thus breaking carte blanche access (not really, because it's already negative) $acl->allow('some-role', 'some-resource', 'some-privilege'); // check card blanche access echo ($acl->isAllowed('some-role','some-resource') ? 'true' : 'false') . PHP_EOL; // returns false reflecting card blanche on resource // check specific privilege echo ($acl->isAllowed('some-role','some-resource', 'some-privilege') ? 'true' : 'false') . PHP_EOL; // returns true, ok - expected // check against a non-existing privilege echo ($acl->isAllowed('some-role','some-resource', 'non-existent-privilige') ? 'true' : 'false') . PHP_EOL; // returns false reflecting card blanche on resourceI guess there's multiple ways to address it (if at all) - let acl be configured for assertions to respond as pessimistic vs. optimistic - let assertions return a mixed state rather than just true or false