Completed
Pull Request — master (#856)
by Andrew
01:41
created

ImplicitGrant::canRespondToAuthorizationRequest()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

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