Zend Framework
Utilizando Zend_ACL
Conforme falamos no post anterior sobre as Diferenças entre Zend_Auth e Zend_ACL, hoje falaremos, de uma forma mais prática, sobre a Zend_ACL (Access Control List).
O objetivo da Zend_ACL é verificar se o usuário tem permissão X para a área Y da aplicação.
Para isso é utilizada a seguinte nomenclatura:
- Role – Praticamente é o grupo ou o nível de hierarquia que o usuário foi designado (Ex: Administrator).
- Resource – Mais especificamente falando, é a área/recurso da aplicação ou seja: Ex: Treinamentos, Profile, Artigos, etc.
- Permission – Permissão de executar algum processo em um determinado resource. (Ex: Treinamentos (resource) – Adicionar (Permission)
Entendendo esses principios básicos tudo fica mais simples.
Abaixo segue uma classe que foi desenvolvida por um dos membros da devZone da Zend que faz todo o controle e mapeamento das permissions e resources dos usuários. Utilize a seguinte modelagem para o seu banco de dados para tal classe funcionar:
[sourcecode language=’sql’]
CREATE TABLE `acl_permissions` (
`role_id` int(11) NOT NULL,
`resource_id` int(11) NOT NULL,
`permission` varchar(64) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE `acl_resources` (
`id` int(11) NOT NULL auto_increment,
`resource` varchar(64) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `resource` (`resource`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE `acl_roles` (
`role_id` int(11) NOT NULL auto_increment,
`role_name` varchar(64) NOT NULL,
PRIMARY KEY (`role_id`),
UNIQUE KEY `role_name` (`role_name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
CREATE TABLE `acl_users` (
`id` int(11) NOT NULL auto_increment,
`role_id` int(11) NOT NULL,
`user_name` varchar(40) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_name` (`user_name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
[/sourcecode]
Classe:
[sourcecode language=’php’]
<?
class MyAcl extends Zend_Acl {
private $_db;
public $_getUserRoleName = null;
public $_getUserRoleId = null;
public $_user = null;
public function __construct($user)
{
$this->_user = $user ? $user : ‘Guest’;
$this->_db = Zend_Registry::get ( ‘database’ );
self::roleResource();
$getUserRole = $this->_db->fetchRow(
$this->_db->select()
->from(‘acl_roles’)
->from(‘acl_users’)
->where(‘acl_users.user_name = “‘ . $this->_user . ‘”‘)
->where(‘acl_users.role_id = acl_roles.role_id’));
$this->_getUserRoleId = $getUserRole[‘role_id’] ? $getUserRole[‘role_id’] : 4;
$this->_getUserRoleName = $getUserRole[‘role_name’] ? $getUserRole[‘role_name’] : ‘User’;
$this->addRole(new Zend_Acl_Role($this->_user), $this->_getUserRoleName);
}
private function initRoles()
{
$roles = $this->_db->fetchAll(
$this->_db->select()
->from(‘acl_roles’)
->order(array(‘role_id DESC’)));
$this->addRole(new Zend_Acl_Role($roles[0][‘role_name’]));
for ($i = 1; $i < count($roles); $i++) {
$this->addRole(new Zend_Acl_Role($roles[$i][‘role_name’]), $roles[$i-1][‘role_name’]);
}
}
private function initResources()
{
self::initRoles();
$resources = $this->_db->fetchAll(
$this->_db->select()
->from(‘acl_resources’));
foreach ($resources as $key=>$value){
if (!$this->has($value[‘resource’])) {
$this->add(new Zend_Acl_Resource($value[‘resource’]));
}
}
}
private function roleResource()
{
self::initResources();
$acl = $this->_db->fetchAll(
$this->_db->select()
->from(‘acl_roles’)
->from(‘acl_resources’)
->from(‘acl_permissions’)
->where(‘acl_roles.role_id = acl_permissions.role_id’));
foreach ($acl as $key=>$value) {
$this->allow($value[‘role_name’], $value[‘resource’],$value[‘permission’]);
}
}
public function listRoles()
{
return $this->_db->fetchAll(
$this->_db->select()
->from(‘acl_roles’));
}
public function getRoleId($roleName)
{
return $this->_db->fetchRow(
$this->_db->select()
->from(‘acl_roles’, ‘role_id’)
->where(‘acl_roles.role_name = “‘ . $roleName . ‘”‘));
}
public function insertAclUser()
{
$data = array(
‘role_id’ => $this->_getUserRoleId,
‘user_name’ => $this->_user);
return $this->_db->insert(‘acl_users’,$data);
}
public function listResources()
{
return $this->_db->fetchAll(
$this->_db->select()
->from(‘acl_resources’)
->from(‘acl_permissions’)
->where(‘resource_id = id’));
}
public function listResourcesByGroup($group)
{
$result = null;
$group = $this->_db->fetchAll($this->_db->select()
->from(‘acl_resources’)
->from(‘acl_permissions’)
->where(‘acl_resources.resource = “‘ . $group . ‘”‘)
->where(‘id = resource_id’)
);
foreach ($group as $key=>$value) {
if($this->isAllowed($this->_user, $value[‘resource’], $value[‘permission’])) {
$result[] = $value[‘permission’];
}
}
return $result;
}
public function isUserAllowed($resource, $permission)
{
return ($this->isAllowed($this->_user, $resource, $permission));
}
}
[/sourcecode]