Skip to content

Commit 897b9a5

Browse files
authoredOct 21, 2024··
Move to dedicated ScopeEntity Factory (#261)
* Move to dedicated ScopeEntity Factory --------- Co-authored-by: Marko Ivančić <marko.ivancic@srce.hr>
1 parent 0029997 commit 897b9a5

14 files changed

+86
-69
lines changed
 

‎src/Entities/ScopeEntity.php

+7-33
Original file line numberDiff line numberDiff line change
@@ -27,41 +27,15 @@ class ScopeEntity implements ScopeEntityInterface
2727
use EntityTrait;
2828

2929
/**
30-
* @var string|null
30+
* @param string[] $claims
3131
*/
32-
private ?string $icon = null;
33-
34-
/**
35-
* @var string|null
36-
*/
37-
private ?string $description = null;
38-
39-
/**
40-
* @var array<string>
41-
*/
42-
private array $claims;
43-
44-
private function __construct()
45-
{
46-
}
47-
48-
/**
49-
* @param array<string> $claims
50-
*/
51-
public static function fromData(
32+
public function __construct(
5233
string $identifier,
53-
string $description = null,
54-
string $icon = null,
55-
array $claims = [],
56-
): self {
57-
$scope = new self();
58-
59-
$scope->identifier = $identifier;
60-
$scope->description = $description;
61-
$scope->icon = $icon;
62-
$scope->claims = $claims;
63-
64-
return $scope;
34+
protected ?string $description = null,
35+
protected ?string $icon = null,
36+
protected array $claims = [],
37+
) {
38+
$this->identifier = $identifier;
6539
}
6640

6741
public function getIcon(): ?string

‎src/Factories/Entities/AccessTokenEntityFactory.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use League\OAuth2\Server\Entities\ClientEntityInterface as OAuth2ClientEntityInterface;
1010
use SimpleSAML\Module\oidc\Entities\AccessTokenEntity;
1111
use SimpleSAML\Module\oidc\Entities\Interfaces\ClientEntityInterface;
12-
use SimpleSAML\Module\oidc\Entities\ScopeEntity;
1312
use SimpleSAML\Module\oidc\Helpers;
1413
use SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException;
1514
use SimpleSAML\Module\oidc\Services\JsonWebTokenBuilderService;
@@ -20,6 +19,7 @@ public function __construct(
2019
protected readonly Helpers $helpers,
2120
protected readonly CryptKey $privateKey,
2221
protected readonly JsonWebTokenBuilderService $jsonWebTokenBuilderService,
22+
protected readonly ScopeEntityFactory $scopeEntityFactory,
2323
) {
2424
}
2525

@@ -71,7 +71,7 @@ public function fromState(array $state): AccessTokenEntity
7171
}
7272

7373
/** @psalm-var string $scope */
74-
$scopes = array_map(fn(string $scope) => ScopeEntity::fromData($scope), $stateScopes);
74+
$scopes = array_map(fn(string $scope) => $this->scopeEntityFactory->fromData($scope), $stateScopes);
7575

7676
$id = $state['id'];
7777
$expiryDateTime = $this->helpers->dateTime()->getUtc($state['expires_at']);

‎src/Factories/Entities/AuthCodeEntityFactory.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
use League\OAuth2\Server\Entities\ClientEntityInterface as OAuth2ClientEntityInterface;
99
use SimpleSAML\Module\oidc\Entities\AuthCodeEntity;
1010
use SimpleSAML\Module\oidc\Entities\Interfaces\ClientEntityInterface;
11-
use SimpleSAML\Module\oidc\Entities\ScopeEntity;
1211
use SimpleSAML\Module\oidc\Helpers;
1312
use SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException;
1413

1514
class AuthCodeEntityFactory
1615
{
1716
public function __construct(
1817
protected readonly Helpers $helpers,
18+
protected readonly ScopeEntityFactory $scopeEntityFactory,
1919
) {
2020
}
2121

@@ -68,9 +68,9 @@ public function fromState(array $state): AuthCodeEntity
6868

6969
$scopes = array_map(
7070
/**
71-
* @return ScopeEntity
71+
* @return \SimpleSAML\Module\oidc\Entities\ScopeEntity
7272
*/
73-
fn(string $scope) => ScopeEntity::fromData($scope),
73+
fn(string $scope) => $this->scopeEntityFactory->fromData($scope),
7474
$stateScopes,
7575
);
7676

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Module\oidc\Factories\Entities;
6+
7+
use SimpleSAML\Module\oidc\Entities\ScopeEntity;
8+
9+
class ScopeEntityFactory
10+
{
11+
/**
12+
* @param string[] $claims
13+
*/
14+
public function fromData(
15+
string $identifier,
16+
string $description = null,
17+
string $icon = null,
18+
array $claims = [],
19+
): ScopeEntity {
20+
return new ScopeEntity(
21+
$identifier,
22+
$description,
23+
$icon,
24+
$claims,
25+
);
26+
}
27+
}

‎src/Repositories/ScopeRepository.php

+10-1
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,21 @@
2020
use League\OAuth2\Server\Repositories\ScopeRepositoryInterface;
2121
use SimpleSAML\Module\oidc\Entities\ClientEntity;
2222
use SimpleSAML\Module\oidc\Entities\ScopeEntity;
23+
use SimpleSAML\Module\oidc\Factories\Entities\ScopeEntityFactory;
24+
use SimpleSAML\Module\oidc\ModuleConfig;
2325

2426
use function array_key_exists;
2527
use function in_array;
2628

2729
class ScopeRepository extends AbstractDatabaseRepository implements ScopeRepositoryInterface
2830
{
31+
public function __construct(
32+
ModuleConfig $moduleConfig,
33+
protected readonly ScopeEntityFactory $scopeEntityFactory,
34+
) {
35+
parent::__construct($moduleConfig);
36+
}
37+
2938
public function getTableName(): ?string
3039
{
3140
return null;
@@ -52,7 +61,7 @@ public function getScopeEntityByIdentifier($identifier): ScopeEntity|ScopeEntity
5261
/** @var string[] $claims */
5362
$claims = $scope['claims'] ?? [];
5463

55-
return ScopeEntity::fromData(
64+
return $this->scopeEntityFactory->fromData(
5665
$identifier,
5766
$description,
5867
$icon,

‎src/Services/Container.php

+10-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
use SimpleSAML\Module\oidc\Factories\Entities\ClaimSetEntityFactory;
4444
use SimpleSAML\Module\oidc\Factories\Entities\ClientEntityFactory;
4545
use SimpleSAML\Module\oidc\Factories\Entities\RefreshTokenEntityFactory;
46+
use SimpleSAML\Module\oidc\Factories\Entities\ScopeEntityFactory;
4647
use SimpleSAML\Module\oidc\Factories\Entities\UserEntityFactory;
4748
use SimpleSAML\Module\oidc\Factories\FederationFactory;
4849
use SimpleSAML\Module\oidc\Factories\FormFactory;
@@ -216,7 +217,13 @@ public function __construct()
216217
);
217218
$this->services[UserRepository::class] = $userRepository;
218219

219-
$authCodeEntityFactory = new AuthCodeEntityFactory($helpers);
220+
$scopeEntityFactory = new ScopeEntityFactory();
221+
$this->services[ScopeEntityFactory::class] = $scopeEntityFactory;
222+
223+
$authCodeEntityFactory = new AuthCodeEntityFactory(
224+
$helpers,
225+
$scopeEntityFactory,
226+
);
220227
$this->services[AuthCodeEntityFactory::class] = $authCodeEntityFactory;
221228

222229
$authCodeRepository = new AuthCodeRepository(
@@ -238,6 +245,7 @@ public function __construct()
238245
$helpers,
239246
$privateKey,
240247
$jsonWebTokenBuilderService,
248+
$scopeEntityFactory,
241249
);
242250
$this->services[AccessTokenEntityFactory::class] = $accessTokenEntityFactory;
243251

@@ -258,7 +266,7 @@ public function __construct()
258266
);
259267
$this->services[RefreshTokenRepository::class] = $refreshTokenRepository;
260268

261-
$scopeRepository = new ScopeRepository($moduleConfig);
269+
$scopeRepository = new ScopeRepository($moduleConfig, $scopeEntityFactory);
262270
$this->services[ScopeRepository::class] = $scopeRepository;
263271

264272
$allowedOriginRepository = new AllowedOriginRepository($moduleConfig);

‎tests/integration/src/Repositories/Traits/RevokeTokenByAuthCodeIdTraitTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use SimpleSAML\Module\oidc\Entities\UserEntity;
1919
use SimpleSAML\Module\oidc\Factories\Entities\AccessTokenEntityFactory;
2020
use SimpleSAML\Module\oidc\Factories\Entities\ClientEntityFactory;
21+
use SimpleSAML\Module\oidc\Factories\Entities\ScopeEntityFactory;
2122
use SimpleSAML\Module\oidc\Factories\Entities\UserEntityFactory;
2223
use SimpleSAML\Module\oidc\Helpers;
2324
use SimpleSAML\Module\oidc\ModuleConfig;
@@ -124,6 +125,7 @@ public function setUp(): void
124125
new Helpers(),
125126
$this->privateKey,
126127
$this->createMock(JsonWebTokenBuilderService::class),
128+
new ScopeEntityFactory(),
127129
);
128130
}
129131

‎tests/unit/src/Entities/ScopeEntityTest.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,26 @@
99

1010
class ScopeEntityTest extends TestCase
1111
{
12-
protected function prepareMockedInstance(
12+
protected function mock(
1313
string $id = 'id',
1414
string $description = 'description',
1515
string $icon = 'icon',
1616
array $attributes = ['attrid' => 'attrval'],
1717
): ScopeEntity {
18-
return ScopeEntity::fromData($id, $description, $icon, $attributes);
18+
return new ScopeEntity($id, $description, $icon, $attributes);
1919
}
2020

2121
public function testItIsInitializable(): void
2222
{
2323
$this->assertInstanceOf(
2424
ScopeEntity::class,
25-
$this->prepareMockedInstance(),
25+
$this->mock(),
2626
);
2727
}
2828

2929
public function testCanGetProperties(): void
3030
{
31-
$scopeEntity = $this->prepareMockedInstance();
31+
$scopeEntity = $this->mock();
3232
$this->assertSame('id', $scopeEntity->getIdentifier());
3333
$this->assertSame('description', $scopeEntity->getDescription());
3434
$this->assertSame('icon', $scopeEntity->getIcon());

‎tests/unit/src/Repositories/AuthCodeRepositoryTest.php

+1-5
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ protected function setUp(): void
7272
$this->clientRepositoryMock = $this->createMock(ClientRepository::class);
7373
$this->clientRepositoryMock->method('findById')->willReturn($this->clientEntityMock);
7474

75-
$this->scopes = [ScopeEntity::fromData('openid')];
75+
$this->scopes = [new ScopeEntity('openid')];
7676

7777
$this->authCodeEntityFactoryMock = $this->createMock(AuthCodeEntityFactory::class);
7878

@@ -96,10 +96,6 @@ public function testGetTableName(): void
9696
*/
9797
public function testAddAndFound(): void
9898
{
99-
$scopes = [
100-
ScopeEntity::fromData('openid'),
101-
];
102-
10399
$authCode = new AuthCodeEntity(
104100
self::AUTH_CODE_ID,
105101
$this->clientEntityMock,

‎tests/unit/src/Repositories/ScopeRepositoryTest.php

+8-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use PHPUnit\Framework\TestCase;
1919
use SimpleSAML\Configuration;
2020
use SimpleSAML\Module\oidc\Entities\ScopeEntity;
21+
use SimpleSAML\Module\oidc\Factories\Entities\ScopeEntityFactory;
2122
use SimpleSAML\Module\oidc\ModuleConfig;
2223
use SimpleSAML\Module\oidc\Repositories\ScopeRepository;
2324
use SimpleSAML\Module\oidc\Services\DatabaseMigration;
@@ -48,11 +49,11 @@ public static function setUpBeforeClass(): void
4849
*/
4950
public function testGetScopeEntityByIdentifier(): void
5051
{
51-
$scopeRepository = new ScopeRepository(new ModuleConfig());
52+
$scopeRepository = new ScopeRepository(new ModuleConfig(), new ScopeEntityFactory());
5253

5354
$scope = $scopeRepository->getScopeEntityByIdentifier('openid');
5455

55-
$expected = ScopeEntity::fromData(
56+
$expected = new ScopeEntity(
5657
'openid',
5758
'openid',
5859
);
@@ -65,7 +66,7 @@ public function testGetScopeEntityByIdentifier(): void
6566
*/
6667
public function testGetUnknownScope(): void
6768
{
68-
$scopeRepository = new ScopeRepository(new ModuleConfig());
69+
$scopeRepository = new ScopeRepository(new ModuleConfig(), new ScopeEntityFactory());
6970

7071
$this->assertNull($scopeRepository->getScopeEntityByIdentifier('none'));
7172
}
@@ -75,17 +76,17 @@ public function testGetUnknownScope(): void
7576
*/
7677
public function testFinalizeScopes(): void
7778
{
78-
$scopeRepository = new ScopeRepository(new ModuleConfig());
79+
$scopeRepository = new ScopeRepository(new ModuleConfig(), new ScopeEntityFactory());
7980
$scopes = [
80-
ScopeEntity::fromData('openid'),
81-
ScopeEntity::fromData('basic'),
81+
new ScopeEntity('openid'),
82+
new ScopeEntity('basic'),
8283
];
8384
$client = ClientRepositoryTest::getClient('clientid');
8485

8586
$finalizedScopes = $scopeRepository->finalizeScopes($scopes, 'any', $client);
8687

8788
$expectedScopes = [
88-
ScopeEntity::fromData('openid'),
89+
new ScopeEntity('openid'),
8990
];
9091
$this->assertEquals($expectedScopes, $finalizedScopes);
9192
}

‎tests/unit/src/Server/RequestRules/Rules/RequiredOpenIdScopeRuleTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ protected function setUp(): void
4444
$this->stateResult = new Result(StateRule::class, '123');
4545
$this->requestStub = $this->createStub(ServerRequestInterface::class);
4646
$this->scopeEntities = [
47-
'openid' => ScopeEntity::fromData('openid'),
48-
'profile' => ScopeEntity::fromData('profile'),
47+
'openid' => new ScopeEntity('openid'),
48+
'profile' => new ScopeEntity('profile'),
4949
];
5050
$this->scopeResult = new Result(ScopeRule::class, $this->scopeEntities);
5151
$this->loggerServiceStub = $this->createStub(LoggerService::class);
@@ -108,7 +108,7 @@ public function testCheckRuleThrowsWhenOpenIdScopeIsNotPresent()
108108
$resultBag->add($this->redirectUriResult);
109109
$resultBag->add($this->stateResult);
110110
$invalidScopeEntities = [
111-
'profile' => ScopeEntity::fromData('profile'),
111+
'profile' => new ScopeEntity('profile'),
112112
];
113113
$resultBag->add(new Result(ScopeRule::class, $invalidScopeEntities));
114114

‎tests/unit/src/Server/RequestRules/Rules/ScopeRuleTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ protected function setUp(): void
5959
$this->stateResult = new Result(StateRule::class, '123');
6060
$this->requestStub = $this->createStub(ServerRequestInterface::class);
6161
$this->scopeEntities = [
62-
'openid' => ScopeEntity::fromData('openid'),
63-
'profile' => ScopeEntity::fromData('profile'),
62+
'openid' => new ScopeEntity('openid'),
63+
'profile' => new ScopeEntity('profile'),
6464
];
6565
$this->loggerServiceStub = $this->createStub(LoggerService::class);
6666
$this->requestParamsResolverStub = $this->createStub(RequestParamsResolver::class);

‎tests/unit/src/Server/ResponseTypes/IdTokenResponseTest.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ protected function setUp(): void
7676
['cn' => ['Homer Simpson'], 'mail' => ['myEmail@example.com'],],
7777
);
7878
$this->scopes = [
79-
ScopeEntity::fromData('openid'),
80-
ScopeEntity::fromData('email'),
79+
new ScopeEntity('openid'),
80+
new ScopeEntity('email'),
8181
];
8282
$this->expiration = (new DateTimeImmutable())->setTimestamp(time() + 3600);
8383

@@ -184,7 +184,7 @@ public function testItCanGenerateResponseWithIndividualRequestedClaims(): void
184184
],
185185
);
186186
$this->accessTokenEntityMock->method('getScopes')->willReturn(
187-
[ScopeEntity::fromData('openid')],
187+
[new ScopeEntity('openid')],
188188
);
189189
$idTokenResponse->setAccessToken($this->accessTokenEntityMock);
190190
$response = $idTokenResponse->generateHttpResponse(new Response());
@@ -198,7 +198,7 @@ public function testNoExtraParamsForNonOidcRequest(): void
198198
{
199199
$this->accessTokenEntityMock->method('getRequestedClaims')->willReturn([]);
200200
$this->accessTokenEntityMock->method('getScopes')->willReturn(
201-
[ScopeEntity::fromData('profile')],
201+
[new ScopeEntity('profile')],
202202
);
203203
$idTokenResponse = $this->prepareMockedInstance();
204204
$idTokenResponse->setAccessToken($this->accessTokenEntityMock);

‎tests/unit/src/Server/Validators/BearerTokenValidatorTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public static function setUpBeforeClass(): void
117117
self::$accessTokenEntity = new AccessTokenEntity(
118118
'accessToken123',
119119
self::$clientEntity,
120-
[ScopeEntity::fromData('openid'), ScopeEntity::fromData('profile')],
120+
[new ScopeEntity('openid'), new ScopeEntity('profile')],
121121
(new \DateTimeImmutable())->add(new \DateInterval('PT60S')),
122122
self::$privateCryptKey,
123123
new JsonWebTokenBuilderService(),
@@ -199,7 +199,7 @@ public function testThrowsForExpiredAccessToken()
199199
$accessTokenEntity = new AccessTokenEntity(
200200
'accessToken123',
201201
self::$clientEntity,
202-
[ScopeEntity::fromData('openid'), ScopeEntity::fromData('profile')],
202+
[new ScopeEntity('openid'), new ScopeEntity('profile')],
203203
(new \DateTimeImmutable())->sub(new \DateInterval('PT60S')),
204204
self::$privateCryptKey,
205205
new JsonWebTokenBuilderService(),
@@ -245,7 +245,7 @@ public function testThrowsForEmptyAccessTokenJti()
245245
$accessTokenEntity = new AccessTokenEntity(
246246
'',
247247
self::$clientEntity,
248-
[ScopeEntity::fromData('openid'), ScopeEntity::fromData('profile')],
248+
[new ScopeEntity('openid'), new ScopeEntity('profile')],
249249
(new \DateTimeImmutable())->add(new \DateInterval('PT60S')),
250250
self::$privateCryptKey,
251251
new JsonWebTokenBuilderService(),

0 commit comments

Comments
 (0)
Please sign in to comment.