Failed Conditions
Push — master ( 393e29...5c5e5d )
by Florent
05:55
created

theRequestedScopeIsValid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 9.0856
c 0
b 0
f 0
cc 1
eloc 16
nc 1
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\Scope\Tests;
15
16
use OAuth2Framework\Component\Core\AccessToken\AccessToken;
17
use OAuth2Framework\Component\Core\AccessToken\AccessTokenId;
18
use OAuth2Framework\Component\Core\Client\Client;
19
use OAuth2Framework\Component\Core\Client\ClientId;
20
use OAuth2Framework\Component\Core\DataBag\DataBag;
21
use OAuth2Framework\Component\Core\ResourceOwner\ResourceOwner;
22
use OAuth2Framework\Component\Core\Message\OAuth2Message;
23
use OAuth2Framework\Component\Core\UserAccount\UserAccountId;
24
use OAuth2Framework\Component\Scope\Policy\NoScopePolicy;
25
use OAuth2Framework\Component\Scope\Policy\ScopePolicyManager;
26
use OAuth2Framework\Component\Scope\Scope;
27
use OAuth2Framework\Component\Scope\ScopeRepository;
28
use OAuth2Framework\Component\Scope\TokenEndpointScopeExtension;
29
use OAuth2Framework\Component\TokenEndpoint\GrantType;
30
use OAuth2Framework\Component\TokenEndpoint\GrantTypeData;
31
use OAuth2Framework\Component\TokenEndpoint\TokenEndpoint;
32
use PHPUnit\Framework\TestCase;
33
use Prophecy\Prophecy\ObjectProphecy;
34
use Psr\Http\Message\ServerRequestInterface;
35
use Psr\Http\Message\StreamInterface;
36
37
/**
38
 * @group TokenEndpointScopeExtension
39
 */
40
final class TokenEndpointScopeExtensionTest extends TestCase
41
{
42
    /**
43
     * @inheritdoc}
44
     */
45
    protected function setUp()
46
    {
47
        if (!class_exists(TokenEndpoint::class)) {
48
            $this->markTestSkipped('The component "oauth2-framework/token-endpoint" is not installed.');
49
        }
50
    }
51
52
    /**
53
     * @test
54
     */
55
    public function theRequestHasNoScope()
56
    {
57
        $client = Client::createEmpty();
58
        $client = $client->create(
59
            ClientId::create('CLIENT_ID'),
60
            DataBag::create([]),
61
            UserAccountId::create('USER_ACCOUNT_ID')
62
        );
63
64
        $request = $this->buildRequest([]);
65
        $grantTypeData = GrantTypeData::create($client);
66
        $grantType = $this->prophesize(GrantType::class);
67
        $next = function (ServerRequestInterface $request, GrantTypeData $grantTypeData, GrantType $grantType): GrantTypeData {
0 ignored issues
show
Unused Code introduced by
The parameter $grantType is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
68
            return $grantTypeData;
69
        };
70
71
        $result = $this->getExtension()->beforeAccessTokenIssuance($request->reveal(), $grantTypeData, $grantType->reveal(), $next);
72
        self::assertSame($grantTypeData, $result);
73
    }
74
75
    /**
76
     * @test
77
     */
78
    public function theRequestedScopeIsNotSupported()
79
    {
80
        $client = Client::createEmpty();
81
        $client = $client->create(
82
            ClientId::create('CLIENT_ID'),
83
            DataBag::create([]),
84
            UserAccountId::create('USER_ACCOUNT_ID')
85
        );
86
87
        $request = $this->buildRequest([
88
            'scope' => 'café',
89
        ]);
90
        $grantTypeData = GrantTypeData::create($client);
91
        $grantType = $this->prophesize(GrantType::class);
92
        $next = function (ServerRequestInterface $request, GrantTypeData $grantTypeData, GrantType $grantType): GrantTypeData {
0 ignored issues
show
Unused Code introduced by
The parameter $grantType is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
93
            return $grantTypeData;
94
        };
95
96
        try {
97
            $this->getExtension()->beforeAccessTokenIssuance($request->reveal(), $grantTypeData, $grantType->reveal(), $next);
98
        } catch (OAuth2Message $e) {
99
            self::assertEquals(400, $e->getCode());
100
            self::assertEquals([
101
                'error' => 'invalid_scope',
102
                'error_description' => 'An unsupported scope was requested. Available scope is/are: scope1, scope2.',
103
            ], $e->getData());
104
        }
105
    }
106
107
    /**
108
     * @test
109
     */
110
    public function theRequestedScopeIsValid()
111
    {
112
        $client = Client::createEmpty();
113
        $client = $client->create(
114
            ClientId::create('CLIENT_ID'),
115
            DataBag::create([]),
116
            UserAccountId::create('USER_ACCOUNT_ID')
117
        );
118
119
        $request = $this->buildRequest([
120
            'scope' => 'scope2 scope1',
121
        ]);
122
        $grantTypeData = GrantTypeData::create($client);
123
        $grantType = $this->prophesize(GrantType::class);
124
        $next = function (ServerRequestInterface $request, GrantTypeData $grantTypeData, GrantType $grantType): GrantTypeData {
0 ignored issues
show
Unused Code introduced by
The parameter $grantType is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
125
            return $grantTypeData;
126
        };
127
128
        $result = $this->getExtension()->beforeAccessTokenIssuance($request->reveal(), $grantTypeData, $grantType->reveal(), $next);
129
        self::assertNotSame($grantTypeData, $result);
130
        self::assertTrue($result->hasParameter('scope'));
131
        self::assertEquals('scope2 scope1', $result->getParameter('scope'));
132
    }
133
134
    /**
135
     * @test
136
     */
137
    public function after()
138
    {
139
        $client = Client::createEmpty();
140
        $client = $client->create(
141
            ClientId::create('CLIENT_ID'),
142
            DataBag::create([]),
143
            UserAccountId::create('USER_ACCOUNT_ID')
144
        );
145
        $accessToken = AccessToken::createEmpty();
146
        $accessToken = $accessToken->create(
147
            AccessTokenId::create('ACCESS_TOKEN_ID'),
148
            $client->getPublicId(),
149
            $client->getPublicId(),
150
            DataBag::create([]),
151
            DataBag::create([]),
152
            new \DateTimeImmutable('now +1 hour'),
153
            null
154
        );
155
156
        $next = function (Client $client, ResourceOwner $resourceOwner, AccessToken $accessToken): array {
157
            return $accessToken->getResponseData();
158
        };
159
160
        $result = $this->getExtension()->afterAccessTokenIssuance($client, $client, $accessToken, $next);
161
        self::assertEquals(2, count($result));
162
    }
163
164
    /**
165
     * @var null|TokenEndpointScopeExtension
166
     */
167
    private $extension = null;
168
169
    /**
170
     * @return TokenEndpointScopeExtension
171
     */
172
    private function getExtension(): TokenEndpointScopeExtension
173
    {
174
        if (null === $this->extension) {
175
            $scope1 = $this->prophesize(Scope::class);
176
            $scope1->name()->willReturn('scope1');
177
            $scope1->__toString()->willReturn('scope1');
178
            $scope2 = $this->prophesize(Scope::class);
179
            $scope2->name()->willReturn('scope2');
180
            $scope2->__toString()->willReturn('scope2');
181
            $scopeRepository = $this->prophesize(ScopeRepository::class);
182
            $scopeRepository->all()->willReturn([
183
                $scope1->reveal(),
184
                $scope2->reveal(),
185
            ]);
186
187
            $scopePolicyManager = new ScopePolicyManager();
188
            $scopePolicyManager->add(new NoScopePolicy(), true);
189
190
            $this->extension = new TokenEndpointScopeExtension(
191
                $scopeRepository->reveal(),
192
                $scopePolicyManager
193
            );
194
        }
195
196
        return $this->extension;
197
    }
198
199
    private function buildRequest(array $data): ObjectProphecy
200
    {
201
        $body = $this->prophesize(StreamInterface::class);
202
        $body->getContents()->willReturn(http_build_query($data));
203
        $request = $this->prophesize(ServerRequestInterface::class);
204
        $request->hasHeader('Content-Type')->willReturn(true);
205
        $request->getHeader('Content-Type')->willReturn(['application/x-www-form-urlencoded']);
206
        $request->getBody()->willReturn($body->reveal());
207
        $request->getParsedBody()->willReturn([]);
208
209
        return $request;
210
    }
211
}
212