src/API/EventSubscriber/Storefront/CartAccessValidationEventSubscriber.php line 39

Open in your IDE?
  1. <?php
  2. /**
  3.  * Copyright (c) 2011-present Qualiteam software Ltd. All rights reserved.
  4.  * See https://www.x-cart.com/license-agreement.html for license details.
  5.  */
  6. namespace XCart\API\EventSubscriber\Storefront;
  7. use ApiPlatform\Exception\InvalidArgumentException;
  8. use ApiPlatform\Exception\ItemNotFoundException;
  9. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  10. use Symfony\Component\HttpKernel\Event\RequestEvent;
  11. use Symfony\Component\HttpKernel\KernelEvents;
  12. use XLite\Model\Cart as CartModel;
  13. use XLite\Model\Profile as ProfileModel;
  14. use XLite\Model\OrderItem as CartItemModel;
  15. use XLite\Model\Repo\Cart as CartRepository;
  16. use XLite\Model\Repo\Orderitem as CartItemRepository;
  17. class CartAccessValidationEventSubscriber implements EventSubscriberInterface
  18. {
  19.     public function __construct(
  20.         private CartRepository $cartRepository,
  21.         private CartItemRepository $cartItemRepository,
  22.     ) {
  23.     }
  24.     public static function getSubscribedEvents(): array
  25.     {
  26.         return [
  27.             KernelEvents::REQUEST => [
  28.                 ['checkCart'6],
  29.                 ['checkCartItem'5],
  30.             ],
  31.         ];
  32.     }
  33.     public function checkCart(RequestEvent $event): void
  34.     {
  35.         if (!$event->isMainRequest() || $event->getRequest()->getMethod() === 'OPTIONS') {
  36.             return;
  37.         }
  38.         if (!preg_match('/api\/storefront\/carts\/([^\/]+)(?:\/|$)/S'$event->getRequest()->getPathInfo(), $match)) {
  39.             return;
  40.         }
  41.         $cartId $match[1];
  42.         /** @var ?CartModel $cart */
  43.         $cart $this->cartRepository->findOneBy(['public_id' => $cartId]);
  44.         if (!$cart) {
  45.             throw new ItemNotFoundException('Cart not found');
  46.         }
  47.         /** @var ProfileModel $user */
  48.         $user $event->getRequest()->attributes->get('_profile');
  49.         $cartProfile     $cart->getProfile();
  50.         $cartOrigProfile $cart->getOrigProfile();
  51.         // User anonymous and cart for registered user - security violation
  52.         if (!$user && !$cartProfile->getAnonymous()) {
  53.             throw new ItemNotFoundException('Cart for anonymous user not found');
  54.         }
  55.         // User is not anonymous and cart for anonymous user - security violation
  56.         if ($user && $cartProfile->getAnonymous()) {
  57.             throw new ItemNotFoundException('Cart for registered user not found');
  58.         }
  59.         if ($user && $user->getProfileId() !== $cartOrigProfile->getProfileId()) {
  60.             throw new ItemNotFoundException('Cart assigned to another user');
  61.         }
  62.         $event->getRequest()->attributes->set('_cart_id'$cart->getOrderId());
  63.         $event->getRequest()->attributes->set('_cart'$cart);
  64.         $event->getRequest()->attributes->set('_profile_id'$cartProfile->getProfileId());
  65.         $event->getRequest()->attributes->set('_profile'$cartProfile);
  66.     }
  67.     public function checkCartItem(RequestEvent $event): void
  68.     {
  69.         if (!$event->isMainRequest() || $event->getRequest()->getMethod() === 'OPTIONS') {
  70.             return;
  71.         }
  72.         if (!preg_match('/api\/storefront\/carts\/[^\/]+\/items\/(\d+)/S'$event->getRequest()->getPathInfo(), $match)) {
  73.             return;
  74.         }
  75.         $itemId = (int) $match[1];
  76.         if ($itemId <= 0) {
  77.             throw new InvalidArgumentException('Cart item ID Must be positive numeric');
  78.         }
  79.         /** @var ?CartItemModel $cart */
  80.         $item $this->cartItemRepository->find($itemId);
  81.         if (!$item) {
  82.             throw new ItemNotFoundException('Cart item not found');
  83.         }
  84.         if ($item->getOrder()->getOrderId() !== $event->getRequest()->attributes->get('_cart')->getOrderId()) {
  85.             throw new ItemNotFoundException('Cart item not found in cart');
  86.         }
  87.     }
  88. }