DG devGiants tech notes

16 février 2018

Constantes de l'interface VoterInterface

Un regard plus attentif sur les constantes de l'interface voter pour le contrôle d'accès.

Ce qui se passe

Il y a quelques semaines, j’ai obtenu un comportement étrange dans le retour des voters en utilisant les constantes de l’interface VoterInterface (VoterInterface::ACCESS_GRANTED, VoterInterface::ACCESS_DENIED et VoterInterface::ACCESS_ABSTAIN). En aparté, voici l’interface concernée.

Voici le code initial de mon Voter :

 /**
     * @param string $attributes
     * @param mixed $subject
     * @param TokenInterface $token
     * @return int
     */
    public function voteOnAttribute($attributes, $subject, TokenInterface $token) {

      $user = $token->getUser();

      // If managed here, meaning support method said yes and subject got Rolable trait, and therefore getAuthorizedRoles() method.

      // skip everything if no roles set
      if(count($subject->getAuthorizedRoles()) > 0) {

        // Roles set and no user. Deny
        if(!$user instanceof User) {
            return static::ACCESS_DENIED;
        }

        // user connected (but skip if admin)
        if(!$user->hasRole(User::ROLE_ADMIN)) {

          // User connected, not admin, check roles intersections
          if(count(array_intersect($subject->getAuthorizedRoles(), $user->getRoles())) === 0) {
            return static::ACCESS_DENIED;
          }
        }
      }

      return static::ACCESS_GRANTED;
    }

Un héritage

En réalité, mon post StackOverflow sur le sujet pointe vers une compatibilité ascendante SF 2.5-. La doc indique qu’à partir de SF 2.5+, les voters doivent retourner true ou false.

C’est particulièrement important pour VoterInterface::ACCESS_DENIED, parce que là où un Voter moderne doit retourner false en cas d’accès refusé, la constante correspondante vaut -1.

Cela dit, une question reste ouverte de mon côté : qu’en est-il de VoterInterface::ACCESS_ABSTAIN ? Je trouve la capacité d’abstention très utile quand un Voter conclut qu’il ne peut pas voter.

Je mettrai cet article à jour dès que j’aurai la réponse.