I have based my application upon the Zend Framework. I am using Zend_Auth
for authentication, but I'm not sure if Zend_Acl
will work for me because, frankly, the examples I've seen are either too simplistic for my needs or confuse me.
I'm thinking of elements in my application as Resources and these Resources can have have Privileges. Roles containing Resource Privileges are dynamically defined assigned to users. I'm storing this information in normalized tables.
- Users have a Role
- A Role can have multiple Resources
- Resources can have multiple Privileges
Roles are really just collections of Resource Privileges with no hierarchy. An example of a Resource would be 'Page'. Everyone can view the pages, but a authenticated user would need 'add', 'edit', or 'delete' privileges to do anything else with pages.
Does this mesh with Zend ACL? Am I thinking ACL in a way that's going to create problems for me?
My Solution
Typeonerror gets the credit, but here's my specific solution.
I extended Zend_Acl
to simplify my usage because I only load the role of the current user:
class My_Acl extends Zend_Acl
{
protected $_role_id;
public function setRole($role_id)
{
$this->_role_id = $role_id;
return $this->addRole($role_id);
}
public function getRole()
{
return $this->_role_id;
}
public function deny($resource, $privilege)
{
return parent::deny($this->_role_id, $resource, $privilege);
}
public function allow($resource, $privilege)
{
return parent::allow($this->_role_id, $resource, $privilege);
}
public function isAllowed($resource, $privilege)
{
return parent::isAllowed($this->_role_id, $resource, $privilege);
}
}
To populate the the ACL I execute a query which returns resource
, privilege
, and role_id
columns. The role_id
column is null in the result set if the user's role does not have that privilege.
$acl = new My_Acl();
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$userInfo = $auth->getStorage()->read();
$acl->setRole($userInfo->role_id);
} else {
$acl->setRole('');
}
// QUERY HERE
foreach ($privileges as $privilege) {
if (!$acl->has($privilege['resource'])) {
$acl->addResource($privilege['resource']);
}
if (is_null($privilege['role_id'])) {
$acl->deny($privilege['resource'], $privilege['privilege']);
} else {
$acl->allow($privilege['resource'], $privilege['privilege']);
}
}