Please help me implement access control lists for my PHP web application. I'm using Zend_ACL specifically.
I want fine grained, application wide control over what specific entity (be it a user or group) has access to what resource. I would like to be able to grant access to a particular resource instance, but also to all resources of that type. For example:
- User #1 has editing privileges on all posts
- User #2 is a guest editor and has edit privileges on post ID #5
- Group #1 (guest) has read privileges on everything
- The users belong to a user group who inherits from guest.
My question is this: should an ACL reference types of resources or specific instances there of? Should I grant users the fundamental, resource-type-wide priviledges using the ACL like this:
- grant edit to user #1 on post
- grant user #2 nothing more than it's inheritance
- grant group #1 read on all resources
- implement an exceptions table to track grants and denys on specific resources
Or should I create resources for all the individual instances of my different types of resources and go on a granting rampage to allow all users to read all resources? Seems rather brute-like.
My current solution is this: using resource inheritance, create a parent most resource of no type, a child of this root for each type, and then a child of each type for each instance. This allows me to grant on one particular type and deny on a few instances, or deny a particular type but grant on one instance (like for user #2 above). This unifies my permissions system nicely, however my needs are more complex. Soon, resource types will be nested. So I will different modules who can be parents or children. An example: a site wide photo gallery module, an announcements module with another more exclusive gallery residing underneath it. I'm not quite sure what to do to address this. I would still like to have the ability to grant on all galleries, or just to one, or just so some photos underneath. Bear in mind that Zend_ACL doesn't support multiple inheritance for resources.
What is the best way to implement this? All with an ACL or using some logic built into each module?