Faciliter la gestion des droits d’accès avec les Voters


laurent
Faciliter la gestion des droits...

Dans beaucoup de projets où une gestion de droits d’accès est nécessaire, les rôles et contrôles d’accès définis dans le fichier « security.yml » peuvent être suffisants.
Par exemple, les administrateurs ont le rôle ROLE_ADMIN, et les utilisateurs ont le rôle ROLE_USER.

Mais dès lors que l’on souhaite affiner un peu plus le contrôle des droits d’accès, ce système devient vite limité.
(suite…)

Show Comments (5)

Comments

  • Seazer

    Merci pour ce guide.
    Tout vos guides sortent des épines du pied pour des problèmes simples mais que symfony gère à sa façon. 🙂
    Voter, OptionsResolver et autres.

    Merci encore.

    • Article Author
  • Galou

    Perso, je l’aurais plutôt écrit comme cela :

    // La méthode principale qui doit retourner le vote
    public function vote(TokenInterface $token, $object, array $attributes)
    {
    // Nous vérifions tous les rôles à tester…
    foreach ($attributes as $attribute) {
    // … et nous ignorons ceux qui ne nous concernent pas
    if (false === $this->supportsAttribute($attribute)) {
    continue;
    }

    // pour les rôles qui nous concernent, nous enverrons par défaut
    // un refus, à moins que l’utilisateur soit propriétaire de
    // l’article
    $user = $token->getUser();

    // $object est l’objet passé en paramètre lors de l’appel de
    // « isGranted » dans notre action, c’est donc notre article
    if ($object->getAuthor()->getId() === $user->getId()) {
    return VoterInterface::ACCESS_GRANTED;
    }

    return VoterInterface::ACCESS_DENIED;
    }

    // Par défaut, nous n’intervenons pas dans la décision de vote
    return VoterInterface::ACCESS_ABSTAIN;
    }

    • Article Author
  • laurent

    @Galou: C’est un peu une question de préférence en terme de présentation du code. La logique reste la même. En ce qui me concerne, je n’aime pas trop utiliser 3 « return » différents dans une méthode aussi courte, et je trouve le code plus clair avec un unique return en bout de méthode. Ca reste complètement subjectif bien sûr !

    • Article Author
  • Alexandre Salomé

    @Galou a raison, il y a une erreur dans ta boucle. Tu dois retourner DENIED si tu vois un truc faux, là ton vote DENIED est perdu, écrasé par le test sur le suivant.

    Bon vu que tu vérifies uniquement que c’est l’auteur de l’article, ça ne devrait néanmoins pas poser problème pour ton exemple.

    • Article Author
  • laurent

    Effectivement, si le test n’était pas simplement l’auteur et pouvait renvoyer un résultat différent selon l’attribut testé, dans mon exemple de code c’est le dernier état de $vote qui serait retourné, et un GRANTED pourrait écraser un précédent DENIED. Mais en allant dans ce sens, l’exemple de code de Galou retourne potentiellement un GRANTED sur le premier attribut supporté, et va ignorer des éventuels DENIED sur les autres attributs supportés, ce qui pose un problème équivalent.

    Une solution serait de complètement sortir le test de la boucle et de l’exécuter une seule fois après avoir déterminé si on doit s’abstenir ou pas. Si tu as des exemples (posts ou gist) de bonnes pratiques sur les Voters je peux les rajouter à l’article!

    • Article Author

Recevez nos articles