Completed
Push — master ( 1de13c...bf55ce )
by Alex
33:38
created

ImplicitGrant::respondToAccessTokenRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 1
eloc 5
nc 1
nop 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
     * @param \DateInterval $accessTokenTTL
31
     */
32
    public function __construct(\DateInterval $accessTokenTTL)
33
    {
34
        $this->accessTokenTTL = $accessTokenTTL;
35
    }
36
37
    /**
38
     * @param \DateInterval $refreshTokenTTL
39
     *
40
     * @throw \LogicException
41
     */
42
    public function setRefreshTokenTTL(\DateInterval $refreshTokenTTL)
43
    {
44
        throw new \LogicException('The Implicit Grant does nto return refresh tokens');
45
    }
46
47
    /**
48
     * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository
49
     *
50
     * @throw \LogicException
51
     */
52
    public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository)
53
    {
54
        throw new \LogicException('The Implicit Grant does nto return refresh tokens');
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    public function canRespondToAccessTokenRequest(ServerRequestInterface $request)
61
    {
62
        return false;
63
    }
64
65
    /**
66
     * Return the grant identifier that can be used in matching up requests.
67
     *
68
     * @return string
69
     */
70
    public function getIdentifier()
71
    {
72
        return 'implicit';
73
    }
74
75
    /**
76
     * Respond to an incoming request.
77
     *
78
     * @param \Psr\Http\Message\ServerRequestInterface                  $request
79
     * @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType
80
     * @param \DateInterval                                             $accessTokenTTL
81
     *
82
     * @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface
83
     */
84
    public function respondToAccessTokenRequest(
85
        ServerRequestInterface $request,
86
        ResponseTypeInterface $responseType,
87
        \DateInterval $accessTokenTTL
88
    ) {
89
        throw new \LogicException('This grant does not used this method');
90
    }
91
92
    /**
93
     * {@inheritdoc}
94
     */
95
    public function canRespondToAuthorizationRequest(ServerRequestInterface $request)
96
    {
97
        return (
98
            array_key_exists('response_type', $request->getQueryParams())
99
            && $request->getQueryParams()['response_type'] === 'token'
100
            && isset($request->getQueryParams()['client_id'])
101
        );
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function validateAuthorizationRequest(ServerRequestInterface $request)
108
    {
109
        $clientId = $this->getQueryStringParameter(
110
            'client_id',
111
            $request,
112
            $this->getServerParameter('PHP_AUTH_USER', $request)
113
        );
114
        if (is_null($clientId)) {
115
            throw OAuthServerException::invalidRequest('client_id');
116
        }
117
118
        $client = $this->clientRepository->getClientEntity(
119
            $clientId,
120
            $this->getIdentifier()
121
        );
122
123
        if ($client instanceof ClientEntityInterface === false) {
124
            $this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
125
            throw OAuthServerException::invalidClient();
126
        }
127
128
        $redirectUri = $this->getQueryStringParameter('redirect_uri', $request);
129
        if ($redirectUri !== null) {
130
            if (
131
                is_string($client->getRedirectUri())
132
                && (strcmp($client->getRedirectUri(), $redirectUri) !== 0)
133
            ) {
134
                $this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
135
                throw OAuthServerException::invalidClient();
136
            } elseif (
137
                is_array($client->getRedirectUri())
138
                && in_array($redirectUri, $client->getRedirectUri()) === false
139
            ) {
140
                $this->getEmitter()->emit(new RequestEvent('client.authentication.failed', $request));
141
                throw OAuthServerException::invalidClient();
142
            }
143
        }
144
145
        $scopes = $this->validateScopes(
146
            $this->getQueryStringParameter('scope', $request),
147
            $client->getRedirectUri()
0 ignored issues
show
Bug introduced by
It seems like $client->getRedirectUri() targeting League\OAuth2\Server\Ent...rface::getRedirectUri() can also be of type array; however, League\OAuth2\Server\Gra...Grant::validateScopes() does only seem to accept string|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
148
        );
149
150
        $stateParameter = $this->getQueryStringParameter('state', $request);
151
152
        $authorizationRequest = new AuthorizationRequest();
153
        $authorizationRequest->setGrantTypeId($this->getIdentifier());
154
        $authorizationRequest->setClient($client);
155
        $authorizationRequest->setRedirectUri($redirectUri);
156
        $authorizationRequest->setState($stateParameter);
157
        $authorizationRequest->setScopes($scopes);
158
159
        return $authorizationRequest;
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165
    public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest)
166
    {
167
        if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) {
168
            throw new \LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest');
169
        }
170
171
        $finalRedirectUri = ($authorizationRequest->getRedirectUri() === null)
172
            ? is_array($authorizationRequest->getClient()->getRedirectUri())
173
                ? $authorizationRequest->getClient()->getRedirectUri()[0]
174
                : $authorizationRequest->getClient()->getRedirectUri()
175
            : $authorizationRequest->getRedirectUri();
176
177
        // The user approved the client, redirect them back with an access token
178
        if ($authorizationRequest->isAuthorizationApproved() === true) {
179
            $accessToken = $this->issueAccessToken(
180
                $this->accessTokenTTL,
181
                $authorizationRequest->getClient(),
182
                $authorizationRequest->getUser()->getIdentifier(),
183
                $authorizationRequest->getScopes()
184
            );
185
186
            $redirectPayload['access_token'] = (string) $accessToken->convertToJWT($this->privateKey);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$redirectPayload was never initialized. Although not strictly required by PHP, it is generally a good practice to add $redirectPayload = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
187
            $redirectPayload['token_type'] = 'bearer';
188
            $redirectPayload['expires_in'] = $accessToken->getExpiryDateTime()->getTimestamp() - (new \DateTime())->getTimestamp();
189
190
            $response = new RedirectResponse();
191
            $response->setRedirectUri(
192
                $this->makeRedirectUri(
193
                    $finalRedirectUri,
194
                    $redirectPayload,
195
                    '#'
196
                )
197
            );
198
199
            return $response;
200
        }
201
202
        // The user denied the client, redirect them back with an error
203
        throw OAuthServerException::accessDenied(
204
            'The user denied the request',
205
            $finalRedirectUri
206
        );
207
    }
208
}
209