src/EventListener/KernelListener.php line 72

Open in your IDE?
  1. <?php
  2. namespace App\EventListener;
  3. use App\Service\App\ApiResponseService;
  4. use InvalidArgumentException;
  5. use Symfony\Component\DependencyInjection\ContainerInterface;
  6. use Symfony\Component\HttpKernel\Event\RequestEvent;
  7. use Symfony\Component\Security\Core\Security;
  8. use Symfony\Component\Yaml\Yaml;
  9. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  10. use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
  11. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  12. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  13. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  14. class KernelListener
  15. {
  16.     /** @var Security */
  17.     private Security $security;
  18.     /** @var ApiResponseService */
  19.     private ApiResponseService $apiResponseService;
  20.     /** @var ContainerInterface */
  21.     private ContainerInterface $container;
  22.     /** @var array */
  23.     private array $userRoles;
  24.     /** @var string */
  25.     private string $configFile;
  26.     /** @var string */
  27.     private string $securityFile;
  28.     /**
  29.      * @param Security $security
  30.      * @param ApiResponseService $apiResponseService
  31.      * @param ContainerInterface $container
  32.      * @param string $configFile
  33.      * @param string $securityFile
  34.      * @throws ClientExceptionInterface
  35.      * @throws RedirectionExceptionInterface
  36.      * @throws ServerExceptionInterface
  37.      */
  38.     public function __construct(
  39.         Security           $security,
  40.         ApiResponseService $apiResponseService,
  41.         ContainerInterface $container,
  42.         string             $configFile,
  43.         string             $securityFile
  44.     )
  45.     {
  46.         $this->security $security;
  47.         $this->apiResponseService $apiResponseService;
  48.         $this->container $container;
  49.         $this->configFile $configFile;
  50.         $this->securityFile $securityFile;
  51.     }
  52.     /**
  53.      * @param RequestEvent $event
  54.      * @throws ClientExceptionInterface
  55.      * @throws DecodingExceptionInterface
  56.      * @throws RedirectionExceptionInterface
  57.      * @throws ServerExceptionInterface
  58.      * @throws TransportExceptionInterface
  59.      */
  60.     public function onKernelRequest(RequestEvent $event)
  61.     {
  62.         $request $event->getRequest();
  63.         $route $request->attributes->get('_route');
  64.         if ($this->security->getUser()) {
  65.             $this->userRoles $this->security->getUser()->getRoles();
  66.             $configArray $this->loadYamlConfigurations($this->configFile);
  67.             $securityArray $this->loadYamlConfigurations($this->securityFile);
  68.             $adminRolesToSecure $securityArray['security']['role_hierarchy']['ADMIN_ROLES_TO_SECURE'];
  69.             $clientRolesToSecure $securityArray['security']['role_hierarchy']['CLIENT_ROLES_TO_SECURE'];
  70.             // secure all admin route
  71.             if (array_intersect($adminRolesToSecure$this->userRoles)) {
  72.                 if (!$this->accessAuthorisation($route$configArray)) {
  73.                     $event->setResponse($this->apiResponseService->getAccessDeniedResponse());
  74.                 }
  75.             }
  76.             // secure client route
  77.             if (array_intersect($clientRolesToSecure$this->userRoles)) {
  78.                 if (!$this->accessAuthorisation($route$configArray)) {
  79.                     $event->setResponse($this->apiResponseService->getAccessDeniedResponse());
  80.                 }
  81.             }
  82.         }
  83.     }
  84.     /**
  85.      * @param string $route
  86.      * @param array $configArray
  87.      * @return bool|null
  88.      */
  89.     private function accessAuthorisation(string $route, array $configArray): ?bool
  90.     {
  91.         if (array_key_exists($route$configArray)) {
  92.             if ($routeConfig $configArray[$route]) {
  93.                 return array_intersect($this->userRoles$routeConfig['requested_roles']) &&
  94.                     $this->container->get('security.authorization_checker')->isGranted($routeConfig['attribute'], $routeConfig['subject']);
  95.             }
  96.         }
  97.         return null;
  98.     }
  99.     /**
  100.      * @return array|mixed
  101.      */
  102.     private function loadYamlConfigurations(string $path)
  103.     {
  104.         $array Yaml::parse(file_get_contents($path));
  105.         if (!is_array($array)) {
  106.             throw new InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.'$path));
  107.         }
  108.         return $array;
  109.     }
  110. }