custom/plugins/VioB2BLogin/src/Core/Framework/Subscriber/RoutePrivilegeCheckSubscriber.php line 83

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace VioB2BLogin\Core\Framework\Subscriber;
  4. use Shopware\Core\Framework\Routing\KernelListenerPriorities;
  5. use Shopware\Core\PlatformRequest;
  6. use Shopware\Core\SalesChannelRequest;
  7. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  8. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  9. use Symfony\Component\HttpFoundation\RedirectResponse;
  10. use Symfony\Component\HttpFoundation\Request;
  11. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  12. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  13. use Symfony\Component\HttpKernel\KernelEvents;
  14. use Symfony\Component\Routing\RouterInterface;
  15. use Symfony\Contracts\Translation\TranslatorInterface;
  16. use VioB2BLogin\Core\Exception\NotAllowedException;
  17. use VioB2BLogin\Core\Services\PrivilegeService;
  18. use VioB2BLogin\Entity\Privilege\AbstractPrivilegeProvider;
  19. use VioB2BLogin\Entity\Privilege\RoutePrivilegeMappingProviderInterface;
  20. class RoutePrivilegeCheckSubscriber implements EventSubscriberInterface
  21. {
  22.     /** @var iterable<AbstractPrivilegeProvider> */
  23.     private iterable $privilegeProviders;
  24.     private PrivilegeService $privilegeService;
  25.     private RouterInterface $router;
  26.     private TranslatorInterface $translator;
  27.     public function __construct(
  28.         iterable $priviligeProviders,
  29.         PrivilegeService $privilegeService,
  30.         RouterInterface $router,
  31.         TranslatorInterface $translator
  32.     )
  33.     {
  34.         $this->privilegeProviders = $priviligeProviders;
  35.         $this->privilegeService = $privilegeService;
  36.         $this->router = $router;
  37.         $this->translator = $translator;
  38.     }
  39.     /**
  40.      * @inheritDoc
  41.      */
  42.     public static function getSubscribedEvents(): array
  43.     {
  44.         return [
  45.             KernelEvents::CONTROLLER => [ 'onKernelController' , KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_CONTEXT_RESOLVE_POST],
  46.             KernelEvents::EXCEPTION => 'onKernelException'
  47.         ];
  48.     }
  49.     public function onKernelController(ControllerEvent $event): void
  50.     {
  51.         $context = $event->getRequest()->attributes->get( PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT );
  52.         if( !$context instanceof SalesChannelContext ) {
  53.             return;
  54.         }
  55.         foreach ($this->privilegeProviders as $privilegeProvider) {
  56.             if ($privilegeProvider instanceof RoutePrivilegeMappingProviderInterface) {
  57.                 $mapping = $privilegeProvider->getRoutePrivilegeMapping();
  58.                 $route = $event->getRequest()->attributes->get('_route');
  59.                 if (array_key_exists($route, $mapping) ) {
  60.                     $privileges = $mapping[$route];
  61.                     foreach ($privileges as $privilegeNamespace => $privilegeNames) {
  62.                         foreach ($privilegeNames as $privilegeName) {
  63.                             if( ! $this->privilegeService->checkPrivilege($context, $privilegeNamespace, $privilegeName) )
  64.                             {
  65.                                 throw new NotAllowedException();
  66.                             }
  67.                         }
  68.                     }
  69.                 }
  70.             }
  71.         }
  72.     }
  73.     public function onKernelException(ExceptionEvent $event): void
  74.     {
  75.         if (!$event->getRequest()->attributes->has(SalesChannelRequest::ATTRIBUTE_IS_SALES_CHANNEL_REQUEST)) {
  76.             return;
  77.         }
  78.         $exception = $event->getThrowable();
  79.         if (!$exception instanceof NotAllowedException ) {
  80.             return;
  81.         }
  82.         $this->addFlashMessage($exception, $event->getRequest());
  83.         $request = $event->getRequest();
  84.         $parameters = [
  85.             'redirectTo' => $request->attributes->get('_route'),
  86.             'redirectParameters' => json_encode($request->attributes->get('_route_params')),
  87.         ];
  88.         $redirectResponse = new RedirectResponse($this->router->generate('frontend.account.profile.page', $parameters));
  89.         $event->setResponse($redirectResponse);
  90.     }
  91.     private function addFlashMessage(NotAllowedException $exception, Request $request): void
  92.     {
  93.         if ($request->hasSession() === false) {
  94.             return;
  95.         }
  96.         $session = $request->getSession();
  97.         if (!method_exists($session, 'getFlashBag')) {
  98.             return;
  99.         }
  100.         $session->getFlashBag()->add('danger', $this->translator->trans('error.'.$exception->getErrorCode()) );
  101.     }
  102. }