src/EventSubscriber/ApiRequestSubscriber.php line 68

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\EventSubscriber;
  4. use App\Checker\RateLimiterChecker;
  5. use App\Entity\Admin\SourceInterface;
  6. use App\Entity\Device\DeviceInterface;
  7. use App\Entity\Franchise\FranchiseInterface;
  8. use App\Entity\Security\Manager;
  9. use App\Entity\Security\ShopManager;
  10. use App\Exception\Global\SourceMandatoryException;
  11. use App\Helper\Response\DeviceResponseInterface;
  12. use App\Helper\Response\FranchiseResponseInterface;
  13. use App\Helper\Response\ResponseInterface as CustomResponseInterface;
  14. use App\Helper\Response\ShopResponseInterface;
  15. use App\Repository\Admin\SourceRepository;
  16. use App\Repository\Franchise\FranchiseRepository;
  17. use App\Repository\Shop\DeviceRepository;
  18. use App\Repository\Shop\ShopRepository;
  19. use App\Verifier\Shop\LicenceVerifier;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. use Symfony\Component\HttpFoundation\Response;
  22. use Symfony\Component\HttpKernel\Event\RequestEvent;
  23. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  24. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  25. use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
  26. use Symfony\Component\Security\Core\Security;
  27. class ApiRequestSubscriber implements EventSubscriberInterface
  28. {
  29.     public const API_VERSION_200 '2.0.0';
  30.     public const API_VERSIONS = [
  31.         self::API_VERSION_200,
  32.     ];
  33.     private array $authorizedRoutes = [
  34.         'api_login_check',
  35.         'api_users_request_request_password_collection',
  36.         'api_users_check_password_reset_token_collection',
  37.         'api_users_reset_password_collection',
  38.         'api_entrypoint',
  39.         'api_doc',
  40.         'foxorders_api_',
  41.         'foxorders_api_doc',
  42.     ];
  43.     public function __construct(
  44.         private $devicePinDev,
  45.         private Security $security,
  46.         private SourceRepository $sourceRepository,
  47.         private RateLimiterChecker $rateLimiterChecker,
  48.         private DeviceRepository $deviceRepository,
  49.         private FranchiseRepository $franchiseRepository,
  50.         private ShopRepository $shopRepository,
  51.         private LicenceVerifier $licenceVerifier,
  52.     ) {
  53.     }
  54.     public static function getSubscribedEvents(): array
  55.     {
  56.         return [
  57.             RequestEvent::class => ['onKernelRequest'6],
  58.         ];
  59.     }
  60.     public function onKernelRequest(RequestEvent $event)
  61.     {
  62.         $request $event->getRequest();
  63.         $route $request->attributes->get('_route');
  64.         $source $request->headers->get('source');
  65.         $version $request->headers->get('version');
  66.         $franchiseToken $request->headers->get('franchise-token');
  67.         $devicePinDev $request->headers->get('device-pin-dev');
  68.         $shopToken $request->headers->get('shop-token');
  69.         $identifier $request->headers->get('device-token');
  70.         $isApiRoute null !== $route && str_contains($route'api_') && false === str_starts_with($route'foxorders_documentation');
  71.         $user $this->security->getUser();
  72.         if (false === $isApiRoute || true === \in_array($route$this->authorizedRoutestrue)) {
  73.             return true;
  74.         }
  75.         $this->rateLimiterChecker->checkRate();
  76.         if (false === $this->security->getUser()) {
  77.             throw new AccessDeniedHttpException(Response::$statusTexts[Response::HTTP_FORBIDDEN]);
  78.         }
  79.         if (null === $source) {
  80.             throw new SourceMandatoryException();
  81.         }
  82.         if (null === $version) {
  83.             throw new BadRequestHttpException(CustomResponseInterface::API_VERSION_MANDATORY);
  84.         }
  85.         if (false === \in_array($versionself::API_VERSIONStrue)) {
  86.             throw new BadRequestHttpException(CustomResponseInterface::API_VERSION_INVALID);
  87.         }
  88.         if (false === $this->sourceRepository->isApiSource($source)) {
  89.             throw new BadRequestHttpException(CustomResponseInterface::SOURCE_INVALID);
  90.         }
  91.         $franchise $shop $device null;
  92.         if ($user instanceof Manager) {
  93.             $franchise $user->getFranchise();
  94.         } elseif ($user instanceof ShopManager) {
  95.             $shop $user->getShop();
  96.             $device $user->getDevice();
  97.             $franchise $shop->getFranchise();
  98.             $shopToken $shop->getToken();
  99.         }
  100.         $franchiseToken $franchise?->getToken() ?? $franchiseToken;
  101.         if (null === $franchiseToken && !\in_array($routeFranchiseInterface::ENDPOINTS_WITHOUT_TOKENtrue)) {
  102.             throw new BadRequestHttpException(FranchiseResponseInterface::FRANCHISE_TOKEN_REQUIRED);
  103.         }
  104.         if (null === $franchise && null !== $franchiseToken) {
  105.             $franchise $this->franchiseRepository->findOneBy(['token' => $franchiseToken]);
  106.             if (null === $franchise) {
  107.                 throw new BadRequestHttpException(FranchiseResponseInterface::FRANCHISE_TOKEN_INVALID);
  108.             }
  109.         }
  110.         if (null === $shop && null !== $shopToken && null !== $franchiseToken) {
  111.             if (false === $this->shopRepository->isMatchedShopTokenFranchiseToken($franchiseToken$shopToken)) {
  112.                 throw new BadRequestHttpException(ShopResponseInterface::SHOP_TOKEN_INVALID);
  113.             }
  114.         }
  115.         if (null !== $franchise && FranchiseInterface::STATUS_DISABLED === $franchise->getStatus()) {
  116.             throw new AccessDeniedHttpException(CustomResponseInterface::ACCOUNT_BLOCKED);
  117.         }
  118.         if (false === $this->licenceVerifier->verify()) {
  119.             throw new UnauthorizedHttpException('Unauthorized access'CustomResponseInterface::ACCESS_DENIED);
  120.         }
  121.         if (SourceInterface::SOURCE_FOXORDERS_FRONT === $source && null !== $shopToken) {
  122.             $device $this->deviceRepository->defaultDevice($shopToken);
  123.             if (null === $device) {
  124.                 throw new BadRequestHttpException(DeviceResponseInterface::DEVICE_TOKEN_INVALID);
  125.             }
  126.             $request->headers->set('device-token'$device->getToken());
  127.             return true;
  128.         }
  129.         if ($this->devicePinDev === $devicePinDev) {
  130.             return;
  131.         }
  132.         if (false === \in_array($sourceSourceInterface::DEVICE_SOURCEStrue) || true === \in_array($routeDeviceInterface::WHITELISTED_DEVICE_ENDPOINTStrue)) {
  133.             return true;
  134.         }
  135.         // if (null === $identifier || '' === trim($identifier)) {
  136.         //     throw new UnauthorizedHttpException('Unauthorized access', DeviceResponseInterface::UNRECOGNIZED_DEVICE);
  137.         // }
  138.         // $device = $this->deviceRepository->findOneByFranchiseTokenAndIdentifier($franchiseToken, $identifier);
  139.         // if (null === $device) {
  140.         //     throw new UnauthorizedHttpException('Unauthorized access', DeviceResponseInterface::UNRECOGNIZED_DEVICE);
  141.         // }
  142.         // $request->headers->set('device-token', $device->getToken());
  143.         if (null !== $identifier && '' !== trim($identifier)) {
  144.             $device $this->deviceRepository->findOneByFranchiseTokenAndIdentifier($franchiseToken$identifier);
  145.             if (null !== $device) {
  146.                 $request->headers->set('device-token'$device->getToken());
  147.             }
  148.         }
  149.     }
  150. }