zend-framework2user-rolesbjyauthorize

How to setup Zend 2 ACL roles for single objects


my simple data model: Users can create Articles, which makes them the Owner of this particular Articles object. Users can also invite other Users to contribute on their Articles, which makes the other Users Contributors of this particular Article.

So, there are the Roles Owner and Contributor and there is the resource Article

Now my question is, how would you implement this construct best, using ZF2's ACL and maybe BjyAuthorize? I struggle here, because the roles of a Users are not globally valid for the resource Article, but have to be assigned to a single Article instance.


Solution

  • Generally

    I think, the strength of ZF2 ACL is the inheritance of privileges according to the role structure and that there are ACL-aware modules, like the MenuHelper.

    If you do not need inheritance or these other - ACL-aware - modules, you can create a very simple solution withouth ACL module.

    Solution 1. - ACL

    Resources, roles and privileges are just data. So what a role mean, depends on what you store as role in the database or what you put in as role, as you create the structure for the authorization.

    The isAllowed method of the Acl object is also just a verification base upon the data structure (of roles, resources and privileges) you created, and you can decide what to do with the information.

    What - i think - you need is and Object Access Control mechanism [can this user/group of users (= role) write/read (= privilege) this particular object (= resource)] besides the Feature Access Control [can this user/goup of users (=role) write/read (= privilege) this kind of object (= resource)].

    So if you store your Article as a resource, connect methods (write, read, delete etc) as privilege and create a relation to these privileges for a given user / group, you have achieved your goal.

    Solution 2. - ACL with Assertion

    If you store an array of contributor users on the Articles, you can use the existence of the to-check user in this array as an Assertion while creating the "allow structure".

    Solution 2.1. - ACL with Assertion - in a separate table

    You can store the Contributors in a separated table, joined with the Article table.

    Solution 3. - Serialized array of contributors

    If you do not need the robust background of ZF2 ACL, you can simply check the existence of user in the array of contributors stored on the article.

    I rather like Solution 1. for its centrally managed AC, but I see pros on Solution 2. side too. (Solution 1. mixes role and user definition, but I have already seen mix of group and user objects, so this disturbs me not that much. :))

    Listing article

    An other thing is also to consider: listing Articles, one can edit (Contributors). Checking all articles with foreach is always there. Using more/less direct database queries would ruin the ZF2 ACL philosophy. If you need to paginate too... that is a problem. :)

    There is a bunch of other solutions (and combinations of them) too. To find the right one you have to consider the count of Articles too. If you store rows for each contributor for each article in the role/resource/privilage tables, they can grow very fast.