PrivateKeyJwtTest::testCreateRequest()   B
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 111
Code Lines 79

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 79
nc 2
nop 1
dl 0
loc 111
rs 8.4581
c 1
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Facile\OpenIDClientTest\AuthMethod;
6
7
use Facile\JoseVerifier\JWK\JwksProviderInterface;
8
use Facile\OpenIDClient\AuthMethod\PrivateKeyJwt;
9
use Facile\OpenIDClient\Client\ClientInterface;
10
use Facile\OpenIDClient\Client\Metadata\ClientMetadataInterface;
11
use Facile\OpenIDClient\Issuer\IssuerInterface;
12
use Facile\OpenIDClient\Issuer\Metadata\IssuerMetadataInterface;
13
use function http_build_query;
14
use Jose\Component\Core\JWK;
15
use Jose\Component\KeyManagement\JWKFactory;
16
use Jose\Component\Signature\JWS;
17
use Jose\Component\Signature\JWSBuilder;
18
use Jose\Component\Signature\Serializer\JWSSerializer;
19
use function json_decode;
20
use Facile\OpenIDClientTest\TestCase;
21
use Prophecy\Argument;
22
use Psr\Http\Message\RequestInterface;
23
use Psr\Http\Message\StreamInterface;
24
use function time;
25
26
class PrivateKeyJwtTest extends TestCase
27
{
28
    public function testGetSupportedMethod(): void
29
    {
30
        $jwsBuilder = $this->prophesize(JWSBuilder::class);
31
        $serializer = $this->prophesize(JWSSerializer::class);
32
33
        $auth = new PrivateKeyJwt(
34
            $jwsBuilder->reveal(),
35
            $serializer->reveal(),
36
            null,
37
            60
38
        );
39
        static::assertSame('private_key_jwt', $auth->getSupportedMethod());
40
    }
41
42
    public function createRequestProvider(): array
43
    {
44
        return [
45
            [true],
46
            [false],
47
        ];
48
    }
49
50
    /**
51
     * @dataProvider createRequestProvider
52
     *
53
     * @param bool $jwkAsDependency
54
     */
55
    public function testCreateRequest(bool $jwkAsDependency = false): void
56
    {
57
        $jwsBuilder = $this->prophesize(JWSBuilder::class);
58
        $serializer = $this->prophesize(JWSSerializer::class);
59
60
        $jwk = JWKFactory::createFromSecret('secret', [
61
            'alg' => 'ALG',
62
            'kid' => 'foo',
63
        ]);
64
65
        $auth = new PrivateKeyJwt(
66
            $jwsBuilder->reveal(),
67
            $serializer->reveal(),
68
            $jwkAsDependency ? $jwk : null,
69
            60
70
        );
71
72
        $jwksProvider = $this->prophesize(JwksProviderInterface::class);
73
74
        $stream = $this->prophesize(StreamInterface::class);
75
        $request = $this->prophesize(RequestInterface::class);
76
        $client = $this->prophesize(ClientInterface::class);
77
        $metadata = $this->prophesize(ClientMetadataInterface::class);
78
        $issuer = $this->prophesize(IssuerInterface::class);
79
        $issuerMetadata = $this->prophesize(IssuerMetadataInterface::class);
80
        $client->getJwksProvider()->willReturn($jwksProvider->reveal());
81
82
        if (! $jwkAsDependency) {
83
            $jwksProvider->getJwks()->willReturn([
84
                'keys' => [
85
                    $jwk->all(),
86
                ],
87
            ]);
88
        }
89
90
        $client->getMetadata()->willReturn($metadata->reveal());
91
        $client->getIssuer()->willReturn($issuer->reveal());
92
        $metadata->getClientId()->willReturn('foo');
93
        $metadata->getClientSecret()->willReturn('bar');
94
        $issuer->getMetadata()->willReturn($issuerMetadata->reveal());
95
        $issuerMetadata->getIssuer()->willReturn('issuer');
96
97
        $jwsBuilder2 = $this->prophesize(JWSBuilder::class);
98
        $jwsBuilder3 = $this->prophesize(JWSBuilder::class);
99
        $jwsBuilder4 = $this->prophesize(JWSBuilder::class);
100
        $jws = $this->prophesize(JWS::class);
101
102
        $jwsBuilder->create()->shouldBeCalled()->willReturn($jwsBuilder2->reveal());
103
        $jwsBuilder2->withPayload(Argument::that(function (string $payload) {
104
            $decoded = json_decode($payload, true);
105
106
            static::assertIsArray($decoded);
107
108
            static::assertArrayHasKey('iss', $decoded);
109
            static::assertArrayHasKey('sub', $decoded);
110
            static::assertArrayHasKey('aud', $decoded);
111
            static::assertArrayHasKey('iat', $decoded);
112
            static::assertArrayHasKey('exp', $decoded);
113
            static::assertArrayHasKey('jti', $decoded);
114
115
            static::assertSame('bar', $decoded['foo'] ?? null);
116
            static::assertSame('foo', $decoded['iss'] ?? null);
117
            static::assertSame('foo', $decoded['sub'] ?? null);
118
            static::assertSame('issuer', $decoded['aud'] ?? null);
119
            static::assertLessThanOrEqual(time(), $decoded['iat']);
120
            static::assertLessThanOrEqual(time() + 60, $decoded['exp']);
121
            static::assertGreaterThan(time(), $decoded['exp']);
122
123
            return true;
124
        }))
125
            ->shouldBeCalled()
126
            ->willReturn($jwsBuilder3->reveal());
127
128
        $jwsBuilder3->addSignature(
129
            Argument::allOf(
130
                Argument::type(JWK::class),
131
                Argument::that(function (JWK $key) {
132
                    return 'foo' === $key->get('kid');
133
                })
134
            ),
135
            Argument::allOf(
136
                Argument::type('array'),
137
                Argument::withEntry('alg', 'ALG'),
138
                Argument::withKey('jti')
139
            )
140
        )
141
            ->shouldBeCalled()
142
            ->willReturn($jwsBuilder4);
143
        $jwsBuilder4->build()->willReturn($jws->reveal());
144
145
        $serializer->serialize($jws->reveal(), 0)
146
            ->shouldBeCalled()
147
            ->willReturn('assertion');
148
149
        $body = http_build_query([
150
            'client_id' => 'foo',
151
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
152
            'client_assertion' => 'assertion',
153
            'foo' => 'bar',
154
        ]);
155
156
        $stream->write($body)->shouldBeCalled();
157
        $request->getBody()->willReturn($stream->reveal());
158
159
        $result = $auth->createRequest(
160
            $request->reveal(),
161
            $client->reveal(),
162
            ['foo' => 'bar']
163
        );
164
165
        static::assertSame($request->reveal(), $result);
166
    }
167
}
168