Remove Zend\Acl from 2.0, update and then add to 2.1?

classic Classic list List threaded Threaded
26 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: Remove Zend\Acl from 2.0, update and then add to 2.1?

weierophinney
Administrator
-- Rob Allen <[hidden email]> wrote
(on Tuesday, 24 July 2012, 10:34 AM +0100):

> On 23 Jul 2012, at 15:24, Matthew Weier O'Phinney wrote:
>
> > I think at this point the only real question I have is what _namespace_
> > our current implementation should live in for the stable release. Right
> > now, it's a top-level component, and I wonder if it should live in a
> > "Zend\Security" namespace, or a "Zend\Permissions" namespace.
>
> Not Zend\Security.
>
> If there's going to be more than one ACL implementation within ZF, then we have two choices:
>
> 1. Separate top level components: Zend\Acl, Zend\Rbac, Zend\Dacl, etc
> 2. A parent namespace: Zend\Permissions or Zend\AccessControl would be obvious choices.
>
> Personally, I don't mind with either way.  
>
> In any case, it would be nice if someone ensured that the public API
> to Zend\Acl was correct for ZF2 before we hit stable.

Followup:

I've renamed it to Zend\Permissions\Acl at this time, and Rob has
reviewed and merged the patch.

--
Matthew Weier O'Phinney
Project Lead            | [hidden email]
Zend Framework          | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Reply | Threaded
Open this post in threaded view
|

Re: Remove Zend\Acl from 2.0, update and then add to 2.1?

EvanDotPro
On Tue, Jul 24, 2012 at 2:22 PM, Matthew Weier O'Phinney <[hidden email]> wrote:
-- Rob Allen <[hidden email]> wrote
(on Tuesday, 24 July 2012, 10:34 AM +0100):
> On 23 Jul 2012, at 15:24, Matthew Weier O'Phinney wrote:
>
> > I think at this point the only real question I have is what _namespace_
> > our current implementation should live in for the stable release. Right
> > now, it's a top-level component, and I wonder if it should live in a
> > "Zend\Security" namespace, or a "Zend\Permissions" namespace.
>
> Not Zend\Security.
>
> If there's going to be more than one ACL implementation within ZF, then we have two choices:
>
> 1. Separate top level components: Zend\Acl, Zend\Rbac, Zend\Dacl, etc
> 2. A parent namespace: Zend\Permissions or Zend\AccessControl would be obvious choices.
>
> Personally, I don't mind with either way.
>
> In any case, it would be nice if someone ensured that the public API
> to Zend\Acl was correct for ZF2 before we hit stable.

Followup:

I've renamed it to Zend\Permissions\Acl at this time, and Rob has
reviewed and merged the patch.

/me grumbles something about namespaces existing to prevent naming collisions, not for organizing hierarchies.

...but I digress.

So at a glance, I see two pimary concerns about Zend\Acl.

1) Performance... There's a lot of talk in this thread and on the ZF-Commons ZfcAcl RFC comments about Zend\Acl having poor performance. However I've yet to see a single benchmark or profiler output. I'm going to play devils advocate here ask that those complaining please provide numbers to back up their claims so that we can have something concrete to work with. Also, we've had planned to refactor to use spl datastructures which we can speculate will help quite a bit with performance. Regardless, we have *NO BENCHMARKS*. Please before anyone says another word about performance, let's see some benchmarks? Otherwise it's just words.

2) Can't easily "reverse" query the ACL... This was brought up by Artur. He says that while Zend\Acl allows you to easily query "Does this user/role have access to this resource?", it doesn't allow for an easy way to ask "Which roles have access to this resource?".

To #2, I'd say that's out of the scope of an ACL component. In my opinion, an ACL component should really just allow for you to add your own way for querying a boolean when isAllowed() is called. That's up to you. If you have to add _every role_ and _every resource_ and _every permission_ for _every request_ to have a functional  ACL, there is something horribly wrong. On a request with a user that has two roles (or maybe even just one role with a parent role), where two resources are queried, those should be the only roles and resources that are "loaded" by the ACL for that request, period. I can't claim to have enough experience with Zend\Acl to know if this is supported, easy, or incredibly convoluted to accomplish, but I would say any refactoring that's done should be working toward something that accomplishes that goal (if it's not already supported).

Personally, in the spirit of modularity, I'd opt for an event-based approach. A call to the ACL service isAllowed() should simply trigger an event with parameters such as the current identity's roles, the resource, and the permission. The listeners (provided by modules) can query for that however they want. That's up to developers (and/or an ACL module!!!).

That said, I suggested a similar approach for Zend\Authentication in the past and was shot down due to introducing a dependency on Zend\EventManager, and I'm sure the same argument can be made here. I ended up building the functionality as a special event-driven aggregate adapter which is included by default in ZfcUser instead.

--
Evan Coury


 
Reply | Threaded
Open this post in threaded view
|

Re: Remove Zend\Acl from 2.0, update and then add to 2.1?

EvanDotPro
On Tue, Jul 24, 2012 at 3:14 PM, Evan Coury <[hidden email]> wrote:

>
> On Tue, Jul 24, 2012 at 2:22 PM, Matthew Weier O'Phinney
> <[hidden email]> wrote:
>>
>> -- Rob Allen <[hidden email]> wrote
>> (on Tuesday, 24 July 2012, 10:34 AM +0100):
>> > On 23 Jul 2012, at 15:24, Matthew Weier O'Phinney wrote:
>> >
>> > > I think at this point the only real question I have is what
>> > > _namespace_
>> > > our current implementation should live in for the stable release.
>> > > Right
>> > > now, it's a top-level component, and I wonder if it should live in a
>> > > "Zend\Security" namespace, or a "Zend\Permissions" namespace.
>> >
>> > Not Zend\Security.
>> >
>> > If there's going to be more than one ACL implementation within ZF, then
>> > we have two choices:
>> >
>> > 1. Separate top level components: Zend\Acl, Zend\Rbac, Zend\Dacl, etc
>> > 2. A parent namespace: Zend\Permissions or Zend\AccessControl would be
>> > obvious choices.
>> >
>> > Personally, I don't mind with either way.
>> >
>> > In any case, it would be nice if someone ensured that the public API
>> > to Zend\Acl was correct for ZF2 before we hit stable.
>>
>> Followup:
>>
>> I've renamed it to Zend\Permissions\Acl at this time, and Rob has
>> reviewed and merged the patch.
>
>
> /me grumbles something about namespaces existing to prevent naming
> collisions, not for organizing hierarchies.
>
> ...but I digress.
>
> So at a glance, I see two pimary concerns about Zend\Acl.
>
> 1) Performance... There's a lot of talk in this thread and on the
> ZF-Commons ZfcAcl RFC comments about Zend\Acl having poor performance.
> However I've yet to see a single benchmark or profiler output. I'm going to
> play devils advocate here ask that those complaining please provide numbers
> to back up their claims so that we can have something concrete to work with.
> Also, we've had planned to refactor to use spl datastructures which we can
> speculate will help quite a bit with performance. Regardless, we have *NO
> BENCHMARKS*. Please before anyone says another word about performance, let's
> see some benchmarks? Otherwise it's just words.
>
> 2) Can't easily "reverse" query the ACL... This was brought up by Artur.
> He says that while Zend\Acl allows you to easily query "Does this user/role
> have access to this resource?", it doesn't allow for an easy way to ask
> "Which roles have access to this resource?".
>
> To #2, I'd say that's out of the scope of an ACL component. In my opinion,
> an ACL component should really just allow for you to add your own way for
> querying a boolean when isAllowed() is called. That's up to you. If you have
> to add _every role_ and _every resource_ and _every permission_ for _every
> request_ to have a functional  ACL, there is something horribly wrong. On a
> request with a user that has two roles (or maybe even just one role with a
> parent role), where two resources are queried, those should be the only
> roles and resources that are "loaded" by the ACL for that request, period. I
> can't claim to have enough experience with Zend\Acl to know if this is
> supported, easy, or incredibly convoluted to accomplish, but I would say any
> refactoring that's done should be working toward something that accomplishes
> that goal (if it's not already supported).
>
> Personally, in the spirit of modularity, I'd opt for an event-based
> approach. A call to the ACL service isAllowed() should simply trigger an
> event with parameters such as the current identity's roles, the resource,
> and the permission. The listeners (provided by modules) can query for that
> however they want. That's up to developers (and/or an ACL module!!!).

To clarify this, it'd look something like:

$events->trigger(AclEvent::EVENT_QUERY_ACL, $event, function($result) {
    if ($result instanceof AclResult) { // honestly this could just
check for a boolean, having an AclResult object is over-engineering.
        return true; // short circuit
    }
    return false; // keep checking remaining listeners
});


And a listener would be as simple as....

$events->attach(AclEvent::EVENT_QUERY_ACL, function($event) {
    $role = $event->getRole();
    $resource = $event->getResource();
    $privilege = $event->getPrivilege();

    // Do anything you want to figure out if you're concerned about
allowing/denying this.
    // Could query a db, check a config file, or simply call the
existing Acl::isAllowed() to maintain the existing behavior and
features.
});

--
Evan Coury
Reply | Threaded
Open this post in threaded view
|

Re: Remove Zend\Acl from 2.0, update and then add to 2.1?

Artur Bodera
In reply to this post by EvanDotPro
On Wed, Jul 25, 2012 at 12:14 AM, Evan Coury <[hidden email]> wrote:
1) Performance... There's a lot of talk in this thread and on the ZF-Commons ZfcAcl RFC comments about Zend\Acl having poor performance. However I've yet to see a single benchmark or profiler output. I'm going to play devils advocate here ask that those complaining please provide numbers to back up their claims so that we can have something concrete to work with. Also, we've had planned to refactor to use spl datastructures which we can speculate will help quite a bit with performance. Regardless, we have *NO BENCHMARKS*. Please before anyone says another word about performance, let's see some benchmarks? Otherwise it's just words.

No need for that. If you know how Zend_Acl is designed and how php works, then you know that container with 1000 resources instantiates significantly slower than container with 10 resources. If you have a (successful) web application you can easily exceed that number in a short period of time (rendering Zend_Acl useless, forcing you to replace it with something else).

Go ahead, make a loop, follow http://framework.zend.com/manual/en/zend.acl.introduction.html and create ACL container filled with moderate amount of data, then re-instantiate it with each and every request. I don't need a benchmark to understand that.

 

2) Can't easily "reverse" query the ACL... This was brought up by Artur. He says that while Zend\Acl allows you to easily query "Does this user/role have access to this resource?", it doesn't allow for an easy way to ask "Which roles have access to this resource?".

It's not a reverse query, it's a normal query. ACL stands for Access Control Lists - so give me a _list_ of users that can access X resource.... or just give me a list of resources. 

No? Why not? I just want a list of resources now - impossible due to dynamic ad-hoc loading from multiple sources? 
If it's not a list, then it's a black-box "permissions checker".

Here's how easily cake implemented the opposite back in 2006! 
drupal before 2006: http://drupal.org/project/acl/


 

To #2, I'd say that's out of the scope of an ACL component. In my opinion, an ACL component should really just allow for you to add your own way for querying a boolean when isAllowed() is called. That's up to you. If you have to add _every role_ and _every resource_ and _every permission_ for _every request_ to have a functional  ACL, there is something horribly wrong. On a request with a user that has two roles (or maybe even just one role with a parent role), where two resources are queried, those should be the only roles and resources that are "loaded" by the ACL for that request, period. I can't claim to have enough experience with Zend\Acl to know if this is supported, easy, or incredibly convoluted to accomplish, but I would say any refactoring that's done should be working toward something that accomplishes that goal (if it's not already supported).

Well, then I don't need the whole Zend_Acl component, I just need isAllowed() method then. 

If everything is loaded ad-hoc I do NOT need a list... 

here's a trivial, book example of ACL:

             resourceA   resource B
====================================
userX         ALLOWED     DENIED
userY         ALLOWED     DENIED
userZ         DENIED      ALLOWED

This list contains 2 resources and 3 users, cross-referenced with permissions. It is an access control list because it lists users, resources and their permissions. Queries work on Cartesian product of multiple dimensions - ACLs can also contain hierarchies and multiple level of access permissions. The only way to archive granularity is to have 1 ACL resource for each 1 real resource (i.e. a page, controller, action, file, model instance etc.). The problem with Zend_Acl is that it lives in PHP memory and there is no way to preserve it in memory between requests. Even when converted to plain arrays and injected upon instantiating it's still a memory hog.

Ad-hoc resource instantiation means, that the ACL looks like this:

                                    
====================================
 ..
 ..              [crickets]
 ..


There is absolutely nothing, up until there's a query. 
In such case, we create needed items ad-hoc:

->isAllowed('userY','resourceB')

                         resource B
====================================
             
userY                     DENIED
             

Now we have an ACL with a single resource and a single user. 
But, it's not a list.... It's merely a vector. I don't need that... just give me true|false to my query.



 

Personally, in the spirit of modularity, I'd opt for an event-based approach. A call to the ACL service isAllowed() should simply trigger an event with parameters such as the current identity's roles, the resource, and the permission. The listeners (provided by modules) can query for that however they want. That's up to developers (and/or an ACL module!!!).

That said, I suggested a similar approach for Zend\Authentication in the past and was shot down due to introducing a dependency on Zend\EventManager, and I'm sure the same argument can be made here. I ended up building the functionality as a special event-driven aggregate adapter which is included by default in ZfcUser instead.


This is permissions resolver service, not a list (ACL) !!!

The API would be:

PermissionsService::isAllowed(RoleInterface $role,  ResourceInterface $resource, PermissionsInterface $perm);

Modules would listen to 

$sm->get('permissions')->listen(PS::isAllowed, $this->checkPermissions);

Now you have a modular approach, but the service would need to loop through all listeners for each query for each module and it still does not allow you to compile any kind of list. It also decentralizes permission control ... what's stopping a malicious module to attach a listener with 

   { return true; // always }
 


My main problem with Zend_Acl is that it's a ticking bomb. It's fine when you got through quick-start, it's fine when you toy with it and include it in your application ... but it's a pain when you figure out that you application has grown in just a month time and now your ACL needs to store thousands of items and it struggles to do so. 
That's all just after following official manual: http://framework.zend.com/manual/en/zend.acl.html

Then comes the time for workarounds, hacks, "solutions" and other ways to make it behave. Ad-hoc loading is NOT a solution, it's a workaround to the problem. If everyone here was to follow Zend_Acl manual, then all resources, roles and rules should live within the ACL at all times. Assertions are there to resolve complex queries _on top_ of the list. They were not meant to replace everything else.... otherwise - I'd still argue you can just use priorityqueue with a few lambdas and you get yourself a permissions checker (or use EM, same thing).

Is Zend_Acl a training material then? 
A component which should not be used in real-world apps ? 
Or am I forced to use hacks with it from the start? Why not include them in the manual then ?

Or why not just redesign the whole thing?

A.
Reply | Threaded
Open this post in threaded view
|

Re: Remove Zend\Acl from 2.0, update and then add to 2.1?

richard
This post has NOT been accepted by the mailing list yet.
I entirely agree with Artur. The current ACL implementation should either be renamed to reflect what it is, or expanded to provide a full set of ACL functionality.

As Access Control Paradims such as ACL, DACL, CACL and RBAC have "Access Control" in common,  I would propose a Zend\AccessControl namespace.

I agree with Evan that an event driven approach to AC core functionality is the way to go. I think this option is the most feasible to consume in the largest number of use cases.

Regards.



Reply | Threaded
Open this post in threaded view
|

Re: Remove Zend\Acl from 2.0, update and then add to 2.1?

EvanDotPro
In reply to this post by Artur Bodera
Hi Artur,

On Wed, Jul 25, 2012 at 2:08 AM, Artur Bodera <[hidden email]> wrote:

> On Wed, Jul 25, 2012 at 12:14 AM, Evan Coury <[hidden email]> wrote:
>>
>> 1) Performance... There's a lot of talk in this thread and on the
>> ZF-Commons ZfcAcl RFC comments about Zend\Acl having poor performance.
>> However I've yet to see a single benchmark or profiler output. I'm going to
>> play devils advocate here ask that those complaining please provide numbers
>> to back up their claims so that we can have something concrete to work with.
>> Also, we've had planned to refactor to use spl datastructures which we can
>> speculate will help quite a bit with performance. Regardless, we have *NO
>> BENCHMARKS*. Please before anyone says another word about performance, let's
>> see some benchmarks? Otherwise it's just words.
>
>
> No need for that. If you know how Zend_Acl is designed and how php works,
> then you know that container with 1000 resources instantiates significantly
> slower than container with 10 resources. If you have a (successful) web
> application you can easily exceed that number in a short period of time
> (rendering Zend_Acl useless, forcing you to replace it with something else).
>
> Go ahead, make a loop, follow
> http://framework.zend.com/manual/en/zend.acl.introduction.html and create
> ACL container filled with moderate amount of data, then re-instantiate it
> with each and every request. I don't need a benchmark to understand that.

As I mentioned lower in my previous response, you should only need to
load as many resources into the container as needed to satisfy the
queries for a particular request. In a small application with only a
handful of resources, it could be beneficial to load all of the
resources into RAM on each request rather than lazy loading (1 query
with 15 results rather than 15 queries with 1 result each). However in
the larger applications you're describing, it's obvious lazy loading
is the only solution that makes any sense in a PHP (stateless,
bootstrap-per-request) environment. You're being counter-productive by
repeating that Zend\Acl is slow because you're loading thousands of
resources and roles on every request. Obviously for ($i=0; $i<10;
$i++) { /* do some work here */ } is going to be faster than for
($i=0; $i<1000; $i++) { /* do some work here */ }. Let's move on from
that, please.

What I'd like to see when I ask for a benchmark or example is some
actual code backing up your claims and use-case. Show me an example
where performance is an issue and illustrates why lazy-loading is not
an acceptable solution; code that the community can look at and say,
"okay, yes this is a valid use-case and performance is definitely a
concern here", or "okay, yes this example has a performance issue, but
THIS is probably how you should have done it instead". Without a
concrete example, you're expecting everyone to just take you at your
word and assume that your use-case is real, the performance issues you
describe are real, and your implementation was correct. While I don't
necessarily doubt your claims, I'm not comfortable with us making a
big decision such as scraping and re-designing an entire component
(and subsequently having a 2.0 release missing such a critical
feature) simply based on, "Well, Artur told us it was bad, and a
couple other people +1'd on the mailing list". By making decisions
this way, we become vulnerable to the bandwagon effect as a community,
which is a Very Bad Thing(tm).

>> 2) Can't easily "reverse" query the ACL... This was brought up by Artur.
>> He says that while Zend\Acl allows you to easily query "Does this user/role
>> have access to this resource?", it doesn't allow for an easy way to ask
>> "Which roles have access to this resource?".
>
>
> It's not a reverse query, it's a normal query. ACL stands for Access Control
> Lists - so give me a _list_ of users that can access X resource.... or just
> give me a list of resources.
>
> No? Why not? I just want a list of resources now - impossible due to dynamic
> ad-hoc loading from multiple sources?

I'm not sure how you drew the conclusion that it's impossible. Quickly
thinking about it, I can think of at least two strategies that could
be used to solve this use-case; the most invasive of which would
simply require a non-breaking addition to the public API of
Zend\Acl\Acl.

> If it's not a list, then it's a black-box "permissions checker".

Okay, so you don't want dynamic or lazy loading because, as you say,
the entire *list* should be available. However, you say that your
biggest problem with Zend\Acl is that.... the entire list is
available. Did I miss the part where you explained what you *do* want?

In the ZF-Commons RFC comments, you said,

"The solution is SQL db backed ACL, which relies on db queries for
checking permissions. It's very easy to implement and is trivial to
scale. Consider your roles, resources and rules as properly indexed
and denormalized db tables. ACL check against that is just a single
compound query, while complex ACL checks can be handled with stored
routines."

However, I fail to see how this is any different? The result is
exactly what you explained below, where the "list" is populated as
queries are made. Also, my suggestion is not exclusive of this, in
fact, I'd argue that either the framework itself or even ZfcAcl should
provide a listener which _does_ use the DB as a source for resolving
ACL queries. With my suggested strategy, this would also be compatible
with the existing in-memory model, as they'd be two separate
listeners.

> Here's how easily cake implemented the opposite back in 2006!
> http://bakery.cakephp.org/articles/theshz/2006/11/28/user-permissions-and-cakephp-acl
> drupal before 2006: http://drupal.org/project/acl/
> joomla since 1.5 or so:
> http://blog.gibilogic.com/2011/03/quick-glance-at-joomla-core-acl-table/

Okay...

>> To #2, I'd say that's out of the scope of an ACL component. In my opinion,
>> an ACL component should really just allow for you to add your own way for
>> querying a boolean when isAllowed() is called. That's up to you. If you have
>> to add _every role_ and _every resource_ and _every permission_ for _every
>> request_ to have a functional  ACL, there is something horribly wrong. On a
>> request with a user that has two roles (or maybe even just one role with a
>> parent role), where two resources are queried, those should be the only
>> roles and resources that are "loaded" by the ACL for that request, period. I
>> can't claim to have enough experience with Zend\Acl to know if this is
>> supported, easy, or incredibly convoluted to accomplish, but I would say any
>> refactoring that's done should be working toward something that accomplishes
>> that goal (if it's not already supported).
>
>
> Well, then I don't need the whole Zend_Acl component, I just need
> isAllowed() method then.
>
> If everything is loaded ad-hoc I do NOT need a list...
>
> here's a trivial, book example of ACL:
>
>              resourceA   resource B
> ====================================
> userX         ALLOWED     DENIED
> userY         ALLOWED     DENIED
> userZ         DENIED      ALLOWED
>
> This list contains 2 resources and 3 users, cross-referenced with
> permissions. It is an access control list because it lists users, resources
> and their permissions. Queries work on Cartesian product of multiple
> dimensions - ACLs can also contain hierarchies and multiple level of access
> permissions. The only way to archive granularity is to have 1 ACL resource
> for each 1 real resource (i.e. a page, controller, action, file, model
> instance etc.). The problem with Zend_Acl is that it lives in PHP memory and
> there is no way to preserve it in memory between requests. Even when
> converted to plain arrays and injected upon instantiating it's still a
> memory hog.
>
> Ad-hoc resource instantiation means, that the ACL looks like this:
>
>
> ====================================
>  ..
>  ..              [crickets]
>  ..
>
>
> There is absolutely nothing, up until there's a query.
> In such case, we create needed items ad-hoc:
>
> ->isAllowed('userY','resourceB')
>
>                          resource B
> ====================================
>
> userY                     DENIED
>
>
> Now we have an ACL with a single resource and a single user.
> But, it's not a list.... It's merely a vector. I don't need that... just
> give me true|false to my query.

Yes, that is exactly the behavior that I'm describing, and I
understand the implications quite well. Thank you for the explanation
though, as it might help others understand what I'm proposing.

I see what you just described as a huge positive, not a negative, and
I'd argue that you're wrong about not needing the list, as it would
still be useful in this model. Assuming we always attach a high
priority listener which checks the in-memory Zend\Acl *list* first, it
serves, at minimum, two useful purposes:

1) It serves as a runtime cache. Upon a listener returning a boolean
resposne for a particular query and it being added to the list as you
describe, subsequent requests for the same resource would be resolved
by the higher priority listener which is checking the in-memory list
first, so no other listeners would need to be called.

2) It solves the use-case I described above: a small application with
only a handful of resources, where it makes more sense to load all of
the resources into RAM on each request rather than lazy loading (1
query with 15 results rather than 15 queries with 1 result each). In a
case like this, you'd simply be able to continue using Zend\Acl as you
do today, building up the ACL using the OOP interface for each
request. While it's not really my concern, this could even be done
without breaking BC at all.


>> Personally, in the spirit of modularity, I'd opt for an event-based
>> approach. A call to the ACL service isAllowed() should simply trigger an
>> event with parameters such as the current identity's roles, the resource,
>> and the permission. The listeners (provided by modules) can query for that
>> however they want. That's up to developers (and/or an ACL module!!!).
>>
>>
>> That said, I suggested a similar approach for Zend\Authentication in the
>> past and was shot down due to introducing a dependency on Zend\EventManager,
>> and I'm sure the same argument can be made here. I ended up building the
>> functionality as a special event-driven aggregate adapter which is included
>> by default in ZfcUser instead.
>
>
>
> This is permissions resolver service, not a list (ACL) !!!
>
> The API would be:
>
> PermissionsService::isAllowed(RoleInterface $role,  ResourceInterface
> $resource, PermissionsInterface $perm);
>
> Modules would listen to
>
> $sm->get('permissions')->listen(PS::isAllowed, $this->checkPermissions);
>
> Now you have a modular approach, but the service would need to loop through
> all listeners for each query for each module and it still does not allow you
> to compile any kind of list. It also decentralizes permission control ...
> what's stopping a malicious module to attach a listener with
>
>    { return true; // always }

I *really* wish people would stop making this argument. It's completely invalid.

What's to stop anyone from making any module that does anything
malicious? Nothing! By installing a module, you're accepting it as
trusted code. If you install a Symfony2 bundle, Wordpress plugin,
Drupal module, etc, you are TRUSTING that code. Anyone could put
die('Haha I broke your app!!'); anywhere they want. If that code has
database access, they could do whatever that db user has permission to
do (delete, truncate, drop table?). We cannot and should not try to
police every function that modules can and cannot run. These issues
have been solved for years and the answer is simple: author reputation
and package signatures (something I'll blog about later).

> My main problem with Zend_Acl is that it's a ticking bomb. It's fine when
> you got through quick-start, it's fine when you toy with it and include it
> in your application ... but it's a pain when you figure out that you
> application has grown in just a month time and now your ACL needs to store
> thousands of items and it struggles to do so.
> That's all just after following official manual:
> http://framework.zend.com/manual/en/zend.acl.html

Sure, and ACL is not the only place where the ZF reference guide is
lacking by any means.

> Then comes the time for workarounds, hacks, "solutions" and other ways to
> make it behave. Ad-hoc loading is NOT a solution, it's a workaround to the
> problem.

I haven't seen a single argument that justifies labeling event or
priority queue based ACL loading a "hack" or "workaround".

> If everyone here was to follow Zend_Acl manual, then all resources,
> roles and rules should live within the ACL at all times. Assertions are
> there to resolve complex queries _on top_ of the list. They were not meant
> to replace everything else.... otherwise - I'd still argue you can just use
> priorityqueue with a few lambdas and you get yourself a permissions checker
> (or use EM, same thing).

Can you please clarify what your actual suggestion is? So far all I've
found is this:

"The solution is SQL db backed ACL, which relies on db queries for
checking permissions. It's very easy to implement and is trivial to
scale. Consider your roles, resources and rules as properly indexed
and denormalized db tables. ACL check against that is just a single
compound query, while complex ACL checks can be handled with stored
routines."

...which directly contradicts other arguments you're trying to make.
Also, my suggestion would be supplemental to such an approach, not
exclusive.

> Is Zend_Acl a training material then?
> A component which should not be used in real-world apps ?
> Or am I forced to use hacks with it from the start? Why not include them in
> the manual then ?

What are you referring to as "hacks" here, and why?

> Or why not just redesign the whole thing?

Bottom line:

1) The public API for Zend\Acl is fine. See Ben Youngblood's post above.
2) We're not redesigning Zend\Acl for ZF2. It's too late to to make a
decision like this for 2.0. Even if we made an exception, we'd have to
ship 2.0 without ACL to be able to introduce a redesigned version in
2.x. I don't think that's okay at all.

--
Evan Coury
12