Creo haber seguido todos los pasos para implementar un security voter con el fin de que los usuarios que hayan creado un objeto sean los únicos que puedan modificarlo.
1) app/config/services.yml
wars.profesorbundle.security.ownervoter: class: Wars\ProfesorBundle\Security\OwnerVoter
2) Implementación de OwnerVoter.php
<?php namespace Wars\ProfesorBundle\Security; use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; class OwnerVoter implements VoterInterface { public function supportsAttribute($attribute) { return 'ROLE_EDITAR_MENSAJE' == $attribute; } public function supportsClass($class) { return true; } public function vote(TokenInterface $token, $object, array $attributes) { $vote = VoterInterface::ACCESS_ABSTAIN; foreach ($attributes as $attribute) { if (false === $this->supportsAttribute($attribute)) { continue; } $user = $token->getUser(); $vote = VoterInterface::ACCESS_DENIED; // comprobar que el mensaje que se edita fue publicado // por este mismo profesor if ($object->getProfesor()->getId() === $user->getId()) { $vote = VoterInterface::ACCESS_GRANTED; } } return $vote; } }
Y no se donde está el error pero no permite que el usuario creador de un objeto pueda editarlo porque siempre me devuelve false
al hacer la comprobación (y eso que me aseguro de que el creador del objeto y el usuario que pretende modificarlo son iguales):
if (false === $this->get('security.context')->isGranted('ROLE_EDITAR_MENSAJE', $panel))
De todas formas, mi duda es que no se si es realmente necesario crear un Security Voter si simplemente en el Controller
puedo comprobar si el usuario conectado es creador del objeto que pide modificar realizando una simple comparación:
$panel->getUsuario()->getId() == this->get('security.context')->getToken()->getUser()
Respuestas
Me lo soluciono yo mismo, como siempre pequeñas cosas que retrasan el trabajo:
Importar a app/config/config.yml
los ficheros como app/config/services.yml
@Jorge_Gante
Respecto a la duda que tienes sobre si sería lo mismo un security voter que hacer la comprobación en el controlador, puede parecer que sí, pero en la práctica son muy diferentes.
Si haces una comprobación en un controlador, ese código deja de ser reutilizable en otras partes de la aplicación. Además, la comprobación es totalmente ajena al sistema de seguridad de Symfony.
Sin emabrgo, si usas un security voter, vas a poder reutilizar esa lógica que decide si un usuario puede hacer una determinada acción. Además, los voters se combinan unos con otros y así puedes llegar a hacer combinaciones muy interesantes. Ejemplo: que los usuarios puedan editar sus propios objetos, pero sólo si acceden desde la intranet de la empresa. En ese caso usarías el voter que has hecho y un voter que compruebe la IP del usuario.
Después, sólo tienes que configurar que la decisión sobre si un usuario puede editar un objeto sea por unanimidad de todos los voters activos. En la sección Changing the Access Decision Strategy de la documentación oficial de Symfony2 se explica mejor.
@javiereguiluz