Skip to content

Commit

Permalink
Merge branch 'next-36874/add-new-context-as-request-attr-on-login' in…
Browse files Browse the repository at this point in the history
…to 'trunk'

NEXT-36874 - Add new context as request attr on login

See merge request shopware/6/product/platform!14106
  • Loading branch information
keulinho committed Jun 24, 2024
2 parents 3bda2a9 + 8ea847f commit 9654325
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Add new context request attribute on customer login
issue: NEXT-36874
---
# Core
* Added listener on `CustomerLoginEvent` to `\Shopware\Core\Framework\Adapter\Cache\Http\CacheResponseSubscriber` in order to save the new Context to the request, which is later used in the subscriber to generate the cache state.
* Removed manually adding the context to the request in the `\Shopware\Storefront\Controller\AuthController` and replaced it with the listener, that should handle all cases (e.g. login, double-opt-in, etc).

14 changes: 14 additions & 0 deletions src/Core/Framework/Adapter/Cache/Http/CacheResponseSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent;
use Shopware\Core\Framework\Adapter\Cache\CacheStateSubscriber;
use Shopware\Core\Framework\Event\BeforeSendResponseEvent;
use Shopware\Core\Framework\Log\Package;
Expand All @@ -14,6 +15,7 @@
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
Expand Down Expand Up @@ -47,6 +49,7 @@ public function __construct(
private readonly int $defaultTtl,
private readonly bool $httpCacheEnabled,
private readonly MaintenanceModeResolver $maintenanceResolver,
private readonly RequestStack $requestStack,
private readonly bool $reverseProxyEnabled,
private readonly ?string $staleWhileRevalidate,
private readonly ?string $staleIfError
Expand All @@ -65,6 +68,7 @@ public static function getSubscribedEvents(): array
['setResponseCacheHeader', 1500],
],
BeforeSendResponseEvent::class => 'updateCacheControlForBrowser',
CustomerLoginEvent::class => 'onCustomerLogin',
];
}

Expand Down Expand Up @@ -217,6 +221,16 @@ private function hasInvalidationState(array $cacheStates, array $states): bool
return false;
}

public function onCustomerLogin(CustomerLoginEvent $event): void
{
$request = $this->requestStack->getCurrentRequest();
if (!$request) {
return;
}

$request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT, $event->getSalesChannelContext());
}

private function buildCacheHash(SalesChannelContext $context): string
{
return md5(json_encode([
Expand Down
1 change: 1 addition & 0 deletions src/Core/Framework/DependencyInjection/cache.xml
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@
<argument>%shopware.http.cache.default_ttl%</argument>
<argument>%shopware.http.cache.enabled%</argument>
<argument type="service" id="Shopware\Core\Framework\Routing\MaintenanceModeResolver"/>
<argument type="service" id="Symfony\Component\HttpFoundation\RequestStack"/>
<argument>%shopware.http_cache.reverse_proxy.enabled%</argument>
<argument>%shopware.http_cache.stale_while_revalidate%</argument>
<argument>%shopware.http_cache.stale_if_error%</argument>
Expand Down
20 changes: 1 addition & 19 deletions src/Storefront/Controller/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@
use Shopware\Core\Framework\Validation\DataBag\DataBag;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
use Shopware\Core\PlatformRequest;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceInterface;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextServiceParameters;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Checkout\Cart\SalesChannel\StorefrontCartFacade;
use Shopware\Storefront\Framework\Routing\RequestTransformer;
Expand Down Expand Up @@ -54,8 +51,7 @@ public function __construct(
private readonly AbstractLoginRoute $loginRoute,
private readonly AbstractLogoutRoute $logoutRoute,
private readonly StorefrontCartFacade $cartFacade,
private readonly AccountRecoverPasswordPageLoader $recoverPasswordPageLoader,
private readonly SalesChannelContextServiceInterface $salesChannelContextService
private readonly AccountRecoverPasswordPageLoader $recoverPasswordPageLoader
) {
}

Expand Down Expand Up @@ -161,20 +157,6 @@ public function login(Request $request, RequestDataBag $data, SalesChannelContex
$token = $this->loginRoute->login($data, $context)->getToken();
$cartBeforeNewContext = $this->cartFacade->get($token, $context);

$newContext = $this->salesChannelContextService->get(
new SalesChannelContextServiceParameters(
$context->getSalesChannelId(),
$token,
$context->getLanguageId(),
$context->getCurrencyId(),
$context->getDomainId(),
$context->getContext()
)
);

// Update the sales channel context for CacheResponseSubscriber
$request->attributes->set(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT, $newContext);

if (!empty($token)) {
$this->addCartErrors($cartBeforeNewContext);

Expand Down
1 change: 0 additions & 1 deletion src/Storefront/DependencyInjection/controller.xml
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@
<argument type="service" id="Shopware\Core\Checkout\Customer\SalesChannel\LogoutRoute"/>
<argument type="service" id="Shopware\Storefront\Checkout\Cart\SalesChannel\StorefrontCartFacade"/>
<argument type="service" id="Shopware\Storefront\Page\Account\RecoverPassword\AccountRecoverPasswordPageLoader"/>
<argument type="service" id="Shopware\Core\System\SalesChannel\Context\SalesChannelContextService"/>
<call method="setContainer">
<argument type="service" id="service_container"/>
</call>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,8 +704,7 @@ private function getAuthController(?AbstractSendPasswordRecoveryMailRoute $sendP
$this->getContainer()->get(LoginRoute::class),
$this->createMock(AbstractLogoutRoute::class),
$this->getContainer()->get(StorefrontCartFacade::class),
$this->getContainer()->get(AccountRecoverPasswordPageLoader::class),
$this->getContainer()->get(SalesChannelContextService::class)
$this->getContainer()->get(AccountRecoverPasswordPageLoader::class)
);
$controller->setContainer($this->getContainer());
$controller->setTwig($this->getContainer()->get('twig'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
use Shopware\Core\SalesChannelRequest;
use Shopware\Core\System\SalesChannel\Context\AbstractSalesChannelContextFactory;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextFactory;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextService;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Checkout\Cart\SalesChannel\StorefrontCartFacade;
use Shopware\Storefront\Controller\AuthController;
Expand Down Expand Up @@ -122,8 +121,7 @@ public function testGenerateAccountRecoveryRateLimit(): void
$this->getContainer()->get(LoginRoute::class),
$this->getContainer()->get(LogoutRoute::class),
$this->getContainer()->get(StorefrontCartFacade::class),
$this->getContainer()->get(AccountRecoverPasswordPageLoader::class),
$this->getContainer()->get(SalesChannelContextService::class)
$this->getContainer()->get(AccountRecoverPasswordPageLoader::class)
);
$controller->setContainer($this->getContainer());

Expand Down Expand Up @@ -154,8 +152,7 @@ public function testAuthControllerGuestLoginShowsRateLimit(): void
$this->createMock(LoginRoute::class),
$this->createMock(AbstractLogoutRoute::class),
$this->getContainer()->get(StorefrontCartFacade::class),
$this->getContainer()->get(AccountRecoverPasswordPageLoader::class),
$this->getContainer()->get(SalesChannelContextService::class)
$this->getContainer()->get(AccountRecoverPasswordPageLoader::class)
);
$controller->setContainer($this->getContainer());
$controller->setTwig($this->getContainer()->get('twig'));
Expand Down Expand Up @@ -192,8 +189,7 @@ public function testAuthControllerLoginShowsRateLimit(): void
$loginRoute,
$this->createMock(AbstractLogoutRoute::class),
$this->getContainer()->get(StorefrontCartFacade::class),
$this->getContainer()->get(AccountRecoverPasswordPageLoader::class),
$this->getContainer()->get(SalesChannelContextService::class)
$this->getContainer()->get(AccountRecoverPasswordPageLoader::class)
);
$controller->setContainer($this->getContainer());

Expand Down
16 changes: 12 additions & 4 deletions tests/integration/Storefront/Controller/RegisterControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\Framework\Validation\DataBag\QueryDataBag;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\PlatformRequest;
use Shopware\Core\SalesChannelRequest;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextFactory;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
Expand Down Expand Up @@ -55,10 +56,7 @@ class RegisterControllerTest extends TestCase
use MailTemplateTestBehaviour;
use StorefrontControllerTestBehaviour;

/**
* @var SalesChannelContext
*/
private $salesChannelContext;
private SalesChannelContext $salesChannelContext;

protected function setUp(): void
{
Expand Down Expand Up @@ -115,6 +113,7 @@ public function testGuestRegisterWithRequirePasswordConfirmation(): void

static::assertEquals(200, $response->getStatusCode());
static::assertCount(1, $customers);
static::assertTrue($request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT));
}

public function testGuestRegister(): void
Expand All @@ -130,6 +129,7 @@ public function testGuestRegister(): void

static::assertEquals(200, $response->getStatusCode());
static::assertCount(1, $customers);
static::assertTrue($request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT));
}

public function testRegisterWithDoubleOptIn(): void
Expand Down Expand Up @@ -165,6 +165,8 @@ public function testRegisterWithDoubleOptIn(): void

$response = $registerController->register($request, $data, $this->salesChannelContext);

static::assertFalse($request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT));

static::assertEquals(302, $response->getStatusCode());
static::assertInstanceOf(RedirectResponse::class, $response);
static::assertEquals('/account/register', $response->getTargetUrl());
Expand Down Expand Up @@ -217,6 +219,8 @@ public function testRegisterWithDoubleOptInDomainChanged(): void

$response = $registerController->register($request, $data, $this->salesChannelContext);

static::assertFalse($request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT));

static::assertEquals(302, $response->getStatusCode());
static::assertInstanceOf(RedirectResponse::class, $response);
static::assertEquals('/account/register', $response->getTargetUrl());
Expand Down Expand Up @@ -275,6 +279,8 @@ public function testConfirmRegisterWithRedirectTo(): void

$registerController->register($request, $data, $this->salesChannelContext);

static::assertFalse($request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT));

static::assertInstanceOf(CustomerDoubleOptInRegistrationEvent::class, $event);

$customer = $customerRepository->search(new Criteria([$event->getCustomer()->getId()]), $this->salesChannelContext->getContext())->getEntities();
Expand All @@ -285,6 +291,8 @@ public function testConfirmRegisterWithRedirectTo(): void

$response = $registerController->confirmRegistration($this->salesChannelContext, $queryData);

static::assertTrue($request->attributes->has(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT));

static::assertEquals(302, $response->getStatusCode());
static::assertInstanceOf(RedirectResponse::class, $response);
static::assertEquals('/checkout/confirm', $response->getTargetUrl());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\Adapter\Cache\Http\CacheResponseSubscriber;
use Shopware\Core\Framework\Event\BeforeSendResponseEvent;
Expand Down Expand Up @@ -52,6 +53,7 @@ public function testHasEvents(): void
['setResponseCacheHeader', 1500],
],
BeforeSendResponseEvent::class => 'updateCacheControlForBrowser',
CustomerLoginEvent::class => 'onCustomerLogin',
];

static::assertSame($expected, CacheResponseSubscriber::getSubscribedEvents());
Expand All @@ -64,6 +66,7 @@ public function testNoHeadersAreSetIfCacheIsDisabled(): void
100,
false,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down Expand Up @@ -98,6 +101,7 @@ public function testNoAutoCacheControlHeader(): void
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down Expand Up @@ -127,6 +131,7 @@ public function testNoAutoCacheControlHeaderCacheDisabled(): void
100,
false,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down Expand Up @@ -156,6 +161,7 @@ public function testNoAutoCacheControlHeaderNoHttpCacheRoute(): void
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down Expand Up @@ -189,6 +195,7 @@ public function testGenerateCashHashWithItemsInCart(?CustomerEntity $customer, C
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down Expand Up @@ -270,6 +277,7 @@ public function testMaintenanceRequest(bool $active, array $whitelist, bool $sho
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
$requestStack,
false,
null,
null
Expand Down Expand Up @@ -308,6 +316,32 @@ public function testMaintenanceRequest(bool $active, array $whitelist, bool $sho
$subscriber->setResponseCache($event);
}

public function testOnCustomerLogin(): void
{
$requestStack = new RequestStack();

$subscriber = new CacheResponseSubscriber(
$this->createMock(CartService::class),
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
$requestStack,
false,
null,
null
);

$salesChannelContext = $this->createMock(SalesChannelContext::class);

$request = new Request();
$requestStack->push($request);

$event = new CustomerLoginEvent($salesChannelContext, new CustomerEntity(), 'token');
$subscriber->onCustomerLogin($event);

static::assertSame($salesChannelContext, $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT));
}

/**
* @return array<string, array<int, CustomerEntity|Cart|bool|string|null>>
*/
Expand Down Expand Up @@ -352,6 +386,7 @@ public function testResponseHeaders(bool $reverseProxyEnabled, ?string $beforeHe
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
$reverseProxyEnabled,
null,
null
Expand Down Expand Up @@ -422,6 +457,7 @@ public function testAddHttpCacheToCoreRoutes(): void
1,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand All @@ -442,6 +478,7 @@ public function testCurrencyChange(?string $currencyId): void
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down Expand Up @@ -485,6 +522,7 @@ public function testStatesGetDeletedOnEmptyState(): void
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down Expand Up @@ -517,6 +555,7 @@ public function testNotCacheablePages(Request $request): void
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down Expand Up @@ -561,6 +600,7 @@ public function testNoCachingWhenInvalidateStateMatches(): void
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down Expand Up @@ -597,6 +637,7 @@ public function testMakeGetsCached(): void
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
'5',
'6'
Expand Down Expand Up @@ -681,6 +722,7 @@ public function testSetResponseCacheOnLogin(
100,
true,
new MaintenanceModeResolver(new EventDispatcher()),
new RequestStack(),
false,
null,
null
Expand Down
Loading

0 comments on commit 9654325

Please sign in to comment.