Skip to content

Commit f9f55a9

Browse files
committed
feature #32 add disable access token saving feature (Orkin)
This PR was squashed before being merged into the 0.1-dev branch. Discussion ---------- add disable access token saving feature `@mtarld` `@chalasr` this is the port of disabled access token saving feature 😉 Commits ------- 03e815d add disable access token saving feature
2 parents 429864a + 03e815d commit f9f55a9

File tree

14 files changed

+280
-32
lines changed

14 files changed

+280
-32
lines changed

docs/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ For implementation into Symfony projects, please see [bundle documentation](docs
7272
# Whether to require code challenge for public clients for the auth code grant
7373
require_code_challenge_for_public_clients: true
7474
75+
# Whether to enable access token saving to persistence layer (default to true)
76+
persist_access_token: true
77+
7578
resource_server: # Required
7679
7780
# Full path to the public key file

src/DependencyInjection/Configuration.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ private function createAuthorizationServerNode(): NodeDefinition
106106
->info('Whether to enable the implicit grant')
107107
->defaultTrue()
108108
->end()
109+
->booleanNode('persist_access_token')
110+
->info('Whether to enable access token saving to persistence layer')
111+
->defaultTrue()
112+
->end()
109113
->end()
110114
;
111115

src/DependencyInjection/LeagueOAuth2ServerExtension.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use League\Bundle\OAuth2ServerBundle\Manager\Doctrine\AuthorizationCodeManager;
1515
use League\Bundle\OAuth2ServerBundle\Manager\Doctrine\ClientManager;
1616
use League\Bundle\OAuth2ServerBundle\Manager\Doctrine\RefreshTokenManager;
17+
use League\Bundle\OAuth2ServerBundle\Manager\InMemory\AccessTokenManager as InMemoryAccessTokenManager;
1718
use League\Bundle\OAuth2ServerBundle\Manager\ScopeManagerInterface;
1819
use League\Bundle\OAuth2ServerBundle\Model\Scope as ScopeModel;
1920
use League\Bundle\OAuth2ServerBundle\Persistence\Mapping\Driver;
@@ -54,6 +55,7 @@ public function load(array $configs, ContainerBuilder $container)
5455

5556
$config = $this->processConfiguration(new Configuration(), $configs);
5657

58+
$this->configureAccessTokenSaving($loader, $config['authorization_server']);
5759
$this->configurePersistence($loader, $container, $config);
5860
$this->configureAuthorizationServer($container, $config['authorization_server']);
5961
$this->configureResourceServer($container, $config['resource_server']);
@@ -206,6 +208,15 @@ private function configureGrants(ContainerBuilder $container, array $config): vo
206208
;
207209
}
208210

211+
private function configureAccessTokenSaving(LoaderInterface $loader, array $config): void
212+
{
213+
if ($config['persist_access_token']) {
214+
$loader->load('access_token/default.php');
215+
} else {
216+
$loader->load('access_token/null.php');
217+
}
218+
}
219+
209220
/**
210221
* @throws \Exception
211222
*/
@@ -221,7 +232,7 @@ private function configurePersistence(LoaderInterface $loader, ContainerBuilder
221232
switch ($persistenceMethod) {
222233
case 'in_memory':
223234
$loader->load('storage/in_memory.php');
224-
$this->configureInMemoryPersistence($container);
235+
$this->configureInMemoryPersistence($container, $config);
225236
break;
226237
case 'doctrine':
227238
$loader->load('storage/doctrine.php');
@@ -241,6 +252,7 @@ private function configureDoctrinePersistence(ContainerBuilder $container, array
241252
$container
242253
->findDefinition(AccessTokenManager::class)
243254
->replaceArgument(0, $entityManager)
255+
->replaceArgument(1, $config['authorization_server']['persist_access_token'])
244256
;
245257

246258
$container
@@ -267,14 +279,19 @@ private function configureDoctrinePersistence(ContainerBuilder $container, array
267279
$container
268280
->findDefinition(Driver::class)
269281
->replaceArgument(0, $config['client']['classname'])
282+
->replaceArgument(1, $config['authorization_server']['persist_access_token'])
270283
;
271284

272285
$container->setParameter('league.oauth2_server.persistence.doctrine.enabled', true);
273286
$container->setParameter('league.oauth2_server.persistence.doctrine.manager', $entityManagerName);
274287
}
275288

276-
private function configureInMemoryPersistence(ContainerBuilder $container): void
289+
private function configureInMemoryPersistence(ContainerBuilder $container, array $config): void
277290
{
291+
$container
292+
->findDefinition(InMemoryAccessTokenManager::class)
293+
->replaceArgument(0, $config['authorization_server']['persist_access_token'])
294+
;
278295
$container->setParameter('league.oauth2_server.persistence.in_memory.enabled', true);
279296
}
280297

src/Manager/InMemory/AccessTokenManager.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,41 @@ final class AccessTokenManager implements AccessTokenManagerInterface
1414
*/
1515
private $accessTokens = [];
1616

17+
/** @var bool */
18+
private $persistAccessToken;
19+
20+
public function __construct(bool $persistAccessToken)
21+
{
22+
$this->persistAccessToken = $persistAccessToken;
23+
}
24+
1725
/**
1826
* @psalm-mutation-free
1927
*/
2028
public function find(string $identifier): ?AccessToken
2129
{
30+
if (!$this->persistAccessToken) {
31+
return null;
32+
}
33+
2234
return $this->accessTokens[$identifier] ?? null;
2335
}
2436

2537
public function save(AccessToken $accessToken): void
2638
{
39+
if (!$this->persistAccessToken) {
40+
return;
41+
}
42+
2743
$this->accessTokens[$accessToken->getIdentifier()] = $accessToken;
2844
}
2945

3046
public function clearExpired(): int
3147
{
48+
if (!$this->persistAccessToken) {
49+
return 0;
50+
}
51+
3252
$count = \count($this->accessTokens);
3353

3454
$now = new \DateTimeImmutable();
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace League\Bundle\OAuth2ServerBundle\Manager\Null;
6+
7+
use League\Bundle\OAuth2ServerBundle\Manager\AccessTokenManagerInterface;
8+
use League\Bundle\OAuth2ServerBundle\Model\AccessToken;
9+
10+
final class AccessTokenManager implements AccessTokenManagerInterface
11+
{
12+
public function find(string $identifier): ?AccessToken
13+
{
14+
return null;
15+
}
16+
17+
public function save(AccessToken $accessToken): void
18+
{
19+
}
20+
21+
public function clearExpired(): int
22+
{
23+
return 0;
24+
}
25+
}

src/Persistence/Mapping/Driver.php

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ class Driver implements MappingDriver
2525
*/
2626
private $clientClass;
2727

28-
public function __construct(string $clientClass)
28+
/** @var bool */
29+
private $persistAccessToken;
30+
31+
public function __construct(string $clientClass, bool $persistAccessToken)
2932
{
3033
$this->clientClass = $clientClass;
34+
$this->persistAccessToken = $persistAccessToken;
3135
}
3236

3337
public function loadMetadataForClass($className, ClassMetadata $metadata): void
@@ -63,11 +67,11 @@ public function getAllClassNames(): array
6367
return array_merge(
6468
[
6569
AbstractClient::class,
66-
AccessToken::class,
6770
AuthorizationCode::class,
6871
RefreshToken::class,
6972
],
70-
Client::class === $this->clientClass ? [Client::class] : []
73+
Client::class === $this->clientClass ? [Client::class] : [],
74+
$this->persistAccessToken ? [AccessToken::class] : []
7175
);
7276
}
7377

@@ -126,12 +130,18 @@ private function buildClientMetadata(ClassMetadata $metadata): void
126130

127131
private function buildRefreshTokenMetadata(ClassMetadata $metadata): void
128132
{
129-
(new ClassMetadataBuilder($metadata))
133+
$classMetadataBuilder = (new ClassMetadataBuilder($metadata))
130134
->setTable('oauth2_refresh_token')
131135
->createField('identifier', 'string')->makePrimaryKey()->length(80)->option('fixed', true)->build()
132136
->addField('expiry', 'datetime_immutable')
133137
->addField('revoked', 'boolean')
134-
->createManyToOne('accessToken', AccessToken::class)->addJoinColumn('access_token', 'identifier', true, false, 'SET NULL')->build()
135138
;
139+
140+
if ($this->persistAccessToken) {
141+
$classMetadataBuilder->createManyToOne('accessToken', AccessToken::class)
142+
->addJoinColumn('access_token', 'identifier', true, false, 'SET NULL')
143+
->build()
144+
;
145+
}
136146
}
137147
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace League\Bundle\OAuth2ServerBundle\Repository;
6+
7+
use League\Bundle\OAuth2ServerBundle\Entity\AccessToken as AccessTokenEntity;
8+
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
9+
use League\OAuth2\Server\Entities\ClientEntityInterface;
10+
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
11+
12+
final class NullAccessTokenRepository implements AccessTokenRepositoryInterface
13+
{
14+
/**
15+
* {@inheritdoc}
16+
*/
17+
public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null): AccessTokenEntityInterface
18+
{
19+
/** @var int|string|null $userIdentifier */
20+
$accessToken = new AccessTokenEntity();
21+
$accessToken->setClient($clientEntity);
22+
$accessToken->setUserIdentifier($userIdentifier);
23+
24+
foreach ($scopes as $scope) {
25+
$accessToken->addScope($scope);
26+
}
27+
28+
return $accessToken;
29+
}
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity): void
35+
{
36+
// do nothing
37+
}
38+
39+
/**
40+
* {@inheritdoc}
41+
*/
42+
public function revokeAccessToken($tokenId): void
43+
{
44+
// do nothing
45+
}
46+
47+
/**
48+
* {@inheritdoc}
49+
*/
50+
public function isAccessTokenRevoked($tokenId): bool
51+
{
52+
return false;
53+
}
54+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use function Symfony\Component\DependencyInjection\Loader\Configurator\service;
6+
use League\Bundle\OAuth2ServerBundle\Converter\ScopeConverterInterface;
7+
use League\Bundle\OAuth2ServerBundle\Manager\AccessTokenManagerInterface;
8+
use League\Bundle\OAuth2ServerBundle\Manager\ClientManagerInterface;
9+
use League\Bundle\OAuth2ServerBundle\Repository\AccessTokenRepository;
10+
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
11+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
12+
13+
return static function (ContainerConfigurator $container): void {
14+
$container->services()
15+
16+
->set('league.oauth2_server.repository.access_token', AccessTokenRepository::class)
17+
->args([
18+
service(AccessTokenManagerInterface::class),
19+
service(ClientManagerInterface::class),
20+
service(ScopeConverterInterface::class),
21+
])
22+
->alias(AccessTokenRepositoryInterface::class, 'league.oauth2_server.repository.access_token')
23+
->alias(AccessTokenRepository::class, 'league.oauth2_server.repository.access_token');
24+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use League\Bundle\OAuth2ServerBundle\Manager\AccessTokenManagerInterface;
6+
use League\Bundle\OAuth2ServerBundle\Manager\Null\AccessTokenManager;
7+
use League\Bundle\OAuth2ServerBundle\Repository\AccessTokenRepository;
8+
use League\Bundle\OAuth2ServerBundle\Repository\NullAccessTokenRepository;
9+
use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface;
10+
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
11+
12+
return static function (ContainerConfigurator $container): void {
13+
$container->services()
14+
->set('league.oauth2_server.repository.access_token', NullAccessTokenRepository::class)
15+
->alias(AccessTokenRepositoryInterface::class, 'league.oauth2_server.repository.access_token')
16+
->alias(AccessTokenRepository::class, 'league.oauth2_server.repository.access_token')
17+
18+
->set('league.oauth2_server.manager.null.access_token', AccessTokenManager::class)
19+
->alias(AccessTokenManagerInterface::class, 'league.oauth2_server.manager.null.access_token')
20+
->alias(AccessTokenManager::class, 'league.oauth2_server.manager.null.access_token');
21+
};

src/Resources/config/services.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
use League\Bundle\OAuth2ServerBundle\Manager\RefreshTokenManagerInterface;
2929
use League\Bundle\OAuth2ServerBundle\Manager\ScopeManagerInterface;
3030
use League\Bundle\OAuth2ServerBundle\OAuth2Events;
31-
use League\Bundle\OAuth2ServerBundle\Repository\AccessTokenRepository;
3231
use League\Bundle\OAuth2ServerBundle\Repository\AuthCodeRepository;
3332
use League\Bundle\OAuth2ServerBundle\Repository\ClientRepository;
3433
use League\Bundle\OAuth2ServerBundle\Repository\RefreshTokenRepository;
@@ -70,15 +69,6 @@
7069
->alias(ClientRepositoryInterface::class, 'league.oauth2_server.repository.client')
7170
->alias(ClientRepository::class, 'league.oauth2_server.repository.client')
7271

73-
->set('league.oauth2_server.repository.access_token', AccessTokenRepository::class)
74-
->args([
75-
service(AccessTokenManagerInterface::class),
76-
service(ClientManagerInterface::class),
77-
service(ScopeConverterInterface::class),
78-
])
79-
->alias(AccessTokenRepositoryInterface::class, 'league.oauth2_server.repository.access_token')
80-
->alias(AccessTokenRepository::class, 'league.oauth2_server.repository.access_token')
81-
8272
->set('league.oauth2_server.repository.refresh_token', RefreshTokenRepository::class)
8373
->args([
8474
service(RefreshTokenManagerInterface::class),

0 commit comments

Comments
 (0)