Failed Conditions
Push — ng ( 870bee...532144 )
by Florent
04:07
created

TokenEndpointTest::getAccessTokenRepository()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2018 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace OAuth2Framework\Component\TokenEndpoint\Tests;
15
16
use Base64Url\Base64Url;
17
use Http\Message\MessageFactory\GuzzleMessageFactory;
18
use OAuth2Framework\Component\Core\AccessToken\AccessTokenId;
19
use OAuth2Framework\Component\Core\AccessToken\AccessTokenIdGenerator;
20
use Psr\Http\Server\RequestHandlerInterface;
21
use OAuth2Framework\Component\Core\AccessToken\AccessToken;
22
use OAuth2Framework\Component\Core\AccessToken\AccessTokenRepository;
23
use OAuth2Framework\Component\Core\Client\Client;
24
use OAuth2Framework\Component\Core\Client\ClientId;
25
use OAuth2Framework\Component\Core\Client\ClientRepository;
26
use OAuth2Framework\Component\Core\DataBag\DataBag;
27
use OAuth2Framework\Component\Core\ResourceOwner\ResourceOwnerId;
28
use OAuth2Framework\Component\Core\Exception\OAuth2Exception;
29
use OAuth2Framework\Component\Core\UserAccount\UserAccountId;
30
use OAuth2Framework\Component\Core\UserAccount\UserAccountRepository;
31
use OAuth2Framework\Component\TokenEndpoint\Extension\TokenEndpointExtensionManager;
32
use OAuth2Framework\Component\TokenEndpoint\TokenEndpoint;
33
use OAuth2Framework\Component\TokenType\TokenType;
34
use PHPUnit\Framework\TestCase;
35
use Prophecy\Argument;
36
use Psr\Http\Message\ServerRequestInterface;
37
38
/**
39
 * @group TokenEndpoint
40
 */
41
class TokenEndpointTest extends TestCase
42
{
43
    /**
44
     * @test
45
     */
46
    public function unauthenticatedClient()
47
    {
48
        $request = $this->prophesize(ServerRequestInterface::class);
49
        $request->getAttribute('grant_type')
50
            ->willReturn(new FooGrantType())
51
            ->shouldBeCalled()
52
        ;
53
        $request->getAttribute('client')
54
            ->willReturn(null)
55
            ->shouldBeCalled()
56
        ;
57
58
        $handler = $this->prophesize(RequestHandlerInterface::class);
59
60
        try {
61
            $this->getTokenEndpoint()->process($request->reveal(), $handler->reveal());
62
        } catch (OAuth2Exception $e) {
63
            self::assertEquals(401, $e->getCode());
64
            self::assertEquals([
65
                'error' => 'invalid_client',
66
                'error_description' => 'Client authentication failed.',
67
            ], $e->getData());
68
        }
69
    }
70
71
    /**
72
     * @test
73
     */
74
    public function theClientIsNotAllowedToUseTheGrantType()
75
    {
76
        $client = Client::createEmpty();
77
        $client = $client->create(
78
            ClientId::create('CLIENT_ID'),
79
            DataBag::create([]),
80
            UserAccountId::create('OWNER_ID')
81
        );
82
        $client->eraseMessages();
83
84
        $request = $this->prophesize(ServerRequestInterface::class);
85
        $request->getAttribute('grant_type')
86
            ->willReturn(new FooGrantType())
87
            ->shouldBeCalled()
88
        ;
89
        $request->getAttribute('client')
90
            ->willReturn($client)
91
            ->shouldBeCalled()
92
        ;
93
94
        $handler = $this->prophesize(RequestHandlerInterface::class);
95
96
        try {
97
            $this->getTokenEndpoint()->process($request->reveal(), $handler->reveal());
98
        } catch (OAuth2Exception $e) {
99
            self::assertEquals(400, $e->getCode());
100
            self::assertEquals([
101
                'error' => 'unauthorized_client',
102
                'error_description' => 'The grant type "foo" is unauthorized for this client.',
103
            ], $e->getData());
104
        }
105
    }
106
107
    /**
108
     * @test
109
     */
110
    public function theTokenRequestIsValidAndAnAccessTokenIsIssued()
111
    {
112
        $client = Client::createEmpty();
113
        $client = $client->create(
114
            ClientId::create('CLIENT_ID'),
115
            DataBag::create([
116
                'grant_types' => ['foo'],
117
            ]),
118
            UserAccountId::create('OWNER_ID')
119
        );
120
        $client->eraseMessages();
121
122
        $request = $this->prophesize(ServerRequestInterface::class);
123
        $request->getAttribute('grant_type')
124
            ->willReturn(new FooGrantType())
125
            ->shouldBeCalled()
126
        ;
127
        $request->getAttribute('client')
128
            ->willReturn($client)
129
            ->shouldBeCalled()
130
        ;
131
132
        $tokenType = $this->prophesize(TokenType::class);
133
        $tokenType->name()->willReturn('TOKEN_TYPE')->shouldBeCalled();
134
        $tokenType->getAdditionalInformation()->willReturn(['token_type_foo' => 'token_type_bar'])->shouldBeCalled();
135
        $request->getAttribute('token_type')
136
            ->willReturn($tokenType->reveal())
137
            ->shouldBeCalled()
138
        ;
139
140
        $handler = $this->prophesize(RequestHandlerInterface::class);
141
        $handler->handle(Argument::type(ServerRequestInterface::class))
142
            ->shouldNotBeCalled();
143
144
        $response = $this->getTokenEndpoint()->process($request->reveal(), $handler->reveal());
145
        $response->getBody()->rewind();
146
        $body = $response->getBody()->getContents();
147
148
        self::assertEquals(200, $response->getStatusCode());
149
        self::assertRegexp('/^\{"token_type_foo"\:"token_type_bar","token_type"\:"TOKEN_TYPE","access_token"\:"\w{10,}","expires_in"\:\d{4}\}$/', $body);
150
    }
151
152
    /**
153
     * @var null|TokenEndpoint
154
     */
155
    private $tokenEndpoint = null;
156
157
    /**
158
     * @return TokenEndpoint
159
     */
160
    private function getTokenEndpoint(): TokenEndpoint
161
    {
162
        if (null === $this->tokenEndpoint) {
163
            $this->tokenEndpoint = new TokenEndpoint(
164
                $this->getClientRepository(),
165
                $this->getUserAccountRepository(),
166
                new TokenEndpointExtensionManager(),
167
                new GuzzleMessageFactory(),
168
                $this->getAccessTokenRepository(),
169
                $this->getAccessTokenIdGenerator(),
170
                1800
171
            );
172
        }
173
174
        return $this->tokenEndpoint;
175
    }
176
177
    /**
178
     * @var null|ClientRepository
179
     */
180
    private $clientRepository = null;
181
182
    /**
183
     * @return ClientRepository
184
     */
185
    private function getClientRepository(): ClientRepository
186
    {
187
        if (null === $this->clientRepository) {
188
            $client = Client::createEmpty();
189
            $client = $client->create(
190
                ClientId::create('CLIENT_ID'),
191
                DataBag::create([
192
                    'grant_types' => ['foo'],
193
                ]),
194
                UserAccountId::create('OWNER_ID')
195
            );
196
            $client->eraseMessages();
197
198
            $clientRepository = $this->prophesize(ClientRepository::class);
199
            $clientRepository->find(Argument::type(ClientId::class))->willReturn($client);
200
201
            $this->clientRepository = $clientRepository->reveal();
202
        }
203
204
        return $this->clientRepository;
205
    }
206
207
    /**
208
     * @var null|UserAccountRepository
209
     */
210
    private $userAccountRepository = null;
211
212
    /**
213
     * @return UserAccountRepository
214
     */
215
    private function getUserAccountRepository(): UserAccountRepository
216
    {
217
        if (null === $this->userAccountRepository) {
218
            $userAccountRepository = $this->prophesize(UserAccountRepository::class);
219
220
            $this->userAccountRepository = $userAccountRepository->reveal();
221
        }
222
223
        return $this->userAccountRepository;
224
    }
225
226
    /**
227
     * @var null|AccessTokenRepository
228
     */
229
    private $accessTokenRepository = null;
230
231
    /**
232
     * @return AccessTokenRepository
233
     */
234
    private function getAccessTokenRepository(): AccessTokenRepository
235
    {
236
        if (null === $this->accessTokenRepository) {
237
            $accessTokenRepository = $this->prophesize(AccessTokenRepository::class);
238
            $accessTokenRepository->save(Argument::type(AccessToken::class))->willReturn(null);
239
240
            $this->accessTokenRepository = $accessTokenRepository->reveal();
241
        }
242
243
        return $this->accessTokenRepository;
244
    }
245
246
    /**
247
     * @var null|AccessTokenIdGenerator
248
     */
249
    private $accessTokenIdGenerator = null;
250
251
    /**
252
     * @return AccessTokenIdGenerator
253
     */
254
    private function getAccessTokenIdGenerator(): AccessTokenIdGenerator
255
    {
256
        if (null === $this->accessTokenIdGenerator) {
257
            $accessTokenIdGenerator = $this->prophesize(AccessTokenIdGenerator::class);
258
            $accessTokenIdGenerator
259
                ->create(Argument::type(ResourceOwnerId::class), Argument::type(ClientId::class), Argument::type(DataBag::class), Argument::type(DataBag::class), null)
260
                ->will(function () {
261
                    $length = random_int(10, 15);
262
263
                    return AccessTokenId::create(Base64Url::encode(random_bytes($length)));
264
                });
265
            $this->accessTokenIdGenerator = $accessTokenIdGenerator->reveal();
266
        }
267
268
        return $this->accessTokenIdGenerator;
269
    }
270
}
271