Skip to content

Commit

Permalink
Merge pull request #228 from BitBagCommerce/hotfix/restrict-wishlist-…
Browse files Browse the repository at this point in the history
…creation

OP-149 - Restrict wishlist creation
  • Loading branch information
senghe authored Oct 24, 2023
2 parents c34dd8b + 97a21f3 commit 4124f89
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 105 deletions.
108 changes: 30 additions & 78 deletions src/EventSubscriber/CreateNewWishlistSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,60 +11,43 @@
namespace BitBag\SyliusWishlistPlugin\EventSubscriber;

use BitBag\SyliusWishlistPlugin\Entity\WishlistInterface;
use BitBag\SyliusWishlistPlugin\Entity\WishlistToken;
use BitBag\SyliusWishlistPlugin\Factory\WishlistFactoryInterface;
use BitBag\SyliusWishlistPlugin\Repository\WishlistRepositoryInterface;
use BitBag\SyliusWishlistPlugin\Resolver\TokenUserResolverInterface;
use BitBag\SyliusWishlistPlugin\Resolver\WishlistCookieTokenResolverInterface;
use BitBag\SyliusWishlistPlugin\Resolver\WishlistsResolverInterface;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Channel\Context\ChannelNotFoundException;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Webmozart\Assert\Assert;

final class CreateNewWishlistSubscriber implements EventSubscriberInterface
{
private const ALLOWED_ENDPOINTS_PREFIX = '/wishlist';

private string $wishlistCookieToken;

private WishlistsResolverInterface $wishlistsResolver;

private WishlistFactoryInterface $wishlistFactory;

private WishlistRepositoryInterface $wishlistRepository;

private TokenStorageInterface $tokenStorage;

private ChannelContextInterface $channelContext;

private WishlistCookieTokenResolverInterface $wishlistCookieTokenResolver;

private TokenUserResolverInterface $tokenUserResolver;
private Request $mainRequest;

public function __construct(
string $wishlistCookieToken,
WishlistsResolverInterface $wishlistsResolver,
WishlistFactoryInterface $wishlistFactory,
WishlistRepositoryInterface $wishlistRepository,
TokenStorageInterface $tokenStorage,
ChannelContextInterface $channelContext,
WishlistCookieTokenResolverInterface $wishlistCookieTokenResolver,
TokenUserResolverInterface $tokenUserResolver,
RequestStack $requestStack,
) {
$this->wishlistCookieToken = $wishlistCookieToken;
$this->wishlistsResolver = $wishlistsResolver;
$this->wishlistFactory = $wishlistFactory;
$this->wishlistRepository = $wishlistRepository;
$this->tokenStorage = $tokenStorage;
$this->channelContext = $channelContext;
$this->wishlistCookieTokenResolver = $wishlistCookieTokenResolver;
$this->tokenUserResolver = $tokenUserResolver;

$mainRequest = $requestStack->getMainRequest();
Assert::notNull($mainRequest, 'The class has to be used in HTTP context only');

$this->mainRequest = $mainRequest;
}

public static function getSubscribedEvents(): array
Expand All @@ -81,25 +64,29 @@ public function onKernelRequest(RequestEvent $event): void
return;
}

$currentPath = $this->mainRequest->getPathInfo();
if (!str_starts_with($currentPath, self::ALLOWED_ENDPOINTS_PREFIX)) {
return;
}

/** @var WishlistInterface[] $wishlists */
$wishlists = $this->wishlistsResolver->resolve();

$wishlistCookieToken = $event->getRequest()->cookies->get($this->wishlistCookieToken);
$wishlistCookieToken = $this->mainRequest->cookies->get($this->wishlistCookieToken);

if (!empty($wishlists)) {
if (null === $wishlistCookieToken) {
$event->getRequest()->attributes->set($this->wishlistCookieToken, reset($wishlists)->getToken());
$this->mainRequest->attributes->set($this->wishlistCookieToken, reset($wishlists)->getToken());
}

return;
}

if (null === $wishlistCookieToken)
{
if (null === $wishlistCookieToken) {
$wishlistCookieToken = $this->wishlistCookieTokenResolver->resolve();
}

$event->getRequest()->attributes->set($this->wishlistCookieToken, $wishlistCookieToken);
$this->mainRequest->attributes->set($this->wishlistCookieToken, $wishlistCookieToken);
}

public function onKernelResponse(ResponseEvent $event): void
Expand All @@ -108,60 +95,25 @@ public function onKernelResponse(ResponseEvent $event): void
return;
}

if ($event->getRequest()->cookies->has($this->wishlistCookieToken)) {
$currentPath = $this->mainRequest->getPathInfo();
if (!str_starts_with($currentPath, self::ALLOWED_ENDPOINTS_PREFIX)) {
return;
}

$response = $event->getResponse();
$wishlistCookieToken = $event->getRequest()->attributes->get($this->wishlistCookieToken);

if (!$wishlistCookieToken) {
if ($this->mainRequest->cookies->has($this->wishlistCookieToken)) {
return;
}
$this->setWishlistCookieToken($response, $wishlistCookieToken);

$event->getRequest()->attributes->remove($this->wishlistCookieToken);
}

private function createNewWishlist(?string $wishlistCookieToken): WishlistInterface
{
$token = $this->tokenStorage->getToken();
$user = $this->tokenUserResolver->resolve($token);

$wishlist = $this->wishlistFactory->createNew();

try {
$channel = $this->channelContext->getChannel();
} catch (ChannelNotFoundException $exception) {
$channel = null;
}

if ($channel instanceof ChannelInterface) {
$wishlist->setChannel($channel);
}

if ($channel instanceof ChannelInterface &&
$user instanceof ShopUserInterface
) {
$wishlist = $this->wishlistFactory->createForUserAndChannel($user, $channel);
} elseif ($user instanceof ShopUserInterface) {
$wishlist = $this->wishlistFactory->createForUser($user);
}
$response = $event->getResponse();
$wishlistCookieToken = $this->mainRequest->attributes->get($this->wishlistCookieToken);

if ($wishlistCookieToken) {
$wishlist->setToken($wishlistCookieToken);
if (!$wishlistCookieToken) {
return;
}

$wishlist->setName('Wishlist');
$this->wishlistRepository->add($wishlist);

return $wishlist;
}

private function setWishlistCookieToken(Response $response, string $wishlistCookieToken): void
{
$cookie = new Cookie($this->wishlistCookieToken, $wishlistCookieToken, strtotime('+1 year'));

$response->headers->setCookie($cookie);

$this->mainRequest->attributes->remove($this->wishlistCookieToken);
}
}
11 changes: 8 additions & 3 deletions src/Resolver/WishlistCookieTokenResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ public function resolve(): string
{
$wishlistCookieToken = $this->requestStack->getMainRequest()->cookies->get($this->wishlistCookieToken);

if (!$wishlistCookieToken) {
return (string) new WishlistToken();
if (null !== $wishlistCookieToken) {
return $wishlistCookieToken;
}

return $wishlistCookieToken;
$wishlistCookieToken = $this->requestStack->getMainRequest()->attributes->get($this->wishlistCookieToken);
if (null !== $wishlistCookieToken) {
return $wishlistCookieToken;
}

return (string) new WishlistToken();
}
}
29 changes: 10 additions & 19 deletions src/Resolver/WishlistsResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,15 @@ public function resolve(): array
$channel = null;
}

return $this->getWishlistsByUserOrCookieToken($wishlistCookieToken, $user, $channel);
if ($user instanceof ShopUserInterface) {
return $this->wishlistRepository->findAllByShopUserAndToken($user->getId(), $wishlistCookieToken);
}

if ($channel instanceof ChannelInterface) {
return $this->wishlistRepository->findAllByAnonymousAndChannel($wishlistCookieToken, $channel);
}

return $this->wishlistRepository->findAllByAnonymous($wishlistCookieToken);
}

public function resolveAndCreate(): array
Expand All @@ -81,8 +89,7 @@ public function resolveAndCreate(): array
$channel = null;
}

if ([] === $wishlists || null === $wishlists)
{
if (0 === count($wishlists)) {
$createWishlist = new CreateWishlist($wishlistCookieToken, $channel?->getCode());
/** @var WishlistInterface $wishlist */
$wishlist = $this->handle($createWishlist);
Expand All @@ -92,20 +99,4 @@ public function resolveAndCreate(): array

return $wishlists;
}

public function getWishlistsByUserOrCookieToken(
string $wishlistCookieToken,
?UserInterface $user,
?ChannelInterface $channel
): ?array {
if ($user instanceof ShopUserInterface) {
return $this->wishlistRepository->findAllByShopUserAndToken($user->getId(), $wishlistCookieToken);
}

if ($channel instanceof ChannelInterface) {
return $this->wishlistRepository->findAllByAnonymousAndChannel($wishlistCookieToken, $channel);
}

return $this->wishlistRepository->findAllByAnonymous($wishlistCookieToken);
}
}
6 changes: 1 addition & 5 deletions src/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,8 @@ services:
arguments:
- "%bitbag_sylius_wishlist_plugin.parameters.wishlist_cookie_token%"
- "@bitbag_sylius_wishlist_plugin.resolver.wishlists_resolver"
- "@bitbag_sylius_wishlist_plugin.factory.wishlist"
- "@bitbag_sylius_wishlist_plugin.repository.wishlist"
- "@security.token_storage"
- "@sylius.context.channel"
- '@bitbag_sylius_wishlist_plugin.resolver.wishlist_cookie_token_resolver'
- '@bitbag_sylius_wishlist_plugin.resolver.token_user_resolver'
- '@request_stack'
tags:
- { name: kernel.event_subscriber, event: kernel.exception }

Expand Down

0 comments on commit 4124f89

Please sign in to comment.