src/Security/Voter/PropietarioContenidoVoter.php line 18

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter;
  3. use App\Entity\PropietarioContenido;
  4. use App\Entity\UsuarioHermes;
  5. use App\Enum\RolEnum;
  6. use App\Exception\Authorization\PropietarioContenidoAuthorizationException;
  7. use App\Exception\Authorization\NoUserException;
  8. use App\Security\PropietarioContenidoAuthorizationService;
  9. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  10. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  11. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  12. /**
  13. * Voter para decidir acceso basado en roles de PropietarioContenido.
  14. */
  15. class PropietarioContenidoVoter extends Voter
  16. {
  17. // Definir constantes para los atributos que manejará este voter
  18. public const ROL_PROPIETARIO_CONTENIDO = 'ROL_PROPIETARIO_CONTENIDO';
  19. private PropietarioContenidoAuthorizationService $authorizationService;
  20. /**
  21. * @var PropietarioContenidoAuthorizationException|null Última excepción que ocurrió al votar
  22. */
  23. private ?PropietarioContenidoAuthorizationException $lastException = null;
  24. public function __construct(PropietarioContenidoAuthorizationService $authorizationService)
  25. {
  26. $this->authorizationService = $authorizationService;
  27. }
  28. /**
  29. * Determina si este voter soporta el atributo y subject dados.
  30. */
  31. protected function supports(string $attribute, $subject): bool
  32. {
  33. // Solo soporta el atributo ROL_PROPIETARIO_CONTENIDO
  34. if ($attribute !== self::ROL_PROPIETARIO_CONTENIDO) {
  35. return false;
  36. }
  37. // El subject debe ser un array de roles de PropietarioContenido permitidos
  38. if (!is_array($subject)) {
  39. return false;
  40. }
  41. return true;
  42. }
  43. /**
  44. * Determina si el acceso está concedido.
  45. *
  46. * @param string $attribute ROL_PROPIETARIO_CONTENIDO
  47. * @param array $subject Array de roles de PropietarioContenido permitidos (RolEnum::PARTICIPANTE, etc.)
  48. * @param TokenInterface $token Token de autenticación
  49. * @return bool
  50. */
  51. protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
  52. {
  53. $user = $token->getUser();
  54. // Si el usuario no es un objeto UsuarioHermes, denegar acceso
  55. if (!$user instanceof UsuarioHermes) {
  56. $this->lastException = new NoUserException(
  57. 'Debe iniciar sesión para acceder a este recurso.',
  58. PropietarioContenidoAuthorizationException::SEVERITY_WARNING
  59. );
  60. return false;
  61. }
  62. // $subject es un array de roles permitidos según RolEnum
  63. $rolesPermitidos = $subject;
  64. try {
  65. // Verificar acceso lanzando excepciones para capturar el motivo del fallo
  66. $this->authorizationService->verificarAcceso(
  67. $rolesPermitidos,
  68. null,
  69. false,
  70. true // Lanzar excepciones
  71. );
  72. // Si no se lanzó excepción, el acceso está permitido
  73. $this->lastException = null;
  74. return true;
  75. } catch (PropietarioContenidoAuthorizationException $e) {
  76. // Guardar la excepción para que el controlador pueda consultarla posteriormente
  77. $this->lastException = $e;
  78. return false;
  79. }
  80. }
  81. /**
  82. * Obtiene la última excepción que ocurrió al votar.
  83. * Esto permite a los controladores entender por qué se denegó el acceso.
  84. *
  85. * @return PropietarioContenidoAuthorizationException|null La última excepción o null si no hay
  86. */
  87. public function getLastException(): ?PropietarioContenidoAuthorizationException
  88. {
  89. return $this->lastException;
  90. }
  91. }