Complex classes like BasePassportServer often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use BasePassportServer, and based on these observations, apply Extract Interface, too.
1 | <?php namespace Limoncello\Passport; |
||
46 | abstract class BasePassportServer extends BaseAuthorizationServer implements PassportServerInterface, LAI |
||
47 | { |
||
48 | use LoggerAwareTrait; |
||
49 | |||
50 | /** |
||
51 | * @param PassportServerIntegrationInterface $integration |
||
52 | * @param ServerRequestInterface $request |
||
53 | * @param array $parameters |
||
54 | * @param string $realm |
||
55 | * |
||
56 | * @return ClientInterface|null |
||
57 | * |
||
58 | * @SuppressWarnings(PHPMD.NPathComplexity) |
||
59 | * @SuppressWarnings(PHPMD.CyclomaticComplexity) |
||
60 | */ |
||
61 | abstract protected function determineClient( |
||
67 | |||
68 | /** |
||
69 | * @var PassportServerIntegrationInterface |
||
70 | */ |
||
71 | private $integration; |
||
72 | |||
73 | /** |
||
74 | * @param PassportServerIntegrationInterface $integration |
||
75 | */ |
||
76 | 17 | public function __construct(PassportServerIntegrationInterface $integration) |
|
82 | |||
83 | /** |
||
84 | * @inheritdoc |
||
85 | * |
||
86 | * @SuppressWarnings(PHPMD.CyclomaticComplexity) |
||
87 | */ |
||
88 | 9 | protected function createAuthorization(array $parameters): ResponseInterface |
|
124 | |||
125 | /** |
||
126 | * @inheritdoc |
||
127 | */ |
||
128 | 8 | public function postCreateToken(ServerRequestInterface $request): ResponseInterface |
|
129 | { |
||
130 | try { |
||
131 | 8 | $parameters = $request->getParsedBody(); |
|
132 | 8 | $determinedClient = $this->determineClient($this->getIntegration(), $request, $parameters); |
|
|
|||
133 | |||
134 | 8 | switch ($grantType = $this->getGrantType($parameters)) { |
|
135 | 8 | case GrantTypes::AUTHORIZATION_CODE: |
|
136 | 1 | $this->logDebug('Handling code grant.'); |
|
137 | 1 | $response = $this->codeIssueToken($parameters, $determinedClient); |
|
138 | 1 | break; |
|
139 | 7 | case GrantTypes::RESOURCE_OWNER_PASSWORD_CREDENTIALS: |
|
140 | 4 | $this->logDebug('Handling resource owner password grant.'); |
|
141 | 4 | $response = $this->passIssueToken($parameters, $determinedClient); |
|
142 | 3 | break; |
|
143 | 5 | case GrantTypes::CLIENT_CREDENTIALS: |
|
144 | 2 | $this->logDebug('Handling client credentials grant.'); |
|
145 | 2 | if ($determinedClient === null) { |
|
146 | 1 | $this->logInfo('Client identification failed.'); |
|
147 | 1 | throw new OAuthTokenBodyException(OAuthTokenBodyException::ERROR_INVALID_CLIENT); |
|
148 | } |
||
149 | 1 | $response = $this->clientIssueToken($parameters, $determinedClient); |
|
150 | 1 | break; |
|
151 | 3 | case GrantTypes::REFRESH_TOKEN: |
|
152 | 2 | $this->logDebug('Handling refresh token grant.'); |
|
153 | 2 | $response = $this->refreshIssueToken($parameters, $determinedClient); |
|
154 | 2 | break; |
|
155 | default: |
||
156 | 1 | $this->logInfo('Unknown grant type.', ['grant_type' => $grantType]); |
|
157 | 6 | throw new OAuthTokenBodyException(OAuthTokenBodyException::ERROR_UNSUPPORTED_GRANT_TYPE); |
|
158 | } |
||
159 | 4 | } catch (OAuthTokenBodyException $exception) { |
|
160 | 4 | $response = $this->createBodyErrorResponse($exception); |
|
161 | } |
||
162 | |||
163 | 8 | return $response; |
|
164 | } |
||
165 | |||
166 | /** |
||
167 | * @inheritdoc |
||
168 | */ |
||
169 | 2 | public function createCodeResponse(TokenInterface $code, string $state = null): ResponseInterface |
|
170 | { |
||
171 | 2 | $client = $this->readClientByIdentifier($code->getClientIdentifier()); |
|
172 | 2 | if ($code->getRedirectUriString() === null || |
|
173 | 2 | in_array($code->getRedirectUriString(), $client->getRedirectUriStrings()) === false |
|
174 | ) { |
||
175 | 1 | $this->logInfo( |
|
176 | 1 | 'Code has invalid redirect URI which do not match any redirect URI for its client.', |
|
177 | 1 | ['id' => $code->getIdentifier()] |
|
178 | ); |
||
179 | 1 | return $this->getIntegration()->createInvalidClientAndRedirectUriErrorResponse(); |
|
180 | } |
||
181 | |||
182 | 1 | $code->setCode($this->getIntegration()->generateCodeValue($code)); |
|
183 | |||
184 | 1 | $tokenRepo = $this->getIntegration()->getTokenRepository(); |
|
185 | 1 | $createdCode = $tokenRepo->createCode($code); |
|
186 | |||
187 | 1 | $response = $this->createRedirectCodeResponse($createdCode, $state); |
|
188 | |||
189 | 1 | return $response; |
|
190 | } |
||
191 | |||
192 | /** |
||
193 | * @inheritdoc |
||
194 | */ |
||
195 | 2 | public function createTokenResponse(TokenInterface $token, string $state = null): ResponseInterface |
|
196 | { |
||
197 | 2 | $client = $this->readClientByIdentifier($token->getClientIdentifier()); |
|
198 | 2 | if ($token->getRedirectUriString() === null || |
|
199 | 2 | in_array($token->getRedirectUriString(), $client->getRedirectUriStrings()) === false |
|
200 | ) { |
||
201 | 1 | $this->logInfo( |
|
202 | 1 | 'Token has invalid redirect URI which do not match any redirect URI for its client.', |
|
203 | 1 | ['id' => $token->getIdentifier()] |
|
204 | ); |
||
205 | 1 | return $this->getIntegration()->createInvalidClientAndRedirectUriErrorResponse(); |
|
206 | } |
||
207 | |||
208 | 1 | list($tokenValue, $tokenType, $tokenExpiresIn) = $this->getIntegration()->generateTokenValues($token); |
|
209 | |||
210 | // refresh value must be null by the spec |
||
211 | 1 | $refreshValue = null; |
|
212 | 1 | $token->setValue($tokenValue)->setType($tokenType)->setRefreshValue($refreshValue); |
|
213 | 1 | $savedToken = $this->getIntegration()->getTokenRepository()->createToken($token); |
|
214 | |||
215 | 1 | $response = $this->createRedirectTokenResponse($savedToken, $tokenExpiresIn, $state); |
|
216 | |||
217 | 1 | return $response; |
|
218 | } |
||
219 | |||
220 | /** @noinspection PhpTooManyParametersInspection |
||
221 | * @inheritdoc |
||
222 | * |
||
223 | * @SuppressWarnings(PHPMD.BooleanArgumentFlag) |
||
224 | */ |
||
225 | 3 | public function codeCreateAskResourceOwnerForApprovalResponse( |
|
226 | ClientInterface $client, |
||
227 | string $redirectUri = null, |
||
228 | bool $isScopeModified = false, |
||
229 | array $scopeList = null, |
||
230 | string $state = null, |
||
231 | array $extraParameters = [] |
||
232 | ): ResponseInterface { |
||
233 | 3 | $this->logDebug('Asking resource owner for scope approval (code grant).'); |
|
234 | 3 | return $this->getIntegration()->createAskResourceOwnerForApprovalResponse( |
|
235 | 3 | ResponseTypes::AUTHORIZATION_CODE, |
|
236 | 3 | $client, |
|
237 | 3 | $redirectUri, |
|
238 | 3 | $isScopeModified, |
|
239 | 3 | $scopeList, |
|
240 | 3 | $state, |
|
241 | 3 | $extraParameters |
|
242 | ); |
||
243 | } |
||
244 | |||
245 | /** |
||
246 | * @inheritdoc |
||
247 | */ |
||
248 | 1 | public function codeReadAuthenticationCode(string $code): ?AuthorizationCodeInterface |
|
249 | { |
||
250 | 1 | return $this->getIntegration()->getTokenRepository() |
|
251 | 1 | ->readByCode($code, $this->getIntegration()->getCodeExpirationPeriod()); |
|
252 | } |
||
253 | |||
254 | /** |
||
255 | * @inheritdoc |
||
256 | */ |
||
257 | 1 | public function codeCreateAccessTokenResponse( |
|
258 | AuthorizationCodeInterface $code, |
||
259 | array $extraParameters = [] |
||
260 | ): ResponseInterface { |
||
261 | /** @var Token $code */ |
||
262 | 1 | assert($code instanceof Token); |
|
263 | 1 | $updatedToken = clone $code; |
|
264 | |||
265 | 1 | $tokenExpiresIn = $this->setUpTokenValues($updatedToken); |
|
266 | 1 | $this->getIntegration()->getTokenRepository()->assignValuesToCode($updatedToken, $tokenExpiresIn); |
|
267 | |||
268 | 1 | $response = $this->createBodyTokenResponse($updatedToken, $tokenExpiresIn); |
|
269 | |||
270 | 1 | $this->logInfo('Authorization code successfully exchanged for a token (code grant).'); |
|
271 | |||
272 | 1 | return $response; |
|
273 | } |
||
274 | |||
275 | /** |
||
276 | * @inheritdoc |
||
277 | */ |
||
278 | 1 | public function codeRevokeTokens(AuthorizationCodeInterface $code): void |
|
279 | { |
||
280 | 1 | assert($code instanceof TokenInterface); |
|
281 | |||
282 | /** @var TokenInterface $code */ |
||
283 | |||
284 | 1 | $identifier = $code->getIdentifier(); |
|
285 | 1 | $this->logInfo('Revoking token.', ['token_id' => $identifier]); |
|
286 | 1 | $this->getIntegration()->getTokenRepository()->disable($identifier); |
|
287 | } |
||
288 | |||
289 | /** @noinspection PhpTooManyParametersInspection |
||
290 | * @inheritdoc |
||
291 | * |
||
292 | * @SuppressWarnings(PHPMD.BooleanArgumentFlag) |
||
293 | */ |
||
294 | 2 | public function implicitCreateAskResourceOwnerForApprovalResponse( |
|
295 | ClientInterface $client, |
||
296 | string $redirectUri = null, |
||
297 | bool $isScopeModified = false, |
||
298 | array $scopeList = null, |
||
299 | string $state = null, |
||
300 | array $extraParameters = [] |
||
301 | ): ResponseInterface { |
||
302 | 2 | $response = $this->getIntegration()->createAskResourceOwnerForApprovalResponse( |
|
303 | 2 | ResponseTypes::IMPLICIT, |
|
304 | 2 | $client, |
|
305 | 2 | $redirectUri, |
|
306 | 2 | $isScopeModified, |
|
307 | 2 | $scopeList, |
|
308 | 2 | $state, |
|
309 | 2 | $extraParameters |
|
310 | ); |
||
311 | |||
312 | 2 | $this->logInfo('Created response asking resource owner for scope approval (implicit grant).'); |
|
313 | |||
314 | 2 | return $response; |
|
315 | } |
||
316 | |||
317 | /** @noinspection PhpTooManyParametersInspection |
||
318 | * @inheritdoc |
||
319 | * |
||
320 | * @SuppressWarnings(PHPMD.BooleanArgumentFlag) |
||
321 | */ |
||
322 | 4 | public function passValidateCredentialsAndCreateAccessTokenResponse( |
|
323 | string $userName, |
||
324 | string $password, |
||
325 | ClientInterface $client = null, |
||
326 | bool $isScopeModified = false, |
||
327 | array $scope = null, |
||
328 | array $extraParameters = [] |
||
329 | ): ResponseInterface { |
||
330 | 4 | assert($client !== null); |
|
331 | |||
332 | 4 | if (($userIdentifier = $this->getIntegration()->validateUserId($userName, $password)) === null) { |
|
333 | 1 | $this->logDebug('User not found with provided username and password.', ['username' => $userName]); |
|
334 | 1 | throw new OAuthTokenBodyException(OAuthTokenBodyException::ERROR_INVALID_GRANT); |
|
335 | } |
||
336 | 3 | assert(is_int($userIdentifier) === true); |
|
337 | 3 | $this->logInfo('User authenticated with provided username and password.', ['username' => $userName]); |
|
338 | |||
339 | 3 | $changedScopeOrNull = $this->getIntegration()->verifyAllowedUserScope($userIdentifier, $scope); |
|
340 | 3 | if ($changedScopeOrNull !== null) { |
|
341 | 3 | assert(is_array($changedScopeOrNull)); |
|
342 | 3 | $isScopeModified = true; |
|
343 | 3 | $scope = $changedScopeOrNull; |
|
344 | } |
||
345 | |||
346 | 3 | $unsavedToken = $this->getIntegration()->createTokenInstance(); |
|
347 | $unsavedToken |
||
348 | 3 | ->setClientIdentifier($client->getIdentifier()) |
|
349 | 3 | ->setScopeIdentifiers($scope) |
|
350 | 3 | ->setUserIdentifier($userIdentifier); |
|
351 | 3 | $isScopeModified === true ? $unsavedToken->setScopeModified() : $unsavedToken->setScopeUnmodified(); |
|
352 | |||
353 | |||
354 | 3 | $tokenExpiresIn = $this->setUpTokenValues($unsavedToken); |
|
355 | 3 | $savedToken = $this->getIntegration()->getTokenRepository()->createToken($unsavedToken); |
|
356 | |||
357 | 3 | $response = $this->createBodyTokenResponse($savedToken, $tokenExpiresIn); |
|
358 | |||
359 | 3 | return $response; |
|
360 | } |
||
361 | |||
362 | /** |
||
363 | * @inheritdoc |
||
364 | */ |
||
365 | 4 | public function passReadDefaultClient(): ClientInterface |
|
366 | { |
||
367 | 4 | $defaultClientId = $this->getIntegration()->getDefaultClientIdentifier(); |
|
368 | |||
369 | 4 | assert(is_string($defaultClientId) === true && empty($defaultClientId) === false); |
|
370 | |||
371 | 4 | $defaultClient = $this->readClientByIdentifier($defaultClientId); |
|
372 | |||
373 | 4 | assert($defaultClient !== null); |
|
374 | |||
375 | 4 | return $defaultClient; |
|
376 | } |
||
377 | |||
378 | /** |
||
379 | * @inheritdoc |
||
380 | */ |
||
381 | 1 | public function clientCreateAccessTokenResponse( |
|
382 | ClientInterface $client, |
||
383 | bool $isScopeModified, |
||
384 | array $scope = null, |
||
385 | array $extraParameters = [] |
||
386 | ): ResponseInterface { |
||
387 | 1 | $this->logDebug('Prepare token for client.'); |
|
388 | 1 | assert($client !== null); |
|
389 | |||
390 | 1 | $unsavedToken = $this->getIntegration()->createTokenInstance(); |
|
391 | $unsavedToken |
||
392 | 1 | ->setClientIdentifier($client->getIdentifier()) |
|
393 | 1 | ->setScopeIdentifiers($scope); |
|
394 | 1 | $isScopeModified === true ? $unsavedToken->setScopeModified() : $unsavedToken->setScopeUnmodified(); |
|
395 | |||
396 | |||
397 | 1 | $tokenExpiresIn = $this->setUpTokenValue($unsavedToken); |
|
398 | 1 | $savedToken = $this->getIntegration()->getTokenRepository()->createToken($unsavedToken); |
|
399 | |||
400 | 1 | $response = $this->createBodyTokenResponse($savedToken, $tokenExpiresIn); |
|
401 | |||
402 | 1 | return $response; |
|
403 | } |
||
404 | |||
405 | /** |
||
406 | * @inheritdoc |
||
407 | * |
||
408 | * @return TokenInterface|null |
||
409 | */ |
||
410 | 2 | public function readTokenByRefreshValue(string $refreshValue): ?\Limoncello\OAuthServer\Contracts\TokenInterface |
|
411 | { |
||
412 | 2 | return $this->getIntegration()->getTokenRepository()->readByRefresh( |
|
413 | 2 | $refreshValue, |
|
414 | 2 | $this->getIntegration()->getTokenExpirationPeriod() |
|
415 | ); |
||
416 | } |
||
417 | |||
418 | /** |
||
419 | * @inheritdoc |
||
420 | * |
||
421 | * @SuppressWarnings(PHPMD.ElseExpression) |
||
422 | */ |
||
423 | 2 | public function refreshCreateAccessTokenResponse( |
|
424 | ClientInterface $client, |
||
425 | \Limoncello\OAuthServer\Contracts\TokenInterface $token, |
||
426 | bool $isScopeModified, |
||
427 | array $scope = null, |
||
428 | array $extraParameters = [] |
||
429 | ): ResponseInterface { |
||
430 | 2 | $this->logDebug('Prepare refresh token.'); |
|
431 | |||
432 | /** @var TokenInterface $token */ |
||
433 | 2 | assert($token instanceof TokenInterface); |
|
434 | |||
435 | 2 | $updatedToken = clone $token; |
|
436 | 2 | $tokenExpiresIn = $this->getIntegration()->isRenewRefreshValue() === false ? |
|
437 | 2 | $this->setUpTokenValue($updatedToken) : $this->setUpTokenValues($updatedToken); |
|
438 | |||
439 | 2 | $tokenRepo = $this->getIntegration()->getTokenRepository(); |
|
440 | 2 | if ($isScopeModified === false) { |
|
441 | 1 | $tokenRepo->updateValues($updatedToken); |
|
442 | } else { |
||
443 | 1 | assert(is_array($scope)); |
|
444 | 1 | $tokenRepo->inTransaction(function () use ($tokenRepo, $updatedToken, $scope) { |
|
445 | 1 | $tokenRepo->updateValues($updatedToken); |
|
446 | 1 | $tokenRepo->unbindScopes($updatedToken->getIdentifier()); |
|
447 | 1 | $tokenRepo->bindScopeIdentifiers($updatedToken->getIdentifier(), $scope); |
|
448 | 1 | }); |
|
449 | 1 | $updatedToken->setScopeModified()->setScopeIdentifiers($scope); |
|
450 | } |
||
451 | 2 | $response = $this->createBodyTokenResponse($updatedToken, $tokenExpiresIn); |
|
452 | |||
453 | 2 | return $response; |
|
454 | } |
||
455 | |||
456 | /** |
||
457 | * @inheritdoc |
||
458 | */ |
||
459 | 13 | public function readClientByIdentifier(string $clientIdentifier): ?ClientInterface |
|
460 | { |
||
461 | 13 | return $this->getIntegration()->getClientRepository()->read($clientIdentifier); |
|
462 | } |
||
463 | |||
464 | /** |
||
465 | * @param string|null $clientId |
||
466 | * @param string|null $redirectFromQuery |
||
467 | * |
||
468 | * @return array [client|null, uri|null] |
||
469 | * |
||
470 | * @SuppressWarnings(PHPMD.ElseExpression) |
||
471 | */ |
||
472 | 9 | protected function getValidClientAndRedirectUri(string $clientId = null, string $redirectFromQuery = null): array |
|
473 | { |
||
474 | 9 | $client = null; |
|
475 | 9 | $validRedirectUri = null; |
|
476 | |||
477 | 9 | if ($clientId !== null && |
|
478 | 9 | ($client = $this->readClientByIdentifier($clientId)) !== null |
|
479 | ) { |
||
480 | 7 | $validRedirectUri = $this->selectValidRedirectUri($client, $redirectFromQuery); |
|
481 | 7 | if ($validRedirectUri === null) { |
|
482 | 1 | $this->logDebug( |
|
483 | 1 | 'Choosing valid redirect URI for client failed.', |
|
484 | 7 | ['client_id' => $clientId, 'redirect_uri_from_query' => $redirectFromQuery] |
|
485 | ); |
||
486 | } |
||
487 | } else { |
||
488 | 2 | $this->logDebug('Client is not found.', ['client_id' => $clientId]); |
|
489 | } |
||
490 | |||
491 | 9 | return [$client, $validRedirectUri]; |
|
492 | } |
||
493 | |||
494 | /** |
||
495 | * @param TokenInterface $token |
||
496 | * @param int $tokenExpiresIn |
||
497 | * |
||
498 | * @return ResponseInterface |
||
499 | */ |
||
500 | 5 | protected function createBodyTokenResponse(TokenInterface $token, int $tokenExpiresIn): ResponseInterface |
|
501 | { |
||
502 | 5 | $this->logDebug('Sending token as JSON response.'); |
|
503 | |||
504 | 5 | $scopeList = $token->isScopeModified() === false || empty($token->getScopeIdentifiers()) === true ? |
|
505 | 5 | null : $token->getScopeList(); |
|
506 | |||
507 | // for access token format @link https://tools.ietf.org/html/rfc6749#section-5.1 |
||
508 | 5 | $parameters = $this->filterNulls([ |
|
509 | 5 | 'access_token' => $token->getValue(), |
|
510 | 5 | 'token_type' => $token->getType(), |
|
511 | 5 | 'expires_in' => $tokenExpiresIn, |
|
512 | 5 | 'refresh_token' => $token->getRefreshValue(), |
|
513 | 5 | 'scope' => $scopeList, |
|
514 | ]); |
||
515 | |||
516 | // extra parameters |
||
517 | // https://tools.ietf.org/html/rfc6749#section-4.1.4 |
||
518 | // https://tools.ietf.org/html/rfc6749#section-4.3.3 |
||
519 | // https://tools.ietf.org/html/rfc6749#section-4.4.3 |
||
520 | 5 | $extraParameters = $this->getIntegration()->getBodyTokenExtraParameters($token); |
|
521 | |||
522 | 5 | $response = new JsonResponse($parameters + $extraParameters, 200, [ |
|
523 | 5 | 'Cache-Control' => 'no-store', |
|
524 | 'Pragma' => 'no-cache' |
||
525 | ]); |
||
526 | |||
527 | 5 | return $response; |
|
528 | } |
||
529 | |||
530 | /** |
||
531 | * @param TokenInterface $code |
||
532 | * @param string|null $state |
||
533 | * |
||
534 | * @return ResponseInterface |
||
535 | */ |
||
536 | 1 | protected function createRedirectCodeResponse(TokenInterface $code, string $state = null): ResponseInterface |
|
537 | { |
||
538 | 1 | $this->logDebug('Sending code as redirect response.'); |
|
539 | |||
540 | // for access token format @link https://tools.ietf.org/html/rfc6749#section-4.1.3 |
||
541 | 1 | $parameters = $this->filterNulls([ |
|
542 | 1 | 'code' => $code->getCode(), |
|
543 | 1 | 'state' => $state, |
|
544 | ]); |
||
545 | |||
546 | 1 | $redirectUri = $code->getRedirectUriString(); |
|
547 | 1 | $query = $this->encodeAsXWwwFormUrlencoded($parameters); |
|
548 | |||
549 | 1 | $response = new RedirectResponse((new Uri($redirectUri))->withQuery($query)); |
|
550 | |||
551 | 1 | return $response; |
|
552 | } |
||
553 | |||
554 | /** |
||
555 | * @param TokenInterface $token |
||
556 | * @param int $tokenExpiresIn |
||
557 | * @param string|null $state |
||
558 | * |
||
559 | * @return ResponseInterface |
||
560 | */ |
||
561 | 1 | protected function createRedirectTokenResponse( |
|
562 | TokenInterface $token, |
||
563 | int $tokenExpiresIn, |
||
564 | string $state = null |
||
565 | ): ResponseInterface { |
||
566 | 1 | $this->logDebug('Sending token as redirect response.'); |
|
567 | |||
568 | 1 | $scopeList = $token->isScopeModified() === false || empty($token->getScopeIdentifiers()) === true ? |
|
569 | 1 | null : $token->getScopeList(); |
|
570 | |||
571 | // for access token format @link https://tools.ietf.org/html/rfc6749#section-5.1 |
||
572 | 1 | $parameters = $this->filterNulls([ |
|
573 | 1 | 'access_token' => $token->getValue(), |
|
574 | 1 | 'token_type' => $token->getType(), |
|
575 | 1 | 'expires_in' => $tokenExpiresIn, |
|
576 | 1 | 'scope' => $scopeList, |
|
577 | 1 | 'state' => $state, |
|
578 | ]); |
||
579 | |||
580 | 1 | $fragment = $this->encodeAsXWwwFormUrlencoded($parameters); |
|
581 | |||
582 | 1 | $response = new RedirectResponse((new Uri($token->getRedirectUriString()))->withFragment($fragment)); |
|
583 | |||
584 | 1 | return $response; |
|
585 | } |
||
586 | |||
587 | /** |
||
588 | * @param OAuthTokenBodyException $exception |
||
589 | * |
||
590 | * @return ResponseInterface |
||
591 | */ |
||
592 | 4 | protected function createBodyErrorResponse(OAuthTokenBodyException $exception): ResponseInterface |
|
593 | { |
||
594 | 4 | $data = $this->filterNulls([ |
|
595 | 4 | 'error' => $exception->getErrorCode(), |
|
596 | 4 | 'error_description' => $exception->getErrorDescription(), |
|
597 | 4 | 'error_uri' => $this->getBodyErrorUri($exception), |
|
598 | ]); |
||
599 | |||
600 | 4 | $this->logDebug('Sending OAuth error as JSON response.', $data); |
|
601 | |||
602 | 4 | $response = new JsonResponse($data, $exception->getHttpCode(), $exception->getHttpHeaders()); |
|
603 | |||
604 | 4 | return $response; |
|
605 | } |
||
606 | |||
607 | /** |
||
608 | * @param OAuthRedirectException $exception |
||
609 | * |
||
610 | * @return ResponseInterface |
||
611 | */ |
||
612 | 1 | protected function createRedirectErrorResponse(OAuthRedirectException $exception): ResponseInterface |
|
613 | { |
||
614 | 1 | $parameters = $this->filterNulls([ |
|
615 | 1 | 'error' => $exception->getErrorCode(), |
|
616 | 1 | 'error_description' => $exception->getErrorDescription(), |
|
617 | 1 | 'error_uri' => $exception->getErrorUri(), |
|
618 | 1 | 'state' => $exception->getState(), |
|
619 | ]); |
||
620 | |||
621 | 1 | $this->logDebug('Sending OAuth error via redirect.', $parameters); |
|
622 | |||
623 | 1 | $fragment = $this->encodeAsXWwwFormUrlencoded($parameters); |
|
624 | 1 | $uri = (new Uri($exception->getRedirectUri()))->withFragment($fragment); |
|
625 | |||
626 | 1 | $response = new RedirectResponse($uri, 302, $exception->getHttpHeaders()); |
|
627 | |||
628 | 1 | return $response; |
|
629 | } |
||
630 | |||
631 | /** |
||
632 | * @param TokenInterface $token |
||
633 | * |
||
634 | * @return int |
||
635 | */ |
||
636 | 1 | protected function setUpTokenValue(TokenInterface $token): int |
|
637 | { |
||
638 | list($tokenValue, $tokenType, $tokenExpiresIn) = |
||
639 | 1 | $this->getIntegration()->generateTokenValues($token); |
|
640 | 1 | $token->setValue($tokenValue)->setType($tokenType); |
|
641 | |||
642 | 1 | return $tokenExpiresIn; |
|
643 | } |
||
644 | |||
645 | /** |
||
646 | * @param TokenInterface $token |
||
647 | * |
||
648 | * @return int |
||
649 | */ |
||
650 | 4 | protected function setUpTokenValues(TokenInterface $token): int |
|
651 | { |
||
652 | list($tokenValue, $tokenType, $tokenExpiresIn, $refreshValue) = |
||
653 | 4 | $this->getIntegration()->generateTokenValues($token); |
|
654 | 4 | $token->setValue($tokenValue)->setType($tokenType)->setRefreshValue($refreshValue); |
|
655 | |||
656 | 4 | return $tokenExpiresIn; |
|
657 | } |
||
658 | |||
659 | /** |
||
660 | * @return PassportServerIntegrationInterface |
||
661 | */ |
||
662 | 16 | protected function getIntegration(): PassportServerIntegrationInterface |
|
666 | |||
667 | /** |
||
668 | * @param PassportServerIntegrationInterface $integration |
||
669 | * |
||
670 | * @return self |
||
671 | */ |
||
672 | 17 | protected function setIntegration(PassportServerIntegrationInterface $integration): self |
|
673 | { |
||
674 | 17 | $this->integration = $integration; |
|
675 | |||
676 | 17 | return $this; |
|
677 | } |
||
678 | |||
679 | /** |
||
680 | * @param OAuthTokenBodyException $exception |
||
681 | * |
||
682 | * @return null|string |
||
683 | */ |
||
684 | 4 | protected function getBodyErrorUri(OAuthTokenBodyException $exception) |
|
685 | { |
||
686 | 4 | assert($exception !== null); |
|
687 | |||
688 | 4 | return null; |
|
689 | } |
||
690 | |||
691 | /** |
||
692 | * @param string $message |
||
693 | * @param array $context |
||
694 | * |
||
695 | * @return void |
||
696 | */ |
||
697 | 16 | protected function logDebug(string $message, array $context = []): void |
|
703 | |||
704 | /** |
||
705 | * @param string $message |
||
706 | * @param array $context |
||
707 | * |
||
708 | * @return void |
||
709 | */ |
||
710 | 10 | protected function logInfo(string $message, array $context = []): void |
|
716 | |||
717 | /** |
||
718 | * @param array $array |
||
719 | * |
||
720 | * @return array |
||
721 | */ |
||
722 | private function filterNulls(array $array): array |
||
728 | } |
||
729 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.