vendor/sylius/rbac-plugin/src/Access/Listener/AccessCheckListener.php line 58

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Sylius\RbacPlugin\Access\Listener;
  4. use Sylius\Component\Core\Model\AdminUserInterface;
  5. use Sylius\RbacPlugin\Access\Checker\AdministratorAccessCheckerInterface;
  6. use Sylius\RbacPlugin\Access\Checker\RouteNameCheckerInterface;
  7. use Sylius\RbacPlugin\Access\Creator\AccessRequestCreatorInterface;
  8. use Sylius\RbacPlugin\Access\Exception\InsecureRequestException;
  9. use Sylius\RbacPlugin\Access\Exception\UnresolvedRouteNameException;
  10. use Sylius\RbacPlugin\Access\Model\AccessRequest;
  11. use Symfony\Component\HttpFoundation\RedirectResponse;
  12. use Symfony\Component\HttpFoundation\Session\Session;
  13. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  14. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  15. use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
  16. use Symfony\Component\Security\Core\User\UserInterface;
  17. use Webmozart\Assert\Assert;
  18. final class AccessCheckListener
  19. {
  20.     /** @var AccessRequestCreatorInterface */
  21.     private $accessRequestCreator;
  22.     /** @var AdministratorAccessCheckerInterface */
  23.     private $administratorAccessChecker;
  24.     /** @var TokenStorageInterface */
  25.     private $tokenStorage;
  26.     /** @var UrlGeneratorInterface */
  27.     private $router;
  28.     /** @var Session */
  29.     private $session;
  30.     /** @var RouteNameCheckerInterface */
  31.     private $adminRouteChecker;
  32.     public function __construct(
  33.         AccessRequestCreatorInterface $accessRequestCreator,
  34.         AdministratorAccessCheckerInterface $administratorAccessChecker,
  35.         TokenStorageInterface $tokenStorage,
  36.         UrlGeneratorInterface $router,
  37.         Session $session,
  38.         RouteNameCheckerInterface $adminRouteChecker
  39.     ) {
  40.         $this->accessRequestCreator $accessRequestCreator;
  41.         $this->administratorAccessChecker $administratorAccessChecker;
  42.         $this->tokenStorage $tokenStorage;
  43.         $this->router $router;
  44.         $this->session $session;
  45.         $this->adminRouteChecker $adminRouteChecker;
  46.     }
  47.     public function onKernelRequest(GetResponseEvent $event): void
  48.     {
  49.         try {
  50.             $accessRequest $this->createAccessRequestFromEvent($event);
  51.         } catch (InsecureRequestException $exception) {
  52.             return;
  53.         }
  54.         if ($this->administratorAccessChecker->canAccessSection($this->getCurrentAdmin(), $accessRequest)) {
  55.             return;
  56.         }
  57.         $this->addAccessErrorFlash($event->getRequest()->getMethod());
  58.         $event->setResponse($this->getRedirectResponse($event->getRequest()->headers->get('referer')));
  59.     }
  60.     /** @throws InsecureRequestException */
  61.     private function createAccessRequestFromEvent(GetResponseEvent $event): AccessRequest
  62.     {
  63.         if (!$event->isMasterRequest()) {
  64.             throw new InsecureRequestException();
  65.         }
  66.         $routeName $event->getRequest()->attributes->get('_route');
  67.         $requestMethod $event->getRequest()->getMethod();
  68.         if ($routeName === null) {
  69.             throw new InsecureRequestException();
  70.         }
  71.         if (!$this->adminRouteChecker->isAdminRoute($routeName)) {
  72.             throw new InsecureRequestException();
  73.         }
  74.         try {
  75.             $accessRequest $this->accessRequestCreator->createFromRouteName($routeName$requestMethod);
  76.         } catch (UnresolvedRouteNameException $exception) {
  77.             throw new InsecureRequestException();
  78.         }
  79.         return $accessRequest;
  80.     }
  81.     private function getCurrentAdmin(): AdminUserInterface
  82.     {
  83.         $token $this->tokenStorage->getToken();
  84.         Assert::notNull($token);
  85.         /** @var AdminUserInterface|null $currentAdmin */
  86.         $currentAdmin $token->getUser();
  87.         Assert::isInstanceOf($currentAdminUserInterface::class);
  88.         return $currentAdmin;
  89.     }
  90.     private function addAccessErrorFlash(string $requestMethod): void
  91.     {
  92.         if ('GET' === $requestMethod || 'HEAD' === $requestMethod) {
  93.             $this->session->getFlashBag()->add('error''sylius_rbac.you_have_no_access_to_this_section');
  94.             return;
  95.         }
  96.         $this->session->getFlashBag()->add('error''sylius_rbac.you_are_not_allowed_to_do_that');
  97.     }
  98.     private function getRedirectResponse(?string $referer): RedirectResponse
  99.     {
  100.         if (null !== $referer) {
  101.             return new RedirectResponse($referer);
  102.         }
  103.         return new RedirectResponse($this->router->generate('sylius_admin_dashboard'));
  104.     }
  105. }