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