src/EventSubscriber/ApiRequestSubscriber.php line 67

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