Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour à tous,
J'ai mis en place Zend_Acl et Zend_Auth pour la gestion d'un site d'annonces (j'ai utilisé le tuto de Julien).
Tout est presque bien... En ce qui concerne les droits d'accès à certains Controllers c'est nickel, mais pour des ressources en particulier c'est plus délicat.
Je voudrais qu'un utilisateur puisse modifier ses annonces uniquement (rien de plus logique!).
Et là avec les assertions, je vois pas comment faire car on ne dispose pas de la ressource elle même mais seulement d'un type de ressources et du type d'actions que l'on peux faire dessus...
La signature ne m'indique pas du tout comment faire pour fournir ma donnée brute histoire de tester (pour parler gras) que l'id utilisateur est bien celui de l'annonce...
public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $role = null, Zend_Acl_Resource_Interface $resource = null, $privilege = null)
Je voudrais (je suis chiant hein?) avoir des options lors des aperçus des annonces. Je m'explique.
Tout comme dans un forum quand un utilisateur consulte un topic, il peut Signaler | Citer un message. Et quand c'est le sien, il peut Signaler | Citer | Modifier | Supprimer (comme sur ce forum quoi ). Mais ça ça sera dans un 2ième temps. Je suppose que quand j'aurais franchile permier pas ça ira mieux...
Une piste ou un p'tit bout de code? Car la doc de Zend sur les assertions ne m'a pas aidé...
Dernière modification par Mr.MoOx (13-11-2007 18:47:57)
Hors ligne
Bonjour Mr MoOx,
C'est marrant ce message ne me parraît pas complètement inconnu (j'avais pas eu le temps de répondre à l'autre).
Voilà un exemple de code qui fait exactement ce que tu demandes :
class Kitpages_ToutEstProjet_Acl_MessageAssert implements Zend_Acl_Assert_Interface { private $itemId = null; public function __construct($param) { $this->itemId = $param; } public function isAllowed() { //creation if ($this->itemId == null) { return true; } // update // valid itemId Zend_Loader::loadClass("Kitpages_Validate_Pk"); $valid = new Kitpages_Validate_Pk(); if (!$valid->isValid($this->itemId)) { return false; } // fetch entity Zend_Loader::loadClass("Kitpages_ToutEstProjet_Facade"); $facade = Kitpages_ToutEstProjet_Facade::getInstance(); $entity = null; $entity = $facade->getPostById($this->itemId); // bounce if ($entity == null) { return false; } // check posterMemberId and currentMemberId $auth = Zend_Auth::getInstance(); if ($auth->hasIdentity()) { if ($entity->posterMemberId == $auth->getIdentity()->id) { return true; } // Adding moderator profile if ($auth->getIdentity()->profile == "moderator") { return true; } if ($auth->getIdentity()->profile == "admin") { return true; } } return false; } public function assert(Zend_Acl $acl, Zend_Acl_Role_Interface $role = null, Zend_Acl_Resource_Interface $resource = null, $privilege = null) { return $this->isAllowed(); } }
Et ensuite dans mes ACLs, je l'utilise comme ça :
$this->deny("member","room","topicEdit"); $this->allow("member","room","topicEdit", new Kitpages_ToutEstProjet_Acl_MessageAssert($request->getParam("topicId",null),"topic"));
Quelques points pour que tu comprennes qch :
- $entity c'est mon topic (j'utilise un Orm maison)
- t'es pas obligé de faire une fonction "isAllowed, tu peux tout mettre directement dans assert, ça revient au même. (moi ça me permet d'appeler isAllowed pour savoir si j'affiche les boutons ou pas en plus de la vérification de droits d'accès).
- en gros : tu instancies ta classe assert avec les valeur dont tu as besoin pour vérifier les droits et dans le assert, tu renvoies true ou false suivant le cas...
A+, Philippe
Hors ligne
Euh petit soucis, je vois pas trop comment utiliser le isAllowed() de mon assertion.
Car le truc c'est que je fais une boucle sur une liste d'annonces, et je veux faire un test pour savoir si le gas est allowed ou pas.
Et je vois pas comment, avec ton code, je fournis le paramètre (l'annonce) pour tester si ça va ou pas. Car la j'ai l'impression (ce n'est qu'une impression je suppose) que ton code ne marche qu'avec le this->_request->getParam() donc que sur un post!
Hors ligne
Là je n'ai pas trouvé de moyen magique pour ce genre de cas, je refais un test à la main pour savoir si j'affiche le bouton ou pas.
En fait, je n'utilise les ACL que pour sécuriser les accès, mais pas trop pour les affichages. Il y aurait moyen d'utiliser les ACL pour les affichages de boutons en envoyant au routeur les URL de chaque lien, mais j'ai peur qu'en termes de perf, ça soit catastrophique (j'ai pas essayé).
A+, Philippe
Hors ligne
Coucou, je remonte ce post pour savoir si tu as réussi à utiliser les ACL pour l'affichage des boutons, ou sinon qu'elle méthode tu as utilisé, merci
Hors ligne
Sur ce bouton là, j'ai utilisé, dans la fonction isAllowed je crois, la méthode static Zend_Auth::getIdentity() où je faisais des tests en bd (perso j'utilise un classe modèle qui regroupe tous les objects et leurs comportements métier que je met aussi dans le registry c'est bien pratique).
Hors ligne
Bonjour à tous.
Petite question relative à ce sujet.
Je me suis inspiré du code de philippe pour tester les assertions (inutile de dire que je débute avec le framework zend... )
Le but est d'empêcher l'édition d'une annonce par un un utilisateur autre que l'auteur de cette annonce. Assertion basique donc.
Seulement, ne pouvant pas accéder à l'objet request, je ne peut pas récupérer l'ID de l'annonce (passé en GET) par ce biais (je suppose qu'il est possible de le récupérer vie $_GET mais cela ne m'intéresse bien sur pas)
J'ai également tenté de récupérer l'objet request (via $this->_request) dans ma classe d'assertion mais encore une fois, sans succès.
Mes deux classes (ACL + Assertion) semblent correctes et héritent / implémentent bien les bonnes classes (respectivement Zend_Acl et Zend_Acl_Assert_Interface)
Si quelqu'un a une solution à mon problème, je suis preneur.
Hors ligne
Erf, pourquoi n'y ai-je pas pensé plus tôt!
Merci à toi ô grand administrateur de ce forum! Félicitations pour la rapidité en tout cas!
Hors ligne
Bon, je m'avoue vaincu et reviens vers vous...
Encore une question conne, je le sens, mais j'ai beau retourner la question dans tous les sens, regarder mon code, fixer avec insistance le schéma trouvé chez M. Philippe (http://www.kitpages.fr/zf_helper_plugin.php ==> génial ce schéma d'ailleurs! ) rien à faire, je coince...
Ou diable dois-je insérer les données qui m'intéresse (en l'occurrence les paramètres passés par GET) dans ma registry?
Dans mon index.php? Je ne trouve pas ça logique... :S
Dois_je mettre mon objet request complet dans la registry?
Bref, encore des questions sans réponses...
Encore merci pour votre aide.
Hors ligne
Bonjour,
Je n'ai pas lu tout l'historique du thread, mais a priori, ça n'est pas utile de mettre des données de _GET dans la registry, elles sont quasiment tjrs accessibles dans le ZF. Disons que tu veuilles récupérer la variable toto passée en GET :
- d'une part $_GET est une "super globale". Tu peux donc y accéder n'importe où dans ton code (rien à voir avec le ZF, c'est une propriété de PHP) => $_GET["toto"]
- sinon si tu est dans un plugin, tu reçois la $request en paramètre des preDispatch et autres. Tu peux faire $request->getParam("toto");
- si tu es dans un helper (preDispatch, postDispatch,...), tu peux faire $this->getRequest()->getParam("toto");
- si tu es dans une action, tu peux faire $this->_getParam("toto");
A+, Philippe
Hors ligne
Merci pour ta réponse Philippe, mais comme dit plus haut, je ne souhaite pas utiliser la variable $_GET. Le framework étant normalement conçu de manière à éviter son utilisation, jouons le jeu.
La classe dans laquelle je souhaite accéder à une variable passée en GET est une classe qui étend Zend_Acl.
Il ne s'agit donc (sauf erreur de ma part) ni d'un plugin, ni d'un helper, ni d'un controller.
Voici le code que je souhaite utiliser pour déclarer mon assertion (dans le constructeur de ma classe héritée de Zend_Acl et qui reçoit en paramètre une instance de la classe Zend_Auth uniquement)
$this->allow('member', 'annonce', 'edit', new Viv_Acl_Assert_AnnonceEditAssertion($idNews));
Cette restriction s'applique bien entendu aux membres, sur l'action edit du controller annonce.
$idNews doit être l'id de la news passé via l'URL (en GET donc)
Mon problème est le suivant, comment récupérer cet id?
Je ne suis pas revenu sur cette partie de mon code depuis le conseil de Mr Moox (mettre l'objet request dans la registry). Mais mis à part cette solution (qui je l'avoue m'emballe moyennement) je ne vois pas du tout comment faire!.
Par contre, encore une dernière petite question: ou dois-je mettre mon objet request dans le registry? Directement dans mon Front Controller?
Encore merci à tous ceux qui ont répondu sur ce topic et à leur réactivité!
Hors ligne
Tu peux toujours faire un Zend_Controller_Front::getInstance()->getRequest() de n'importe où, n'importe quand (une fois la request initialisé bien sur)
J'dis ça, j'dis rien
Hors ligne
Ah tiens je connaissais pas ça!
J'adore quand tu ne dis rien! \o/
Encore merci!
Hors ligne
Dites, une petite question ... plus haut, dans l'exemple donné, un test d'authentification est effectué à l'intérieur de "isAllowed", quel en est l'utilité ?
J'imagine que s'il est "membre" il est forcément authentifié, alors Zend_Acl vérifierai-t-il, malgré le rôle, la condition d'assertion finale ?
Je vous remercie
Hors ligne
Les droits ne sont pas forcément liés à l'identification.
Par exemple, tu peux parcourir les sujets d'un forum sans être identifié.
Sur cette page, il y a des 'isAllowed()'
Par exemple, on peut ou ne peut pas autoriser le clic sur le bouton 'nouveau sujet' aux 'inconnus'
Tu as donc bien sur cette page un appel à la fonction isAllowed alors que la personne n'est pas identifié.
Le 'codeur' a donc décidé de faire un test dans sa fonction isAllowed
Je sais pas si j'ai été clair
Hors ligne
Oui oui, je sais cela peut-être me suis-je mal fais comprendre, je voulais dire : s'il appelle un rôle "member", m'ai avis qu'il a défini un rôle "guest" également, mais tu as raison, peut-être n'est-ce pas le cas !
J'ai fais le rapprochement trop rapidement.
Hors ligne