Skip to content

Commit 31b67e5

Browse files
committed
Enable building JwksDecorator from JwkDecorators
1 parent feaef2c commit 31b67e5

File tree

6 files changed

+90
-3
lines changed

6 files changed

+90
-3
lines changed

src/Jwk/Factories/JwkDecoratorFactory.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public function fromPkcs1Or8KeyFile(
3232
): JwkDecorator {
3333
return new JwkDecorator(
3434
JWKFactory::createFromKeyFile($path, $password, $additionalData),
35+
$additionalData,
3536
);
3637
}
3738

@@ -47,6 +48,7 @@ public function fromPkcs1Or8Key(
4748
): JwkDecorator {
4849
return new JwkDecorator(
4950
JWKFactory::createFromKey($key, $password, $additionalData),
51+
$additionalData,
5052
);
5153
}
5254

@@ -62,6 +64,7 @@ public function fromPkcs12CertificateFile(
6264
): JwkDecorator {
6365
return new JwkDecorator(
6466
JWKFactory::createFromPKCS12CertificateFile($path, $password, $additionalData),
67+
$additionalData,
6568
);
6669
}
6770

@@ -76,6 +79,7 @@ public function fromX509CertificateFile(
7679
): JwkDecorator {
7780
return new JwkDecorator(
7881
JWKFactory::createFromCertificateFile($path, $additionalData),
82+
$additionalData,
7983
);
8084
}
8185

@@ -90,6 +94,7 @@ public function fromX509Certificate(
9094
): JwkDecorator {
9195
return new JwkDecorator(
9296
JWKFactory::createFromCertificate($certificate, $additionalData),
97+
$additionalData,
9398
);
9499
}
95100
}

src/Jwk/JwkDecorator.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66

77
use Jose\Component\Core\JWK;
88

9-
class JwkDecorator
9+
class JwkDecorator implements \JsonSerializable
1010
{
11+
/**
12+
* @param mixed[] $additionalData
13+
*/
1114
public function __construct(
1215
protected readonly JWK $jwk,
16+
protected readonly array $additionalData = [],
1317
) {
1418
}
1519

@@ -18,4 +22,22 @@ public function jwk(): JWK
1822
{
1923
return $this->jwk;
2024
}
25+
26+
27+
/**
28+
* @return mixed[]
29+
*/
30+
public function getAdditionalData(): array
31+
{
32+
return $this->additionalData;
33+
}
34+
35+
36+
/**
37+
* @return mixed[]
38+
*/
39+
public function jsonSerialize(): array
40+
{
41+
return array_merge($this->jwk->jsonSerialize(), $this->additionalData);
42+
}
2143
}

src/Jwks/Factories/JwksDecoratorFactory.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,29 @@
55
namespace SimpleSAML\OpenID\Jwks\Factories;
66

77
use Jose\Component\Core\JWKSet;
8+
use SimpleSAML\OpenID\Jwk\JwkDecorator;
89
use SimpleSAML\OpenID\Jwks\JwksDecorator;
910

1011
class JwksDecoratorFactory
1112
{
1213
/**
13-
* @phpstan-ignore missingType.iterableValue (JWKS array is validated later)
14+
* @param mixed[] $jwks JWKS array (validated later)
1415
*/
1516
public function fromKeySetData(array $jwks): JwksDecorator
1617
{
1718
return new JwksDecorator(JWKSet::createFromKeyData($jwks));
1819
}
20+
21+
22+
public function fromJwkDecorators(JwkDecorator ...$jwkDecorators): JwksDecorator
23+
{
24+
$jwks = [
25+
'keys' => array_map(
26+
fn (JwkDecorator $jwkDecorator): array => $jwkDecorator->jsonSerialize(),
27+
$jwkDecorators,
28+
),
29+
];
30+
31+
return $this->fromKeySetData($jwks);
32+
}
1933
}

tests/src/CoreTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use SimpleSAML\OpenID\Algorithms\AlgorithmManagerDecorator;
1414
use SimpleSAML\OpenID\Core;
1515
use SimpleSAML\OpenID\Core\Factories\ClientAssertionFactory;
16+
use SimpleSAML\OpenID\Core\Factories\IdTokenFactory;
1617
use SimpleSAML\OpenID\Core\Factories\RequestObjectFactory;
1718
use SimpleSAML\OpenID\Decorators\DateIntervalDecorator;
1819
use SimpleSAML\OpenID\Factories\AlgorithmManagerDecoratorFactory;
@@ -43,6 +44,7 @@
4344
#[UsesClass(JwsVerifierDecorator::class)]
4445
#[UsesClass(JwsSerializerManagerDecorator::class)]
4546
#[UsesClass(ClaimFactory::class)]
47+
#[UsesClass(IdTokenFactory::class)]
4648
final class CoreTest extends TestCase
4749
{
4850
protected MockObject $supportedAlgorithmsMock;
@@ -105,5 +107,10 @@ public function testCanBuildTools(): void
105107
ClientAssertionFactory::class,
106108
$sut->clientAssertionFactory(),
107109
);
110+
111+
$this->assertInstanceOf(
112+
IdTokenFactory::class,
113+
$sut->idTokenFactory(),
114+
);
108115
}
109116
}

tests/src/Jwk/JwkDecoratorTest.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ final class JwkDecoratorTest extends TestCase
1515
{
1616
protected MockObject $jwkMock;
1717

18+
protected array $additionalData = [];
19+
1820

1921
protected function setUp(): void
2022
{
@@ -24,10 +26,12 @@ protected function setUp(): void
2426

2527
protected function sut(
2628
?JWK $jwk = null,
29+
?array $additionalData = null,
2730
): JwkDecorator {
2831
$jwk ??= $this->jwkMock;
32+
$additionalData ??= $this->additionalData;
2933

30-
return new JwkDecorator($jwk);
34+
return new JwkDecorator($jwk, $additionalData);
3135
}
3236

3337

@@ -47,4 +51,22 @@ public function testCanGetJwk(): void
4751
$this->sut()->jwk(),
4852
);
4953
}
54+
55+
56+
public function testCanGetAdditionalData(): void
57+
{
58+
$this->additionalData = ['foo' => 'bar'];
59+
60+
$this->assertSame($this->additionalData, $this->sut()->getAdditionalData());
61+
}
62+
63+
64+
public function testCanJsonSerialize(): void
65+
{
66+
$this->jwkMock->expects($this->once())->method('jsonSerialize')
67+
->willReturn(['a' => 'b']);
68+
$this->additionalData = ['foo' => 'bar'];
69+
70+
$this->assertSame(['a' => 'b', 'foo' => 'bar'], $this->sut()->jsonSerialize());
71+
}
5072
}

tests/src/Jwks/Factories/JwksDecoratorFactoryTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PHPUnit\Framework\Attributes\CoversClass;
88
use PHPUnit\Framework\Attributes\UsesClass;
99
use PHPUnit\Framework\TestCase;
10+
use SimpleSAML\OpenID\Jwk\JwkDecorator;
1011
use SimpleSAML\OpenID\Jwks;
1112
use SimpleSAML\OpenID\Jwks\Factories\JwksDecoratorFactory;
1213
use SimpleSAML\OpenID\Jwks\JwksDecorator;
@@ -52,4 +53,20 @@ public function testCanBuildFromKeyData(): void
5253
{
5354
$this->assertInstanceOf(Jwks\JwksDecorator::class, $this->sut()->fromKeySetData($this->jwksArraySample));
5455
}
56+
57+
58+
public function testCanBuildFromJwkDecorators(): void
59+
{
60+
$key1 = $this->createMock(JwkDecorator::class);
61+
$key2 = $this->createMock(JwkDecorator::class);
62+
$key1->expects($this->once())->method('jsonSerialize')->willReturn(['kty' => 'RSA']);
63+
$key2->expects($this->once())->method('jsonSerialize')->willReturn(['kty' => 'EC']);
64+
65+
$jwksDecorator = $this->sut()->fromJwkDecorators($key1, $key2);
66+
67+
$this->assertSame(
68+
['keys' => [['kty' => 'RSA'], ['kty' => 'EC']]],
69+
$jwksDecorator->jsonSerialize(),
70+
);
71+
}
5572
}

0 commit comments

Comments
 (0)