Skip to content

Commit 65e2728

Browse files
PWA-1938: Resetting user context when auth token is revoked
1 parent 39e1300 commit 65e2728

File tree

4 files changed

+90
-6
lines changed

4 files changed

+90
-6
lines changed

app/code/Magento/GraphQlCache/Model/Plugin/Integration/Api/UserTokenIssuer.php renamed to app/code/Magento/GraphQlCache/Model/Plugin/Auth/TokenIssuer.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
*/
66
declare(strict_types=1);
77

8-
namespace Magento\GraphQlCache\Model\Plugin\Integration\Api;
8+
namespace Magento\GraphQlCache\Model\Plugin\Auth;
99

1010
use Magento\Authorization\Model\UserContextInterface;
11-
use Magento\Framework\App\ResponseInterface;
1211
use Magento\GraphQl\Model\Query\ContextFactoryInterface;
1312
use Magento\Integration\Api\UserTokenIssuerInterface;
13+
use Magento\Integration\Model\CustomUserContext;
1414

1515
/**
16-
* Load the shared UserContext with data for the user used to generate the token
16+
* Load the shared UserContext with data for the new user after a token is generated
1717
*/
18-
class UserTokenIssuer
18+
class TokenIssuer
1919
{
2020
/**
2121
* @var ContextFactoryInterface
@@ -36,7 +36,7 @@ public function __construct(ContextFactoryInterface $contextFactory)
3636
* @param UserTokenIssuerInterface $issuer
3737
* @param string $result
3838
* @param UserContextInterface $userContext
39-
* @return ResponseInterface
39+
* @return string
4040
*
4141
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
4242
*/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GraphQlCache\Model\Plugin\Auth;
9+
10+
use Magento\Authorization\Model\UserContextInterface;
11+
use Magento\GraphQl\Model\Query\ContextFactoryInterface;
12+
use Magento\Integration\Model\CustomUserContext;
13+
14+
/**
15+
* Load the shared UserContext with data for guest after a token is revoked
16+
*/
17+
class TokenRevoker
18+
{
19+
/**
20+
* @var ContextFactoryInterface
21+
*/
22+
private $contextFactory;
23+
24+
/**
25+
* @param ContextFactoryInterface $contextFactory
26+
*/
27+
public function __construct(ContextFactoryInterface $contextFactory)
28+
{
29+
$this->contextFactory = $contextFactory;
30+
}
31+
32+
/**
33+
* Reset the shared user context to guest after a token is revoked
34+
*
35+
* @return void
36+
*/
37+
public function afterRevokeFor(): void
38+
{
39+
$this->contextFactory->create(new CustomUserContext(0, UserContextInterface::USER_TYPE_GUEST));
40+
}
41+
}

app/code/Magento/GraphQlCache/etc/graphql/di.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
<plugin name="result-varnish-cache" type="Magento\PageCache\Model\Controller\Result\VarnishPlugin"/>
2525
</type>
2626
<type name="Magento\Integration\Api\UserTokenIssuerInterface">
27-
<plugin name="set-context-after-token" type="Magento\GraphQlCache\Model\Plugin\Integration\Api\UserTokenIssuer"/>
27+
<plugin name="set-context-after-token" type="Magento\GraphQlCache\Model\Plugin\Auth\TokenIssuer"/>
28+
</type>
29+
<type name="Magento\Integration\Api\UserTokenRevokerInterface">
30+
<plugin name="set-guest-after-revoke" type="Magento\GraphQlCache\Model\Plugin\Auth\TokenRevoker"/>
2831
</type>
2932
</config>

dev/tests/api-functional/testsuite/Magento/GraphQl/GraphQlCache/CacheIdFactorProviders/Customer/IsLoggedInProviderTest.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,44 @@ public function testCacheIdHeaderWithIsLoggedIn()
9393
$addProductToCustomerCartResponse['headers'][CacheIdCalculator::CACHE_ID_HEADER]
9494
);
9595
}
96+
97+
/**
98+
* Tests that cache id header resets to the one for guest when a customer token is revoked
99+
*
100+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
101+
* @magentoApiDataFixture Magento/GraphQl/Catalog/_files/simple_product.php
102+
*/
103+
public function testCacheIdHeaderAfterRevokeToken()
104+
{
105+
// Get the guest cache id
106+
$guestCartResponse = $this->graphQlMutationWithResponseHeaders('mutation{createEmptyCart}');
107+
$this->assertArrayHasKey(CacheIdCalculator::CACHE_ID_HEADER, $guestCartResponse['headers']);
108+
$guestCacheId = $guestCartResponse['headers'][CacheIdCalculator::CACHE_ID_HEADER];
109+
110+
// Get the customer cache id and token to send to the revoke mutation
111+
$generateToken = <<<MUTATION
112+
mutation{
113+
generateCustomerToken(email:"customer@example.com", password:"password")
114+
{token}
115+
}
116+
MUTATION;
117+
$tokenResponse = $this->graphQlMutationWithResponseHeaders($generateToken);
118+
$this->assertArrayHasKey('generateCustomerToken', $tokenResponse['body']);
119+
$customerToken = $tokenResponse['body']['generateCustomerToken']['token'];
120+
$this->assertArrayHasKey(CacheIdCalculator::CACHE_ID_HEADER, $tokenResponse['headers']);
121+
$customerCacheId = $tokenResponse['headers'][CacheIdCalculator::CACHE_ID_HEADER];
122+
$this->assertNotEquals($customerCacheId, $guestCacheId);
123+
124+
// Revoke the token and check that it returns the guest cache id
125+
$revokeCustomerToken = "mutation{revokeCustomerToken{result}}";
126+
$revokeResponse = $this->graphQlMutationWithResponseHeaders(
127+
$revokeCustomerToken,
128+
[],
129+
'',
130+
['Authorization' => 'Bearer ' . $customerToken]
131+
);
132+
$this->assertArrayHasKey(CacheIdCalculator::CACHE_ID_HEADER, $revokeResponse['headers']);
133+
$revokeCacheId = $revokeResponse['headers'][CacheIdCalculator::CACHE_ID_HEADER];
134+
$this->assertEquals($guestCacheId, $revokeCacheId);
135+
}
96136
}

0 commit comments

Comments
 (0)