Zend Framework: necesita un ejemplo típico de ACL
zend-framework zend-acl (2)
Puedo pegarte mi ACL. Consta de tres elementos: acl.ini, el complemento del controlador de ACL (My_Controller_Plugin_Acl) y la clase My_Acl, y la tabla USER. Sin embargo, no se trata de módulos, sino de controladores y acciones. Sin embargo, puede darle una idea general sobre ACL. Mi uso de ACL se basa en el de un libro llamado "Zend Framework en Acción".
Tabla USER (el campo de privilegio se usa para ACL):
CREATE TABLE IF NOT EXISTS `USER` (
`user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`email` VARCHAR(85) NOT NULL ,
`password` CHAR(32) NOT NULL,
`phone` VARCHAR(45) NULL ,
`phone_public` TINYINT(1) NULL DEFAULT 0 ,
`first_name` VARCHAR(45) NULL ,
`last_name` VARCHAR(45) NULL ,
`last_name_public` TINYINT(1) NULL DEFAULT 1 ,
`is_enabled` TINYINT(1) NOT NULL DEFAULT 1 ,
`created` TIMESTAMP NOT NULL,
`privilage` ENUM(''BASIC'',''PREMIUM'',''ADMIN'') NOT NULL DEFAULT ''BASIC'' ,
PRIMARY KEY (`user_id`) ,
UNIQUE INDEX `email_UNIQUE` (`email` ASC) )
ENGINE = InnoDB;
acl.ini (tengo cuatro privilegios, tales que herencias básicas de guest, premium hereda de forma básica y administrador para premium):
; roles
acl.roles.guest = null
acl.roles.basic = guest
acl.roles.premium = basic
acl.roles.administrator = premium
; resources
acl.resources.deny.all.all = guest
acl.resources.allow.index.all = guest
acl.resources.allow.error.all = guest
acl.resources.allow.user.login = guest
acl.resources.allow.user.logout = guest
acl.resources.allow.user.create = guest
acl.resources.allow.user.index = basic
acl.resources.allow.user.success = basic
Clase My_Acl (crea roles y recursos de ACL basados en el archivo ini):
class My_Acl extends Zend_Acl {
public function __construct() {
$aclConfig = Zend_Registry::get(''acl'');
$roles = $aclConfig->acl->roles;
$resources = $aclConfig->acl->resources;
$this->_addRoles($roles);
$this->_addResources($resources);
}
protected function _addRoles($roles) {
foreach ($roles as $name => $parents) {
if (!$this->hasRole($name)) {
if (empty($parents)) {
$parents = null;
} else {
$parents = explode('','', $parents);
}
$this->addRole(new Zend_Acl_Role($name), $parents);
}
}
}
protected function _addResources($resources) {
foreach ($resources as $permissions => $controllers) {
foreach ($controllers as $controller => $actions) {
if ($controller == ''all'') {
$controller = null;
} else {
if (!$this->has($controller)) {
$this->add(new Zend_Acl_Resource($controller));
}
}
foreach ($actions as $action => $role) {
if ($action == ''all'') {
$action = null;
}
if ($permissions == ''allow'') {
$this->allow($role, $controller, $action);
}
if ($permissions == ''deny'') {
$this->deny($role, $controller, $action);
}
}
}
}
}
}
My_Controller_Plugin_Acl :
class My_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract {
/**
*
* @var Zend_Auth
*/
protected $_auth;
protected $_acl;
protected $_action;
protected $_controller;
protected $_currentRole;
public function __construct(Zend_Acl $acl, array $options = array()) {
$this->_auth = Zend_Auth::getInstance();
$this->_acl = $acl;
}
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$this->_init($request);
// if the current user role is not allowed to do something
if (!$this->_acl->isAllowed($this->_currentRole, $this->_controller, $this->_action)) {
if (''guest'' == $this->_currentRole) {
$request->setControllerName(''user'');
$request->setActionName(''login'');
} else {
$request->setControllerName(''error'');
$request->setActionName(''noauth'');
}
}
}
protected function _init($request) {
$this->_action = $request->getActionName();
$this->_controller = $request->getControllerName();
$this->_currentRole = $this->_getCurrentUserRole();
}
protected function _getCurrentUserRole() {
if ($this->_auth->hasIdentity()) {
$authData = $this->_auth->getIdentity();
$role = isset($authData->property->privilage)?strtolower($authData->property->privilage): ''guest'';
} else {
$role = ''guest'';
}
return $role;
}
}
Finalmente una parte de Bootstrap.php donde todo se inicializa:
protected function _initLoadAclIni() {
$config = new Zend_Config_Ini(APPLICATION_PATH . ''/configs/acl.ini'');
Zend_Registry::set(''acl'', $config);
}
protected function _initAclControllerPlugin() {
$this->bootstrap(''frontcontroller'');
$this->bootstrap(''loadAclIni'');
$front = Zend_Controller_Front::getInstance();
$aclPlugin = new My_Controller_Plugin_Acl(new My_Acl());
$front->registerPlugin($aclPlugin);
}
¿Puede alguien guiarme para un ejemplo típico de implementación de ACL? Al igual que ''admin'' puede acceder al módulo ''admin'', ''usuario'' puede acceder al ''módulo de usuario'' y el invitado puede acceder a las páginas ''abiertas''.
Tengo un ejemplo simple que puede satisfacer sus necesidades.
class Dagho_Acl_Main extends Zend_Acl {
public function __construct() {
$anonymous = new Zend_Acl_Role("anonymous");
$customer = new Zend_Acl_Role("customer");
$admin = new Zend_Acl_Role("admin");
$anonymousResource = new Zend_Acl_Resource("acl");
$defaultResource = new Zend_Acl_Resource("default");
$customerResource = new Zend_Acl_Resource("user");
$adminResource = new Zend_Acl_Resource("manage");
$this->addRole($anonymous)
->addRole($customer)
->addRole($admin);
$this->addResource($anonymousResource)
->addResource($defaultResource)
->addResource($customerResource)
->addResource($adminResource);
$this->allow($anonymous, $anonymousResource);
$this->allow($anonymous, $defaultResource);
$this->deny($anonymous, $customerResource);
$this->deny($anonymous, $adminResource);
$this->allow($customer, $anonymousResource);
$this->allow($customer, $defaultResource);
$this->allow($customer, $customerResource);
$this->deny($customer, $adminResource);
$this->allow($admin, $defaultResource);
$this->allow($admin, $anonymousResource);
$this->allow($admin, $adminResource);
$this->deny($admin, $customerResource);
return $this ;
}
}
y aquí está mi plugin:
<?php
class Dagho_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract {
public function preDispatch(Zend_Controller_Request_Abstract $request) {
$module = $request->getModuleName();
$controller = $request->getControllerName();
$action = $request->getActionName();
$doctrineAuth = new Dagho_Auth_Doctrine();
$logged = $doctrineAuth->checklogin();
$identity = $doctrineAuth->getIdentity();
Zend_Registry::set("identity", $identity);
if ($logged && $identity["role"] !== "anonymous") {
/// user had an identity let''s check the ACL
$acl = new Dagho_Acl_Main();
$isAllowed = $acl->isAllowed($identity["role"], $module);
if (!$isAllowed) {
return $request->setModuleName("acl")->setControllerName("index")
->setActionName("denied")->setDispatched(true);
} else {
/// user has identity and he is allowed to access it
return;
}
} elseif ($logged === false || ($logged && $identity["role"] === "anonymous" )) {
//// user not logged on > login.php or its his first visit
$identity = $doctrineAuth->getStorage()->write(array(''name'' => ''anonymous'', ''role'' => "anonymous",));
Zend_Registry::set("identity", $identity);
return $request->setModuleName("acl")->setControllerName("index")
->setActionName("login")->setDispatched(true);
} else {
return $request->setModuleName("acl")->setControllerName("index")
->setActionName("denied")->setDispatched(true);
}
parent::preDispatch($request);
}
}