src/EventListener/AuthorizationListener.php line 84

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\EventListener;
  4. use App\Entity\Franchise\FranchiseInterface;
  5. use App\Entity\Security\Administrator;
  6. use App\Entity\Security\Manager;
  7. use App\Entity\Security\RoleInterface;
  8. use App\Entity\Security\ShopManager;
  9. use App\Entity\Shop\ShopInterface;
  10. use App\Helper\String\StringHelper;
  11. use App\Service\Franchise\FranchiseService;
  12. use App\Service\Shop\ShopService;
  13. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\HttpFoundation\RedirectResponse;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
  18. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  19. use Symfony\Component\HttpKernel\Event\RequestEvent;
  20. use Symfony\Component\HttpKernel\Event\ResponseEvent;
  21. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  22. use Symfony\Component\Routing\RouterInterface;
  23. use Symfony\Component\Security\Core\Security;
  24. use Symfony\Contracts\Translation\TranslatorInterface;
  25. class AuthorizationListener implements EventSubscriberInterface
  26. {
  27.     private string $apiRouteBase;
  28.     private array $allowedInLightLicense = [
  29.         'foxorders_shop_menu_',
  30.         'foxorders_shop_category_',
  31.         'foxorders_shop_product_',
  32.         'foxorders_shop_option_',
  33.         'foxorders_shop_dashboard',
  34.         'foxorders_shop_qrcode_dematerialized_menu',
  35.         'foxorders_dashboard',
  36.         'foxorders_home',
  37.         'security_login',
  38.         'foxorders_franchise_',
  39.         'foxorders_google_cloud_translation',
  40.     ];
  41.     private array $shopAuthorizedRoutes = [
  42.         'foxorders_shop_shop_edit',
  43.         'foxorders_shop_qrcode_dematerialized_menu',
  44.         'foxorders_shop_dashboard',
  45.         'foxorders_shop_menu_show',
  46.     ];
  47.     public function __construct(
  48.         private Security $security,
  49.         private SessionInterface $session,
  50.         private StringHelper $stringHelper,
  51.         private ShopService $shopService,
  52.         private FranchiseService $franchiseService,
  53.         private FlashBagInterface $flash,
  54.         private RouterInterface $router,
  55.         private TranslatorInterface $translator,
  56.         private ParameterBagInterface $parameterBag,
  57.     ) {
  58.         $this->apiRouteBase '/' $this->parameterBag->get('api.route.base');
  59.     }
  60.     public static function getSubscribedEvents(): array
  61.     {
  62.         return [
  63.             ResponseEvent::class => 'onKernelResponse',
  64.             RequestEvent::class => 'onKernelRequest',
  65.         ];
  66.     }
  67.     public function onKernelResponse(ResponseEvent $event)
  68.     {
  69.         $pathInfo $event->getRequest()->getPathInfo();
  70.         if (null !== $pathInfo && true === str_starts_with($pathInfo$this->apiRouteBase)) {
  71.             return true;
  72.         }
  73.         $shop null;
  74.         $user $this->security->getUser();
  75.         $franchise $event->getRequest()->getSession()->get('franchise') ?? null;
  76.         $route $event->getRequest()->get('_route') ?? null;
  77.         if ($user instanceof Manager) {
  78.             $shop $this->session->get('shop');
  79.         }
  80.         if ($user instanceof ShopManager) {
  81.             $shop $user->getShop();
  82.         }
  83.         if (
  84.             null !== $franchise
  85.             && $user instanceof Manager
  86.             && false === $this->franchiseService->belongsToUser($franchise$user)
  87.         ) {
  88.             throw new AccessDeniedHttpException(Response::$statusTexts[Response::HTTP_FORBIDDEN]);
  89.         }
  90.         if (
  91.             null !== $route
  92.             && (true === str_ends_with($route'_index') || true === $this->stringHelper->contain($route$this->shopAuthorizedRoutes))
  93.             && ($user instanceof ShopManager || $user instanceof Manager)
  94.             && (null !== $event->getRequest()->getSession()->get('shop') && false === $this->shopService->belongsToUser($event->getRequest()->getSession()->get('shop'), $user))
  95.         ) {
  96.             throw new AccessDeniedHttpException(Response::$statusTexts[Response::HTTP_FORBIDDEN]);
  97.         }
  98.         if (
  99.             null !== $route
  100.             && true === $user instanceof ShopManager
  101.             && ShopInterface::LICENCE_LIGHT === $shop?->getLicence()
  102.             && false === $this->stringHelper->contain($route$this->allowedInLightLicense)
  103.         ) {
  104.             throw new AccessDeniedHttpException(Response::$statusTexts[Response::HTTP_FORBIDDEN]);
  105.         }
  106.         return true;
  107.     }
  108.     public function onKernelRequest(RequestEvent $event): void
  109.     {
  110.         $this->session->set('logged'null);
  111.         $user $this->security->getUser();
  112.         $route $event->getRequest()->get('_route');
  113.         $isApiRoute null !== $route && str_contains($route'api_') && false === str_starts_with($route'foxorders_documentation');
  114.         if (
  115.             null !== $route && false === $isApiRoute && 'security_login' !== $route
  116.             && (
  117.                 ($user instanceof Manager && FranchiseInterface::STATUS_DISABLED === $user->getFranchise()->getStatus())
  118.                  || ($user instanceof ShopManager && FranchiseInterface::STATUS_DISABLED === $user->getShop()->getFranchise()->getStatus())
  119.             )
  120.             && === \count(array_intersect([RoleInterface::ROLE_ADMINRoleInterface::ROLE_PREVIOUS_ADMIN], $this->security->getToken()->getRoleNames()))
  121.         ) {
  122.             $this->flash->add('account_locked'$this->translator->trans('app.global.messages.account_suspended'));
  123.             $event->setResponse(new RedirectResponse($this->router->generate('security_login')));
  124.         }
  125.         if ($user instanceof Administrator && null !== $route && (true === str_starts_with($route'foxorders_admin') || 'foxorders_shop_shop_index' === $route)) {
  126.             $this->session->set('shop'null);
  127.         }
  128.         if (null !== $route && true === str_starts_with($route'foxorders_franchise')) {
  129.             $this->session->set('logged''franchise');
  130.         }
  131.     }
  132. }