Zend Framework

Utilizando Zend_ACL

Por em

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]