ClientSecretJwtTest::testCreateRequest()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 94
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 69
nc 1
nop 0
dl 0
loc 94
rs 8.6763
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\OpenIDClient\AuthMethod\ClientSecretJwt;
8
use function Facile\OpenIDClient\base64url_encode;
9
use Facile\OpenIDClient\Client\ClientInterface;
10
use Facile\OpenIDClient\Client\Metadata\ClientMetadataInterface;
11
use Facile\OpenIDClient\Exception\InvalidArgumentException;
12
use Facile\OpenIDClient\Issuer\IssuerInterface;
13
use Facile\OpenIDClient\Issuer\Metadata\IssuerMetadataInterface;
14
use function http_build_query;
15
use Jose\Component\Core\JWK;
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 ClientSecretJwtTest extends TestCase
27
{
28
    public function testGetSupportedMethod(): void
29
    {
30
        $auth = new ClientSecretJwt();
31
        static::assertSame('client_secret_jwt', $auth->getSupportedMethod());
32
    }
33
34
    public function testCreateRequest(): void
35
    {
36
        $jwsBuilder = $this->prophesize(JWSBuilder::class);
37
        $serializer = $this->prophesize(JWSSerializer::class);
38
39
        $auth = new ClientSecretJwt(
40
            $jwsBuilder->reveal(),
41
            $serializer->reveal()
42
        );
43
44
        $stream = $this->prophesize(StreamInterface::class);
45
        $request = $this->prophesize(RequestInterface::class);
46
        $client = $this->prophesize(ClientInterface::class);
47
        $metadata = $this->prophesize(ClientMetadataInterface::class);
48
        $issuer = $this->prophesize(IssuerInterface::class);
49
        $issuerMetadata = $this->prophesize(IssuerMetadataInterface::class);
50
51
        $client->getMetadata()->willReturn($metadata->reveal());
52
        $client->getIssuer()->willReturn($issuer->reveal());
53
        $metadata->getClientId()->willReturn('foo');
54
        $metadata->getClientSecret()->willReturn('bar');
55
        $issuer->getMetadata()->willReturn($issuerMetadata->reveal());
56
        $issuerMetadata->getIssuer()->willReturn('issuer');
57
58
        $jwsBuilder2 = $this->prophesize(JWSBuilder::class);
59
        $jwsBuilder3 = $this->prophesize(JWSBuilder::class);
60
        $jwsBuilder4 = $this->prophesize(JWSBuilder::class);
61
        $jws = $this->prophesize(JWS::class);
62
63
        $jwsBuilder->create()->shouldBeCalled()->willReturn($jwsBuilder2->reveal());
64
        $jwsBuilder2->withPayload(Argument::that(function (string $payload) {
65
            $decoded = json_decode($payload, true);
66
67
            static::assertIsArray($decoded);
68
69
            static::assertArrayHasKey('iss', $decoded);
70
            static::assertArrayHasKey('sub', $decoded);
71
            static::assertArrayHasKey('aud', $decoded);
72
            static::assertArrayHasKey('iat', $decoded);
73
            static::assertArrayHasKey('exp', $decoded);
74
            static::assertArrayHasKey('jti', $decoded);
75
76
            static::assertSame('bar', $decoded['foo'] ?? null);
77
            static::assertSame('foo', $decoded['iss'] ?? null);
78
            static::assertSame('foo', $decoded['sub'] ?? null);
79
            static::assertSame('issuer', $decoded['aud'] ?? null);
80
            static::assertLessThanOrEqual(time(), $decoded['iat']);
81
            static::assertLessThanOrEqual(time() + 60, $decoded['exp']);
82
            static::assertGreaterThan(time(), $decoded['exp']);
83
84
            return true;
85
        }))
86
            ->shouldBeCalled()
87
            ->willReturn($jwsBuilder3->reveal());
88
89
        $jwsBuilder3->addSignature(Argument::allOf(
90
            Argument::type(JWK::class),
91
            Argument::that(function (JWK $jwk) {
92
                static::assertSame('oct', $jwk->get('kty'));
93
                static::assertSame(base64url_encode('bar'), $jwk->get('k'));
94
95
                return true;
96
            })
97
        ), Argument::allOf(
98
            Argument::type('array'),
99
            Argument::withEntry('alg', 'HS256'),
100
            Argument::withKey('jti')
101
        ))
102
            ->shouldBeCalled()
103
            ->willReturn($jwsBuilder4);
104
        $jwsBuilder4->build()->willReturn($jws->reveal());
105
106
        $serializer->serialize($jws->reveal(), 0)
107
            ->shouldBeCalled()
108
            ->willReturn('assertion');
109
110
        $body = http_build_query([
111
            'client_id' => 'foo',
112
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
113
            'client_assertion' => 'assertion',
114
            'foo' => 'bar',
115
        ]);
116
117
        $stream->write($body)->shouldBeCalled();
118
119
        $request->getBody()->willReturn($stream->reveal());
120
121
        $result = $auth->createRequest(
122
            $request->reveal(),
123
            $client->reveal(),
124
            ['foo' => 'bar']
125
        );
126
127
        static::assertSame($request->reveal(), $result);
128
    }
129
130
    public function testCreateRequestWithNoClientSecret(): void
131
    {
132
        $this->expectException(InvalidArgumentException::class);
133
134
        $jwsBuilder = $this->prophesize(JWSBuilder::class);
135
        $serializer = $this->prophesize(JWSSerializer::class);
136
137
        $auth = new ClientSecretJwt(
138
            $jwsBuilder->reveal(),
139
            $serializer->reveal()
140
        );
141
142
        $request = $this->prophesize(RequestInterface::class);
143
        $client = $this->prophesize(ClientInterface::class);
144
        $metadata = $this->prophesize(ClientMetadataInterface::class);
145
146
        $client->getMetadata()->willReturn($metadata->reveal());
147
        $metadata->getClientId()->willReturn('foo');
148
        $metadata->getClientSecret()->willReturn(null);
149
150
        $auth->createRequest(
151
            $request->reveal(),
152
            $client->reveal(),
153
            []
154
        );
155
    }
156
}
157