src/Security/SwitchUserSubscriber.php line 39

Open in your IDE?
  1. <?php
  2. namespace App\Security;
  3. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  4. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  5. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  6. use Symfony\Component\Security\Http\Event\SwitchUserEvent;
  7. use Symfony\Component\Security\Http\SecurityEvents;
  8. class SwitchUserSubscriber implements EventSubscriberInterface
  9. {
  10. private const ROLE_PRIORITY = [
  11. 'ROLE_SUPERADMIN' => 60,
  12. 'ROLE_ADMIN' => 50,
  13. 'ROLE_MANAGER' => 40,
  14. 'ROLE_SUPPORT_MASTER' => 35,
  15. 'ROLE_SUPPORT' => 30,
  16. 'ROLE_SECRETARIAT' => 20,
  17. 'ROLE_TEACHER' => 10,
  18. 'ROLE_USER' => 10,
  19. 'ROLE_EMAIL' => 10,
  20. ];
  21. private TokenStorageInterface $tokenStorage;
  22. public function __construct(TokenStorageInterface $tokenStorage)
  23. {
  24. $this->tokenStorage = $tokenStorage;
  25. }
  26. public static function getSubscribedEvents(): array
  27. {
  28. return [
  29. SecurityEvents::SWITCH_USER => 'onSwitchUser',
  30. ];
  31. }
  32. public function onSwitchUser(SwitchUserEvent $event): void
  33. {
  34. // Ne pas bloquer le retour à son propre compte
  35. if ($event->getRequest()->get('_switch_user') === '_exit') {
  36. return;
  37. }
  38. $token = $this->tokenStorage->getToken();
  39. if ($token === null) {
  40. throw new AccessDeniedException();
  41. }
  42. $switcherLevel = $this->getMaxRoleLevel($token->getUser()->getRoles());
  43. $targetLevel = $this->getMaxRoleLevel($event->getTargetUser()->getRoles());
  44. if ($targetLevel >= $switcherLevel) {
  45. throw new AccessDeniedException('Vous ne pouvez pas prendre le contrôle d\'un compte avec un niveau de permissions égal ou supérieur au vôtre.');
  46. }
  47. }
  48. private function getMaxRoleLevel(array $roles): int
  49. {
  50. $max = 0;
  51. foreach ($roles as $role) {
  52. $max = max($max, self::ROLE_PRIORITY[$role] ?? 0);
  53. }
  54. return $max;
  55. }
  56. }