src/Listener/AclAnnotationListener.php line 47

Open in your IDE?
  1. <?php
  2.     /******************************************************************************
  3.      * Copyright (c) Echo-numeric 2020-2023.                                      *
  4.      ******************************************************************************/
  5.     namespace App\Listener;
  6.     use App\Annotation\Acl as AclAnnotation;
  7.     use App\Entity\User;
  8.     use App\Services\Common\AclService;
  9.     use Doctrine\Common\Annotations\Reader;
  10.     use Psr\Cache\InvalidArgumentException;
  11.     use ReflectionClass;
  12.     use ReflectionException;
  13.     use RuntimeException;
  14.     use Symfony\Component\HttpKernel\Event\ControllerEvent;
  15.     use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  16.     use Symfony\Component\Security\Core\Security;
  17.     class AclAnnotationListener
  18.     {
  19.         private Reader          $annotationReader;
  20.         private Security        $security;
  21.         private AclService      $aclService;
  22.         private ControllerEvent $event;
  23.         public function __construct(
  24.             Reader     $annotationReader,
  25.             Security   $security,
  26.             AclService $aclService
  27.         )
  28.         {
  29.             $this->annotationReader $annotationReader;
  30.             $this->security         $security;
  31.             $this->aclService       $aclService;
  32.         }
  33.         /**
  34.          * @param ControllerEvent $event
  35.          *
  36.          * @return void
  37.          * @throws ReflectionException|InvalidArgumentException
  38.          */
  39.         public function onKernelControllerControllerEvent $event ): void
  40.         {
  41.             $this->event $event;
  42.             if ( !$event->isMainRequest() ) {
  43.                 return;
  44.             }
  45.             $controllers $event->getController();
  46.             if ( !is_array$controllers ) ) {
  47.                 return;
  48.             }
  49.             $this->handleAnnotation$controllers );
  50.         }
  51.         /**
  52.          * @param iterable $controllers
  53.          *
  54.          * @return void
  55.          *
  56.          * @throws ReflectionException
  57.          * @throws InvalidArgumentException
  58.          */
  59.         private function handleAnnotationiterable $controllers ): void
  60.         {
  61.             [ $controller$method ] = $controllers;
  62.             try {
  63.                 $controller = new ReflectionClass$controller );
  64.             }
  65.             catch ( ReflectionException $e ) {
  66.                 throw new RuntimeException'Failed to read annotation!' );
  67.             }
  68.             $this->handleMethodAnnotation$controller$method );
  69.         }
  70.         /**
  71.          * @param ReflectionClass $controller
  72.          * @param string          $method
  73.          *
  74.          * @return void
  75.          *
  76.          * @throws ReflectionException
  77.          * @throws InvalidArgumentException
  78.          */
  79.         private function handleMethodAnnotationReflectionClass $controllerstring $method ): void
  80.         {
  81.             $method     $controller->getMethod$method );
  82.             $annotation $this->annotationReader->getMethodAnnotation$methodAclAnnotation::class );
  83.             if ( $annotation instanceof AclAnnotation ) {
  84.                 /** @var User $user */
  85.                 $user $this->security->getUser();
  86.                 foreach ( $annotation->rules as $slug => $action ) {
  87.                     $request $this->event->getRequest();
  88.                     switch ( $request->get'_route' ) ) {
  89.                         case 'front_catalogue_homepage':
  90.                             $slug .= '.' $request->get'catalogue' );
  91.                             break;
  92.                         case 'front_catalogue_product':
  93.                         case 'front_recompense_boutique_collective_show':
  94.                             $slug .= '.' $request->get'catalogueType' );
  95.                             break;
  96.                         default:
  97.                             break;
  98.                     }
  99.                     if ( $this->aclService->userIsGranted$user$slug$action$this->event->getRequest()
  100.                                                                                               ->get'_env' ) ?? 'front' ) === TRUE ) {
  101.                         return;
  102.                     }
  103.                 }
  104.                 throw new AccessDeniedException'Vous ne disposez pas des droits suffisants pour cette page. ("' json_encode$annotation->rules ) . ')' );
  105.             }
  106.         }
  107.     }