Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 25-08-2009 10:36:03

nicko
Membre
Lieu: Chambéry
Date d'inscription: 25-05-2009
Messages: 190

[Résolu][Zend_Acl] Il ne trouve pas mes resources

Bonjour,

J'ai tenté de faire une gestion des permissions "automatique", mais il y a un bug quelque part, je viens demander un œil extérieur. De plus, si le script fonctionne il pourra toujours servir à quelqu'un d'autre wink

je suis dans le cas d'une structure modulaire de ce type :

Code:

/root
       /application
            /manager
                  /controllers
            /public
                  /controllers

j'explique (accrochez vous y a du code smile ... )


1ere partie :
J'ai 3 tables (j'ai laissé quelques valeurs volontairement):

acl_roles avec members qui héritent de visitors:

Code:

CREATE TABLE IF NOT EXISTS `acl_roles` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `heritage` int(255) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

-- Contenu de la table `acl_roles`

INSERT INTO `acl_roles` (`id`, `name`, `heritage`) VALUES
(1, 'visitors', 0),
(2, 'members', 1),
(3, 'superAdministrators', 0);

acl_resources :

Code:

CREATE TABLE IF NOT EXISTS `acl_resources` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  `label` varchar(255) DEFAULT NULL,
  `module` varchar(255) NOT NULL,
  `controller` varchar(255) NOT NULL DEFAULT 'index',
  `action` varchar(255) NOT NULL DEFAULT 'index',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

-- Contenu de la table `acl_resources`

INSERT INTO `acl_resources` (`id`, `label`, `module`, `controller`, `action`) VALUES
(1, 'manger', 'manger', 'index', 'index'),
(2, NULL, 'manger', 'index', 'login'),
(3, NULL, 'manger', 'index', 'logout');

et une table acl_permissions qui régis l'enssemble :

Code:

CREATE TABLE IF NOT EXISTS `acl_permissions` (
  `id` int(255) NOT NULL AUTO_INCREMENT,
  `roleId` int(255) NOT NULL,
  `resourceId` int(255) NOT NULL,
  `state` int(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;

-- Contenu de la table `acl_permissions`

INSERT INTO `acl_permissions` (`id`, `roleId`, `resourceId`, `state`) VALUES
(1, 1, 1, 0),
(2, 2, 1, 1),
(3, 3, 1, 1),
(4, 1, 2, 1),
(5, 2, 2, 0),
(6, 3, 2, 0),
(7, 1, 3, 0),
(8, 2, 3, 1),
(9, 3, 3, 1);

Pour la colonne "state", vous vous en serez certainement douté, 1 = allow, 0 = deny et roleId et resourceId font respectivement référence aux tables acl_roles et acl_resources.

2eme partie :

J'ai donc créer un petit plugin qui créer toutes les autorisation et le voici :

Code:

    public function __construct()
    {
        parent::__construct();
                /* Ca c'est pour la suite ... */
        $this->_auth    = $this->_registry->get('auth');

                /* DEPART ... */        
        $acl = new Zend_Acl;
                
                /*Je vais chercher la liste de tous les roles (visitors, members et superAdministrators)*/
        $roles           = new System_Models_Roles;
        $rowRoles         = $roles->getRoles();
                
                /*Je creer les différents roles avec les héritages*/
        foreach ($rowRoles as $rowRole)
        {
            if($rowRole->heritage == 0)
            {
                $acl->addRole(new Zend_Acl_Role($rowRole->name));
                #echo '$acl->addRole(new Zend_Acl_Role('.$rowRole->name.'))<br />';
                                /*Ce qui donne visitors qlq chose comme ceci :
                                $acl->addRole(new Zend_Acl_Role('visitors'))*/
            }
            else
            {
                $heritage = $roles->getNameHeritageRoleById($rowRole->heritage);
                $acl->addRole(new Zend_Acl_Role($rowRole->name), $heritage);
                #echo '$acl->addRole(new Zend_Acl_Role('.$rowRole->name.', '.$heritage.'))<br />';

            }
        }
        
                 /*Ensuite j'appel toutes mes resources */
        $resources       = new System_Models_Resources;
        $rowResources = $resources->getResources();
        
                /*Puis je les déclares */
        foreach($rowResources as $rowResource)
        {
            if($rowResource->controller == 'index'
                && $rowResource->action == 'index')
            {
                $acl->add(new Zend_Acl_Resource($rowResource->module));
                #echo '$acl->add(new Zend_Acl_Resource('.$rowResource->module.'))<br />';
                
                $acl->add(new Zend_Acl_Resource($rowResource->module.'_'.
                                                $rowResource->controller));
                #echo '$acl->add(new Zend_Acl_Resource('.$rowResource->module.'_'.$rowResource->controller.'))<br />';
                
            }
            else if($rowResource->controller != 'index'
                && $rowResource->action == 'index')
            {
                $acl->add(new Zend_Acl_Resource($rowResource->module.'_'.
                                                $rowResource->controller));
                #echo '$acl->add(new Zend_Acl_Resource('.$rowResource->module.'_'.$rowResource->controller.'))<br />';
            }
        }
        
                $permissions = new System_Models_Permissions;
        
                /*Enfin, je régis les roles avec les resources */
        foreach($rowRoles as $rowRole)
        {
                         /*Récupération du nom du role (visitors ou members ou ...)
            $rowPermissionsByRoleId = $permissions->getPermissionsByRoleId($rowRole->id);
            
            foreach($rowPermissionsByRoleId as $rowPermissionByRoleId)
            {
                $rowResource = $resources->getResourceById($rowPermissionByRoleId->resourceId);
                
                                /*Pour les allow */
                if($rowPermissionByRoleId->state === 1)
                {
                    if($rowResource->controller == 'index')
                    {
                        
                        $acl->allow($rowRole->name,
                                    $rowResource->module,
                                    $rowResource->action);
                        
                        $acl->allow($rowRole->name,
                                    $rowResource->module.'_'.
                                    $rowResource->controller,
                                    $rowResource->action);
                        
                        #echo '$acl->allow('.$rowRole->name.', '.$rowResource->module.', '.$rowResource->action.')<br />';
                        #echo '$acl->allow('.$rowRole->name.', '.$rowResource->module.'_'.$rowResource->controller.', '.$rowResource->action.')<br />';

                    }
                    else if($rowResource->controller != 'index')
                    {
                        
                        $acl->allow($rowRole->name,
                                    $rowResource->module.'_'.
                                    $rowResource->controller,
                                    $rowResource->action);
                        #echo '$acl->allow('.$rowRole->name.', '.$rowResource->module.'_'.$rowResource->controller.', '.$rowResource->action.')<br />';
                    }
                }
                               /*Pour les deny */
                else if($rowPermissionByRoleId->state === 0)
                {
                    if($rowResource->controller == 'index')
                    {
                        $acl->deny($rowRole->name,
                                   $rowResource->module,
                                   $rowResource->action);
                        
                        $acl->deny($rowRole->name,
                                   $rowResource->module.'_'.
                                   $rowResource->controller,
                                   $rowResource->action);
                        
                        #echo '$acl->deny('.$rowRole->name.', '.$rowResource->module.', '.$rowResource->action.')<br />';
                        #echo '$acl->deny('.$rowRole->name.', '.$rowResource->module.'_'.$rowResource->controller.', '.$rowResource->action.')<br />';
                    }
                    else if($rowResource->controller != 'index')
                    {
                        $acl->deny($rowRole->name,
                                   $rowResource->module.'_'.
                                   $rowResource->controller,
                                   $rowResource->action);
                        
                        #echo '$acl->deny('.$rowRole->name.', '.$rowResource->module.'_'.$rowResource->controller.', '.$rowResource->action.')<br />';
                    }
                }
            }
        }
        
        $this->_acl = $acl;
    }

Donc cette partie, lorsque je dé commente les dièse m'affiche ceci :

pour les roles :

Code:

$acl->addRole(new Zend_Acl_Role(visitors))
$acl->addRole(new Zend_Acl_Role(members, visitors))
$acl->addRole(new Zend_Acl_Role(superAdministrators))

pour les resources :

Code:

$acl->add(new Zend_Acl_Resource(manger))
$acl->add(new Zend_Acl_Resource(manger_index))

pour les permissions :

Code:

$acl->deny(visitors, manger, index)
$acl->deny(visitors, manger_index, index)
$acl->allow(visitors, manger, login)
$acl->allow(visitors, manger_index, login)
$acl->deny(visitors, manger, logout)
$acl->deny(visitors, manger_index, logout)
$acl->allow(members, manger, index)
$acl->allow(members, manger_index, index)
$acl->deny(members, manger, login)
$acl->deny(members, manger_index, login)
$acl->allow(members, manger, logout)
$acl->allow(members, manger_index, logout)
$acl->allow(superAdministrators, manger, index)
$acl->allow(superAdministrators, manger_index, index)
$acl->deny(superAdministrators, manger, login)
$acl->deny(superAdministrators, manger_index, login)
$acl->allow(superAdministrators, manger, logout)
$acl->allow(superAdministrators, manger_index, logout)

3eme partie
Je travail avec l'url suivante : http://monsite/manager/
lorsque que je veux attaquer les redirections, je test plusieurs chose suivant les tutos que j'ai trouvé a droite à gauche :

Code:

    public function routeShutdown(Zend_Controller_Request_Abstract $request)
    {
        if(!$request->isXmlHttpRequest())
        {
            if ($this->_auth->hasIdentity())
            {
                $role = $this->_auth->getIdentity()->role;
            }
            else
            {
                $role = $this->_sys->setDefaultRole;/*visitors*/
            }
            
            $module     = $request->getModuleName();
            $controller    = $request->getControllerName();
            $action    = $request->getActionName();

                if($module == $this->_user->admin->module/*manager*/)
                {
                    $resource = $controller;
                }
                else
                {
                    $resource = $module.'_'.$controller;
                }
                
            
                if(!$this->_acl->has($resource))
                {
                    $resource = NULL;
                }
                
                echo $resource; 
                                /*il m'affiche rien puisqu'il ne trouve pas de ressources et c'est là le problème*/
            
                print_r($this->_acl->isAllowed($role, $resource, $action));
        }
    }
}

mais lorsque je fait ce code ci simplifié :

Code:

                if($module == $this->_user->admin->module/*manager*/)
                {
                    $resource = $controller;
                }
                else
                {
                    $resource = $module.'_'.$controller;
                }
                echo $resource; 
                                /*il affiche index*/
                print_r($this->_acl->isAllowed($role, $resource, $action));

Génère l'exception suivante :

Code:

Fatal error: Uncaught exception 'Zend_Acl_Exception' with message 'Resource 'index' not found' in ....

logique puisque si on regarde bien il n'y pas de resources créée pour index (le controller), j'ai donc créer le code suivant :

Code:

                $resource = $module.'_'.$controller;

                echo $resource; 
                                /*il affiche manager_index*/
                print_r($this->_acl->isAllowed($role, $resource, $action));

mais j'ai la même exception qui s'affiche en remplacent index par manager_index.


Conclution
Je sais que ça fait beaucoup de code à analyser, mais je ne comprends pas pourquoi il me dit que ma ressource n'existe pas.
Je vous serais énormément reconnaissant si vous pouviez m'aider cas je peine dessus depuis quelques jours et je m'arrache les cheveux wink.

Merci beaucoup d'avance

Cordialement

Dernière modification par Vincent (30-08-2009 13:53:46)

Hors ligne

 

#2 25-08-2009 10:48:30

nicko
Membre
Lieu: Chambéry
Date d'inscription: 25-05-2009
Messages: 190

Re: [Résolu][Zend_Acl] Il ne trouve pas mes resources

Honte sur moi !!!!!!!!!

Il suffit que je vienne demander de l'aide pour trouver la solution ...
Dans la table acl_resources, j'ai mis "manger" au lieu de "manager".

Donc ce script a l'air correcte mais avant que vous le copiez, j'espère que quelqu'un pourrais me donner sont avis car ça m'intéresse.

Merci

Hors ligne

 

#3 25-08-2009 15:13:52

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [Résolu][Zend_Acl] Il ne trouve pas mes resources

C'est très bien. Tu peux encore allé plus loin en implémentant directement les interfaces nécessaires dans tes objets (Zend_Acl_Role_Interface et Zend_Acl_Resource_Interface) et ainsi évité les accès aux propriétés de tes objets et diverses manipulations de chaines.


----
Gruiiik !

Hors ligne

 

#4 30-08-2009 10:05:09

nicko
Membre
Lieu: Chambéry
Date d'inscription: 25-05-2009
Messages: 190

Re: [Résolu][Zend_Acl] Il ne trouve pas mes resources

Peux-tu m'en dire plus sur l'implémentation de ces interfaces s'il te plait,  car je n'ai pas trouvé d'exemple d'utilisation sur la doc de ZF ?

Merci.

Hors ligne

 

#5 04-09-2009 10:30:08

Ender
Membre
Date d'inscription: 01-09-2009
Messages: 52

Re: [Résolu][Zend_Acl] Il ne trouve pas mes resources

Bonjour nicko,

Je tombe sur ce topic par hasard et il se trouve que c'est précisément ce genre de choses que je cherchais.
Mais plusieurs choses me gênent à première vue.

Premièrement tu charges tous les rôles et leurs permissions associées. Ne serait-il pas mieux de laisser, dans le cas ou ça ne serait pas un plugin (je n'ai aucune utilité de routeShutdown() personnellement) aussi la solution de ne charger les ACl que d'un rôle que l'on passerait en argument ? Et que dans le cas où on ne passe pas d'argument qu'il récupère tous les rôles.
Personnellement ça me gêne de charger tous les rôles alors que le seul endroit où j'ai besoin de tous les charger c'est sur ma page de contrôle des droits.

Deuxièmement ne serait-il pas intéressant de prévoir un moyen de spécifier si on souhaite utiliser les modules ou non ?


Voila, j'aurais aimé avoir ton avis sur ces deux points. Je dis peut-être une absurdité hein. smile

Hors ligne

 

#6 04-09-2009 11:23:39

nicko
Membre
Lieu: Chambéry
Date d'inscription: 25-05-2009
Messages: 190

Re: [Résolu][Zend_Acl] Il ne trouve pas mes resources

Bonjour Ender

Ta première idée est très intéressante, et c'est ce que j'étais entrain de mettre en place afin d'améliorer mon plugin et du coup de ne pas charger inutilement des rôles.

Deuxièmement ne serait-il pas intéressant de prévoir un moyen de spécifier si on souhaite utiliser les modules ou non ?

Par contre, je ne vois pas vraiment ce que tu veux dire dans cette question. wink Tu peux me ré-expliquer stp ?

Hors ligne

 

#7 04-09-2009 11:45:01

Ender
Membre
Date d'inscription: 01-09-2009
Messages: 52

Re: [Résolu][Zend_Acl] Il ne trouve pas mes resources

J'entends par là de pouvoir spécifier ou non si on utilise des modules dans notre application. Et par conséquent ne pas insérer $module dans les noms et autres comme tu le fais actuellement.
Selon moi, les développeurs ZF se font une très mauvaise idée des modules tels que ZF les conçoit.
Un module doit être une partie de l'application qui pourrait être un site web à elle toute seulle : blog, forum...
Mais des parties telles que les news ne sont pas à mon sens des modules.

Par conséquent, je pense qu'il est extrêmement rare que l'on ait à utiliser les modules dans une application avec ZF. Ça doit rester relativement exceptionnel.
Ce n'est qu'un avis personnel...

Serait-il possible que tu postes ce que tu es en train de faire afin qu'on puisse réfléchir ensemble ?

Dernière modification par Ender (04-09-2009 11:45:54)

Hors ligne

 

#8 06-09-2009 17:27:12

nicko
Membre
Lieu: Chambéry
Date d'inscription: 25-05-2009
Messages: 190

Re: [Résolu][Zend_Acl] Il ne trouve pas mes resources

Désolé de ne pas avoir répondu avant.

Je le termine car pour le moment il est en chantier (restructuration). Mais je le mettrais volontiers en ligne prochainement.

Hors ligne

 

#9 08-09-2009 08:41:18

nicko
Membre
Lieu: Chambéry
Date d'inscription: 25-05-2009
Messages: 190

Re: [Résolu][Zend_Acl] Il ne trouve pas mes resources

Bonjour,

Bon je ne l'ai pas encore testé mais voilà ce que ça me donne avec mon débug maison wink :

Code:

$this->addRole(new Zend_Acl_Role(guest)) - 1

$this->add(new Zend_Acl_Resource(index)); - 1
$this->add(new Zend_Acl_Resource(manager_index)); - 1

$this->allow(guest, index) - 1
$this->deny(guest, manager_index) - 2
$this->allow(guest, manager_index, login) - 7

Et voila mon code :

Code:

class Acl extends Zend_Acl {
    private $_config = null;

    private $_MResources = null;

    public function __construct($role)
    {
        $registry = Zend_Registry::getInstance();
        $this->_config = $registry->get('config');

        $this->_MResources = new Models_Resources;
        $this->_MRoles = new Models_Roles;

        if (is_null($role)) {
            $role = $this->_config->acl->defaultRole;
        }

        $this->setRoles($role);
        $this->setResources();
        $this->setPrivileges($role);
    }

    private function setRoles($role)
    {
        $rowRole = $this->_MRoles->getRoleByName($role);

        if (!empty($rowRole)) {
            if ($rowRole->heritage === null) {
                $this->addRole(new Zend_Acl_Role($rowRole->name));
                echo '$this->addRole(new Zend_Acl_Role(' . $rowRole->name . ')) - 1 <br />';
            }

            if ($rowRole->heritage !== null) {
                $this->addHeritages($rowRole->heritage, $rowRole->name);
            }
        }
    }

    private function addHeritages($heritages, $role)
    {
        $heritages = explode(',', $heritages);
        foreach($heritages as $heritage) {
            $roleHeritage = $this->_MRoles->getRoleById($heritage);
            if (!$this->hasRole($roleHeritage->name)) {
                $this->addRole(new Zend_Acl_Role($roleHeritage->name));
                echo '$this->addRole(new Zend_Acl_Role(' . $roleHeritage->name . ')) - 2 <br />';

                if ($roleHeritage->heritage !== null) {
                    $this->addHeritages($roleHeritage->heritage, $role);
                }

                $this->addRole(new Zend_Acl_Role($role), $roleHeritage->name);
                echo '$this->addRole(new Zend_Acl_Role(' . $role . ', ' . $roleHeritage->name . ')) - 3 <br />';
            }
        }

        return true;
    }

    private function setResources()
    {
        $listResources = $this->_MResources->getLists();

        foreach($listResources as $listResource) {
            if ($listResource->modules == $this->_config->resources->frontController->defaultModule) {
                $this->add(new Zend_Acl_Resource($listResource->controllers));
                echo '$this->add(new Zend_Acl_Resource(' . $listResource->controllers . ')); - 1 <br />';
            } else {
                if ($listResource->controllers == 'index' && $listResource->actions == 'index') {
                    $this->add(new Zend_Acl_Resource($listResource->modules . '_' . $listResource->controllers));
                    echo '$this->add(new Zend_Acl_Resource(' . $listResource->modules . '_' . $listResource->controllers . ')); - 1 <br />';
                } elseif ($listResource->controllers != 'index' && $listResource->actions == 'index') {
                    $this->add(new Zend_Acl_Resource($listResource->modules . '_' . $listResource->controller));
                    echo '$this->add(new Zend_Acl_Resource(' . $listResource->modules . '_' . $listResource->controllers . ')); - 1 <br />';
                }
            }
        }
    }

    private function setPrivileges($role)
    {
        $roleRow = $this->_MRoles->getRoleByName($role);
        $listResources = $this->_MResources->getLists();

        if ($roleRow->id === 1) {
            $this->allow($roleRow->name);
        }

        foreach($listResources as $listResource) {
            if ($listResource->modules == $this->_config->resources->frontController->defaultModule && $listResource->actions == 'index') {
                $this->allow($role, $listResource->controllers);
                echo '$this->allow(' . $role . ', ' . $listResource->controllers . ') - 1 <br />';
            } else {
                if ($listResource->modules == $this->_config->resources->frontController->defaultModuleAdmin && $listResource->actions == 'index') {
                    if ($role == $this->_config->acl->defaultRole) {
                        if ($listResource->controllers == 'index' && $listResource->actions == 'index') {
                            $this->deny($roleRow->name, $listResource->controllers);
                            echo '$this->deny(' . $roleRow->name . ', ' . $listResource->modules . '_' . $listResource->controllers . ') - 2 <br />';
                        } elseif ($listResource->controllers != 'index' && $listResource->actions == 'index') {
                            $this->deny($roleRow->name, $listResource->modules . '_' . $listResource->controllers);
                            echo '$this->deny(' . $roleRow->name . ', ' . $listResource->modules . '_' . $listResource->controllers . ') - 3 <br />';
                        }
                    } else {
                        if ($listResource->controllers == 'index' && $listResource->actions == 'index') {
                            $this->allow($roleRow->name, $listResource->controllers);
                            echo '$this->allow(' . $roleRow->name . ', ' . $listResource->modules . '_' . $listResource->controllers . ') - 2 <br />';
                        } elseif ($listResource->controllers != 'index' && $listResource->actions == 'index') {
                            $this->allow($roleRow->name, $listResource->modules . '_' . $listResource->controllers);
                            echo '$this->allow(' . $roleRow->name . ', ' . $listResource->modules . '_' . $listResource->controllers . ') - 3 <br />';
                        }
                    }
                }
            }
        }

        $MPrivileges = new Models_Privileges;
        $privileges = $MPrivileges->getPrivilegesById($roleRow->id);

        foreach($privileges as $privilege) {
            $roleRow = $this->_MRoles->getRoleById($privilege->roles_id);
            $resource = $this->_MResources->getRowResourcesById($privilege->resources_id);
            $access = $privilege->access;

            if ($resource->modules == $this->_config->resources->frontController->defaultModule) {
                $this->$access($roleRow->name, $resource->controllers, $resource->actions);
                echo '$this->' . $privilege->access . '(' . $roleRow->name . ', ' . $resource->controllers . ', ' . $resource->actions . ') - 6 <br />';
            } else {
                $this->$access($roleRow->name, $resource->modules . '_' . $resource->controllers, $resource->actions);
                echo '$this->' . $privilege->access . '(' . $roleRow->name . ', ' . $resource->modules . '_' . $resource->controllers . ', ' . $resource->actions . ') - 7 <br />';
            }
        }
    }
}

A voir. Ton avis ?

Hors ligne

 

#10 08-09-2009 09:46:41

nicko
Membre
Lieu: Chambéry
Date d'inscription: 25-05-2009
Messages: 190

Re: [Résolu][Zend_Acl] Il ne trouve pas mes resources

Heu, je confirme, ça à l'air de fonctionner wink

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages