Issues

ZF-7838: Null privilege tests incorrectly when explicit privileges are defined

Issue Type: Bug Created: 2009-09-12T14:41:03.000+0000 Last Updated: 2009-09-15T08:51:24.000+0000 Status: Resolved Fix version(s): Reporter: Juergen Schreck (mirage) Assignee: Ralph Schindler (ralph) Tags: - Zend_Acl

Related issues: Attachments:

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:

<pre class="highlight">
$acl = new Zend_Acl();
$acl->addRole('some-role');
$acl->addResource('some-resource');
$acl->allow('some-role', 'some-resource');

echo ($acl->isAllowed('some-role','some-resource') ? 'true' : 'false') . PHP_EOL; // returns true

$acl->deny('some-role', 'some-resource', 'some-privilege');

echo ($acl->isAllowed('some-role','some-resource') ? 'true' : 'false') . PHP_EOL; // returns false

Posted by Ralph Schindler (ralph) on 2009-09-15T06:54:30.000+0000

Consider this code in addendum to the above:

<pre class="highlight">
// give carte blanche access
$acl->allow('some-role', 'some-resource');

echo ($acl->isAllowed('some-role','some-resource') ? 'true' : 'false') . PHP_EOL; // returns true

// deny for a very specific priv, thus breaking carte blanche access
$acl->deny('some-role', 'some-resource', 'some-privilege');

echo ($acl->isAllowed('some-role','some-resource') ? 'true' : 'false') . PHP_EOL; // returns false
echo ($acl->isAllowed('some-role','some-resource', 'some-privildge') ? 'true' : 'false') . PHP_EOL; // returns false

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:

<pre class="literal">
// 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 GOOD

Compared to reversing the acl

<pre class="literal">
// 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 resource

I 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

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