Failed Conditions
Push — ng ( 03dae5...ac104a )
by Florent
04:27
created

TokenEndpointTest::getUserAccountRepository()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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