This question came up while designing a dedicated ACL system for a custom application, but I think it applies to ACL systems in general, as I haven't found out how to tackle this problem by looking at some of the mainstream systems, like Zend_ACL.
In my application, the permissions are granted dynamically, for example: a user gets view permissions on an activity because he is a member of the team the activity is linked to. This builds on the assumption that you always have an Employee (user) that wants to perform an action (view/edit/etc) on an Item (one of the objects in my application, eg Activity, Team, etc). This is sufficient for my targeted use;
$Activity = new Activity( $_POST['activity_id'] );
$Acl = new Acl( $Activity );
if ( !$Acl->check( 'edit' ) {
throw new AclException('no permission to edit');
}
My Acl class contains all the business rules to grant the permissions, and they're created 'on the fly' (although sometimes cached for performance reasons);
/**
* Check the permissions on a given activity.
* @param Activity $Activity
* @param int $permission (optional) check for a specific permission
* @return mixed integer containing all the permissions, or a bool when $permission is set
*/
public function checkActivity( Activity $Activity, $permission = null ) {
$permissions = 0;
if ( $Activity->owner_actor_id == $this->Employee->employee_id ) {
$permissions |= $this->activity['view'];
$permissions |= $this->activity['remove'];
$permissions |= $this->activity['edit'];
} elseif ( in_array( $this->Employee->employee_id, $Activity->contributor_ids_arr ) ) {
$permissions |= $this->activity['view'];
} else {
/**
* Logged in user is not the owner of the activity, he can contribute
* if he's in the team the activity is linked to