zend-frameworkzend-acl

Zend_Acl, How to check a user with multiple roles for resource access



i am implementing RBAC for my app, and everything is managed from database.

for example i am storing all resources/permissions in a table called permission , all roles in role table, and another table called role_permission to define which role have access to which resources/permissions.

the purpose for going with this approach is because i want the administrator of the app to create the role and assign the permission to role by himself.

User of the app can have multiple roles for example administrator, supervisor, player, referee etc.

I created a model class for Zend_Acl to add roles and resources and assign permission to it.

Below is what i did.

foreach($this->_roles as $role) {
    $this->addRole(new Zend_Acl_Role($role['id']));
}
foreach($this->_permissions as $permmission) {
    $this->addResource(new Zend_Acl_Resource($permmission['id']));
}
foreach($this->_rolePermissions as $value) {
    $this->allow($value['role_id'], $value['permmission_id']);
}
$this->allow($this->_roleAdmin);

it works fine if i want to check wether a permission exist for a particular role for example by using this code.

echo $acl->isAllowed($role, $permission) ? 'allowed' : 'denied';

however i want to check with multiple roles wether the current permission exist for a user with multiple roles.

how am i supposed to check wether the user with multiple roles such as referee, supervisor has the access to resource create report. with isAllowed() you can only check for permission for only 1 role.


Solution

  • The approach I usually take is to create a class that extends Zend_Acl, and extend the isAllowed() function so it can take my user object as a parameter instead. It then loops through that user's roles performing the check for each one. E.g.:

    public function isAllowed($roleOrUser = null, $resource = null, $privilege = null)
    {
        if ($roleOrUser instanceof Users_Model_User) {
            // check each of that user's roles
            foreach ($roleOrUser->roles as $role) {
                if (parent::isAllowed($role, $resource, $privilege)) {
                    return true;
                }
            }
    
            return false;
        } else {
            return parent::isAllowed($roleOrUser, $resource, $privilege);
        }
    }