Skip to content

Commit a78cf00

Browse files
committed
Add VcSdJwtFactory
1 parent b910509 commit a78cf00

File tree

3 files changed

+221
-2
lines changed

3 files changed

+221
-2
lines changed

composer.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,24 @@
5959
},
6060
"scripts": {
6161
"pre-commit": [
62-
"vendor/bin/phpcbf",
62+
"vendor/bin/phpcbf -pn",
6363
"vendor/bin/phpcs -p",
6464
"composer update web-token/jwt-framework --with web-token/jwt-framework:^3.0",
6565
"vendor/bin/phpstan --memory-limit=1024M",
6666
"vendor/bin/phpunit --no-coverage",
6767
"composer update web-token/jwt-framework --with web-token/jwt-framework:^4.0",
68-
"vendor/bin/phpstan",
68+
"vendor/bin/phpstan --memory-limit=1024M",
69+
"vendor/bin/phpunit",
70+
"vendor/bin/rector",
71+
"vendor/bin/phpstan analyze -c phpstan-dev.neon --memory-limit=1024M"
72+
],
73+
"on-commit": [
74+
"vendor/bin/phpcs -p",
75+
"composer update web-token/jwt-framework --with web-token/jwt-framework:^3.0",
76+
"vendor/bin/phpstan --memory-limit=1024M",
77+
"vendor/bin/phpunit --no-coverage",
78+
"composer update web-token/jwt-framework --with web-token/jwt-framework:^4.0",
79+
"vendor/bin/phpstan --memory-limit=1024M",
6980
"vendor/bin/phpunit",
7081
"vendor/bin/rector --dry-run",
7182
"vendor/bin/phpstan analyze -c phpstan-dev.neon --memory-limit=1024M"
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\OpenID\VerifiableCredentials\VcDataModel2\Factories;
6+
7+
use SimpleSAML\OpenID\Algorithms\SignatureAlgorithmEnum;
8+
use SimpleSAML\OpenID\Codebooks\ClaimsEnum;
9+
use SimpleSAML\OpenID\Codebooks\JwtTypesEnum;
10+
use SimpleSAML\OpenID\Jwk\JwkDecorator;
11+
use SimpleSAML\OpenID\Jws\Factories\ParsedJwsFactory;
12+
use SimpleSAML\OpenID\VerifiableCredentials\VcDataModel2\VcSdJwt;
13+
14+
class VcSdJwtFactory extends ParsedJwsFactory
15+
{
16+
public function fromToken(string $token): VcSdJwt
17+
{
18+
return new VcSdJwt(
19+
$this->jwsDecoratorBuilder->fromToken($token),
20+
$this->jwsVerifierDecorator,
21+
$this->jwksDecoratorFactory,
22+
$this->jwsSerializerManagerDecorator,
23+
$this->timestampValidationLeeway,
24+
$this->helpers,
25+
$this->claimFactory,
26+
);
27+
}
28+
29+
30+
/**
31+
* @param array<non-empty-string,mixed> $payload
32+
* @param array<non-empty-string,mixed> $header
33+
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
34+
*/
35+
public function fromData(
36+
JwkDecorator $signingKey,
37+
SignatureAlgorithmEnum $signatureAlgorithm,
38+
array $payload,
39+
array $header,
40+
): VcSdJwt {
41+
$header[ClaimsEnum::Typ->value] = JwtTypesEnum::VcSdJwt->value;
42+
43+
return new VcSdJwt(
44+
$this->jwsDecoratorBuilder->fromData(
45+
$signingKey,
46+
$signatureAlgorithm,
47+
$payload,
48+
$header,
49+
),
50+
$this->jwsVerifierDecorator,
51+
$this->jwksDecoratorFactory,
52+
$this->jwsSerializerManagerDecorator,
53+
$this->timestampValidationLeeway,
54+
$this->helpers,
55+
$this->claimFactory,
56+
);
57+
}
58+
}
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SimpleSAML\Test\OpenID\VerifiableCredentials\VcDataModel2\Factories;
6+
7+
use PHPUnit\Framework\Attributes\CoversClass;
8+
use PHPUnit\Framework\Attributes\UsesClass;
9+
use PHPUnit\Framework\MockObject\MockObject;
10+
use PHPUnit\Framework\TestCase;
11+
use SimpleSAML\OpenID\Algorithms\SignatureAlgorithmEnum;
12+
use SimpleSAML\OpenID\Codebooks\ClaimsEnum;
13+
use SimpleSAML\OpenID\Codebooks\JwtTypesEnum;
14+
use SimpleSAML\OpenID\Decorators\DateIntervalDecorator;
15+
use SimpleSAML\OpenID\Factories\ClaimFactory;
16+
use SimpleSAML\OpenID\Helpers;
17+
use SimpleSAML\OpenID\Jwk\JwkDecorator;
18+
use SimpleSAML\OpenID\Jwks\Factories\JwksDecoratorFactory;
19+
use SimpleSAML\OpenID\Jws\Factories\ParsedJwsFactory;
20+
use SimpleSAML\OpenID\Jws\JwsDecorator;
21+
use SimpleSAML\OpenID\Jws\JwsDecoratorBuilder;
22+
use SimpleSAML\OpenID\Jws\JwsVerifierDecorator;
23+
use SimpleSAML\OpenID\Jws\ParsedJws;
24+
use SimpleSAML\OpenID\Serializers\JwsSerializerManagerDecorator;
25+
use SimpleSAML\OpenID\VerifiableCredentials\VcDataModel2\Factories\VcSdJwtFactory;
26+
use SimpleSAML\OpenID\VerifiableCredentials\VcDataModel2\VcSdJwt;
27+
28+
#[CoversClass(VcSdJwtFactory::class)]
29+
#[UsesClass(ParsedJwsFactory::class)]
30+
#[UsesClass(VcSdJwt::class)]
31+
#[UsesClass(ParsedJws::class)]
32+
#[UsesClass(DateIntervalDecorator::class)]
33+
#[UsesClass(Helpers::class)]
34+
#[UsesClass(Helpers\DateTime::class)]
35+
#[UsesClass(Helpers\Json::class)]
36+
#[UsesClass(Helpers\Type::class)]
37+
final class VcSdJwtFactoryTest extends TestCase
38+
{
39+
protected JwsDecoratorBuilder&MockObject $jwsDecoratorBuilderMock;
40+
41+
protected \PHPUnit\Framework\MockObject\Stub&JwsVerifierDecorator $jwsVerifierDecoratorMock;
42+
43+
protected \PHPUnit\Framework\MockObject\Stub&JwksDecoratorFactory $jwksDecoratorFactoryMock;
44+
45+
protected \PHPUnit\Framework\MockObject\Stub&JwsSerializerManagerDecorator $jwsSerializerManagerDecoratorMock;
46+
47+
protected DateIntervalDecorator $dateIntervalDecorator;
48+
49+
protected Helpers $helpers;
50+
51+
protected \PHPUnit\Framework\MockObject\Stub&ClaimFactory $claimFactoryMock;
52+
53+
54+
protected function setUp(): void
55+
{
56+
$this->jwsDecoratorBuilderMock = $this->createMock(JwsDecoratorBuilder::class);
57+
$this->jwsVerifierDecoratorMock = $this->createStub(JwsVerifierDecorator::class);
58+
$this->jwksDecoratorFactoryMock = $this->createStub(JwksDecoratorFactory::class);
59+
$this->jwsSerializerManagerDecoratorMock = $this->createStub(JwsSerializerManagerDecorator::class);
60+
$this->dateIntervalDecorator = new DateIntervalDecorator(new \DateInterval('PT0S'));
61+
$this->helpers = new Helpers();
62+
$this->claimFactoryMock = $this->createStub(ClaimFactory::class);
63+
}
64+
65+
66+
protected function sut(): VcSdJwtFactory
67+
{
68+
return new VcSdJwtFactory(
69+
$this->jwsDecoratorBuilderMock,
70+
$this->jwsVerifierDecoratorMock,
71+
$this->jwksDecoratorFactoryMock,
72+
$this->jwsSerializerManagerDecoratorMock,
73+
$this->dateIntervalDecorator,
74+
$this->helpers,
75+
$this->claimFactoryMock,
76+
);
77+
}
78+
79+
80+
public function testCanCreateInstance(): void
81+
{
82+
$this->assertInstanceOf(VcSdJwtFactory::class, $this->sut());
83+
}
84+
85+
86+
protected function createJwsDecoratorMock(array $payload = []): MockObject
87+
{
88+
$payload = array_merge(['iat' => time()], $payload);
89+
$jwsMock = $this->createMock(\Jose\Component\Signature\JWS::class);
90+
$jwsMock->method('getPayload')->willReturn(json_encode($payload));
91+
92+
$jwsDecoratorMock = $this->createMock(JwsDecorator::class);
93+
$jwsDecoratorMock->method('jws')->willReturn($jwsMock);
94+
95+
return $jwsDecoratorMock;
96+
}
97+
98+
99+
public function testCanBuildFromToken(): void
100+
{
101+
$jwsDecoratorMock = $this->createJwsDecoratorMock();
102+
103+
$this->jwsDecoratorBuilderMock
104+
->expects($this->once())
105+
->method('fromToken')
106+
->with('token')
107+
->willReturn($jwsDecoratorMock);
108+
109+
$this->assertInstanceOf(
110+
VcSdJwt::class,
111+
$this->sut()->fromToken('token'),
112+
);
113+
}
114+
115+
116+
public function testCanBuildFromData(): void
117+
{
118+
$signingKey = $this->createStub(JwkDecorator::class);
119+
$signatureAlgorithm = SignatureAlgorithmEnum::RS256;
120+
$payload = ['foo' => 'bar'];
121+
$header = ['alg' => 'RS256'];
122+
123+
$jwsDecoratorMock = $this->createJwsDecoratorMock($payload);
124+
125+
$this->jwsDecoratorBuilderMock
126+
->expects($this->once())
127+
->method('fromData')
128+
->with(
129+
$signingKey,
130+
$signatureAlgorithm,
131+
$payload,
132+
$this->callback(function (array $header): true {
133+
$this->assertArrayHasKey(ClaimsEnum::Typ->value, $header);
134+
$this->assertSame(JwtTypesEnum::VcSdJwt->value, $header[ClaimsEnum::Typ->value]);
135+
return true;
136+
}),
137+
)
138+
->willReturn($jwsDecoratorMock);
139+
140+
$this->assertInstanceOf(
141+
VcSdJwt::class,
142+
$this->sut()->fromData(
143+
$signingKey,
144+
$signatureAlgorithm,
145+
$payload,
146+
$header,
147+
),
148+
);
149+
}
150+
}

0 commit comments

Comments
 (0)