src/Mm/Escmid/EaaBundle/EventListener/AuthListener.php line 29

Open in your IDE?
  1. <?php
  2. namespace Mm\Escmid\EaaBundle\EventListener;
  3. use Mm\Escmid\EaaBundle\Controller\ApiControllerInterface;
  4. use Mm\Escmid\EaaBundle\Controller\AuthenticatedControllerInterface;
  5. use Mm\Escmid\EaaBundle\Controller\LegacyController;
  6. use Mm\Escmid\EaaBundle\Platform\Security\AccessDeniedHttpException;
  7. use Mm\Escmid\EaaBundle\Platform\Security\AuthenticationException;
  8. use Symfony\Bundle\FrameworkBundle\Controller\RedirectController;
  9. use Symfony\Bundle\WebProfilerBundle\Controller\ExceptionPanelController;
  10. use Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController;
  11. use Symfony\Bundle\WebProfilerBundle\Controller\RouterController;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  14. use Symfony\Component\HttpKernel\KernelEvents;
  15. class AuthListener implements EventSubscriberInterface
  16. {
  17. private $controllersWhitelist = [
  18. 'Mm\\Escmid\\ApiBundle\\',
  19. ];
  20. /**
  21. * AuthListener constructor.
  22. */
  23. public function __construct()
  24. {
  25. }
  26. public function onKernelController(ControllerEvent $event): void
  27. {
  28. /** @var Controller[] */
  29. $controllers = $event->getController();
  30. /*
  31. * $controller passed can be either a class or a Closure. This is not usual in Symfony but it may happen.
  32. * If it is a class, it comes in array format.
  33. */
  34. if (!is_array($controllers)) {
  35. return;
  36. }
  37. if ($controllers[0] instanceof AuthenticatedControllerInterface) {
  38. $controllers[0]->setRequest($event->getRequest());
  39. $this->checkController($controllers[0]);
  40. } elseif (($controllers[0] instanceof ProfilerController)
  41. || ($controllers[0] instanceof RouterController)
  42. ) {
  43. /*
  44. * allow access for Symfony WebProfilerBundle controllers
  45. */
  46. } elseif ($controllers[0] instanceof ApiControllerInterface) {
  47. // allow access to API
  48. } elseif ($controllers[0] instanceof RedirectController) {
  49. // allow redirects
  50. } elseif ($controllers[0] instanceof ExceptionPanelController) {
  51. // allow handling exceptions
  52. } else {
  53. $unknown = true;
  54. foreach ($this->controllersWhitelist as $className) {
  55. if (
  56. $controllers[0] instanceof $className
  57. || str_starts_with(get_class($controllers[0]), $className)
  58. ) {
  59. $unknown = false;
  60. break;
  61. }
  62. }
  63. if ($unknown) {
  64. throw new \Exception("Invalid controller '".$controllers[0]::class."', must be instance of either one of these:
  65. \n* Mm\\Escmid\\EaaBundle\\Controller\\AuthenticatedControllerInterface\n
  66. * Symfony\\Bundle\\WebProfilerBundle\\Controller\\ProfilerController\n
  67. * Symfony\\Bundle\\WebProfilerBundle\\Controller\\RouterController\n
  68. * Mm\\Escmid\\EaaBundle\\Controller\\ApiControllerInterface\n
  69. * Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController\n
  70. * Symfony\\Bundle\\WebProfilerBundle\\Controller\\ExceptionPanelController\n".'* '.implode("\n* ", $this->controllersWhitelist));
  71. }
  72. }
  73. }
  74. public function checkController(AuthenticatedControllerInterface $controller): void
  75. {
  76. $principal = $controller->getPrincipal();
  77. $controller->refreshLastSessionActivity();
  78. if ($controller->requiresLogin() || LegacyController::class === $controller::class) {
  79. if (null === $principal || !$principal->isLoggedIn()) {
  80. throw new AuthenticationException('Not logged in.');
  81. }
  82. }
  83. if (!$controller->checkAreaPermissions()) {
  84. $path = $controller->getCurrentPath();
  85. throw new AccessDeniedHttpException(sprintf('Area Access denied for path %s.', $path));
  86. }
  87. if (!$controller->checkPermissions()) {
  88. throw new AccessDeniedHttpException('Access denied.');
  89. }
  90. }
  91. /**
  92. * @return array<string, mixed>
  93. */
  94. public static function getSubscribedEvents(): array
  95. {
  96. return [
  97. KernelEvents::CONTROLLER => 'onKernelController'
  98. ];
  99. }
  100. }