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.