ImplicitGrant   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 173
Duplicated Lines 0 %

Test Coverage

Coverage 94.51%

Importance

Changes 6
Bugs 1 Features 0
Metric Value
eloc 70
c 6
b 1
f 0
dl 0
loc 173
ccs 86
cts 91
cp 0.9451
rs 10
wmc 20

9 Methods

Rating   Name   Duplication   Size   Complexity  
A canRespondToAccessTokenRequest() 0 3 1
A respondToAccessTokenRequest() 0 6 1
A getIdentifier() 0 3 1
A setRefreshTokenRepository() 0 3 1
A __construct() 0 2 1
A setRefreshTokenTTL() 0 3 1
A canRespondToAuthorizationRequest() 0 6 3
B validateAuthorizationRequest() 0 49 8
A completeAuthorizationRequest() 0 55 3
1
<?php
2
3
/**
4
 * @author      Alex Bilbie <[email protected]>
5
 * @copyright   Copyright (c) Alex Bilbie
6
 * @license     http://mit-license.org/
7
 *
8
 * @link        https://github.com/thephpleague/oauth2-server
9
 */
10
11
declare(strict_types=1);
12
13
namespace League\OAuth2\Server\Grant;
14
15
use DateInterval;
16
use League\OAuth2\Server\Entities\UserEntityInterface;
17
use League\OAuth2\Server\Exception\OAuthServerException;
18
use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface;
19
use League\OAuth2\Server\RequestEvent;
20
use League\OAuth2\Server\RequestTypes\AuthorizationRequestInterface;
21
use League\OAuth2\Server\ResponseTypes\RedirectResponse;
22
use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface;
23
use LogicException;
24
use Psr\Http\Message\ServerRequestInterface;
25
26
use function count;
27
use function is_array;
28
use function is_null;
29
use function time;
30
31
class ImplicitGrant extends AbstractAuthorizeGrant
32
{
33 19
    public function __construct(private DateInterval $accessTokenTTL, private string $queryDelimiter = '#')
34
    {
35 19
    }
36
37
    /**
38
     * @throws LogicException
39
     */
40 1
    public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void
41
    {
42 1
        throw new LogicException('The Implicit Grant does not return refresh tokens');
43
    }
44
45
    /**
46
     * @throws LogicException
47
     */
48 1
    public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository): void
49
    {
50 1
        throw new LogicException('The Implicit Grant does not return refresh tokens');
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 1
    public function canRespondToAccessTokenRequest(ServerRequestInterface $request): bool
57
    {
58 1
        return false;
59
    }
60
61
    /**
62
     * Return the grant identifier that can be used in matching up requests.
63
     */
64 10
    public function getIdentifier(): string
65
    {
66 10
        return 'implicit';
67
    }
68
69
    /**
70
     * Respond to an incoming request.
71
     */
72 1
    public function respondToAccessTokenRequest(
73
        ServerRequestInterface $request,
74
        ResponseTypeInterface $responseType,
75
        DateInterval $accessTokenTTL
76
    ): ResponseTypeInterface {
77 1
        throw new LogicException('This grant does not used this method');
78
    }
79
80
    /**
81
     * {@inheritdoc}
82
     */
83 1
    public function canRespondToAuthorizationRequest(ServerRequestInterface $request): bool
84
    {
85 1
        return (
86 1
            isset($request->getQueryParams()['response_type'])
87 1
            && $request->getQueryParams()['response_type'] === 'token'
88 1
            && isset($request->getQueryParams()['client_id'])
89 1
        );
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95 7
    public function validateAuthorizationRequest(ServerRequestInterface $request): AuthorizationRequestInterface
96
    {
97 7
        $clientId = $this->getQueryStringParameter(
98 7
            'client_id',
99 7
            $request,
100 7
            $this->getServerParameter('PHP_AUTH_USER', $request)
101 7
        );
102
103 7
        if (is_null($clientId)) {
104 1
            throw OAuthServerException::invalidRequest('client_id');
105
        }
106
107 6
        $client = $this->getClientEntityOrFail($clientId, $request);
108
109 5
        $redirectUri = $this->getQueryStringParameter('redirect_uri', $request);
110
111 5
        if ($redirectUri !== null) {
112 5
            $this->validateRedirectUri($redirectUri, $client, $request);
113
        } elseif (
114
            $client->getRedirectUri() === '' ||
115
            (is_array($client->getRedirectUri()) && count($client->getRedirectUri()) !== 1)
116
        ) {
117
            $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request));
118
            throw OAuthServerException::invalidClient($request);
119
        }
120
121 3
        $stateParameter = $this->getQueryStringParameter('state', $request);
122
123 3
        $scopes = $this->validateScopes(
124 3
            $this->getQueryStringParameter('scope', $request, $this->defaultScope),
125 3
            $this->makeRedirectUri(
126 3
                $redirectUri ?? $this->getClientRedirectUri($client),
127 3
                $stateParameter !== null ? ['state' => $stateParameter] : [],
128 3
                $this->queryDelimiter
129 3
            )
130 3
        );
131
132 2
        $authorizationRequest = $this->createAuthorizationRequest();
133 2
        $authorizationRequest->setGrantTypeId($this->getIdentifier());
134 2
        $authorizationRequest->setClient($client);
135 2
        $authorizationRequest->setRedirectUri($redirectUri);
136
137 2
        if ($stateParameter !== null) {
138
            $authorizationRequest->setState($stateParameter);
139
        }
140
141 2
        $authorizationRequest->setScopes($scopes);
142
143 2
        return $authorizationRequest;
144
    }
145
146
    /**
147
     * {@inheritdoc}
148
     */
149 6
    public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest): ResponseTypeInterface
150
    {
151 6
        if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) {
152 1
            throw new LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest');
153
        }
154
155 5
        $finalRedirectUri = $authorizationRequest->getRedirectUri()
156 5
                          ?? $this->getClientRedirectUri($authorizationRequest->getClient());
157
158
        // The user approved the client, redirect them back with an access token
159 5
        if ($authorizationRequest->isAuthorizationApproved() === true) {
160
            // Finalize the requested scopes
161 4
            $finalizedScopes = $this->scopeRepository->finalizeScopes(
162 4
                $authorizationRequest->getScopes(),
163 4
                $this->getIdentifier(),
164 4
                $authorizationRequest->getClient(),
165 4
                $authorizationRequest->getUser()->getIdentifier()
166 4
            );
167
168 4
            $accessToken = $this->issueAccessToken(
169 4
                $this->accessTokenTTL,
170 4
                $authorizationRequest->getClient(),
171 4
                $authorizationRequest->getUser()->getIdentifier(),
172 4
                $finalizedScopes
173 4
            );
174
175
            // TODO: next major release: this method needs `ServerRequestInterface` as an argument
176
            // $this->getEmitter()->emit(new RequestAccessTokenEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request, $accessToken));
177
178 2
            $response = new RedirectResponse();
179 2
            $response->setRedirectUri(
180 2
                $this->makeRedirectUri(
181 2
                    $finalRedirectUri,
182 2
                    [
183 2
                        'access_token' => $accessToken->toString(),
184 2
                        'token_type'   => 'Bearer',
185 2
                        'expires_in'   => $accessToken->getExpiryDateTime()->getTimestamp() - time(),
186 2
                        'state'        => $authorizationRequest->getState(),
187 2
                    ],
188 2
                    $this->queryDelimiter
189 2
                )
190 2
            );
191
192 2
            return $response;
193
        }
194
195
        // The user denied the client, redirect them back with an error
196 1
        throw OAuthServerException::accessDenied(
197 1
            'The user denied the request',
198 1
            $this->makeRedirectUri(
199 1
                $finalRedirectUri,
200 1
                [
201 1
                    'state' => $authorizationRequest->getState(),
202 1
                ],
203 1
                $this->queryDelimiter
204 1
            )
205 1
        );
206
    }
207
}
208