From 86186321d5157f5e6902fa3ead96addb1cd922ff Mon Sep 17 00:00:00 2001 From: sephster Date: Mon, 17 Jan 2022 20:50:32 +0000 Subject: [PATCH 01/46] Update tests to only run on PHP 7.4, 8.0, and 8.1 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1f1db9e1b..092a9312d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - php: [7.2, 7.3, 7.4, 8.0] + php: [7.4, 8.0, 8.1] stability: [prefer-lowest, prefer-stable] name: PHP ${{ matrix.php }} - ${{ matrix.stability }} From 9f39bf9ee7f55f928ef2922afe19204d4fcb9829 Mon Sep 17 00:00:00 2001 From: sephster Date: Mon, 17 Jan 2022 21:02:14 +0000 Subject: [PATCH 02/46] Update dependencies for PHP 7.4+ --- composer.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 7cfbc0cc4..57e646555 100644 --- a/composer.json +++ b/composer.json @@ -4,19 +4,19 @@ "homepage": "https://oauth2.thephpleague.com/", "license": "MIT", "require": { - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "ext-openssl": "*", "league/event": "^2.2", - "lcobucci/jwt": "^3.4.6 || ^4.0.4", + "lcobucci/jwt": "^4.1.5", "psr/http-message": "^1.0.1", - "defuse/php-encryption": "^2.2.1", + "defuse/php-encryption": "^2.3.1", "ext-json": "*" }, "require-dev": { - "phpunit/phpunit": "^8.5.13", - "laminas/laminas-diactoros": "^2.4.1", - "phpstan/phpstan": "^0.12.57", - "phpstan/phpstan-phpunit": "^0.12.16", + "phpunit/phpunit": "^9.5.11", + "laminas/laminas-diactoros": "^2.8.0", + "phpstan/phpstan": "^1.4.1", + "phpstan/phpstan-phpunit": "^1.0.0", "roave/security-advisories": "dev-master" }, "repositories": [ From ec05e01c7433fbb8c6d83067e0ababfa27cad50b Mon Sep 17 00:00:00 2001 From: sephster Date: Mon, 17 Jan 2022 22:49:57 +0000 Subject: [PATCH 03/46] Add mock returns for revoke refresh token tests --- tests/Grant/RefreshTokenGrantTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index ef14cabe7..5b5491bbc 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -563,6 +563,7 @@ public function testRevokedRefreshToken() $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); + $scopeRepositoryMock->method('finalizeScopes')->willReturn([$scopeEntity]); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); @@ -621,6 +622,7 @@ public function testUnrevokedRefreshToken() $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); + $scopeRepositoryMock->method('finalizeScopes')->willReturn([$scopeEntity]); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); From 19dc018d31da58893b1c31cdb07c2e61a9c9a2bb Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 24 Jan 2022 23:11:48 +0000 Subject: [PATCH 04/46] re-introduce phpstan --- composer.json | 7 ++++++- phpstan.neon => phpstan.neon.dist.tmp | 0 src/Exception/OAuthServerException.php | 2 +- tests/Utils/CryptKeyTest.php | 8 -------- 4 files changed, 7 insertions(+), 10 deletions(-) rename phpstan.neon => phpstan.neon.dist.tmp (100%) diff --git a/composer.json b/composer.json index 57e646555..52b6df7ac 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "require-dev": { "phpunit/phpunit": "^9.5.11", "laminas/laminas-diactoros": "^2.8.0", - "phpstan/phpstan": "^1.4.1", + "phpstan/phpstan": "^1.4", "phpstan/phpstan-phpunit": "^1.0.0", "roave/security-advisories": "dev-master" }, @@ -68,5 +68,10 @@ "psr-4": { "LeagueTests\\": "tests/" } + }, + "config": { + "allow-plugins": { + "ocramius/package-versions": true + } } } diff --git a/phpstan.neon b/phpstan.neon.dist.tmp similarity index 100% rename from phpstan.neon rename to phpstan.neon.dist.tmp diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index fc1b9f022..f57c68951 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -57,7 +57,7 @@ class OAuthServerException extends Exception * @param null|string $redirectUri A HTTP URI to redirect the user back to * @param Throwable $previous Previous exception */ - public function __construct($message, $code, $errorType, $httpStatusCode = 400, $hint = null, $redirectUri = null, Throwable $previous = null) + final public function __construct($message, $code, $errorType, $httpStatusCode = 400, $hint = null, $redirectUri = null, Throwable $previous = null) { parent::__construct($message, $code, $previous); $this->httpStatusCode = $httpStatusCode; diff --git a/tests/Utils/CryptKeyTest.php b/tests/Utils/CryptKeyTest.php index b9c53b660..55808fc17 100644 --- a/tests/Utils/CryptKeyTest.php +++ b/tests/Utils/CryptKeyTest.php @@ -94,10 +94,6 @@ public function testECKeyType() $this->assertEquals('mystrongpassword', $key->getPassPhrase()); } catch (\Throwable $e) { $this->fail('The EC key was not created'); - } finally { - if (isset($path)) { - @\unlink($path); - } } } @@ -119,10 +115,6 @@ public function testRSAKeyType() $this->assertEquals('mystrongpassword', $key->getPassPhrase()); } catch (\Throwable $e) { $this->fail('The RSA key was not created'); - } finally { - if (isset($path)) { - @\unlink($path); - } } } From 6844f4ea7444125bf854ace4b39ebf9d45aee150 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Sat, 29 Jan 2022 14:08:59 +0000 Subject: [PATCH 05/46] Add revokeRefreshTokens to GrantTypeInterface --- CHANGELOG.md | 1 + src/Grant/GrantTypeInterface.php | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49ea711b0..7c1307ebd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added +- GrantTypeInterface has a new function, `revokeRefreshTokens()` for enabling or disabling refresh tokens after use (PR #XXXX) - A CryptKeyInterface to allow developers to change the CryptKey implementation with greater ease (PR #1044) - The authorization server can now finalize scopes when a client uses a refresh token (PR #1094) - An AuthorizationRequestInterface to make it easier to extend the AuthorizationRequest (PR #1110) diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index bf1dd792f..9f66639c0 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -141,4 +141,13 @@ public function setPrivateKey(CryptKeyInterface $privateKey); * @param string|Key|null $key */ public function setEncryptionKey($key = null); + + /** + * Enable or prevent the revocation of refresh tokens upon usage. + * + * @param bool $willRevoke + * + * @return void + */ + public function revokeRefreshTokens(bool $willRevoke); } From 39cca0b460f2dd2999023e3638a392f87ac9716e Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 2 Feb 2022 10:17:20 +0000 Subject: [PATCH 06/46] change phpstan.neon.dist name --- phpstan.neon.dist.tmp => phpstan.neon.dist | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename phpstan.neon.dist.tmp => phpstan.neon.dist (100%) diff --git a/phpstan.neon.dist.tmp b/phpstan.neon.dist similarity index 100% rename from phpstan.neon.dist.tmp rename to phpstan.neon.dist From c15f5d9d02f677d3fd8b400c7650f34ae79ebaab Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 2 Feb 2022 10:18:00 +0000 Subject: [PATCH 07/46] Update phpstan default config --- phpstan.neon.dist | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ba1fb4915..b815a6d4d 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,8 +1,5 @@ -includes: - - vendor/phpstan/phpstan-phpunit/extension.neon - - vendor/phpstan/phpstan-phpunit/rules.neon -services: - - - class: LeagueTests\PHPStan\AbstractGrantExtension - tags: - - phpstan.broker.dynamicMethodReturnTypeExtension +parameters: + level: 1 + paths: + - src + - tests \ No newline at end of file From e7b4c4dac984b1a92ccbe3571b329b5056ad25ba Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 22 Feb 2022 15:42:50 +0000 Subject: [PATCH 08/46] Ignore unresolvable phpstan error --- phpstan.neon.dist | 5 ++++- src/Grant/AbstractGrant.php | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index b815a6d4d..aaa03768a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -2,4 +2,7 @@ parameters: level: 1 paths: - src - - tests \ No newline at end of file + - tests + ignoreErrors: + - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAccessToken\(\) should return string but return statement is missing\.#' + - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAuthCode\(\) should return League\\OAuth2\\Server\\Entities\\AuthCodeEntityInterface but return statement is missing\.#' \ No newline at end of file diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index a03df5090..957d83c32 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -444,7 +444,7 @@ protected function getServerParameter($parameter, ServerRequestInterface $reques * @throws OAuthServerException * @throws UniqueTokenIdentifierConstraintViolationException * - * @return AccessTokenEntityInterface + * @return string */ protected function issueAccessToken( DateInterval $accessTokenTTL, From 2e9582d2de070701eeac424234bd805dad50638c Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 22 Feb 2022 16:09:26 +0000 Subject: [PATCH 09/46] Add getKeyContents() to CryptKeyInterface --- CHANGELOG.md | 1 + phpstan.neon.dist | 2 +- src/CryptKey.php | 4 +--- src/CryptKeyInterface.php | 7 +++++++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c1307ebd..c4ffbe134 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - A CryptKeyInterface to allow developers to change the CryptKey implementation with greater ease (PR #1044) - The authorization server can now finalize scopes when a client uses a refresh token (PR #1094) - An AuthorizationRequestInterface to make it easier to extend the AuthorizationRequest (PR #1110) +- Added function `getKeyContents()` to the `CryptKeyInterface` (PR #XXXX) ### Fixed - If a refresh token has expired, been revoked, cannot be decrypted, or does not belong to the correct client, the server will now issue an `invalid_grant` error and a HTTP 400 response. In previous versions the server incorrectly issued an `invalid_request` and HTTP 401 response (PR #1042) (PR #1082) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index aaa03768a..b9f3634b9 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: 1 + level: 2 paths: - src - tests diff --git a/src/CryptKey.php b/src/CryptKey.php index 45604f16d..b9f8ef314 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -84,9 +84,7 @@ public function __construct($keyPath, $passPhrase = null, $keyPermissionsCheck = } /** - * Get key contents - * - * @return string Key contents + * {@inheritdoc} */ public function getKeyContents(): string { diff --git a/src/CryptKeyInterface.php b/src/CryptKeyInterface.php index 86c7b0446..15c34b8d7 100644 --- a/src/CryptKeyInterface.php +++ b/src/CryptKeyInterface.php @@ -17,4 +17,11 @@ public function getKeyPath(); * @return null|string */ public function getPassPhrase(); + + /** + * Get key contents + * + * @return string Key contents + */ + public function getKeyContents(): string; } From e29a40cd3d210ae1a5a3ab1303abe675efef0ba0 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 22 Feb 2022 16:23:34 +0000 Subject: [PATCH 10/46] Ensure UnencryptedToken is returned when parsing token --- src/AuthorizationValidators/BearerTokenValidator.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index 7687843c5..6ee52f85e 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -14,6 +14,7 @@ use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer\Key\InMemory; use Lcobucci\JWT\Signer\Rsa\Sha256; +use Lcobucci\JWT\UnencryptedToken; use Lcobucci\JWT\Validation\Constraint\SignedWith; use Lcobucci\JWT\Validation\Constraint\StrictValidAt; use Lcobucci\JWT\Validation\Constraint\ValidAt; @@ -111,6 +112,10 @@ public function validateAuthorization(ServerRequestInterface $request) throw OAuthServerException::accessDenied('Access token could not be verified'); } + if (! $token instanceof UnencryptedToken) { + throw OAuthServerException::accessDenied('Access token is not an instance of UnencryptedToken'); + } + $claims = $token->claims(); // Check if token has been revoked From d32367beffb06e4162a82288391c9347780577e9 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 22 Feb 2022 16:25:50 +0000 Subject: [PATCH 11/46] Ignore unresolvable phpstan error --- phpstan.neon.dist | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index b9f3634b9..48fe80973 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,4 +5,5 @@ parameters: - tests ignoreErrors: - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAccessToken\(\) should return string but return statement is missing\.#' - - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAuthCode\(\) should return League\\OAuth2\\Server\\Entities\\AuthCodeEntityInterface but return statement is missing\.#' \ No newline at end of file + - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAuthCode\(\) should return League\\OAuth2\\Server\\Entities\\AuthCodeEntityInterface but return statement is missing\.#' + - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueRefreshToken\(\) should return League\\OAuth2\\Server\\Entities\\RefreshTokenEntityInterface\|null but return statement is missing\.#' \ No newline at end of file From ece2df18c3819be25bd1bbf19580309735055310 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 22 Feb 2022 16:32:12 +0000 Subject: [PATCH 12/46] Revert accidental commit --- src/Grant/AbstractGrant.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 957d83c32..a03df5090 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -444,7 +444,7 @@ protected function getServerParameter($parameter, ServerRequestInterface $reques * @throws OAuthServerException * @throws UniqueTokenIdentifierConstraintViolationException * - * @return string + * @return AccessTokenEntityInterface */ protected function issueAccessToken( DateInterval $accessTokenTTL, From 9275867522b622aa8e643fad848b52cd259fb9bf Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 22 Feb 2022 16:34:07 +0000 Subject: [PATCH 13/46] Update phpstan ignore parameters --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 48fe80973..fd9811988 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -4,6 +4,6 @@ parameters: - src - tests ignoreErrors: - - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAccessToken\(\) should return string but return statement is missing\.#' + - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAccessToken\(\) should return League\\OAuth2\\Server\\Entities\\AccessTokenEntityInterface but return statement is missing\.#' - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAuthCode\(\) should return League\\OAuth2\\Server\\Entities\\AuthCodeEntityInterface but return statement is missing\.#' - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueRefreshToken\(\) should return League\\OAuth2\\Server\\Entities\\RefreshTokenEntityInterface\|null but return statement is missing\.#' \ No newline at end of file From 285d90c00d8d47e5f67485b0b4fa062ddfce4a3e Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 22 Feb 2022 16:40:04 +0000 Subject: [PATCH 14/46] Fix name of variable from allowedRedirectUri to allowedRedirectUris --- src/RedirectUriValidators/RedirectUriValidator.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/RedirectUriValidators/RedirectUriValidator.php b/src/RedirectUriValidators/RedirectUriValidator.php index 2cb020801..4cd82b4a9 100644 --- a/src/RedirectUriValidators/RedirectUriValidator.php +++ b/src/RedirectUriValidators/RedirectUriValidator.php @@ -21,12 +21,12 @@ class RedirectUriValidator implements RedirectUriValidatorInterface * * @param string|array $allowedRedirectUris */ - public function __construct($allowedRedirectUri) + public function __construct($allowedRedirectUris) { - if (\is_string($allowedRedirectUri)) { - $this->allowedRedirectUris = [$allowedRedirectUri]; - } elseif (\is_array($allowedRedirectUri)) { - $this->allowedRedirectUris = $allowedRedirectUri; + if (\is_string($allowedRedirectUris)) { + $this->allowedRedirectUris = [$allowedRedirectUris]; + } elseif (\is_array($allowedRedirectUris)) { + $this->allowedRedirectUris = $allowedRedirectUris; } else { $this->allowedRedirectUris = []; } From 89c89a905dd727119f48ba207e8814790c5a1aec Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 4 May 2022 21:48:21 +0100 Subject: [PATCH 15/46] update PHPStan level --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index fd9811988..32d859033 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: 2 + level: 4 paths: - src - tests From 14f5133908459090b99279c1769757c6fc97aba4 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 4 May 2022 21:48:51 +0100 Subject: [PATCH 16/46] Fix condition that always evaluates to false --- src/Grant/AbstractGrant.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index a03df5090..7745ab504 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -262,7 +262,7 @@ protected function getClientCredentials(ServerRequestInterface $request) $clientSecret = $this->getRequestParameter('client_secret', $request, $basicAuthPassword); - if ($clientSecret !== null && !\is_string($clientSecret)) { + if ($clientSecret === null) { throw OAuthServerException::invalidRequest('client_secret'); } From 492b531044418ffefdeba02cdac1be7cc26d564b Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 4 May 2022 21:54:59 +0100 Subject: [PATCH 17/46] Revert type check on scopes as needlessly complicated --- src/Grant/AbstractGrant.php | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 7745ab504..0d5972d29 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -303,14 +303,8 @@ protected function validateRedirectUri( */ public function validateScopes($scopes, $redirectUri = null) { - if ($scopes === null) { - $scopes = []; - } elseif (\is_string($scopes)) { - $scopes = $this->convertScopesQueryStringToArray($scopes); - } - if (!\is_array($scopes)) { - throw OAuthServerException::invalidRequest('scope'); + $scopes = $this->convertScopesQueryStringToArray($scopes); } $validScopes = []; From b5c67af3705f2baf73e5e578b2ab3a11dcdd26b0 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 4 May 2022 21:57:00 +0100 Subject: [PATCH 18/46] Remove always false check on state parameter --- src/Grant/ImplicitGrant.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index f23cc4e1d..a39bf0733 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -151,10 +151,6 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) $stateParameter = $this->getQueryStringParameter('state', $request); - if ($stateParameter !== null && !\is_string($stateParameter)) { - throw OAuthServerException::invalidRequest('state'); - } - $authorizationRequest = $this->createAuthorizationRequest(); $authorizationRequest->setGrantTypeId($this->getIdentifier()); $authorizationRequest->setClient($client); From 157c48a52183b1dc692dd17c70413cc8de3aad0b Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 4 May 2022 22:09:43 +0100 Subject: [PATCH 19/46] Remove exception catches that aren't thrown --- src/Middleware/AuthorizationServerMiddleware.php | 5 ----- src/Middleware/ResourceServerMiddleware.php | 5 ----- 2 files changed, 10 deletions(-) diff --git a/src/Middleware/AuthorizationServerMiddleware.php b/src/Middleware/AuthorizationServerMiddleware.php index 9b78b4585..f1a743af5 100644 --- a/src/Middleware/AuthorizationServerMiddleware.php +++ b/src/Middleware/AuthorizationServerMiddleware.php @@ -43,11 +43,6 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res $response = $this->server->respondToAccessTokenRequest($request, $response); } catch (OAuthServerException $exception) { return $exception->generateHttpResponse($response); - // @codeCoverageIgnoreStart - } catch (Exception $exception) { - return (new OAuthServerException($exception->getMessage(), 0, 'unknown_error', 500)) - ->generateHttpResponse($response); - // @codeCoverageIgnoreEnd } // Pass the request and response on to the next responder in the chain diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php index e152a9999..8a5103f3e 100644 --- a/src/Middleware/ResourceServerMiddleware.php +++ b/src/Middleware/ResourceServerMiddleware.php @@ -43,11 +43,6 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res $request = $this->server->validateAuthenticatedRequest($request); } catch (OAuthServerException $exception) { return $exception->generateHttpResponse($response); - // @codeCoverageIgnoreStart - } catch (Exception $exception) { - return (new OAuthServerException($exception->getMessage(), 0, 'unknown_error', 500)) - ->generateHttpResponse($response); - // @codeCoverageIgnoreEnd } // Pass the request and response on to the next responder in the chain From 2f214a4deb1160cc54c08d1960db8068e51eaed1 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 14 Nov 2022 19:24:03 +0000 Subject: [PATCH 20/46] Add ReturnTypeWillChange to jsonSerialize --- tests/Stubs/ScopeEntity.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Stubs/ScopeEntity.php b/tests/Stubs/ScopeEntity.php index 4e4a6bec5..4c93d91dc 100644 --- a/tests/Stubs/ScopeEntity.php +++ b/tests/Stubs/ScopeEntity.php @@ -9,6 +9,7 @@ class ScopeEntity implements ScopeEntityInterface { use EntityTrait; + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->getIdentifier(); From b3d8a74105af010ef35dbb7e3c7a2fbbb631f480 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 12:11:37 +0000 Subject: [PATCH 21/46] Fix tests by reverting phpstan changes --- src/Grant/AbstractGrant.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 0d5972d29..a03df5090 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -262,7 +262,7 @@ protected function getClientCredentials(ServerRequestInterface $request) $clientSecret = $this->getRequestParameter('client_secret', $request, $basicAuthPassword); - if ($clientSecret === null) { + if ($clientSecret !== null && !\is_string($clientSecret)) { throw OAuthServerException::invalidRequest('client_secret'); } @@ -303,10 +303,16 @@ protected function validateRedirectUri( */ public function validateScopes($scopes, $redirectUri = null) { - if (!\is_array($scopes)) { + if ($scopes === null) { + $scopes = []; + } elseif (\is_string($scopes)) { $scopes = $this->convertScopesQueryStringToArray($scopes); } + if (!\is_array($scopes)) { + throw OAuthServerException::invalidRequest('scope'); + } + $validScopes = []; foreach ($scopes as $scopeItem) { From f04eef8eb7bc05e0f25c7eae8d232dd8dba6f652 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 12:16:02 +0000 Subject: [PATCH 22/46] Fix types --- src/Grant/AbstractGrant.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index a03df5090..d13188c2a 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -294,8 +294,8 @@ protected function validateRedirectUri( /** * Validate scopes in the request. * - * @param string|array $scopes - * @param string $redirectUri + * @param null|string|array $scopes + * @param string $redirectUri * * @throws OAuthServerException * @@ -349,7 +349,7 @@ private function convertScopesQueryStringToArray(string $scopes) * @param ServerRequestInterface $request * @param mixed $default * - * @return null|string + * @return mixed */ protected function getRequestParameter($parameter, ServerRequestInterface $request, $default = null) { From 0e5d3dda5b679ea0a8fb44519965d753622295f5 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 14:15:39 +0000 Subject: [PATCH 23/46] Fix PHPStan errors --- src/RedirectUriValidators/RedirectUriValidator.php | 2 +- tests/Stubs/GrantType.php | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/RedirectUriValidators/RedirectUriValidator.php b/src/RedirectUriValidators/RedirectUriValidator.php index 29f763544..8723917f3 100644 --- a/src/RedirectUriValidators/RedirectUriValidator.php +++ b/src/RedirectUriValidators/RedirectUriValidator.php @@ -109,7 +109,7 @@ private function matchUriExcludingPort($redirectUri) * * @param string $url * - * @return array + * @return string */ private function parseUrlAndRemovePort($url) { diff --git a/tests/Stubs/GrantType.php b/tests/Stubs/GrantType.php index 5270a47a0..f419d9360 100644 --- a/tests/Stubs/GrantType.php +++ b/tests/Stubs/GrantType.php @@ -6,12 +6,14 @@ use DateInterval; use League\Event\EmitterInterface; -use League\OAuth2\Server\CryptKey; +use League\OAuth2\Server\CryptKeyInterface; use League\OAuth2\Server\Grant\GrantTypeInterface; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\RequestTypes\AuthorizationRequest; +use League\OAuth2\Server\RequestTypes\AuthorizationRequestInterface; +use League\OAuth2\Server\ResponseTypes\BearerTokenResponse; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use Psr\Http\Message\ServerRequestInterface; @@ -61,8 +63,9 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) return $authRequest; } - public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest) + public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest) { + return new BearerTokenResponse(); } public function canRespondToAccessTokenRequest(ServerRequestInterface $request) @@ -86,11 +89,15 @@ public function setDefaultScope($scope) { } - public function setPrivateKey(CryptKey $privateKey) + public function setPrivateKey(CryptKeyInterface $privateKey) { } public function setEncryptionKey($key = null) { } + + public function revokeRefreshTokens(bool $willRevoke) + { + } } From c4f493f6d8bec422ea252b0df4ca925bad9cbf90 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 15:20:28 +0000 Subject: [PATCH 24/46] Support PHPStan level 5 --- phpstan.neon.dist | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 32d859033..c54e4aa14 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,9 +1,10 @@ parameters: - level: 4 + level: 5 paths: - src - tests ignoreErrors: - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAccessToken\(\) should return League\\OAuth2\\Server\\Entities\\AccessTokenEntityInterface but return statement is missing\.#' - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAuthCode\(\) should return League\\OAuth2\\Server\\Entities\\AuthCodeEntityInterface but return statement is missing\.#' - - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueRefreshToken\(\) should return League\\OAuth2\\Server\\Entities\\RefreshTokenEntityInterface\|null but return statement is missing\.#' \ No newline at end of file + - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueRefreshToken\(\) should return League\\OAuth2\\Server\\Entities\\RefreshTokenEntityInterface\|null but return statement is missing\.#' + - '#Parameter \#1 \$contents of static method Lcobucci\\JWT\\Signer\\Key\\InMemory::plainText\(\) expects non-empty-string, string given\.#' From f67cfb63217338d87ef33bcd18f871b72620f1cb Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 15:57:31 +0000 Subject: [PATCH 25/46] Fix return types for CryptKeyTest and CryptTraitTest --- phpstan.neon.dist | 2 +- tests/Utils/CryptKeyTest.php | 12 ++++++------ tests/Utils/CryptTraitTest.php | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index c54e4aa14..3b729de80 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: 5 + level: 6 paths: - src - tests diff --git a/tests/Utils/CryptKeyTest.php b/tests/Utils/CryptKeyTest.php index 55808fc17..453d30dfa 100644 --- a/tests/Utils/CryptKeyTest.php +++ b/tests/Utils/CryptKeyTest.php @@ -7,14 +7,14 @@ class CryptKeyTest extends TestCase { - public function testNoFile() + public function testNoFile(): void { $this->expectException(\LogicException::class); new CryptKey('undefined file'); } - public function testKeyCreation() + public function testKeyCreation(): void { $keyFile = __DIR__ . '/../Stubs/public.key'; $key = new CryptKey($keyFile, 'secret'); @@ -23,7 +23,7 @@ public function testKeyCreation() $this->assertEquals('secret', $key->getPassPhrase()); } - public function testKeyString() + public function testKeyString(): void { $keyContent = \file_get_contents(__DIR__ . '/../Stubs/public.key'); @@ -52,7 +52,7 @@ public function testKeyString() ); } - public function testUnsupportedKeyType() + public function testUnsupportedKeyType(): void { $this->expectException(\LogicException::class); $this->expectExceptionMessage('Unable to read key'); @@ -76,7 +76,7 @@ public function testUnsupportedKeyType() } } - public function testECKeyType() + public function testECKeyType(): void { try { // Create the keypair @@ -97,7 +97,7 @@ public function testECKeyType() } } - public function testRSAKeyType() + public function testRSAKeyType(): void { try { // Create the keypair diff --git a/tests/Utils/CryptTraitTest.php b/tests/Utils/CryptTraitTest.php index a07d6d50c..912c4e568 100644 --- a/tests/Utils/CryptTraitTest.php +++ b/tests/Utils/CryptTraitTest.php @@ -8,28 +8,28 @@ class CryptTraitTest extends TestCase { - protected $cryptStub; + protected CryptTraitStub $cryptStub; protected function setUp(): void { $this->cryptStub = new CryptTraitStub(); } - public function testEncryptDecryptWithPassword() + public function testEncryptDecryptWithPassword(): void { $this->cryptStub->setEncryptionKey(\base64_encode(\random_bytes(36))); $this->encryptDecrypt(); } - public function testEncryptDecryptWithKey() + public function testEncryptDecryptWithKey(): void { $this->cryptStub->setEncryptionKey(Key::createNewRandomKey()); $this->encryptDecrypt(); } - private function encryptDecrypt() + private function encryptDecrypt(): void { $payload = 'alex loves whisky'; $encrypted = $this->cryptStub->doEncrypt($payload); From b2e680a4504788e7a7cd63ea1a356cdc46e1b3aa Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 18:32:09 +0000 Subject: [PATCH 26/46] Fix return types for StubResponseType --- tests/Stubs/StubResponseType.php | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/tests/Stubs/StubResponseType.php b/tests/Stubs/StubResponseType.php index 7aa71f67e..f04d44395 100644 --- a/tests/Stubs/StubResponseType.php +++ b/tests/Stubs/StubResponseType.php @@ -16,40 +16,30 @@ public function __construct() { } - public function getAccessToken() + public function getAccessToken(): AccessTokenEntityInterface { return $this->accessToken; } - public function getRefreshToken() + public function getRefreshToken(): RefreshTokenEntityInterface|null { return $this->refreshToken; } - /** - * @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessToken - */ - public function setAccessToken(AccessTokenEntityInterface $accessToken) + public function setAccessToken(AccessTokenEntityInterface $accessToken): void { $this->accessToken = $accessToken; } - /** - * @param \League\OAuth2\Server\Entities\RefreshTokenEntityInterface $refreshToken - */ - public function setRefreshToken(RefreshTokenEntityInterface $refreshToken) + public function setRefreshToken(RefreshTokenEntityInterface $refreshToken): void { $this->refreshToken = $refreshToken; } /** - * @param ServerRequestInterface $request - * * @throws \League\OAuth2\Server\Exception\OAuthServerException - * - * @return \Psr\Http\Message\ServerRequestInterface */ - public function validateAccessToken(ServerRequestInterface $request) + public function validateAccessToken(ServerRequestInterface $request): ServerRequestInterface { if ($request->getHeader('authorization')[0] === 'Basic test') { return $request->withAttribute('oauth_access_token_id', 'test'); @@ -58,12 +48,7 @@ public function validateAccessToken(ServerRequestInterface $request) throw OAuthServerException::accessDenied(); } - /** - * @param ResponseInterface $response - * - * @return ResponseInterface - */ - public function generateHttpResponse(ResponseInterface $response) + public function generateHttpResponse(ResponseInterface $response): ResponseInterface { return new Response(); } From 2d116206135d7658a48c17132bf22b777b7521d6 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 18:40:36 +0000 Subject: [PATCH 27/46] Add return types for stubs/GrantType --- tests/Stubs/GrantType.php | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/Stubs/GrantType.php b/tests/Stubs/GrantType.php index f419d9360..be1a5ab67 100644 --- a/tests/Stubs/GrantType.php +++ b/tests/Stubs/GrantType.php @@ -19,25 +19,25 @@ final class GrantType implements GrantTypeInterface { - private $emitter; + private EmitterInterface $emitter; - public function setEmitter(EmitterInterface $emitter = null) + public function setEmitter(EmitterInterface $emitter = null): self { $this->emitter = $emitter; return $this; } - public function getEmitter() + public function getEmitter(): EmitterInterface { return $this->emitter; } - public function setRefreshTokenTTL(DateInterval $refreshTokenTTL) + public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void { } - public function getIdentifier() + public function getIdentifier(): string { return 'grant_type_identifier'; } @@ -50,12 +50,12 @@ public function respondToAccessTokenRequest( return $responseType; } - public function canRespondToAuthorizationRequest(ServerRequestInterface $request) + public function canRespondToAuthorizationRequest(ServerRequestInterface $request): bool { return true; } - public function validateAuthorizationRequest(ServerRequestInterface $request) + public function validateAuthorizationRequest(ServerRequestInterface $request): AuthorizationRequest { $authRequest = new AuthorizationRequest(); $authRequest->setGrantTypeId(self::class); @@ -63,41 +63,41 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) return $authRequest; } - public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest) + public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest): BearerTokenResponse { return new BearerTokenResponse(); } - public function canRespondToAccessTokenRequest(ServerRequestInterface $request) + public function canRespondToAccessTokenRequest(ServerRequestInterface $request): bool { return true; } - public function setClientRepository(ClientRepositoryInterface $clientRepository) + public function setClientRepository(ClientRepositoryInterface $clientRepository): void { } - public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository) + public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository): void { } - public function setScopeRepository(ScopeRepositoryInterface $scopeRepository) + public function setScopeRepository(ScopeRepositoryInterface $scopeRepository): void { } - public function setDefaultScope($scope) + public function setDefaultScope($scope): void { } - public function setPrivateKey(CryptKeyInterface $privateKey) + public function setPrivateKey(CryptKeyInterface $privateKey): void { } - public function setEncryptionKey($key = null) + public function setEncryptionKey($key = null): void { } - public function revokeRefreshTokens(bool $willRevoke) + public function revokeRefreshTokens(bool $willRevoke): void { } } From b5ebfd62733741dabbf20389c9538abda72fb1d3 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 19:34:20 +0000 Subject: [PATCH 28/46] Fix types for stubs/CryptTraitStub --- tests/Stubs/CryptTraitStub.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/Stubs/CryptTraitStub.php b/tests/Stubs/CryptTraitStub.php index d4d8f1c68..faaaa27f3 100644 --- a/tests/Stubs/CryptTraitStub.php +++ b/tests/Stubs/CryptTraitStub.php @@ -2,6 +2,7 @@ namespace LeagueTests\Stubs; +use Defuse\Crypto\Key; use League\OAuth2\Server\CryptTrait; class CryptTraitStub @@ -13,17 +14,17 @@ public function __construct() $this->setEncryptionKey(\base64_encode(\random_bytes(36))); } - public function getKey() + public function getKey(): string|Key|null { return $this->encryptionKey; } - public function doEncrypt($unencryptedData) + public function doEncrypt(string $unencryptedData): string { return $this->encrypt($unencryptedData); } - public function doDecrypt($encryptedData) + public function doDecrypt(string $encryptedData): string { return $this->decrypt($encryptedData); } From 840d350ff81062c29282b1146b8334b5332869be Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 20:00:04 +0000 Subject: [PATCH 29/46] Set types in stubs/ClientEntity --- tests/Stubs/ClientEntity.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Stubs/ClientEntity.php b/tests/Stubs/ClientEntity.php index d908248ba..7d8c1a243 100644 --- a/tests/Stubs/ClientEntity.php +++ b/tests/Stubs/ClientEntity.php @@ -10,12 +10,12 @@ class ClientEntity implements ClientEntityInterface { use EntityTrait, ClientTrait; - public function setRedirectUri($uri) + public function setRedirectUri(string|array $uri): void { $this->redirectUri = $uri; } - public function setConfidential() + public function setConfidential(): void { $this->isConfidential = true; } From 4244acc1bccb1edfc445d5ceb5e09405960ba6dc Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 20:07:01 +0000 Subject: [PATCH 30/46] Fix array type for PHPStan --- tests/ResponseTypes/BearerTokenResponseWithParams.php | 6 +++++- tests/Stubs/ClientEntity.php | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/ResponseTypes/BearerTokenResponseWithParams.php b/tests/ResponseTypes/BearerTokenResponseWithParams.php index 4ba09f4b9..71c1665b2 100644 --- a/tests/ResponseTypes/BearerTokenResponseWithParams.php +++ b/tests/ResponseTypes/BearerTokenResponseWithParams.php @@ -7,7 +7,11 @@ class BearerTokenResponseWithParams extends BearerTokenResponse { - protected function getExtraParams(AccessTokenEntityInterface $accessToken) + + /** + * @return array + */ + protected function getExtraParams(AccessTokenEntityInterface $accessToken): array { return ['foo' => 'bar', 'token_type' => 'Should not overwrite']; } diff --git a/tests/Stubs/ClientEntity.php b/tests/Stubs/ClientEntity.php index 7d8c1a243..c77ca136b 100644 --- a/tests/Stubs/ClientEntity.php +++ b/tests/Stubs/ClientEntity.php @@ -10,6 +10,9 @@ class ClientEntity implements ClientEntityInterface { use EntityTrait, ClientTrait; + /** + * @param string|string[] $uri + */ public function setRedirectUri(string|array $uri): void { $this->redirectUri = $uri; From ddd6a304d4a43d62260ea25f2587181f75c4b23a Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 20:18:59 +0000 Subject: [PATCH 31/46] Add return types for tests --- tests/ResourceServerTest.php | 2 +- tests/ResponseTypes/BearerResponseTypeTest.php | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/ResourceServerTest.php b/tests/ResourceServerTest.php index 7281070e2..cd622c488 100644 --- a/tests/ResourceServerTest.php +++ b/tests/ResourceServerTest.php @@ -11,7 +11,7 @@ class ResourceServerTest extends TestCase { - public function testValidateAuthenticatedRequest() + public function testValidateAuthenticatedRequest(): void { $server = new ResourceServer( $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index da7242651..7b7c85fa1 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -20,7 +20,7 @@ class BearerResponseTypeTest extends TestCase { - public function testGenerateHttpResponse() + public function testGenerateHttpResponse(): void { $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); @@ -63,7 +63,7 @@ public function testGenerateHttpResponse() $this->assertObjectHasAttribute('refresh_token', $json); } - public function testGenerateHttpResponseWithExtraParams() + public function testGenerateHttpResponseWithExtraParams(): void { $responseType = new BearerTokenResponseWithParams(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); @@ -109,7 +109,7 @@ public function testGenerateHttpResponseWithExtraParams() $this->assertEquals('bar', $json->foo); } - public function testDetermineAccessTokenInHeaderValidToken() + public function testDetermineAccessTokenInHeaderValidToken(): void { $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); @@ -152,7 +152,7 @@ public function testDetermineAccessTokenInHeaderValidToken() $this->assertEquals([], $request->getAttribute('oauth_scopes')); } - public function testDetermineAccessTokenInHeaderInvalidJWT() + public function testDetermineAccessTokenInHeaderInvalidJWT(): void { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); @@ -196,7 +196,7 @@ public function testDetermineAccessTokenInHeaderInvalidJWT() } } - public function testDetermineAccessTokenInHeaderRevokedToken() + public function testDetermineAccessTokenInHeaderRevokedToken(): void { $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); @@ -241,7 +241,7 @@ public function testDetermineAccessTokenInHeaderRevokedToken() } } - public function testDetermineAccessTokenInHeaderInvalidToken() + public function testDetermineAccessTokenInHeaderInvalidToken(): void { $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); @@ -264,7 +264,7 @@ public function testDetermineAccessTokenInHeaderInvalidToken() } } - public function testDetermineMissingBearerInHeader() + public function testDetermineMissingBearerInHeader(): void { $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); From bf8b73a464fb3989fa8bd26c26011242c8179b7a Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 20:22:00 +0000 Subject: [PATCH 32/46] Add return types for tests --- .../RedirectUriValidatorTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/RedirectUriValidators/RedirectUriValidatorTest.php b/tests/RedirectUriValidators/RedirectUriValidatorTest.php index 2f297c264..11e7a07e4 100644 --- a/tests/RedirectUriValidators/RedirectUriValidatorTest.php +++ b/tests/RedirectUriValidators/RedirectUriValidatorTest.php @@ -7,7 +7,7 @@ class RedirectUriValidatorTest extends TestCase { - public function testInvalidNonLoopbackUri() + public function testInvalidNonLoopbackUri(): void { $validator = new RedirectUriValidator([ 'https://example.com:8443/endpoint', @@ -22,7 +22,7 @@ public function testInvalidNonLoopbackUri() ); } - public function testValidNonLoopbackUri() + public function testValidNonLoopbackUri(): void { $validator = new RedirectUriValidator([ 'https://example.com:8443/endpoint', @@ -37,7 +37,7 @@ public function testValidNonLoopbackUri() ); } - public function testInvalidLoopbackUri() + public function testInvalidLoopbackUri(): void { $validator = new RedirectUriValidator('http://127.0.0.1:8443/endpoint'); @@ -49,7 +49,7 @@ public function testInvalidLoopbackUri() ); } - public function testValidLoopbackUri() + public function testValidLoopbackUri(): void { $validator = new RedirectUriValidator('http://127.0.0.1:8443/endpoint'); @@ -61,7 +61,7 @@ public function testValidLoopbackUri() ); } - public function testValidIpv6LoopbackUri() + public function testValidIpv6LoopbackUri(): void { $validator = new RedirectUriValidator('http://[::1]:8443/endpoint'); @@ -73,7 +73,7 @@ public function testValidIpv6LoopbackUri() ); } - public function testCanValidateUrn() + public function testCanValidateUrn(): void { $validator = new RedirectUriValidator('urn:ietf:wg:oauth:2.0:oob'); @@ -83,7 +83,7 @@ public function testCanValidateUrn() ); } - public function canValidateCustomSchemeHost() + public function canValidateCustomSchemeHost(): void { $validator = new RedirectUriValidator('msal://redirect'); @@ -93,7 +93,7 @@ public function canValidateCustomSchemeHost() ); } - public function canValidateCustomSchemePath() + public function canValidateCustomSchemePath(): void { $validator = new RedirectUriValidator('com.example.app:/oauth2redirect/example-provider'); From f3007f99f3d095f69b274caed51814a57cfd3649 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 15 Nov 2022 20:23:05 +0000 Subject: [PATCH 33/46] Add return types for tests --- tests/Middleware/ResourceServerMiddlewareTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Middleware/ResourceServerMiddlewareTest.php b/tests/Middleware/ResourceServerMiddlewareTest.php index 106111885..994d5b5d2 100644 --- a/tests/Middleware/ResourceServerMiddlewareTest.php +++ b/tests/Middleware/ResourceServerMiddlewareTest.php @@ -16,7 +16,7 @@ class ResourceServerMiddlewareTest extends TestCase { - public function testValidResponse() + public function testValidResponse(): void { $server = new ResourceServer( $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), @@ -51,7 +51,7 @@ function () { $this->assertEquals(200, $response->getStatusCode()); } - public function testValidResponseExpiredToken() + public function testValidResponseExpiredToken(): void { $server = new ResourceServer( $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), @@ -86,7 +86,7 @@ function () { $this->assertEquals(401, $response->getStatusCode()); } - public function testErrorResponse() + public function testErrorResponse(): void { $server = new ResourceServer( $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), From bca5d67f6f5e44935dd1f96e507571cf4e6ec60e Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Fri, 2 Dec 2022 12:00:23 +0000 Subject: [PATCH 34/46] Add types to satisfy phpstan --- src/CryptTrait.php | 7 +- src/Grant/GrantTypeInterface.php | 7 +- .../RedirectUriValidator.php | 8 +- .../AccessTokenRepositoryInterface.php | 28 ++---- .../AuthCodeRepositoryInterface.php | 29 +----- .../RefreshTokenRepositoryInterface.php | 29 +----- src/RequestTypes/AuthorizationRequest.php | 84 ++++------------ .../AuthorizationRequestInterface.php | 84 ++++------------ src/ResponseTypes/AbstractResponseType.php | 17 +--- src/ResponseTypes/BearerTokenResponse.php | 11 +-- src/ResponseTypes/RedirectResponse.php | 17 +--- src/ResponseTypes/ResponseTypeInterface.php | 24 +---- tests/AuthorizationServerTest.php | 23 +++-- .../BearerTokenValidatorTest.php | 4 +- .../PlainVerifierTest.php | 4 +- .../S256VerifierTest.php | 8 +- tests/Exception/OAuthServerExceptionTest.php | 23 ++--- tests/Grant/AbstractGrantTest.php | 56 +++++------ tests/Grant/AuthCodeGrantTest.php | 98 ++++++++++--------- tests/Grant/ClientCredentialsGrantTest.php | 4 +- tests/Grant/ImplicitGrantTest.php | 41 ++++---- tests/Grant/PasswordGrantTest.php | 12 +-- tests/Grant/RefreshTokenGrantTest.php | 26 ++--- .../AuthorizationServerMiddlewareTest.php | 8 +- tests/Stubs/GrantType.php | 3 +- 25 files changed, 225 insertions(+), 430 deletions(-) diff --git a/src/CryptTrait.php b/src/CryptTrait.php index a17e69709..9b746dc9f 100644 --- a/src/CryptTrait.php +++ b/src/CryptTrait.php @@ -75,12 +75,7 @@ protected function decrypt($encryptedData) } } - /** - * Set the encryption key - * - * @param string|Key $key - */ - public function setEncryptionKey($key = null) + public function setEncryptionKey(Key|string|null $key = null): void { $this->encryptionKey = $key; } diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index 9f66639c0..d7e003835 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -135,12 +135,7 @@ public function setDefaultScope($scope); */ public function setPrivateKey(CryptKeyInterface $privateKey); - /** - * Set the encryption key - * - * @param string|Key|null $key - */ - public function setEncryptionKey($key = null); + public function setEncryptionKey(Key|string|null $key = null): void; /** * Enable or prevent the revocation of refresh tokens upon usage. diff --git a/src/RedirectUriValidators/RedirectUriValidator.php b/src/RedirectUriValidators/RedirectUriValidator.php index 8723917f3..3efa356d3 100644 --- a/src/RedirectUriValidators/RedirectUriValidator.php +++ b/src/RedirectUriValidators/RedirectUriValidator.php @@ -15,16 +15,16 @@ class RedirectUriValidator implements RedirectUriValidatorInterface { /** - * @var array + * @var string[] */ - private $allowedRedirectUris; + private array $allowedRedirectUris; /** * New validator instance for the given uri * - * @param string|array $allowedRedirectUris + * @param string[]|string $allowedRedirectUris */ - public function __construct($allowedRedirectUris) + public function __construct(array|string $allowedRedirectUris) { if (\is_string($allowedRedirectUris)) { $this->allowedRedirectUris = [$allowedRedirectUris]; diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index 72ddf1f4c..fb1c967ce 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -22,36 +22,22 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface /** * Create a new access token * - * @param ClientEntityInterface $clientEntity * @param ScopeEntityInterface[] $scopes * @param mixed $userIdentifier * * @return AccessTokenEntityInterface */ - public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null); + public function getNewToken( + ClientEntityInterface $clientEntity, + array $scopes, $userIdentifier = null + ): AccessTokenEntityInterface; /** - * Persists a new access token to permanent storage. - * - * @param AccessTokenEntityInterface $accessTokenEntity - * * @throws UniqueTokenIdentifierConstraintViolationException */ - public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity); + public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity): void; - /** - * Revoke an access token. - * - * @param string $tokenId - */ - public function revokeAccessToken($tokenId); + public function revokeAccessToken(string $tokenId): void; - /** - * Check if the access token has been revoked. - * - * @param string $tokenId - * - * @return bool Return true if this token has been revoked - */ - public function isAccessTokenRevoked($tokenId); + public function isAccessTokenRevoked(string $tokenId): bool; } diff --git a/src/Repositories/AuthCodeRepositoryInterface.php b/src/Repositories/AuthCodeRepositoryInterface.php index 2dc285b83..64954aaf5 100644 --- a/src/Repositories/AuthCodeRepositoryInterface.php +++ b/src/Repositories/AuthCodeRepositoryInterface.php @@ -17,35 +17,14 @@ */ interface AuthCodeRepositoryInterface extends RepositoryInterface { - /** - * Creates a new AuthCode - * - * @return AuthCodeEntityInterface - */ - public function getNewAuthCode(); + public function getNewAuthCode(): AuthCodeEntityInterface; /** - * Persists a new auth code to permanent storage. - * - * @param AuthCodeEntityInterface $authCodeEntity - * * @throws UniqueTokenIdentifierConstraintViolationException */ - public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity); + public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity): void; - /** - * Revoke an auth code. - * - * @param string $codeId - */ - public function revokeAuthCode($codeId); + public function revokeAuthCode(string $codeId): void; - /** - * Check if the auth code has been revoked. - * - * @param string $codeId - * - * @return bool Return true if this code has been revoked - */ - public function isAuthCodeRevoked($codeId); + public function isAuthCodeRevoked(string $codeId): bool; } diff --git a/src/Repositories/RefreshTokenRepositoryInterface.php b/src/Repositories/RefreshTokenRepositoryInterface.php index a769cf6d3..106a2ef7d 100644 --- a/src/Repositories/RefreshTokenRepositoryInterface.php +++ b/src/Repositories/RefreshTokenRepositoryInterface.php @@ -17,35 +17,14 @@ */ interface RefreshTokenRepositoryInterface extends RepositoryInterface { - /** - * Creates a new refresh token - * - * @return RefreshTokenEntityInterface|null - */ - public function getNewRefreshToken(); + public function getNewRefreshToken(): ?RefreshTokenEntityInterface; /** - * Create a new refresh token_name. - * - * @param RefreshTokenEntityInterface $refreshTokenEntity - * * @throws UniqueTokenIdentifierConstraintViolationException */ - public function persistNewRefreshToken(RefreshTokenEntityInterface $refreshTokenEntity); + public function persistNewRefreshToken(RefreshTokenEntityInterface $refreshTokenEntity): void; - /** - * Revoke the refresh token. - * - * @param string $tokenId - */ - public function revokeRefreshToken($tokenId); + public function revokeRefreshToken(string $tokenId): void; - /** - * Check if the refresh token has been revoked. - * - * @param string $tokenId - * - * @return bool Return true if this token has been revoked - */ - public function isRefreshTokenRevoked($tokenId); + public function isRefreshTokenRevoked(string $tokenId): bool; } diff --git a/src/RequestTypes/AuthorizationRequest.php b/src/RequestTypes/AuthorizationRequest.php index d05e5b394..f9460d0f5 100644 --- a/src/RequestTypes/AuthorizationRequest.php +++ b/src/RequestTypes/AuthorizationRequest.php @@ -78,50 +78,32 @@ class AuthorizationRequest implements AuthorizationRequestInterface */ protected $codeChallengeMethod; - /** - * @return string - */ - public function getGrantTypeId() + public function getGrantTypeId(): string { return $this->grantTypeId; } - /** - * @param string $grantTypeId - */ - public function setGrantTypeId($grantTypeId) + public function setGrantTypeId(string $grantTypeId): void { $this->grantTypeId = $grantTypeId; } - /** - * @return ClientEntityInterface - */ - public function getClient() + public function getClient(): ClientEntityInterface { return $this->client; } - /** - * @param ClientEntityInterface $client - */ - public function setClient(ClientEntityInterface $client) + public function setClient(ClientEntityInterface $client): void { $this->client = $client; } - /** - * @return UserEntityInterface|null - */ - public function getUser() + public function getUser(): ?UserEntityInterface { return $this->user; } - /** - * @param UserEntityInterface $user - */ - public function setUser(UserEntityInterface $user) + public function setUser(UserEntityInterface $user): void { $this->user = $user; } @@ -129,7 +111,7 @@ public function setUser(UserEntityInterface $user) /** * @return ScopeEntityInterface[] */ - public function getScopes() + public function getScopes(): array { return $this->scopes; } @@ -137,87 +119,57 @@ public function getScopes() /** * @param ScopeEntityInterface[] $scopes */ - public function setScopes(array $scopes) + public function setScopes(array $scopes): void { $this->scopes = $scopes; } - /** - * @return bool - */ - public function isAuthorizationApproved() + public function isAuthorizationApproved(): bool { return $this->authorizationApproved; } - /** - * @param bool $authorizationApproved - */ - public function setAuthorizationApproved($authorizationApproved) + public function setAuthorizationApproved(bool $authorizationApproved): void { $this->authorizationApproved = $authorizationApproved; } - /** - * @return string|null - */ - public function getRedirectUri() + public function getRedirectUri(): ?string { return $this->redirectUri; } - /** - * @param string|null $redirectUri - */ - public function setRedirectUri($redirectUri) + public function setRedirectUri(?string $redirectUri): void { $this->redirectUri = $redirectUri; } - /** - * @return string|null - */ - public function getState() + public function getState(): ?string { return $this->state; } - /** - * @param string $state - */ - public function setState($state) + public function setState(string $state): void { $this->state = $state; } - /** - * @return string - */ - public function getCodeChallenge() + public function getCodeChallenge(): ?string { return $this->codeChallenge; } - /** - * @param string $codeChallenge - */ - public function setCodeChallenge($codeChallenge) + public function setCodeChallenge(string $codeChallenge): void { $this->codeChallenge = $codeChallenge; } - /** - * @return string - */ - public function getCodeChallengeMethod() + public function getCodeChallengeMethod(): ?string { return $this->codeChallengeMethod; } - /** - * @param string $codeChallengeMethod - */ - public function setCodeChallengeMethod($codeChallengeMethod) + public function setCodeChallengeMethod(string $codeChallengeMethod): void { $this->codeChallengeMethod = $codeChallengeMethod; } diff --git a/src/RequestTypes/AuthorizationRequestInterface.php b/src/RequestTypes/AuthorizationRequestInterface.php index 869dc1ea2..10ea08ace 100644 --- a/src/RequestTypes/AuthorizationRequestInterface.php +++ b/src/RequestTypes/AuthorizationRequestInterface.php @@ -15,93 +15,45 @@ interface AuthorizationRequestInterface { - /** - * @return UserEntityInterface|null - */ - public function getUser(); + public function getUser(): UserEntityInterface|null; - /** - * @param string $state - */ - public function setState($state); + public function setState(string $state): void; - /** - * @return ClientEntityInterface - */ - public function getClient(); + public function getClient(): ClientEntityInterface; - /** - * @param bool $authorizationApproved - */ - public function setAuthorizationApproved($authorizationApproved); + public function setAuthorizationApproved(bool $authorizationApproved): void; /** * @param ScopeEntityInterface[] $scopes */ - public function setScopes(array $scopes); + public function setScopes(array $scopes): void; - /** - * @param string|null $redirectUri - */ - public function setRedirectUri($redirectUri); + public function setRedirectUri(?string $redirectUri): void; - /** - * @return string|null - */ - public function getRedirectUri(); + public function getRedirectUri(): ?string; - /** - * @return string - */ - public function getCodeChallengeMethod(); + public function getCodeChallengeMethod(): ?string; - /** - * @param string $grantTypeId - */ - public function setGrantTypeId($grantTypeId); + public function setGrantTypeId(string $grantTypeId): void; - /** - * @param UserEntityInterface $user - */ - public function setUser(UserEntityInterface $user); + public function setUser(UserEntityInterface $user): void; - /** - * @param ClientEntityInterface $client - */ - public function setClient(ClientEntityInterface $client); + public function setClient(ClientEntityInterface $client): void; - /** - * @param string $codeChallenge - */ - public function setCodeChallenge($codeChallenge); + public function setCodeChallenge(string $codeChallenge): void; - /** - * @return bool - */ - public function isAuthorizationApproved(); + public function isAuthorizationApproved(): bool; - /** - * @return string|null - */ - public function getState(); + public function getState(): ?string; - /** - * @return string - */ - public function getCodeChallenge(); + public function getCodeChallenge(): ?string; - /** - * @param string $codeChallengeMethod - */ - public function setCodeChallengeMethod($codeChallengeMethod); + public function setCodeChallengeMethod(string $codeChallengeMethod): void; /** * @return ScopeEntityInterface[] */ - public function getScopes(); + public function getScopes(): array; - /** - * @return string - */ - public function getGrantTypeId(); + public function getGrantTypeId(): string; } diff --git a/src/ResponseTypes/AbstractResponseType.php b/src/ResponseTypes/AbstractResponseType.php index f5f201908..dd2c15041 100644 --- a/src/ResponseTypes/AbstractResponseType.php +++ b/src/ResponseTypes/AbstractResponseType.php @@ -35,28 +35,17 @@ abstract class AbstractResponseType implements ResponseTypeInterface */ protected $privateKey; - /** - * {@inheritdoc} - */ - public function setAccessToken(AccessTokenEntityInterface $accessToken) + public function setAccessToken(AccessTokenEntityInterface $accessToken): void { $this->accessToken = $accessToken; } - /** - * {@inheritdoc} - */ - public function setRefreshToken(RefreshTokenEntityInterface $refreshToken) + public function setRefreshToken(RefreshTokenEntityInterface $refreshToken): void { $this->refreshToken = $refreshToken; } - /** - * Set the private key - * - * @param CryptKeyInterface $key - */ - public function setPrivateKey(CryptKeyInterface $key) + public function setPrivateKey(CryptKeyInterface $key): void { $this->privateKey = $key; } diff --git a/src/ResponseTypes/BearerTokenResponse.php b/src/ResponseTypes/BearerTokenResponse.php index 33c1606e8..c06216346 100644 --- a/src/ResponseTypes/BearerTokenResponse.php +++ b/src/ResponseTypes/BearerTokenResponse.php @@ -18,10 +18,7 @@ class BearerTokenResponse extends AbstractResponseType { - /** - * {@inheritdoc} - */ - public function generateHttpResponse(ResponseInterface $response) + public function generateHttpResponse(ResponseInterface $response): ResponseInterface { $expireDateTime = $this->accessToken->getExpiryDateTime()->getTimestamp(); @@ -70,11 +67,9 @@ public function generateHttpResponse(ResponseInterface $response) * AuthorizationServer::getResponseType() to pull in your version of * this class rather than the default. * - * @param AccessTokenEntityInterface $accessToken - * - * @return array + * @return mixed[] */ - protected function getExtraParams(AccessTokenEntityInterface $accessToken) + protected function getExtraParams(AccessTokenEntityInterface $accessToken): array { return []; } diff --git a/src/ResponseTypes/RedirectResponse.php b/src/ResponseTypes/RedirectResponse.php index e4639148d..2006a8f0d 100644 --- a/src/ResponseTypes/RedirectResponse.php +++ b/src/ResponseTypes/RedirectResponse.php @@ -15,25 +15,14 @@ class RedirectResponse extends AbstractResponseType { - /** - * @var string - */ - private $redirectUri; + private string $redirectUri; - /** - * @param string $redirectUri - */ - public function setRedirectUri($redirectUri) + public function setRedirectUri(string $redirectUri): void { $this->redirectUri = $redirectUri; } - /** - * @param ResponseInterface $response - * - * @return ResponseInterface - */ - public function generateHttpResponse(ResponseInterface $response) + public function generateHttpResponse(ResponseInterface $response): ResponseInterface { return $response->withStatus(302)->withHeader('Location', $this->redirectUri); } diff --git a/src/ResponseTypes/ResponseTypeInterface.php b/src/ResponseTypes/ResponseTypeInterface.php index 5eddd6079..71efba5e8 100644 --- a/src/ResponseTypes/ResponseTypeInterface.php +++ b/src/ResponseTypes/ResponseTypeInterface.php @@ -18,27 +18,11 @@ interface ResponseTypeInterface { - /** - * @param AccessTokenEntityInterface $accessToken - */ - public function setAccessToken(AccessTokenEntityInterface $accessToken); + public function setAccessToken(AccessTokenEntityInterface $accessToken): void; - /** - * @param RefreshTokenEntityInterface $refreshToken - */ - public function setRefreshToken(RefreshTokenEntityInterface $refreshToken); + public function setRefreshToken(RefreshTokenEntityInterface $refreshToken): void; - /** - * @param ResponseInterface $response - * - * @return ResponseInterface - */ - public function generateHttpResponse(ResponseInterface $response); + public function generateHttpResponse(ResponseInterface $response): ResponseInterface; - /** - * Set the encryption key - * - * @param string|Key|null $key - */ - public function setEncryptionKey($key = null); + public function setEncryptionKey(Key|string|null $key = null): void; } diff --git a/tests/AuthorizationServerTest.php b/tests/AuthorizationServerTest.php index ff395cdbe..e49e8ac1a 100644 --- a/tests/AuthorizationServerTest.php +++ b/tests/AuthorizationServerTest.php @@ -60,7 +60,7 @@ public function testGrantTypeGetsEnabled() } */ - public function testRespondToRequestInvalidGrantType() + public function testRespondToRequestInvalidGrantType(): void { $server = new AuthorizationServer( $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(), @@ -81,7 +81,7 @@ public function testRespondToRequestInvalidGrantType() } } - public function testRespondToRequest() + public function testRespondToRequest(): void { $client = new ClientEntity(); @@ -118,7 +118,7 @@ public function testRespondToRequest() $this->assertEquals(200, $response->getStatusCode()); } - public function testGetResponseType() + public function testGetResponseType(): void { $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); @@ -137,7 +137,7 @@ public function testGetResponseType() $this->assertInstanceOf(BearerTokenResponse::class, $method->invoke($server)); } - public function testGetResponseTypeExtended() + public function testGetResponseTypeExtended(): void { $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $privateKey = 'file://' . __DIR__ . '/Stubs/private.key'; @@ -170,19 +170,18 @@ public function testGetResponseTypeExtended() $this->assertSame($encryptionKey, $encryptionKeyProperty->getValue($responseType)); } - public function testMultipleRequestsGetDifferentResponseTypeInstances() + public function testMultipleRequestsGetDifferentResponseTypeInstances(): void { $privateKey = 'file://' . __DIR__ . '/Stubs/private.key'; $encryptionKey = 'file://' . __DIR__ . '/Stubs/public.key'; $responseTypePrototype = new class extends BearerTokenResponse { - /* @return null|CryptKeyInterface */ - public function getPrivateKey() + public function getPrivateKey(): CryptKeyInterface|null { return $this->privateKey; } - public function getEncryptionKey() + public function getEncryptionKey(): string|null { return $this->encryptionKey; } @@ -222,7 +221,7 @@ public function getEncryptionKey() $this->assertNotSame($responseTypeA, $responseTypeB); } - public function testCompleteAuthorizationRequest() + public function testCompleteAuthorizationRequest(): void { $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); @@ -257,7 +256,7 @@ public function testCompleteAuthorizationRequest() ); } - public function testValidateAuthorizationRequest() + public function testValidateAuthorizationRequest(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -304,7 +303,7 @@ public function testValidateAuthorizationRequest() $this->assertInstanceOf(AuthorizationRequest::class, $server->validateAuthorizationRequest($request)); } - public function testValidateAuthorizationRequestWithMissingRedirectUri() + public function testValidateAuthorizationRequestWithMissingRedirectUri(): void { $client = new ClientEntity(); $client->setConfidential(); @@ -350,7 +349,7 @@ public function testValidateAuthorizationRequestWithMissingRedirectUri() } } - public function testValidateAuthorizationRequestUnregistered() + public function testValidateAuthorizationRequestUnregistered(): void { $server = new AuthorizationServer( $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(), diff --git a/tests/AuthorizationValidators/BearerTokenValidatorTest.php b/tests/AuthorizationValidators/BearerTokenValidatorTest.php index 838d2bbae..51ab8ecba 100644 --- a/tests/AuthorizationValidators/BearerTokenValidatorTest.php +++ b/tests/AuthorizationValidators/BearerTokenValidatorTest.php @@ -15,7 +15,7 @@ class BearerTokenValidatorTest extends TestCase { - public function testBearerTokenValidatorAcceptsValidToken() + public function testBearerTokenValidatorAcceptsValidToken(): void { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); @@ -43,7 +43,7 @@ public function testBearerTokenValidatorAcceptsValidToken() $this->assertArrayHasKey('authorization', $validRequest->getHeaders()); } - public function testBearerTokenValidatorRejectsExpiredToken() + public function testBearerTokenValidatorRejectsExpiredToken(): void { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); diff --git a/tests/CodeChallengeVerifiers/PlainVerifierTest.php b/tests/CodeChallengeVerifiers/PlainVerifierTest.php index 437c0c2f6..62d3da2c7 100644 --- a/tests/CodeChallengeVerifiers/PlainVerifierTest.php +++ b/tests/CodeChallengeVerifiers/PlainVerifierTest.php @@ -7,14 +7,14 @@ class PlainVerifierTest extends TestCase { - public function testGetMethod() + public function testGetMethod(): void { $verifier = new PlainVerifier(); $this->assertEquals('plain', $verifier->getMethod()); } - public function testVerifyCodeChallenge() + public function testVerifyCodeChallenge(): void { $verifier = new PlainVerifier(); diff --git a/tests/CodeChallengeVerifiers/S256VerifierTest.php b/tests/CodeChallengeVerifiers/S256VerifierTest.php index 58185a452..14ef1957f 100644 --- a/tests/CodeChallengeVerifiers/S256VerifierTest.php +++ b/tests/CodeChallengeVerifiers/S256VerifierTest.php @@ -7,14 +7,14 @@ class S256VerifierTest extends TestCase { - public function testGetMethod() + public function testGetMethod(): void { $verifier = new S256Verifier(); $this->assertEquals('S256', $verifier->getMethod()); } - public function testVerifyCodeChallengeSucceeds() + public function testVerifyCodeChallengeSucceeds(): void { $codeChallenge = $this->createCodeChallenge('foo'); $verifier = new S256Verifier(); @@ -22,7 +22,7 @@ public function testVerifyCodeChallengeSucceeds() $this->assertTrue($verifier->verifyCodeChallenge('foo', $codeChallenge)); } - public function testVerifyCodeChallengeFails() + public function testVerifyCodeChallengeFails(): void { $codeChallenge = $this->createCodeChallenge('bar'); $verifier = new S256Verifier(); @@ -30,7 +30,7 @@ public function testVerifyCodeChallengeFails() $this->assertFalse($verifier->verifyCodeChallenge('foo', $codeChallenge)); } - private function createCodeChallenge($codeVerifier) + private function createCodeChallenge(string $codeVerifier): string { return \strtr(\rtrim(\base64_encode(\hash('sha256', $codeVerifier, true)), '='), '+/', '-_'); } diff --git a/tests/Exception/OAuthServerExceptionTest.php b/tests/Exception/OAuthServerExceptionTest.php index 38b86d433..d0d6641b6 100644 --- a/tests/Exception/OAuthServerExceptionTest.php +++ b/tests/Exception/OAuthServerExceptionTest.php @@ -9,10 +9,11 @@ use League\OAuth2\Server\Grant\AbstractGrant; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ServerRequestInterface; class OAuthServerExceptionTest extends TestCase { - public function testInvalidClientExceptionSetsAuthenticateHeader() + public function testInvalidClientExceptionSetsAuthenticateHeader(): void { $serverRequest = (new ServerRequest()) ->withParsedBody([ @@ -29,7 +30,7 @@ public function testInvalidClientExceptionSetsAuthenticateHeader() } } - public function testInvalidClientExceptionSetsBearerAuthenticateHeader() + public function testInvalidClientExceptionSetsBearerAuthenticateHeader(): void { $serverRequest = (new ServerRequest()) ->withParsedBody([ @@ -46,7 +47,7 @@ public function testInvalidClientExceptionSetsBearerAuthenticateHeader() } } - public function testInvalidClientExceptionOmitsAuthenticateHeader() + public function testInvalidClientExceptionOmitsAuthenticateHeader(): void { $serverRequest = (new ServerRequest()) ->withParsedBody([ @@ -62,7 +63,7 @@ public function testInvalidClientExceptionOmitsAuthenticateHeader() } } - public function testInvalidClientExceptionOmitsAuthenticateHeaderGivenEmptyAuthorizationHeader() + public function testInvalidClientExceptionOmitsAuthenticateHeaderGivenEmptyAuthorizationHeader(): void { $serverRequest = (new ServerRequest()) ->withParsedBody([ @@ -84,7 +85,7 @@ public function testInvalidClientExceptionOmitsAuthenticateHeaderGivenEmptyAutho * * @throws OAuthServerException */ - private function issueInvalidClientException($serverRequest) + private function issueInvalidClientException(ServerRequestInterface $serverRequest): void { $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('validateClient')->willReturn(false); @@ -100,21 +101,21 @@ private function issueInvalidClientException($serverRequest) $validateClientMethod->invoke($grantMock, $serverRequest); } - public function testHasRedirect() + public function testHasRedirect(): void { $exceptionWithRedirect = OAuthServerException::accessDenied('some hint', 'https://example.com/error'); $this->assertTrue($exceptionWithRedirect->hasRedirect()); } - public function testDoesNotHaveRedirect() + public function testDoesNotHaveRedirect(): void { $exceptionWithoutRedirect = OAuthServerException::accessDenied('Some hint'); $this->assertFalse($exceptionWithoutRedirect->hasRedirect()); } - public function testHasPrevious() + public function testHasPrevious(): void { $previous = new Exception('This is the previous'); $exceptionWithPrevious = OAuthServerException::accessDenied(null, null, $previous); @@ -124,21 +125,21 @@ public function testHasPrevious() $this->assertSame('This is the previous', $previousMessage); } - public function testDoesNotHavePrevious() + public function testDoesNotHavePrevious(): void { $exceptionWithoutPrevious = OAuthServerException::accessDenied(); $this->assertNull($exceptionWithoutPrevious->getPrevious()); } - public function testCanGetRedirectionUri() + public function testCanGetRedirectionUri(): void { $exceptionWithRedirect = OAuthServerException::accessDenied('some hint', 'https://example.com/error'); $this->assertSame('https://example.com/error', $exceptionWithRedirect->getRedirectUri()); } - public function testInvalidCredentialsIsInvalidGrant() + public function testInvalidCredentialsIsInvalidGrant(): void { $exception = OAuthServerException::invalidCredentials(); diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index 618545efe..9bf569c66 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -24,7 +24,7 @@ class AbstractGrantTest extends TestCase { - public function testHttpBasicWithPassword() + public function testHttpBasicWithPassword(): void { /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); @@ -37,7 +37,7 @@ public function testHttpBasicWithPassword() $this->assertSame(['Open', 'Sesame'], $basicAuthMethod->invoke($grantMock, $serverRequest)); } - public function testHttpBasicNoPassword() + public function testHttpBasicNoPassword(): void { /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); @@ -50,7 +50,7 @@ public function testHttpBasicNoPassword() $this->assertSame(['Open', ''], $basicAuthMethod->invoke($grantMock, $serverRequest)); } - public function testHttpBasicNotBasic() + public function testHttpBasicNotBasic(): void { /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); @@ -63,7 +63,7 @@ public function testHttpBasicNotBasic() $this->assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); } - public function testHttpBasicNotBase64() + public function testHttpBasicNotBase64(): void { /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); @@ -76,7 +76,7 @@ public function testHttpBasicNotBase64() $this->assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); } - public function testHttpBasicNoColon() + public function testHttpBasicNoColon(): void { /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); @@ -89,7 +89,7 @@ public function testHttpBasicNoColon() $this->assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); } - public function testGetClientCredentialsClientSecretNotAString() + public function testGetClientCredentialsClientSecretNotAString(): void { $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); @@ -121,7 +121,7 @@ public function testGetClientCredentialsClientSecretNotAString() $getClientCredentialsMethod->invoke($grantMock, $serverRequest, true, true); } - public function testValidateClientPublic() + public function testValidateClientPublic(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -146,7 +146,7 @@ public function testValidateClientPublic() $this->assertEquals($client, $result); } - public function testValidateClientConfidential() + public function testValidateClientConfidential(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -173,7 +173,7 @@ public function testValidateClientConfidential() $this->assertEquals($client, $result); } - public function testValidateClientMissingClientId() + public function testValidateClientMissingClientId(): void { $client = new ClientEntity(); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); @@ -194,7 +194,7 @@ public function testValidateClientMissingClientId() $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } - public function testValidateClientMissingClientSecret() + public function testValidateClientMissingClientSecret(): void { $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('validateClient')->willReturn(false); @@ -217,7 +217,7 @@ public function testValidateClientMissingClientSecret() $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } - public function testValidateClientInvalidClientSecret() + public function testValidateClientInvalidClientSecret(): void { $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('validateClient')->willReturn(false); @@ -241,7 +241,7 @@ public function testValidateClientInvalidClientSecret() $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } - public function testValidateClientInvalidRedirectUri() + public function testValidateClientInvalidRedirectUri(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -267,7 +267,7 @@ public function testValidateClientInvalidRedirectUri() $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } - public function testValidateClientInvalidRedirectUriArray() + public function testValidateClientInvalidRedirectUriArray(): void { $client = new ClientEntity(); $client->setRedirectUri(['http://foo/bar']); @@ -293,7 +293,7 @@ public function testValidateClientInvalidRedirectUriArray() $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } - public function testValidateClientMalformedRedirectUri() + public function testValidateClientMalformedRedirectUri(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -319,7 +319,7 @@ public function testValidateClientMalformedRedirectUri() $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } - public function testValidateClientBadClient() + public function testValidateClientBadClient(): void { $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('validateClient')->willReturn(false); @@ -343,7 +343,7 @@ public function testValidateClientBadClient() $validateClientMethod->invoke($grantMock, $serverRequest, true); } - public function testCanRespondToRequest() + public function testCanRespondToRequest(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->method('getIdentifier')->willReturn('foobar'); @@ -355,7 +355,7 @@ public function testCanRespondToRequest() $this->assertTrue($grantMock->canRespondToAccessTokenRequest($serverRequest)); } - public function testIssueRefreshToken() + public function testIssueRefreshToken(): void { $refreshTokenRepoMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepoMock @@ -379,7 +379,7 @@ public function testIssueRefreshToken() $this->assertEquals($accessToken, $refreshToken->getAccessToken()); } - public function testIssueNullRefreshToken() + public function testIssueNullRefreshToken(): void { $refreshTokenRepoMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepoMock @@ -400,7 +400,7 @@ public function testIssueNullRefreshToken() $this->assertNull($issueRefreshTokenMethod->invoke($grantMock, $accessToken)); } - public function testIssueAccessToken() + public function testIssueAccessToken(): void { $accessTokenRepoMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepoMock->method('getNewToken')->willReturn(new AccessTokenEntity()); @@ -425,7 +425,7 @@ public function testIssueAccessToken() $this->assertInstanceOf(AccessTokenEntityInterface::class, $accessToken); } - public function testIssueAuthCode() + public function testIssueAuthCode(): void { $authCodeRepoMock = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(); $authCodeRepoMock->expects($this->once())->method('getNewAuthCode')->willReturn(new AuthCodeEntity()); @@ -451,7 +451,7 @@ public function testIssueAuthCode() ); } - public function testGetCookieParameter() + public function testGetCookieParameter(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->method('getIdentifier')->willReturn('foobar'); @@ -468,7 +468,7 @@ public function testGetCookieParameter() $this->assertEquals('foo', $method->invoke($grantMock, 'bar', $serverRequest, 'foo')); } - public function testGetQueryStringParameter() + public function testGetQueryStringParameter(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->method('getIdentifier')->willReturn('foobar'); @@ -485,7 +485,7 @@ public function testGetQueryStringParameter() $this->assertEquals('foo', $method->invoke($grantMock, 'bar', $serverRequest, 'foo')); } - public function testValidateScopes() + public function testValidateScopes(): void { $scope = new ScopeEntity(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); @@ -498,7 +498,7 @@ public function testValidateScopes() $this->assertEquals([$scope, $scope, $scope], $grantMock->validateScopes('basic test 0 ')); } - public function testValidateScopesBadScope() + public function testValidateScopesBadScope(): void { $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn(null); @@ -512,7 +512,7 @@ public function testValidateScopesBadScope() $grantMock->validateScopes('basic '); } - public function testGenerateUniqueIdentifier() + public function testGenerateUniqueIdentifier(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); @@ -523,13 +523,13 @@ public function testGenerateUniqueIdentifier() $this->assertIsString($method->invoke($grantMock)); } - public function testCanRespondToAuthorizationRequest() + public function testCanRespondToAuthorizationRequest(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $this->assertFalse($grantMock->canRespondToAuthorizationRequest(new ServerRequest())); } - public function testValidateAuthorizationRequest() + public function testValidateAuthorizationRequest(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); @@ -538,7 +538,7 @@ public function testValidateAuthorizationRequest() $grantMock->validateAuthorizationRequest(new ServerRequest()); } - public function testCompleteAuthorizationRequest() + public function testCompleteAuthorizationRequest(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index 7e5cb80cd..086f37dde 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -46,7 +46,7 @@ public function setUp(): void $this->cryptStub = new CryptTraitStub(); } - public function testGetIdentifier() + public function testGetIdentifier(): void { $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), @@ -57,7 +57,7 @@ public function testGetIdentifier() $this->assertEquals('authorization_code', $grant->getIdentifier()); } - public function testCanRespondToAuthorizationRequest() + public function testCanRespondToAuthorizationRequest(): void { $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), @@ -82,7 +82,7 @@ public function testCanRespondToAuthorizationRequest() $this->assertTrue($grant->canRespondToAuthorizationRequest($request)); } - public function testValidateAuthorizationRequest() + public function testValidateAuthorizationRequest(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -122,7 +122,7 @@ public function testValidateAuthorizationRequest() $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } - public function testValidateAuthorizationRequestRedirectUriArray() + public function testValidateAuthorizationRequestRedirectUriArray(): void { $client = new ClientEntity(); $client->setRedirectUri(['http://foo/bar']); @@ -161,7 +161,7 @@ public function testValidateAuthorizationRequestRedirectUriArray() $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } - public function testValidateAuthorizationRequestWithoutRedirectUri() + public function testValidateAuthorizationRequestWithoutRedirectUri(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -203,7 +203,7 @@ public function testValidateAuthorizationRequestWithoutRedirectUri() $this->assertEmpty($authorizationRequest->getRedirectUri()); } - public function testValidateAuthorizationRequestCodeChallenge() + public function testValidateAuthorizationRequestCodeChallenge(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -243,7 +243,7 @@ public function testValidateAuthorizationRequestCodeChallenge() $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } - public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooShort() + public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooShort(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -270,7 +270,7 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooSho $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooLong() + public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooLong(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -297,7 +297,7 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooLon $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestCodeChallengeInvalidCharacters() + public function testValidateAuthorizationRequestCodeChallengeInvalidCharacters(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -324,7 +324,7 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidCharacters() $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestMissingClientId() + public function testValidateAuthorizationRequestMissingClientId(): void { $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); @@ -345,7 +345,7 @@ public function testValidateAuthorizationRequestMissingClientId() $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestInvalidClientId() + public function testValidateAuthorizationRequestInvalidClientId(): void { $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn(null); @@ -368,7 +368,7 @@ public function testValidateAuthorizationRequestInvalidClientId() $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestBadRedirectUriString() + public function testValidateAuthorizationRequestBadRedirectUriString(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -394,7 +394,7 @@ public function testValidateAuthorizationRequestBadRedirectUriString() $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestBadRedirectUriArray() + public function testValidateAuthorizationRequestBadRedirectUriArray(): void { $client = new ClientEntity(); $client->setRedirectUri(['http://foo/bar']); @@ -420,7 +420,7 @@ public function testValidateAuthorizationRequestBadRedirectUriArray() $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestInvalidCodeChallengeMethod() + public function testValidateAuthorizationRequestInvalidCodeChallengeMethod(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -455,7 +455,7 @@ public function testValidateAuthorizationRequestInvalidCodeChallengeMethod() $grant->validateAuthorizationRequest($request); } - public function testCompleteAuthorizationRequest() + public function testCompleteAuthorizationRequest(): void { $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); @@ -476,7 +476,7 @@ public function testCompleteAuthorizationRequest() $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } - public function testCompleteAuthorizationRequestWithMultipleRedirectUrisOnClient() + public function testCompleteAuthorizationRequestWithMultipleRedirectUrisOnClient(): void { $client = new ClientEntity(); $client->setRedirectUri(['uriOne', 'uriTwo']); @@ -499,7 +499,7 @@ public function testCompleteAuthorizationRequestWithMultipleRedirectUrisOnClient $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } - public function testCompleteAuthorizationRequestDenied() + public function testCompleteAuthorizationRequestDenied(): void { $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(false); @@ -523,7 +523,7 @@ public function testCompleteAuthorizationRequestDenied() $grant->completeAuthorizationRequest($authRequest); } - public function testRespondToAccessTokenRequest() + public function testRespondToAccessTokenRequest(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -592,7 +592,7 @@ public function testRespondToAccessTokenRequest() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } - public function testRespondToAccessTokenRequestUsingHttpBasicAuth() + public function testRespondToAccessTokenRequestUsingHttpBasicAuth(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -658,7 +658,7 @@ public function testRespondToAccessTokenRequestUsingHttpBasicAuth() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } - public function testRespondToAccessTokenRequestForPublicClient() + public function testRespondToAccessTokenRequestForPublicClient(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -726,7 +726,7 @@ public function testRespondToAccessTokenRequestForPublicClient() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } - public function testRespondToAccessTokenRequestNullRefreshToken() + public function testRespondToAccessTokenRequestNullRefreshToken(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -794,7 +794,7 @@ public function testRespondToAccessTokenRequestNullRefreshToken() $this->assertNull($response->getRefreshToken()); } - public function testRespondToAccessTokenRequestCodeChallengePlain() + public function testRespondToAccessTokenRequestCodeChallengePlain(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -867,7 +867,7 @@ public function testRespondToAccessTokenRequestCodeChallengePlain() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } - public function testRespondToAccessTokenRequestCodeChallengeS256() + public function testRespondToAccessTokenRequestCodeChallengeS256(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -940,7 +940,7 @@ public function testRespondToAccessTokenRequestCodeChallengeS256() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } - public function testRespondToAccessTokenRequestMissingRedirectUri() + public function testRespondToAccessTokenRequestMissingRedirectUri(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -988,7 +988,7 @@ public function testRespondToAccessTokenRequestMissingRedirectUri() $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } - public function testRespondToAccessTokenRequestRedirectUriMismatch() + public function testRespondToAccessTokenRequestRedirectUriMismatch(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1037,7 +1037,7 @@ public function testRespondToAccessTokenRequestRedirectUriMismatch() $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } - public function testRespondToAccessTokenRequestMissingCode() + public function testRespondToAccessTokenRequestMissingCode(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -1082,7 +1082,7 @@ public function testRespondToAccessTokenRequestMissingCode() $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } - public function testRespondToAccessTokenRequestWithRefreshTokenInsteadOfAuthCode() + public function testRespondToAccessTokenRequestWithRefreshTokenInsteadOfAuthCode(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -1135,7 +1135,7 @@ public function testRespondToAccessTokenRequestWithRefreshTokenInsteadOfAuthCode } } - public function testRespondToAccessTokenRequestWithAuthCodeNotAString() + public function testRespondToAccessTokenRequestWithAuthCodeNotAString(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -1173,7 +1173,7 @@ public function testRespondToAccessTokenRequestWithAuthCodeNotAString() $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } - public function testRespondToAccessTokenRequestExpiredCode() + public function testRespondToAccessTokenRequestExpiredCode(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -1226,7 +1226,7 @@ public function testRespondToAccessTokenRequestExpiredCode() } } - public function testRespondToAccessTokenRequestRevokedCode() + public function testRespondToAccessTokenRequestRevokedCode(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1291,7 +1291,7 @@ public function testRespondToAccessTokenRequestRevokedCode() } } - public function testRespondToAccessTokenRequestClientMismatch() + public function testRespondToAccessTokenRequestClientMismatch(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1352,7 +1352,7 @@ public function testRespondToAccessTokenRequestClientMismatch() } } - public function testRespondToAccessTokenRequestBadCodeEncryption() + public function testRespondToAccessTokenRequestBadCodeEncryption(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1402,7 +1402,7 @@ public function testRespondToAccessTokenRequestBadCodeEncryption() } } - public function testRespondToAccessTokenRequestBadCodeVerifierPlain() + public function testRespondToAccessTokenRequestBadCodeVerifierPlain(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1475,7 +1475,7 @@ public function testRespondToAccessTokenRequestBadCodeVerifierPlain() } } - public function testRespondToAccessTokenRequestBadCodeVerifierS256() + public function testRespondToAccessTokenRequestBadCodeVerifierS256(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1548,7 +1548,7 @@ public function testRespondToAccessTokenRequestBadCodeVerifierS256() } } - public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInvalidChars() + public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInvalidChars(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1621,7 +1621,7 @@ public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInva } } - public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInvalidLength() + public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInvalidLength(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1694,7 +1694,7 @@ public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInva } } - public function testRespondToAccessTokenRequestMissingCodeVerifier() + public function testRespondToAccessTokenRequestMissingCodeVerifier(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1766,7 +1766,7 @@ public function testRespondToAccessTokenRequestMissingCodeVerifier() } } - public function testAuthCodeRepositoryUniqueConstraintCheck() + public function testAuthCodeRepositoryUniqueConstraintCheck(): void { $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); @@ -1799,7 +1799,7 @@ public function testAuthCodeRepositoryUniqueConstraintCheck() $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } - public function testAuthCodeRepositoryFailToPersist() + public function testAuthCodeRepositoryFailToPersist(): void { $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); @@ -1824,7 +1824,7 @@ public function testAuthCodeRepositoryFailToPersist() $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } - public function testAuthCodeRepositoryFailToPersistUniqueNoInfiniteLoop() + public function testAuthCodeRepositoryFailToPersistUniqueNoInfiniteLoop(): void { $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); @@ -1848,7 +1848,7 @@ public function testAuthCodeRepositoryFailToPersistUniqueNoInfiniteLoop() $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } - public function testRefreshTokenRepositoryUniqueConstraintCheck() + public function testRefreshTokenRepositoryUniqueConstraintCheck(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1926,7 +1926,7 @@ public function testRefreshTokenRepositoryUniqueConstraintCheck() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } - public function testRefreshTokenRepositoryFailToPersist() + public function testRefreshTokenRepositoryFailToPersist(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -1997,7 +1997,7 @@ public function testRefreshTokenRepositoryFailToPersist() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } - public function testRefreshTokenRepositoryFailToPersistUniqueNoInfiniteLoop() + public function testRefreshTokenRepositoryFailToPersistUniqueNoInfiniteLoop(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -2068,7 +2068,7 @@ public function testRefreshTokenRepositoryFailToPersistUniqueNoInfiniteLoop() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } - public function testCompleteAuthorizationRequestNoUser() + public function testCompleteAuthorizationRequestNoUser(): void { $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), @@ -2081,7 +2081,7 @@ public function testCompleteAuthorizationRequestNoUser() $grant->completeAuthorizationRequest(new AuthorizationRequest()); } - public function testPublicClientAuthCodeRequestRejectedWhenCodeChallengeRequiredButNotGiven() + public function testPublicClientAuthCodeRequestRejectedWhenCodeChallengeRequiredButNotGiven(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -2116,7 +2116,7 @@ public function testPublicClientAuthCodeRequestRejectedWhenCodeChallengeRequired $grant->validateAuthorizationRequest($request); } - public function testUseValidRedirectUriIfScopeCheckFails() + public function testUseValidRedirectUriIfScopeCheckFails(): void { $client = new ClientEntity(); $client->setRedirectUri(['http://foo/bar', 'http://bar/foo']); @@ -2162,9 +2162,11 @@ public function testUseValidRedirectUriIfScopeCheckFails() } } - public function testThrowExceptionWhenNoClientRedirectUriRegistered() + public function testThrowExceptionWhenNoClientRedirectUriRegistered(): void { - $client = (new ClientEntity())->setConfidential(); + $client = new ClientEntity(); + + $client->setConfidential(); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); diff --git a/tests/Grant/ClientCredentialsGrantTest.php b/tests/Grant/ClientCredentialsGrantTest.php index 13ea78bae..e3d9b9268 100644 --- a/tests/Grant/ClientCredentialsGrantTest.php +++ b/tests/Grant/ClientCredentialsGrantTest.php @@ -20,13 +20,13 @@ class ClientCredentialsGrantTest extends TestCase { const DEFAULT_SCOPE = 'basic'; - public function testGetIdentifier() + public function testGetIdentifier(): void { $grant = new ClientCredentialsGrant(); $this->assertEquals('client_credentials', $grant->getIdentifier()); } - public function testRespondToRequest() + public function testRespondToRequest(): void { $client = new ClientEntity(); $client->setConfidential(); diff --git a/tests/Grant/ImplicitGrantTest.php b/tests/Grant/ImplicitGrantTest.php index 546450384..45777b755 100644 --- a/tests/Grant/ImplicitGrantTest.php +++ b/tests/Grant/ImplicitGrantTest.php @@ -26,23 +26,20 @@ class ImplicitGrantTest extends TestCase { const DEFAULT_SCOPE = 'basic'; - /** - * CryptTrait stub - */ - protected $cryptStub; + protected CryptTraitStub $cryptStub; public function setUp(): void { $this->cryptStub = new CryptTraitStub(); } - public function testGetIdentifier() + public function testGetIdentifier(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); $this->assertEquals('implicit', $grant->getIdentifier()); } - public function testCanRespondToAccessTokenRequest() + public function testCanRespondToAccessTokenRequest(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); @@ -51,7 +48,7 @@ public function testCanRespondToAccessTokenRequest() ); } - public function testRespondToAccessTokenRequest() + public function testRespondToAccessTokenRequest(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); @@ -64,7 +61,7 @@ public function testRespondToAccessTokenRequest() ); } - public function testCanRespondToAuthorizationRequest() + public function testCanRespondToAuthorizationRequest(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); @@ -76,7 +73,7 @@ public function testCanRespondToAuthorizationRequest() $this->assertTrue($grant->canRespondToAuthorizationRequest($request)); } - public function testValidateAuthorizationRequest() + public function testValidateAuthorizationRequest(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -101,7 +98,7 @@ public function testValidateAuthorizationRequest() $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } - public function testValidateAuthorizationRequestRedirectUriArray() + public function testValidateAuthorizationRequestRedirectUriArray(): void { $client = new ClientEntity(); $client->setRedirectUri(['http://foo/bar']); @@ -126,7 +123,7 @@ public function testValidateAuthorizationRequestRedirectUriArray() $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } - public function testValidateAuthorizationRequestMissingClientId() + public function testValidateAuthorizationRequestMissingClientId(): void { $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); @@ -141,7 +138,7 @@ public function testValidateAuthorizationRequestMissingClientId() $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestInvalidClientId() + public function testValidateAuthorizationRequestInvalidClientId(): void { $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn(null); @@ -160,7 +157,7 @@ public function testValidateAuthorizationRequestInvalidClientId() $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestBadRedirectUriString() + public function testValidateAuthorizationRequestBadRedirectUriString(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -182,7 +179,7 @@ public function testValidateAuthorizationRequestBadRedirectUriString() $grant->validateAuthorizationRequest($request); } - public function testValidateAuthorizationRequestBadRedirectUriArray() + public function testValidateAuthorizationRequestBadRedirectUriArray(): void { $client = new ClientEntity(); $client->setRedirectUri(['http://foo/bar']); @@ -204,7 +201,7 @@ public function testValidateAuthorizationRequestBadRedirectUriArray() $grant->validateAuthorizationRequest($request); } - public function testCompleteAuthorizationRequest() + public function testCompleteAuthorizationRequest(): void { $client = new ClientEntity(); $client->setIdentifier('identifier'); @@ -233,7 +230,7 @@ public function testCompleteAuthorizationRequest() $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } - public function testCompleteAuthorizationRequestDenied() + public function testCompleteAuthorizationRequestDenied(): void { $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(false); @@ -259,7 +256,7 @@ public function testCompleteAuthorizationRequestDenied() $grant->completeAuthorizationRequest($authRequest); } - public function testAccessTokenRepositoryUniqueConstraintCheck() + public function testAccessTokenRepositoryUniqueConstraintCheck(): void { $client = new ClientEntity(); $client->setIdentifier('identifier'); @@ -299,7 +296,7 @@ public function testAccessTokenRepositoryUniqueConstraintCheck() $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } - public function testAccessTokenRepositoryFailToPersist() + public function testAccessTokenRepositoryFailToPersist(): void { $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); @@ -326,7 +323,7 @@ public function testAccessTokenRepositoryFailToPersist() $grant->completeAuthorizationRequest($authRequest); } - public function testAccessTokenRepositoryFailToPersistUniqueNoInfiniteLoop() + public function testAccessTokenRepositoryFailToPersistUniqueNoInfiniteLoop(): void { $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); @@ -353,7 +350,7 @@ public function testAccessTokenRepositoryFailToPersistUniqueNoInfiniteLoop() $grant->completeAuthorizationRequest($authRequest); } - public function testSetRefreshTokenTTL() + public function testSetRefreshTokenTTL(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); @@ -362,7 +359,7 @@ public function testSetRefreshTokenTTL() $grant->setRefreshTokenTTL(new DateInterval('PT10M')); } - public function testSetRefreshTokenRepository() + public function testSetRefreshTokenRepository(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); @@ -373,7 +370,7 @@ public function testSetRefreshTokenRepository() $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); } - public function testCompleteAuthorizationRequestNoUser() + public function testCompleteAuthorizationRequestNoUser(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); diff --git a/tests/Grant/PasswordGrantTest.php b/tests/Grant/PasswordGrantTest.php index b53ab2357..1eb2e0895 100644 --- a/tests/Grant/PasswordGrantTest.php +++ b/tests/Grant/PasswordGrantTest.php @@ -25,7 +25,7 @@ class PasswordGrantTest extends TestCase { const DEFAULT_SCOPE = 'basic'; - public function testGetIdentifier() + public function testGetIdentifier(): void { $userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); @@ -34,7 +34,7 @@ public function testGetIdentifier() $this->assertEquals('password', $grant->getIdentifier()); } - public function testRespondToRequest() + public function testRespondToRequest(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -80,7 +80,7 @@ public function testRespondToRequest() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); } - public function testRespondToRequestNullRefreshToken() + public function testRespondToRequestNullRefreshToken(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); @@ -125,7 +125,7 @@ public function testRespondToRequestNullRefreshToken() $this->assertNull($responseType->getRefreshToken()); } - public function testRespondToRequestMissingUsername() + public function testRespondToRequestMissingUsername(): void { $client = new ClientEntity(); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); @@ -153,7 +153,7 @@ public function testRespondToRequestMissingUsername() $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } - public function testRespondToRequestMissingPassword() + public function testRespondToRequestMissingPassword(): void { $client = new ClientEntity(); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); @@ -182,7 +182,7 @@ public function testRespondToRequestMissingPassword() $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } - public function testRespondToRequestBadCredentials() + public function testRespondToRequestBadCredentials(): void { $client = new ClientEntity(); $client->setRedirectUri('http://foo/bar'); diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index 5b5491bbc..f61c4e530 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -33,7 +33,7 @@ public function setUp(): void $this->cryptStub = new CryptTraitStub(); } - public function testGetIdentifier() + public function testGetIdentifier(): void { $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); @@ -41,7 +41,7 @@ public function testGetIdentifier() $this->assertEquals('refresh_token', $grant->getIdentifier()); } - public function testRespondToRequest() + public function testRespondToRequest(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -99,7 +99,7 @@ public function testRespondToRequest() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); } - public function testRespondToRequestNullRefreshToken() + public function testRespondToRequestNullRefreshToken(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -157,7 +157,7 @@ public function testRespondToRequestNullRefreshToken() $this->assertNull($responseType->getRefreshToken()); } - public function testRespondToReducedScopes() + public function testRespondToReducedScopes(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -215,7 +215,7 @@ public function testRespondToReducedScopes() $this->assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); } - public function testRespondToUnexpectedScope() + public function testRespondToUnexpectedScope(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -270,7 +270,7 @@ public function testRespondToUnexpectedScope() $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } - public function testRespondToRequestMissingOldToken() + public function testRespondToRequestMissingOldToken(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -301,7 +301,7 @@ public function testRespondToRequestMissingOldToken() $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } - public function testRespondToRequestInvalidOldToken() + public function testRespondToRequestInvalidOldToken(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -335,7 +335,7 @@ public function testRespondToRequestInvalidOldToken() $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } - public function testRespondToRequestClientMismatch() + public function testRespondToRequestClientMismatch(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -383,7 +383,7 @@ public function testRespondToRequestClientMismatch() $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } - public function testRespondToRequestExpiredToken() + public function testRespondToRequestExpiredToken(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -428,7 +428,7 @@ public function testRespondToRequestExpiredToken() $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } - public function testRespondToRequestRevokedToken() + public function testRespondToRequestRevokedToken(): void { $client = new ClientEntity(); $client->setIdentifier('foo'); @@ -474,7 +474,7 @@ public function testRespondToRequestRevokedToken() $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } - public function testRespondToRequestFinalizeScopes() + public function testRespondToRequestFinalizeScopes(): void { $client = new ClientEntity(); @@ -547,7 +547,7 @@ public function testRespondToRequestFinalizeScopes() $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } - public function testRevokedRefreshToken() + public function testRevokedRefreshToken(): void { $refreshTokenId = 'foo'; @@ -606,7 +606,7 @@ public function testRevokedRefreshToken() Assert::assertTrue($refreshTokenRepositoryMock->isRefreshTokenRevoked($refreshTokenId)); } - public function testUnrevokedRefreshToken() + public function testUnrevokedRefreshToken(): void { $refreshTokenId = 'foo'; diff --git a/tests/Middleware/AuthorizationServerMiddlewareTest.php b/tests/Middleware/AuthorizationServerMiddlewareTest.php index 69c8d3791..696b5cfe3 100644 --- a/tests/Middleware/AuthorizationServerMiddlewareTest.php +++ b/tests/Middleware/AuthorizationServerMiddlewareTest.php @@ -22,7 +22,7 @@ class AuthorizationServerMiddlewareTest extends TestCase { const DEFAULT_SCOPE = 'basic'; - public function testValidResponse() + public function testValidResponse(): void { $client = new ClientEntity(); $client->setConfidential(); @@ -68,7 +68,7 @@ function () { $this->assertEquals(200, $response->getStatusCode()); } - public function testOAuthErrorResponse() + public function testOAuthErrorResponse(): void { $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository->method('validateClient')->willReturn(false); @@ -103,7 +103,7 @@ function () { $this->assertEquals(401, $response->getStatusCode()); } - public function testOAuthErrorResponseRedirectUri() + public function testOAuthErrorResponseRedirectUri(): void { $exception = OAuthServerException::invalidScope('test', 'http://foo/bar'); $response = $exception->generateHttpResponse(new Response()); @@ -115,7 +115,7 @@ public function testOAuthErrorResponseRedirectUri() ); } - public function testOAuthErrorResponseRedirectUriFragment() + public function testOAuthErrorResponseRedirectUriFragment(): void { $exception = OAuthServerException::invalidScope('test', 'http://foo/bar'); $response = $exception->generateHttpResponse(new Response(), true); diff --git a/tests/Stubs/GrantType.php b/tests/Stubs/GrantType.php index be1a5ab67..d08d99b03 100644 --- a/tests/Stubs/GrantType.php +++ b/tests/Stubs/GrantType.php @@ -5,6 +5,7 @@ namespace LeagueTests\Stubs; use DateInterval; +use Defuse\Crypto\Key; use League\Event\EmitterInterface; use League\OAuth2\Server\CryptKeyInterface; use League\OAuth2\Server\Grant\GrantTypeInterface; @@ -93,7 +94,7 @@ public function setPrivateKey(CryptKeyInterface $privateKey): void { } - public function setEncryptionKey($key = null): void + public function setEncryptionKey(Key|string|null $key = null): void { } From cc599afe2f05d94a02918d7c2a3e266c9a4bc844 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Thu, 20 Jul 2023 00:06:31 +0100 Subject: [PATCH 35/46] More PHPStan fixes --- phpstan.neon.dist | 1 - src/AuthorizationServer.php | 4 +-- .../BearerTokenValidator.php | 8 ++--- src/Entities/AccessTokenEntityInterface.php | 2 +- src/Entities/AuthCodeEntityInterface.php | 10 ++---- src/Entities/RefreshTokenEntityInterface.php | 20 +++-------- src/Entities/TokenInterface.php | 28 ++++------------ src/Entities/Traits/AccessTokenTrait.php | 4 +-- src/Entities/Traits/AuthCodeTrait.php | 10 ++---- src/Entities/Traits/EntityTrait.php | 2 +- src/Entities/Traits/RefreshTokenTrait.php | 22 ++++--------- src/Entities/Traits/TokenEntityTrait.php | 24 +++++--------- src/Exception/OAuthServerException.php | 18 +++++----- src/Grant/AbstractAuthorizeGrant.php | 2 +- src/Grant/AbstractGrant.php | 33 ++++++++++--------- src/Grant/AuthCodeGrant.php | 5 ++- src/Grant/GrantTypeInterface.php | 12 +++---- src/Grant/ImplicitGrant.php | 4 +-- src/Grant/RefreshTokenGrant.php | 4 +-- 19 files changed, 79 insertions(+), 134 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 3b729de80..ea81a8e66 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,4 +7,3 @@ parameters: - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAccessToken\(\) should return League\\OAuth2\\Server\\Entities\\AccessTokenEntityInterface but return statement is missing\.#' - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAuthCode\(\) should return League\\OAuth2\\Server\\Entities\\AuthCodeEntityInterface but return statement is missing\.#' - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueRefreshToken\(\) should return League\\OAuth2\\Server\\Entities\\RefreshTokenEntityInterface\|null but return statement is missing\.#' - - '#Parameter \#1 \$contents of static method Lcobucci\\JWT\\Signer\\Key\\InMemory::plainText\(\) expects non-empty-string, string given\.#' diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index 6089adbf0..85369a0bc 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -128,7 +128,7 @@ public function __construct( * @param GrantTypeInterface $grantType * @param null|DateInterval $accessTokenTTL */ - public function enableGrantType(GrantTypeInterface $grantType, DateInterval $accessTokenTTL = null) + public function enableGrantType(GrantTypeInterface $grantType, DateInterval $accessTokenTTL = null): void { if ($accessTokenTTL === null) { $accessTokenTTL = new DateInterval('PT1H'); @@ -237,7 +237,7 @@ protected function getResponseType() * * @param string $defaultScope */ - public function setDefaultScope($defaultScope) + public function setDefaultScope($defaultScope): void { $this->defaultScope = $defaultScope; } diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index 9f2062719..f9b0ae5db 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -57,7 +57,7 @@ public function __construct(AccessTokenRepositoryInterface $accessTokenRepositor * * @param CryptKeyInterface $key */ - public function setPublicKey(CryptKeyInterface $key) + public function setPublicKey(CryptKeyInterface $key): void { $this->publicKey = $key; @@ -67,7 +67,7 @@ public function setPublicKey(CryptKeyInterface $key) /** * Initialise the JWT configuration. */ - private function initJwtConfiguration() + private function initJwtConfiguration(): void { $this->jwtConfiguration = Configuration::forSymmetricSigner( new Sha256(), @@ -136,9 +136,9 @@ public function validateAuthorization(ServerRequestInterface $request) * * @param mixed $aud * - * @return array|string + * @return array|string */ - private function convertSingleRecordAudToString($aud) + private function convertSingleRecordAudToString($aud): array|string { return \is_array($aud) && \count($aud) === 1 ? $aud[0] : $aud; } diff --git a/src/Entities/AccessTokenEntityInterface.php b/src/Entities/AccessTokenEntityInterface.php index 041d528b3..33306b174 100644 --- a/src/Entities/AccessTokenEntityInterface.php +++ b/src/Entities/AccessTokenEntityInterface.php @@ -16,7 +16,7 @@ interface AccessTokenEntityInterface extends TokenInterface /** * Set a private key used to encrypt the access token. */ - public function setPrivateKey(CryptKeyInterface $privateKey); + public function setPrivateKey(CryptKeyInterface $privateKey): void; /** * Generate a string representation of the access token. diff --git a/src/Entities/AuthCodeEntityInterface.php b/src/Entities/AuthCodeEntityInterface.php index 00e939c2c..40d581245 100644 --- a/src/Entities/AuthCodeEntityInterface.php +++ b/src/Entities/AuthCodeEntityInterface.php @@ -11,13 +11,7 @@ interface AuthCodeEntityInterface extends TokenInterface { - /** - * @return string|null - */ - public function getRedirectUri(); + public function getRedirectUri(): string|null; - /** - * @param string $uri - */ - public function setRedirectUri($uri); + public function setRedirectUri(string $uri): void; } diff --git a/src/Entities/RefreshTokenEntityInterface.php b/src/Entities/RefreshTokenEntityInterface.php index 551ad0527..63f9732c6 100644 --- a/src/Entities/RefreshTokenEntityInterface.php +++ b/src/Entities/RefreshTokenEntityInterface.php @@ -22,36 +22,26 @@ public function getIdentifier(); /** * Set the token's identifier. - * - * @param mixed $identifier */ - public function setIdentifier($identifier); + public function setIdentifier(mixed $identifier): void; /** * Get the token's expiry date time. - * - * @return DateTimeImmutable */ - public function getExpiryDateTime(); + public function getExpiryDateTime(): DateTimeImmutable; /** * Set the date time when the token expires. - * - * @param DateTimeImmutable $dateTime */ - public function setExpiryDateTime(DateTimeImmutable $dateTime); + public function setExpiryDateTime(DateTimeImmutable $dateTime): void; /** * Set the access token that the refresh token was associated with. - * - * @param AccessTokenEntityInterface $accessToken */ - public function setAccessToken(AccessTokenEntityInterface $accessToken); + public function setAccessToken(AccessTokenEntityInterface $accessToken): void; /** * Get the access token that the refresh token was originally associated with. - * - * @return AccessTokenEntityInterface */ - public function getAccessToken(); + public function getAccessToken(): AccessTokenEntityInterface; } diff --git a/src/Entities/TokenInterface.php b/src/Entities/TokenInterface.php index 7b063e138..75aa261af 100644 --- a/src/Entities/TokenInterface.php +++ b/src/Entities/TokenInterface.php @@ -22,10 +22,8 @@ public function getIdentifier(); /** * Set the token's identifier. - * - * @param mixed $identifier */ - public function setIdentifier($identifier); + public function setIdentifier(mixed $identifier): void; /** * Get the token's expiry date time. @@ -36,45 +34,33 @@ public function getExpiryDateTime(); /** * Set the date time when the token expires. - * - * @param DateTimeImmutable $dateTime */ - public function setExpiryDateTime(DateTimeImmutable $dateTime); + public function setExpiryDateTime(DateTimeImmutable $dateTime): void; /** * Set the identifier of the user associated with the token. - * - * @param string|int|null $identifier The identifier of the user */ - public function setUserIdentifier($identifier); + public function setUserIdentifier(string|int|null $identifier): void; /** * Get the token user's identifier. - * - * @return string|int|null */ - public function getUserIdentifier(); + public function getUserIdentifier(): string|int|null; /** * Get the client that the token was issued to. - * - * @return ClientEntityInterface */ - public function getClient(); + public function getClient(): ClientEntityInterface; /** * Set the client that the token was issued to. - * - * @param ClientEntityInterface $client */ - public function setClient(ClientEntityInterface $client); + public function setClient(ClientEntityInterface $client): void; /** * Associate a scope with the token. - * - * @param ScopeEntityInterface $scope */ - public function addScope(ScopeEntityInterface $scope); + public function addScope(ScopeEntityInterface $scope): void; /** * Return an array of scopes associated with the token. diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index 65537ac9b..9056db833 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -33,7 +33,7 @@ trait AccessTokenTrait /** * Set the private key used to encrypt this access token. */ - public function setPrivateKey(CryptKeyInterface $privateKey) + public function setPrivateKey(CryptKeyInterface $privateKey): void { $this->privateKey = $privateKey; } @@ -41,7 +41,7 @@ public function setPrivateKey(CryptKeyInterface $privateKey) /** * Initialise the JWT Configuration. */ - public function initJwtConfiguration() + public function initJwtConfiguration(): void { $this->jwtConfiguration = Configuration::forAsymmetricSigner( new Sha256(), diff --git a/src/Entities/Traits/AuthCodeTrait.php b/src/Entities/Traits/AuthCodeTrait.php index 542d36789..35cbff295 100644 --- a/src/Entities/Traits/AuthCodeTrait.php +++ b/src/Entities/Traits/AuthCodeTrait.php @@ -16,18 +16,12 @@ trait AuthCodeTrait */ protected $redirectUri; - /** - * @return string|null - */ - public function getRedirectUri() + public function getRedirectUri(): string|null { return $this->redirectUri; } - /** - * @param string $uri - */ - public function setRedirectUri($uri) + public function setRedirectUri(string $uri): void { $this->redirectUri = $uri; } diff --git a/src/Entities/Traits/EntityTrait.php b/src/Entities/Traits/EntityTrait.php index 05452923a..6748aea18 100644 --- a/src/Entities/Traits/EntityTrait.php +++ b/src/Entities/Traits/EntityTrait.php @@ -27,7 +27,7 @@ public function getIdentifier() /** * @param mixed $identifier */ - public function setIdentifier($identifier) + public function setIdentifier($identifier): void { $this->identifier = $identifier; } diff --git a/src/Entities/Traits/RefreshTokenTrait.php b/src/Entities/Traits/RefreshTokenTrait.php index f0f15444c..568b2a733 100644 --- a/src/Entities/Traits/RefreshTokenTrait.php +++ b/src/Entities/Traits/RefreshTokenTrait.php @@ -14,20 +14,14 @@ trait RefreshTokenTrait { - /** - * @var AccessTokenEntityInterface - */ - protected $accessToken; + protected AccessTokenEntityInterface $accessToken; - /** - * @var DateTimeImmutable - */ - protected $expiryDateTime; + protected DateTimeImmutable $expiryDateTime; /** * {@inheritdoc} */ - public function setAccessToken(AccessTokenEntityInterface $accessToken) + public function setAccessToken(AccessTokenEntityInterface $accessToken): void { $this->accessToken = $accessToken; } @@ -35,27 +29,23 @@ public function setAccessToken(AccessTokenEntityInterface $accessToken) /** * {@inheritdoc} */ - public function getAccessToken() + public function getAccessToken(): AccessTokenEntityInterface { return $this->accessToken; } /** * Get the token's expiry date time. - * - * @return DateTimeImmutable */ - public function getExpiryDateTime() + public function getExpiryDateTime(): DateTimeImmutable { return $this->expiryDateTime; } /** * Set the date time when the token expires. - * - * @param DateTimeImmutable $dateTime */ - public function setExpiryDateTime(DateTimeImmutable $dateTime) + public function setExpiryDateTime(DateTimeImmutable $dateTime): void { $this->expiryDateTime = $dateTime; } diff --git a/src/Entities/Traits/TokenEntityTrait.php b/src/Entities/Traits/TokenEntityTrait.php index 83b172322..d9cfa6fa2 100644 --- a/src/Entities/Traits/TokenEntityTrait.php +++ b/src/Entities/Traits/TokenEntityTrait.php @@ -40,7 +40,7 @@ trait TokenEntityTrait * * @param ScopeEntityInterface $scope */ - public function addScope(ScopeEntityInterface $scope) + public function addScope(ScopeEntityInterface $scope): void { $this->scopes[$scope->getIdentifier()] = $scope; } @@ -50,27 +50,23 @@ public function addScope(ScopeEntityInterface $scope) * * @return ScopeEntityInterface[] */ - public function getScopes() + public function getScopes(): array { return \array_values($this->scopes); } /** * Get the token's expiry date time. - * - * @return DateTimeImmutable */ - public function getExpiryDateTime() + public function getExpiryDateTime(): DateTimeImmutable { return $this->expiryDateTime; } /** * Set the date time when the token expires. - * - * @param DateTimeImmutable $dateTime */ - public function setExpiryDateTime(DateTimeImmutable $dateTime) + public function setExpiryDateTime(DateTimeImmutable $dateTime): void { $this->expiryDateTime = $dateTime; } @@ -80,7 +76,7 @@ public function setExpiryDateTime(DateTimeImmutable $dateTime) * * @param string|int|null $identifier The identifier of the user */ - public function setUserIdentifier($identifier) + public function setUserIdentifier($identifier): void { $this->userIdentifier = $identifier; } @@ -90,27 +86,23 @@ public function setUserIdentifier($identifier) * * @return string|int|null */ - public function getUserIdentifier() + public function getUserIdentifier(): string|int|null { return $this->userIdentifier; } /** * Get the client that the token was issued to. - * - * @return ClientEntityInterface */ - public function getClient() + public function getClient(): ClientEntityInterface { return $this->client; } /** * Set the client that the token was issued to. - * - * @param ClientEntityInterface $client */ - public function setClient(ClientEntityInterface $client) + public function setClient(ClientEntityInterface $client): void { $this->client = $client; } diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index f57c68951..32104ef0d 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -37,9 +37,9 @@ class OAuthServerException extends Exception private $redirectUri; /** - * @var array + * @var array */ - private $payload; + private array $payload; /** * @var ServerRequestInterface @@ -76,9 +76,9 @@ final public function __construct($message, $code, $errorType, $httpStatusCode = /** * Returns the current payload. * - * @return array + * @return array */ - public function getPayload() + public function getPayload(): array { $payload = $this->payload; @@ -94,9 +94,9 @@ public function getPayload() /** * Updates the current payload. * - * @param array $payload + * @param array $payload */ - public function setPayload(array $payload) + public function setPayload(array $payload): void { $this->payload = $payload; } @@ -106,7 +106,7 @@ public function setPayload(array $payload) * * @param ServerRequestInterface $serverRequest */ - public function setServerRequest(ServerRequestInterface $serverRequest) + public function setServerRequest(ServerRequestInterface $serverRequest): void { $this->serverRequest = $serverRequest; } @@ -318,9 +318,9 @@ public function generateHttpResponse(ResponseInterface $response, $useFragment = /** * Get all headers that have to be send with the error response. * - * @return array Array with header values + * @return array Array with header values */ - public function getHttpHeaders() + public function getHttpHeaders(): array { $headers = [ 'Content-type' => 'application/json', diff --git a/src/Grant/AbstractAuthorizeGrant.php b/src/Grant/AbstractAuthorizeGrant.php index 3a8bb4074..9a78ae562 100644 --- a/src/Grant/AbstractAuthorizeGrant.php +++ b/src/Grant/AbstractAuthorizeGrant.php @@ -18,7 +18,7 @@ abstract class AbstractAuthorizeGrant extends AbstractGrant { /** * @param string $uri - * @param array $params + * @param mixed[] $params * @param string $queryDelimiter * * @return string diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index d13188c2a..9cdbde944 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -101,7 +101,7 @@ abstract class AbstractGrant implements GrantTypeInterface /** * @param ClientRepositoryInterface $clientRepository */ - public function setClientRepository(ClientRepositoryInterface $clientRepository) + public function setClientRepository(ClientRepositoryInterface $clientRepository): void { $this->clientRepository = $clientRepository; } @@ -109,7 +109,7 @@ public function setClientRepository(ClientRepositoryInterface $clientRepository) /** * @param AccessTokenRepositoryInterface $accessTokenRepository */ - public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository) + public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository): void { $this->accessTokenRepository = $accessTokenRepository; } @@ -117,7 +117,7 @@ public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessT /** * @param ScopeRepositoryInterface $scopeRepository */ - public function setScopeRepository(ScopeRepositoryInterface $scopeRepository) + public function setScopeRepository(ScopeRepositoryInterface $scopeRepository): void { $this->scopeRepository = $scopeRepository; } @@ -125,7 +125,7 @@ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository) /** * @param RefreshTokenRepositoryInterface $refreshTokenRepository */ - public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository) + public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository): void { $this->refreshTokenRepository = $refreshTokenRepository; } @@ -133,7 +133,7 @@ public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refre /** * @param AuthCodeRepositoryInterface $authCodeRepository */ - public function setAuthCodeRepository(AuthCodeRepositoryInterface $authCodeRepository) + public function setAuthCodeRepository(AuthCodeRepositoryInterface $authCodeRepository): void { $this->authCodeRepository = $authCodeRepository; } @@ -141,7 +141,7 @@ public function setAuthCodeRepository(AuthCodeRepositoryInterface $authCodeRepos /** * @param UserRepositoryInterface $userRepository */ - public function setUserRepository(UserRepositoryInterface $userRepository) + public function setUserRepository(UserRepositoryInterface $userRepository): void { $this->userRepository = $userRepository; } @@ -149,7 +149,7 @@ public function setUserRepository(UserRepositoryInterface $userRepository) /** * {@inheritdoc} */ - public function setRefreshTokenTTL(DateInterval $refreshTokenTTL) + public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void { $this->refreshTokenTTL = $refreshTokenTTL; } @@ -159,7 +159,7 @@ public function setRefreshTokenTTL(DateInterval $refreshTokenTTL) * * @param CryptKeyInterface $key */ - public function setPrivateKey(CryptKeyInterface $key) + public function setPrivateKey(CryptKeyInterface $key): void { $this->privateKey = $key; } @@ -167,7 +167,7 @@ public function setPrivateKey(CryptKeyInterface $key) /** * @param string $scope */ - public function setDefaultScope($scope) + public function setDefaultScope($scope): void { $this->defaultScope = $scope; } @@ -248,9 +248,9 @@ protected function getClientEntityOrFail($clientId, ServerRequestInterface $requ * * @param ServerRequestInterface $request * - * @return array + * @return string[] */ - protected function getClientCredentials(ServerRequestInterface $request) + protected function getClientCredentials(ServerRequestInterface $request): array { [$basicAuthUser, $basicAuthPassword] = $this->getBasicAuthCredentials($request); @@ -283,8 +283,9 @@ protected function validateRedirectUri( string $redirectUri, ClientEntityInterface $client, ServerRequestInterface $request - ) { + ): void { $validator = new RedirectUriValidator($client->getRedirectUri()); + if (!$validator->validateRedirectUri($redirectUri)) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); throw OAuthServerException::invalidClient($request); @@ -294,14 +295,14 @@ protected function validateRedirectUri( /** * Validate scopes in the request. * - * @param null|string|array $scopes + * @param null|string|string[] $scopes * @param string $redirectUri * * @throws OAuthServerException * * @return ScopeEntityInterface[] */ - public function validateScopes($scopes, $redirectUri = null) + public function validateScopes($scopes, $redirectUri = null): array { if ($scopes === null) { $scopes = []; @@ -333,9 +334,9 @@ public function validateScopes($scopes, $redirectUri = null) * * @param string $scopes * - * @return array + * @return string[] */ - private function convertScopesQueryStringToArray(string $scopes) + private function convertScopesQueryStringToArray(string $scopes): array { return \array_filter(\explode(self::SCOPE_DELIMITER_STRING, \trim($scopes)), function ($scope) { return $scope !== ''; diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index d08dffc86..125562d6f 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -24,7 +24,6 @@ use League\OAuth2\Server\RequestEvent; use League\OAuth2\Server\RequestRefreshTokenEvent; use League\OAuth2\Server\RequestTypes\AuthorizationRequestInterface; -use League\OAuth2\Server\RequestTypes\AuthorizationRequest; use League\OAuth2\Server\ResponseTypes\RedirectResponse; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; use LogicException; @@ -77,7 +76,7 @@ public function __construct( /** * Disable the requirement for a code challenge for public clients. */ - public function disableRequireCodeChallengeForPublicClients() + public function disableRequireCodeChallengeForPublicClients(): void { $this->requireCodeChallengeForPublicClients = false; } @@ -194,7 +193,7 @@ private function validateAuthorizationCode( $authCodePayload, ClientEntityInterface $client, ServerRequestInterface $request - ) { + ): void { if (!\property_exists($authCodePayload, 'auth_code_id')) { throw OAuthServerException::invalidRequest('code', 'Authorization code malformed'); } diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index d7e003835..f8dffd578 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -32,7 +32,7 @@ interface GrantTypeInterface extends EmitterAwareInterface * * @param DateInterval $refreshTokenTTL */ - public function setRefreshTokenTTL(DateInterval $refreshTokenTTL); + public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void; /** * Return the grant identifier that can be used in matching up requests. @@ -105,35 +105,35 @@ public function canRespondToAccessTokenRequest(ServerRequestInterface $request); * * @param ClientRepositoryInterface $clientRepository */ - public function setClientRepository(ClientRepositoryInterface $clientRepository); + public function setClientRepository(ClientRepositoryInterface $clientRepository): void; /** * Set the access token repository. * * @param AccessTokenRepositoryInterface $accessTokenRepository */ - public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository); + public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository): void; /** * Set the scope repository. * * @param ScopeRepositoryInterface $scopeRepository */ - public function setScopeRepository(ScopeRepositoryInterface $scopeRepository); + public function setScopeRepository(ScopeRepositoryInterface $scopeRepository): void; /** * Set the default scope. * * @param string $scope */ - public function setDefaultScope($scope); + public function setDefaultScope($scope): void; /** * Set the path to the private key. * * @param CryptKeyInterface $privateKey */ - public function setPrivateKey(CryptKeyInterface $privateKey); + public function setPrivateKey(CryptKeyInterface $privateKey): void; public function setEncryptionKey(Key|string|null $key = null): void; diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index a39bf0733..e6acede56 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -47,7 +47,7 @@ public function __construct(DateInterval $accessTokenTTL, $queryDelimiter = '#') * * @throw LogicException */ - public function setRefreshTokenTTL(DateInterval $refreshTokenTTL) + public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void { throw new LogicException('The Implicit Grant does not return refresh tokens'); } @@ -57,7 +57,7 @@ public function setRefreshTokenTTL(DateInterval $refreshTokenTTL) * * @throw LogicException */ - public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository) + public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository): void { throw new LogicException('The Implicit Grant does not return refresh tokens'); } diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index e8248b242..541faa4ab 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -95,9 +95,9 @@ public function respondToAccessTokenRequest( * * @throws OAuthServerException * - * @return array + * @return array */ - protected function validateOldRefreshToken(ServerRequestInterface $request, $clientId) + protected function validateOldRefreshToken(ServerRequestInterface $request, $clientId): array { $encryptedRefreshToken = $this->getRequestParameter('refresh_token', $request); if (!\is_string($encryptedRefreshToken)) { From cfcdf2870525a699b4e3aacbfef061334b649fe0 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 25 Jul 2023 23:36:26 +0100 Subject: [PATCH 36/46] Fix PHP stan issues to level 8 --- composer.json | 8 +- phpstan.neon.dist | 2 +- .../BearerTokenValidator.php | 9 +- src/CryptKey.php | 12 +- src/Entities/Traits/AccessTokenTrait.php | 9 +- src/Grant/AbstractGrant.php | 15 +- src/Grant/AuthCodeGrant.php | 7 + tests/AuthorizationServerTest.php | 5 +- tests/Grant/AuthCodeGrantTest.php | 425 +++++++----------- tests/Grant/RefreshTokenGrantTest.php | 300 ++++++++----- tests/PHPStan/AbstractGrantExtension.php | 2 +- tests/Stubs/GrantType.php | 4 +- tests/Utils/CryptKeyTest.php | 15 + 13 files changed, 423 insertions(+), 390 deletions(-) diff --git a/composer.json b/composer.json index b4e02c928..5f1ec4721 100644 --- a/composer.json +++ b/composer.json @@ -16,9 +16,10 @@ "require-dev": { "phpunit/phpunit": "^9.5.11", "laminas/laminas-diactoros": "^2.8.0", - "phpstan/phpstan": "^1.4", + "phpstan/phpstan": "^1.10.26", "phpstan/phpstan-phpunit": "^1.0.0", - "roave/security-advisories": "dev-master" + "roave/security-advisories": "dev-master", + "phpstan/extension-installer": "^1.3" }, "repositories": [ { @@ -72,7 +73,8 @@ }, "config": { "allow-plugins": { - "ocramius/package-versions": true + "ocramius/package-versions": true, + "phpstan/extension-installer": true } } } diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ea81a8e66..44d720f86 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: 6 + level: 8 paths: - src - tests diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index f9b0ae5db..d8854efb5 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -24,6 +24,7 @@ use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use Psr\Http\Message\ServerRequestInterface; +use RuntimeException; class BearerTokenValidator implements AuthorizationValidatorInterface { @@ -74,13 +75,19 @@ private function initJwtConfiguration(): void InMemory::plainText('empty', 'empty') ); + $publicKeyContents = $this->publicKey->getKeyContents(); + + if ($publicKeyContents === '') { + throw new RuntimeException('Public key is empty'); + } + $this->jwtConfiguration->setValidationConstraints( \class_exists(LooseValidAt::class) ? new LooseValidAt(new SystemClock(new DateTimeZone(\date_default_timezone_get()))) : new ValidAt(new SystemClock(new DateTimeZone(\date_default_timezone_get()))), new SignedWith( new Sha256(), - InMemory::plainText($this->publicKey->getKeyContents(), $this->publicKey->getPassPhrase() ?? '') + InMemory::plainText($publicKeyContents, $this->publicKey->getPassPhrase() ?? '') ) ); } diff --git a/src/CryptKey.php b/src/CryptKey.php index b9f8ef314..351bf9cf0 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -13,6 +13,8 @@ use LogicException; +use function file_get_contents; + class CryptKey implements CryptKeyInterface { /** @deprecated left for backward compatibility check */ @@ -58,8 +60,16 @@ public function __construct($keyPath, $passPhrase = null, $keyPermissionsCheck = if (!\is_readable($keyPath)) { throw new LogicException(\sprintf('Key path "%s" does not exist or is not readable', $keyPath)); } - $this->keyContents = \file_get_contents($keyPath); + + $keyContents = file_get_contents($keyPath); + + if ($keyContents === false) { + throw new LogicException('Unable to read key from file ' . $keyPath); + } + + $this->keyContents = $keyContents; $this->keyPath = $keyPath; + if (!$this->isValidKey($this->keyContents, $this->passPhrase ?? '')) { throw new LogicException('Unable to read key from file ' . $keyPath); } diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index 9056db833..35300fa4c 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -17,6 +17,7 @@ use League\OAuth2\Server\CryptKeyInterface; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; +use RuntimeException; trait AccessTokenTrait { @@ -43,9 +44,15 @@ public function setPrivateKey(CryptKeyInterface $privateKey): void */ public function initJwtConfiguration(): void { + $privateKeyContents = $this->privateKey->getKeyContents(); + + if ($privateKeyContents === '') { + throw new RuntimeException('Private key is empty'); + } + $this->jwtConfiguration = Configuration::forAsymmetricSigner( new Sha256(), - InMemory::plainText($this->privateKey->getKeyContents(), $this->privateKey->getPassPhrase() ?? ''), + InMemory::plainText($privateKeyContents, $this->privateKey->getPassPhrase() ?? ''), InMemory::plainText('empty', 'empty') ); } diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 9cdbde944..ee8cc6ae9 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -1,4 +1,5 @@ getQueryStringParameter('code_challenge_method', $request, 'plain'); + if ($codeChallengeMethod === null) { + throw OAuthServerException::invalidRequest( + 'code_challenge_method', + 'Code challenge method must be provided when `code_challenge` is set.' + ); + } + if (\array_key_exists($codeChallengeMethod, $this->codeChallengeVerifiers) === false) { throw OAuthServerException::invalidRequest( 'code_challenge_method', diff --git a/tests/AuthorizationServerTest.php b/tests/AuthorizationServerTest.php index e49e8ac1a..3e9805472 100644 --- a/tests/AuthorizationServerTest.php +++ b/tests/AuthorizationServerTest.php @@ -3,6 +3,7 @@ namespace LeagueTests; use DateInterval; +use Defuse\Crypto\Key; use Laminas\Diactoros\Response; use Laminas\Diactoros\ServerRequest; use Laminas\Diactoros\ServerRequestFactory; @@ -21,13 +22,11 @@ use LeagueTests\Stubs\AccessTokenEntity; use LeagueTests\Stubs\AuthCodeEntity; use LeagueTests\Stubs\ClientEntity; -use LeagueTests\Stubs\GrantType; use LeagueTests\Stubs\ScopeEntity; use LeagueTests\Stubs\StubResponseType; use LeagueTests\Stubs\UserEntity; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\ServerRequestInterface; class AuthorizationServerTest extends TestCase { @@ -181,7 +180,7 @@ public function getPrivateKey(): CryptKeyInterface|null return $this->privateKey; } - public function getEncryptionKey(): string|null + public function getEncryptionKey(): Key|string|null { return $this->encryptionKey; } diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index 086f37dde..b5843c29b 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -28,6 +28,8 @@ use LeagueTests\Stubs\UserEntity; use PHPUnit\Framework\TestCase; +use function json_encode; + class AuthCodeGrantTest extends TestCase { const DEFAULT_SCOPE = 'basic'; @@ -571,16 +573,14 @@ public function testRespondToAccessTokenRequest(): void 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -637,16 +637,14 @@ public function testRespondToAccessTokenRequestUsingHttpBasicAuth(): void 'grant_type' => 'authorization_code', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'client_id' => 'foo', - 'expire_time' => \time() + 3600, - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'client_id' => 'foo', + 'expire_time' => \time() + 3600, + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -705,16 +703,14 @@ public function testRespondToAccessTokenRequestForPublicClient(): void 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -773,16 +769,14 @@ public function testRespondToAccessTokenRequestNullRefreshToken(): void 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -844,18 +838,16 @@ public function testRespondToAccessTokenRequestCodeChallengePlain(): void 'redirect_uri' => 'http://foo/bar', 'code_verifier' => self::CODE_VERIFIER, 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => self::CODE_VERIFIER, - 'code_challenge_method' => 'plain', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + 'code_challenge' => self::CODE_VERIFIER, + 'code_challenge_method' => 'plain', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -917,18 +909,16 @@ public function testRespondToAccessTokenRequestCodeChallengeS256(): void 'redirect_uri' => 'http://foo/bar', 'code_verifier' => self::CODE_VERIFIER, 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => self::CODE_CHALLENGE, - 'code_challenge_method' => 'S256', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + 'code_challenge' => self::CODE_CHALLENGE, + 'code_challenge_method' => 'S256', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -970,14 +960,12 @@ public function testRespondToAccessTokenRequestMissingRedirectUri(): void 'client_id' => 'foo', 'grant_type' => 'authorization_code', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1019,14 +1007,12 @@ public function testRespondToAccessTokenRequestRedirectUriMismatch(): void 'grant_type' => 'authorization_code', 'redirect_uri' => 'http://bar/foo', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1113,16 +1099,14 @@ public function testRespondToAccessTokenRequestWithRefreshTokenInsteadOfAuthCode 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => 'zyxwvu', - 'access_token_id' => 'abcdef', - 'scopes' => ['foo'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + json_encode([ + 'client_id' => 'foo', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1204,16 +1188,14 @@ public function testRespondToAccessTokenRequestExpiredCode(): void 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() - 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() - 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1268,16 +1250,14 @@ public function testRespondToAccessTokenRequestRevokedCode(): void 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1330,16 +1310,14 @@ public function testRespondToAccessTokenRequestClientMismatch(): void 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'bar', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'bar', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1451,18 +1429,16 @@ public function testRespondToAccessTokenRequestBadCodeVerifierPlain(): void 'redirect_uri' => 'http://foo/bar', 'code_verifier' => self::CODE_VERIFIER, 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => 'foobar', - 'code_challenge_method' => 'plain', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + 'code_challenge' => 'foobar', + 'code_challenge_method' => 'plain', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1524,18 +1500,16 @@ public function testRespondToAccessTokenRequestBadCodeVerifierS256(): void 'redirect_uri' => 'http://foo/bar', 'code_verifier' => 'nope', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => 'foobar', - 'code_challenge_method' => 'S256', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + 'code_challenge' => 'foobar', + 'code_challenge_method' => 'S256', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1597,18 +1571,16 @@ public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInva 'redirect_uri' => 'http://foo/bar', 'code_verifier' => 'dqX7C-RbqjHYtytmhGTigKdZCXfxq-+xbsk9_GxUcaE', // Malformed code. Contains `+`. 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => self::CODE_CHALLENGE, - 'code_challenge_method' => 'S256', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + 'code_challenge' => self::CODE_CHALLENGE, + 'code_challenge_method' => 'S256', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1670,18 +1642,16 @@ public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInva 'redirect_uri' => 'http://foo/bar', 'code_verifier' => 'dqX7C-RbqjHY', // Malformed code. Invalid length. 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => 'R7T1y1HPNFvs1WDCrx4lfoBS6KD2c71pr8OHvULjvv8', - 'code_challenge_method' => 'S256', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + 'code_challenge' => 'R7T1y1HPNFvs1WDCrx4lfoBS6KD2c71pr8OHvULjvv8', + 'code_challenge_method' => 'S256', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1742,18 +1712,16 @@ public function testRespondToAccessTokenRequestMissingCodeVerifier(): void 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => 'foobar', - 'code_challenge_method' => 'plain', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + 'code_challenge' => 'foobar', + 'code_challenge_method' => 'plain', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1905,16 +1873,14 @@ public function testRefreshTokenRepositoryUniqueConstraintCheck(): void 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -1973,16 +1939,14 @@ public function testRefreshTokenRepositoryFailToPersist(): void 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -2044,16 +2008,14 @@ public function testRefreshTokenRepositoryFailToPersistUniqueNoInfiniteLoop(): v 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( - \json_encode( - [ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, - 'client_id' => 'foo', - 'user_id' => 123, - 'scopes' => ['foo'], - 'redirect_uri' => 'http://foo/bar', - ] - ) + json_encode([ + 'auth_code_id' => \uniqid(), + 'expire_time' => \time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ], JSON_THROW_ON_ERROR) ), ] ); @@ -2161,47 +2123,4 @@ public function testUseValidRedirectUriIfScopeCheckFails(): void $this->assertStringStartsWith('http://bar/foo', $response->getHeader('Location')[0]); } } - - public function testThrowExceptionWhenNoClientRedirectUriRegistered(): void - { - $client = new ClientEntity(); - - $client->setConfidential(); - - $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); - $clientRepositoryMock->method('getClientEntity')->willReturn($client); - - $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); - $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn(null); - - $grant = new AuthCodeGrant( - $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), - $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), - new DateInterval('PT10M') - ); - - $grant->setClientRepository($clientRepositoryMock); - $grant->setScopeRepository($scopeRepositoryMock); - $grant->setDefaultScope(self::DEFAULT_SCOPE); - - $request = new ServerRequest( - [], - [], - null, - null, - 'php://input', - [], - [], - [ - 'response_type' => 'code', - 'client_id' => 'foo', - 'redirect_uri' => 'http://bar/foo', - ] - ); - - $this->expectException(OAuthServerException::class); - $this->expectExceptionCode(4); - - $grant->validateAuthorizationRequest($request); - } } diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index f61c4e530..aa2bb101e 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -72,23 +72,29 @@ public function testRespondToRequest(): void $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->revokeRefreshTokens(true); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => 'zyxwvu', - 'access_token_id' => 'abcdef', - 'scopes' => ['foo'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, 'scopes' => ['foo'], ]); @@ -130,23 +136,29 @@ public function testRespondToRequestNullRefreshToken(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => 'zyxwvu', - 'access_token_id' => 'abcdef', - 'scopes' => ['foo'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, 'scopes' => ['foo'], ]); @@ -188,23 +200,29 @@ public function testRespondToReducedScopes(): void $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->revokeRefreshTokens(true); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => 'zyxwvu', - 'access_token_id' => 'abcdef', - 'scopes' => ['foo', 'bar'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo', 'bar'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, 'scope' => 'foo', ]); @@ -242,23 +260,29 @@ public function testRespondToUnexpectedScope(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => 'zyxwvu', - 'access_token_id' => 'abcdef', - 'scopes' => ['foo', 'bar'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo', 'bar'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, 'scope' => 'foobar', ]); @@ -356,23 +380,29 @@ public function testRespondToRequestClientMismatch(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'bar', - 'refresh_token_id' => 'zyxwvu', - 'access_token_id' => 'abcdef', - 'scopes' => ['foo'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'bar', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, ]); $responseType = new StubResponseType(); @@ -401,23 +431,29 @@ public function testRespondToRequestExpiredToken(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => 'zyxwvu', - 'access_token_id' => 'abcdef', - 'scopes' => ['foo'], - 'user_id' => 123, - 'expire_time' => \time() - 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo'], + 'user_id' => 123, + 'expire_time' => \time() - 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, ]); $responseType = new StubResponseType(); @@ -447,23 +483,29 @@ public function testRespondToRequestRevokedToken(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => 'zyxwvu', - 'access_token_id' => 'abcdef', - 'scopes' => ['foo'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, ]); $responseType = new StubResponseType(); @@ -522,23 +564,29 @@ public function testRespondToRequestFinalizeScopes(): void ->with($client, $finalizedScopes) ->willReturn(new AccessTokenEntity()); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => 'zyxwvu', - 'access_token_id' => 'abcdef', - 'scopes' => ['foo', 'bar'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo', 'bar'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, 'scope' => ['foo', 'bar'], ]); @@ -574,23 +622,29 @@ public function testRevokedRefreshToken(): void ->will($this->onConsecutiveCalls(false, true)); $refreshTokenRepositoryMock->expects($this->once())->method('revokeRefreshToken')->with($this->equalTo($refreshTokenId)); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => $refreshTokenId, - 'access_token_id' => 'abcdef', - 'scopes' => ['foo'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => $refreshTokenId, + 'access_token_id' => 'abcdef', + 'scopes' => ['foo'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, 'scope' => ['foo'], ]); @@ -632,23 +686,29 @@ public function testUnrevokedRefreshToken(): void $refreshTokenRepositoryMock->method('isRefreshTokenRevoked')->willReturn(false); $refreshTokenRepositoryMock->expects($this->never())->method('revokeRefreshToken'); - $oldRefreshToken = $this->cryptStub->doEncrypt( - \json_encode( - [ - 'client_id' => 'foo', - 'refresh_token_id' => $refreshTokenId, - 'access_token_id' => 'abcdef', - 'scopes' => ['foo'], - 'user_id' => 123, - 'expire_time' => \time() + 3600, - ] - ) + $oldRefreshToken = \json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => $refreshTokenId, + 'access_token_id' => 'abcdef', + 'scopes' => ['foo'], + 'user_id' => 123, + 'expire_time' => \time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + $this->fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', 'client_secret' => 'bar', - 'refresh_token' => $oldRefreshToken, + 'refresh_token' => $encryptedOldRefreshToken, 'scope' => ['foo'], ]); diff --git a/tests/PHPStan/AbstractGrantExtension.php b/tests/PHPStan/AbstractGrantExtension.php index da65ab961..121648e13 100644 --- a/tests/PHPStan/AbstractGrantExtension.php +++ b/tests/PHPStan/AbstractGrantExtension.php @@ -33,7 +33,7 @@ public function getTypeFromMethodCall(MethodReflection $methodReflection, Method { return TypeCombinator::union(...[ new StringType(), - isset($methodCall->args[2]) ? $scope->getType($methodCall->args[2]->value) : new NullType(), + isset($methodCall->getArgs[2]) ? $scope->getType($methodCall->getArgs[2]->value) : new NullType(), ]); } } diff --git a/tests/Stubs/GrantType.php b/tests/Stubs/GrantType.php index d08d99b03..37c75fdcd 100644 --- a/tests/Stubs/GrantType.php +++ b/tests/Stubs/GrantType.php @@ -20,7 +20,7 @@ final class GrantType implements GrantTypeInterface { - private EmitterInterface $emitter; + private ?EmitterInterface $emitter; public function setEmitter(EmitterInterface $emitter = null): self { @@ -29,7 +29,7 @@ public function setEmitter(EmitterInterface $emitter = null): self return $this; } - public function getEmitter(): EmitterInterface + public function getEmitter(): ?EmitterInterface { return $this->emitter; } diff --git a/tests/Utils/CryptKeyTest.php b/tests/Utils/CryptKeyTest.php index 453d30dfa..542fdc2b9 100644 --- a/tests/Utils/CryptKeyTest.php +++ b/tests/Utils/CryptKeyTest.php @@ -64,6 +64,11 @@ public function testUnsupportedKeyType(): void 'private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_DSA, ]); + + if ($res === false) { + $this->fail('The keypair was not created'); + } + // Get private key \openssl_pkey_export($res, $keyContent, 'mystrongpassword'); $path = self::generateKeyPath($keyContent); @@ -85,6 +90,11 @@ public function testECKeyType(): void 'curve_name' => 'prime256v1', 'private_key_type' => OPENSSL_KEYTYPE_EC, ]); + + if ($res === false) { + $this->fail('The keypair was not created'); + } + // Get private key \openssl_pkey_export($res, $keyContent, 'mystrongpassword'); @@ -106,6 +116,11 @@ public function testRSAKeyType(): void 'private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA, ]); + + if ($res === false) { + $this->fail('The keypair was not created'); + } + // Get private key \openssl_pkey_export($res, $keyContent, 'mystrongpassword'); From 9433aea26c8fe94352743fcd7b4dadceec722f7e Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 5 Sep 2023 22:02:51 +0100 Subject: [PATCH 37/46] Fix deprecation in PHPUnit --- tests/ResponseTypes/BearerResponseTypeTest.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index 7b7c85fa1..6c8c1fd03 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -58,9 +58,9 @@ public function testGenerateHttpResponse(): void $response->getBody()->rewind(); $json = \json_decode($response->getBody()->getContents()); $this->assertEquals('Bearer', $json->token_type); - $this->assertObjectHasAttribute('expires_in', $json); - $this->assertObjectHasAttribute('access_token', $json); - $this->assertObjectHasAttribute('refresh_token', $json); + $this->assertObjectHasProperty('expires_in', $json); + $this->assertObjectHasProperty('access_token', $json); + $this->assertObjectHasProperty('refresh_token', $json); } public function testGenerateHttpResponseWithExtraParams(): void @@ -101,11 +101,11 @@ public function testGenerateHttpResponseWithExtraParams(): void $response->getBody()->rewind(); $json = \json_decode($response->getBody()->getContents()); $this->assertEquals('Bearer', $json->token_type); - $this->assertObjectHasAttribute('expires_in', $json); - $this->assertObjectHasAttribute('access_token', $json); - $this->assertObjectHasAttribute('refresh_token', $json); + $this->assertObjectHasProperty('expires_in', $json); + $this->assertObjectHasProperty('access_token', $json); + $this->assertObjectHasProperty('refresh_token', $json); - $this->assertObjectHasAttribute('foo', $json); + $this->assertObjectHasProperty('foo', $json); $this->assertEquals('bar', $json->foo); } From 068a13e3e32fc424e9bdd9b5f9ae4c78220be8c3 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 27 Sep 2023 23:44:43 +0100 Subject: [PATCH 38/46] Fix tests --- composer.json | 12 +- src/AuthorizationServer.php | 109 ++----- .../AuthorizationValidatorInterface.php | 12 +- .../BearerTokenValidator.php | 30 +- .../CodeChallengeVerifierInterface.php | 11 +- src/CodeChallengeVerifiers/PlainVerifier.php | 15 +- src/CodeChallengeVerifiers/S256Verifier.php | 21 +- src/CryptKey.php | 63 ++-- src/CryptKeyInterface.php | 9 +- src/CryptTrait.php | 17 +- src/Entities/AccessTokenEntityInterface.php | 5 +- src/Entities/AuthCodeEntityInterface.php | 3 + src/Entities/ClientEntityInterface.php | 14 +- src/Entities/RefreshTokenEntityInterface.php | 6 +- src/Entities/ScopeEntityInterface.php | 6 +- src/Entities/TokenInterface.php | 11 +- src/Entities/Traits/AccessTokenTrait.php | 22 +- src/Entities/Traits/AuthCodeTrait.php | 3 + src/Entities/Traits/ClientTrait.php | 11 +- src/Entities/Traits/EntityTrait.php | 16 +- src/Entities/Traits/RefreshTokenTrait.php | 3 + src/Entities/Traits/ScopeTrait.php | 9 +- src/Entities/Traits/TokenEntityTrait.php | 11 +- src/Entities/UserEntityInterface.php | 6 +- src/Exception/OAuthServerException.php | 91 +++--- ...IdentifierConstraintViolationException.php | 6 +- src/Grant/AbstractAuthorizeGrant.php | 18 +- src/Grant/AbstractGrant.php | 140 +++----- src/Grant/AuthCodeGrant.php | 92 +++--- src/Grant/ClientCredentialsGrant.php | 7 +- src/Grant/GrantTypeInterface.php | 40 +-- src/Grant/ImplicitGrant.php | 41 ++- src/Grant/PasswordGrant.php | 21 +- src/Grant/RefreshTokenGrant.php | 26 +- .../AuthorizationServerMiddleware.php | 10 +- src/Middleware/ResourceServerMiddleware.php | 10 +- .../RedirectUriValidator.php | 33 +- .../RedirectUriValidatorInterface.php | 6 +- .../AccessTokenRepositoryInterface.php | 8 +- .../AuthCodeRepositoryInterface.php | 3 + .../ClientRepositoryInterface.php | 9 +- .../RefreshTokenRepositoryInterface.php | 3 + src/Repositories/RepositoryInterface.php | 3 + src/Repositories/ScopeRepositoryInterface.php | 18 +- src/Repositories/UserRepositoryInterface.php | 15 +- src/RequestAccessTokenEvent.php | 10 +- src/RequestEvent.php | 20 +- src/RequestRefreshTokenEvent.php | 10 +- src/RequestTypes/AuthorizationRequest.php | 3 + .../AuthorizationRequestInterface.php | 3 + src/ResourceServer.php | 14 +- src/ResponseTypes/AbstractResponseType.php | 3 + src/ResponseTypes/BearerTokenResponse.php | 25 +- src/ResponseTypes/RedirectResponse.php | 3 + src/ResponseTypes/ResponseTypeInterface.php | 3 + tests/AuthorizationServerTest.php | 133 +++----- .../BearerTokenValidatorTest.php | 13 +- tests/Bootstrap.php | 2 + .../PlainVerifierTest.php | 8 +- .../S256VerifierTest.php | 15 +- tests/Exception/OAuthServerExceptionTest.php | 25 +- tests/Grant/AbstractGrantTest.php | 147 +++++---- tests/Grant/AuthCodeGrantTest.php | 299 +++++++++++------- tests/Grant/ClientCredentialsGrantTest.php | 12 +- tests/Grant/ImplicitGrantTest.php | 65 ++-- tests/Grant/PasswordGrantTest.php | 21 +- tests/Grant/RefreshTokenGrantTest.php | 121 +++---- .../AuthorizationServerMiddlewareTest.php | 30 +- .../ResourceServerMiddlewareTest.php | 25 +- tests/PHPStan/AbstractGrantExtension.php | 7 +- .../RedirectUriValidatorTest.php | 18 +- tests/ResourceServerTest.php | 3 +- .../ResponseTypes/BearerResponseTypeTest.php | 93 +++--- .../BearerTokenResponseWithParams.php | 3 +- tests/Stubs/AccessTokenEntity.php | 6 +- tests/Stubs/AuthCodeEntity.php | 6 +- tests/Stubs/ClientEntity.php | 5 +- tests/Stubs/CryptTraitStub.php | 7 +- tests/Stubs/GrantType.php | 4 +- tests/Stubs/RefreshTokenEntity.php | 5 +- tests/Stubs/ScopeEntity.php | 7 +- tests/Stubs/StubResponseType.php | 2 + tests/Stubs/UserEntity.php | 4 +- tests/Utils/CryptKeyTest.php | 78 +++-- tests/Utils/CryptTraitTest.php | 11 +- 85 files changed, 1196 insertions(+), 1098 deletions(-) diff --git a/composer.json b/composer.json index 5f1ec4721..6c7d6fc0d 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,14 @@ "phpunit/phpunit": "^9.5.11", "laminas/laminas-diactoros": "^2.8.0", "phpstan/phpstan": "^1.10.26", - "phpstan/phpstan-phpunit": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.3.14", "roave/security-advisories": "dev-master", - "phpstan/extension-installer": "^1.3" + "phpstan/extension-installer": "^1.3", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-strict-rules": "^1.5", + "slevomat/coding-standard": "^8.13", + "php-parallel-lint/php-parallel-lint": "^1.3", + "squizlabs/php_codesniffer": "^3.7" }, "repositories": [ { @@ -74,7 +79,8 @@ "config": { "allow-plugins": { "ocramius/package-versions": true, - "phpstan/extension-installer": true + "phpstan/extension-installer": true, + "dealerdirect/phpcodesniffer-composer-installer": false } } } diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index 85369a0bc..05e32060a 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server; use DateInterval; @@ -32,75 +35,41 @@ class AuthorizationServer implements EmitterAwareInterface /** * @var GrantTypeInterface[] */ - protected $enabledGrantTypes = []; + protected array $enabledGrantTypes = []; /** * @var DateInterval[] */ - protected $grantTypeAccessTokenTTL = []; + protected array $grantTypeAccessTokenTTL = []; - /** - * @var CryptKeyInterface - */ - protected $privateKey; + protected CryptKeyInterface $privateKey; - /** - * @var CryptKeyInterface - */ - protected $publicKey; + protected CryptKeyInterface $publicKey; - /** - * @var ResponseTypeInterface - */ - protected $responseType; + protected ResponseTypeInterface $responseType; - /** - * @var ClientRepositoryInterface - */ - private $clientRepository; + private ClientRepositoryInterface $clientRepository; - /** - * @var AccessTokenRepositoryInterface - */ - private $accessTokenRepository; + private AccessTokenRepositoryInterface $accessTokenRepository; - /** - * @var ScopeRepositoryInterface - */ - private $scopeRepository; + private ScopeRepositoryInterface $scopeRepository; - /** - * @var string|Key - */ - private $encryptionKey; + private string|Key $encryptionKey; - /** - * @var string - */ - private $defaultScope = ''; + private string $defaultScope = ''; - /** - * @var bool - */ - private $revokeRefreshTokens = true; + private bool $revokeRefreshTokens = true; /** - * New server instance. - * - * @param ClientRepositoryInterface $clientRepository - * @param AccessTokenRepositoryInterface $accessTokenRepository - * @param ScopeRepositoryInterface $scopeRepository - * @param CryptKeyInterface|string $privateKey - * @param string|Key $encryptionKey - * @param null|ResponseTypeInterface $responseType + * New server instance */ public function __construct( ClientRepositoryInterface $clientRepository, AccessTokenRepositoryInterface $accessTokenRepository, ScopeRepositoryInterface $scopeRepository, - $privateKey, - $encryptionKey, - ResponseTypeInterface $responseType = null + CryptKeyInterface|string $privateKey, + Key|string $encryptionKey, + ResponseTypeInterface|null $responseType = null ) { $this->clientRepository = $clientRepository; $this->accessTokenRepository = $accessTokenRepository; @@ -123,12 +92,9 @@ public function __construct( } /** - * Enable a grant type on the server. - * - * @param GrantTypeInterface $grantType - * @param null|DateInterval $accessTokenTTL + * Enable a grant type on the server */ - public function enableGrantType(GrantTypeInterface $grantType, DateInterval $accessTokenTTL = null): void + public function enableGrantType(GrantTypeInterface $grantType, DateInterval|null $accessTokenTTL = null): void { if ($accessTokenTTL === null) { $accessTokenTTL = new DateInterval('PT1H'); @@ -150,13 +116,9 @@ public function enableGrantType(GrantTypeInterface $grantType, DateInterval $acc /** * Validate an authorization request * - * @param ServerRequestInterface $request - * * @throws OAuthServerException - * - * @return AuthorizationRequestInterface */ - public function validateAuthorizationRequest(ServerRequestInterface $request) + public function validateAuthorizationRequest(ServerRequestInterface $request): AuthorizationRequestInterface { foreach ($this->enabledGrantTypes as $grantType) { if ($grantType->canRespondToAuthorizationRequest($request)) { @@ -169,16 +131,11 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) /** * Complete an authorization request - * - * @param AuthorizationRequestInterface $authRequest - * @param ResponseInterface $response - * - * @return ResponseInterface */ public function completeAuthorizationRequest( AuthorizationRequestInterface $authRequest, ResponseInterface $response - ) { + ): ResponseInterface { return $this->enabledGrantTypes[$authRequest->getGrantTypeId()] ->completeAuthorizationRequest($authRequest) ->generateHttpResponse($response); @@ -187,28 +144,22 @@ public function completeAuthorizationRequest( /** * Return an access token response. * - * @param ServerRequestInterface $request - * @param ResponseInterface $response - * * @throws OAuthServerException - * - * @return ResponseInterface */ - public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response) + public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { foreach ($this->enabledGrantTypes as $grantType) { if (!$grantType->canRespondToAccessTokenRequest($request)) { continue; } + $tokenResponse = $grantType->respondToAccessTokenRequest( $request, $this->getResponseType(), $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] ); - if ($tokenResponse instanceof ResponseTypeInterface) { - return $tokenResponse->generateHttpResponse($response); - } + return $tokenResponse->generateHttpResponse($response); } throw OAuthServerException::unsupportedGrantType(); @@ -216,10 +167,8 @@ public function respondToAccessTokenRequest(ServerRequestInterface $request, Res /** * Get the token type that grants will return in the HTTP response. - * - * @return ResponseTypeInterface */ - protected function getResponseType() + protected function getResponseType(): ResponseTypeInterface { $responseType = clone $this->responseType; @@ -234,18 +183,14 @@ protected function getResponseType() /** * Set the default scope for the authorization server. - * - * @param string $defaultScope */ - public function setDefaultScope($defaultScope): void + public function setDefaultScope(string $defaultScope): void { $this->defaultScope = $defaultScope; } /** * Sets whether to revoke refresh tokens or not (for all grant types). - * - * @param bool $revokeRefreshTokens */ public function revokeRefreshTokens(bool $revokeRefreshTokens): void { diff --git a/src/AuthorizationValidators/AuthorizationValidatorInterface.php b/src/AuthorizationValidators/AuthorizationValidatorInterface.php index 7e49f8477..275853409 100644 --- a/src/AuthorizationValidators/AuthorizationValidatorInterface.php +++ b/src/AuthorizationValidators/AuthorizationValidatorInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\AuthorizationValidators; use Psr\Http\Message\ServerRequestInterface; @@ -14,12 +17,9 @@ interface AuthorizationValidatorInterface { /** - * Determine the access token in the authorization header and append OAUth properties to the request - * as attributes. - * - * @param ServerRequestInterface $request + * Determine the access token in the authorization header and append OAUth + * properties to the request as attributes. * - * @return ServerRequestInterface */ - public function validateAuthorization(ServerRequestInterface $request); + public function validateAuthorization(ServerRequestInterface $request): ServerRequestInterface; } diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index d8854efb5..e7e32700d 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,17 +8,19 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\AuthorizationValidators; use DateTimeZone; use Lcobucci\Clock\SystemClock; use Lcobucci\JWT\Configuration; +use Lcobucci\JWT\Exception; use Lcobucci\JWT\Signer\Key\InMemory; use Lcobucci\JWT\Signer\Rsa\Sha256; use Lcobucci\JWT\UnencryptedToken; -use Lcobucci\JWT\Validation\Constraint\SignedWith; use Lcobucci\JWT\Validation\Constraint\LooseValidAt; -use Lcobucci\JWT\Validation\Constraint\ValidAt; +use Lcobucci\JWT\Validation\Constraint\SignedWith; use Lcobucci\JWT\Validation\RequiredConstraintsViolated; use League\OAuth2\Server\CryptKeyInterface; use League\OAuth2\Server\CryptTrait; @@ -26,6 +29,12 @@ use Psr\Http\Message\ServerRequestInterface; use RuntimeException; +use function count; +use function date_default_timezone_get; +use function is_array; +use function preg_replace; +use function trim; + class BearerTokenValidator implements AuthorizationValidatorInterface { use CryptTrait; @@ -46,7 +55,6 @@ class BearerTokenValidator implements AuthorizationValidatorInterface private $jwtConfiguration; /** - * @param AccessTokenRepositoryInterface $accessTokenRepository */ public function __construct(AccessTokenRepositoryInterface $accessTokenRepository) { @@ -56,7 +64,6 @@ public function __construct(AccessTokenRepositoryInterface $accessTokenRepositor /** * Set the public key * - * @param CryptKeyInterface $key */ public function setPublicKey(CryptKeyInterface $key): void { @@ -82,9 +89,7 @@ private function initJwtConfiguration(): void } $this->jwtConfiguration->setValidationConstraints( - \class_exists(LooseValidAt::class) - ? new LooseValidAt(new SystemClock(new DateTimeZone(\date_default_timezone_get()))) - : new ValidAt(new SystemClock(new DateTimeZone(\date_default_timezone_get()))), + new LooseValidAt(new SystemClock(new DateTimeZone(date_default_timezone_get()))), new SignedWith( new Sha256(), InMemory::plainText($publicKeyContents, $this->publicKey->getPassPhrase() ?? '') @@ -95,19 +100,19 @@ private function initJwtConfiguration(): void /** * {@inheritdoc} */ - public function validateAuthorization(ServerRequestInterface $request) + public function validateAuthorization(ServerRequestInterface $request): ServerRequestInterface { if ($request->hasHeader('authorization') === false) { throw OAuthServerException::accessDenied('Missing "Authorization" header'); } $header = $request->getHeader('authorization'); - $jwt = \trim((string) \preg_replace('/^\s*Bearer\s/', '', $header[0])); + $jwt = trim((string) preg_replace('/^\s*Bearer\s/', '', $header[0])); try { // Attempt to parse the JWT $token = $this->jwtConfiguration->parser()->parse($jwt); - } catch (\Lcobucci\JWT\Exception $exception) { + } catch (Exception $exception) { throw OAuthServerException::accessDenied($exception->getMessage(), null, $exception); } @@ -141,12 +146,11 @@ public function validateAuthorization(ServerRequestInterface $request) /** * Convert single record arrays into strings to ensure backwards compatibility between v4 and v3.x of lcobucci/jwt * - * @param mixed $aud * * @return array|string */ - private function convertSingleRecordAudToString($aud): array|string + private function convertSingleRecordAudToString(mixed $aud): array|string { - return \is_array($aud) && \count($aud) === 1 ? $aud[0] : $aud; + return is_array($aud) && count($aud) === 1 ? $aud[0] : $aud; } } diff --git a/src/CodeChallengeVerifiers/CodeChallengeVerifierInterface.php b/src/CodeChallengeVerifiers/CodeChallengeVerifierInterface.php index 3d7ad59c5..f358b5c17 100644 --- a/src/CodeChallengeVerifiers/CodeChallengeVerifierInterface.php +++ b/src/CodeChallengeVerifiers/CodeChallengeVerifierInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Lukáš Unger @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\CodeChallengeVerifiers; interface CodeChallengeVerifierInterface @@ -14,17 +17,13 @@ interface CodeChallengeVerifierInterface /** * Return code challenge method. * - * @return string */ - public function getMethod(); + public function getMethod(): string; /** * Verify the code challenge. * - * @param string $codeVerifier - * @param string $codeChallenge * - * @return bool */ - public function verifyCodeChallenge($codeVerifier, $codeChallenge); + public function verifyCodeChallenge(string $codeVerifier, string $codeChallenge): bool; } diff --git a/src/CodeChallengeVerifiers/PlainVerifier.php b/src/CodeChallengeVerifiers/PlainVerifier.php index cf6b70af1..34a60615c 100644 --- a/src/CodeChallengeVerifiers/PlainVerifier.php +++ b/src/CodeChallengeVerifiers/PlainVerifier.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Lukáš Unger @@ -7,16 +8,19 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\CodeChallengeVerifiers; +use function hash_equals; + class PlainVerifier implements CodeChallengeVerifierInterface { /** * Return code challenge method. * - * @return string */ - public function getMethod() + public function getMethod(): string { return 'plain'; } @@ -24,13 +28,10 @@ public function getMethod() /** * Verify the code challenge. * - * @param string $codeVerifier - * @param string $codeChallenge * - * @return bool */ - public function verifyCodeChallenge($codeVerifier, $codeChallenge) + public function verifyCodeChallenge(string $codeVerifier, string $codeChallenge): bool { - return \hash_equals($codeVerifier, $codeChallenge); + return hash_equals($codeVerifier, $codeChallenge); } } diff --git a/src/CodeChallengeVerifiers/S256Verifier.php b/src/CodeChallengeVerifiers/S256Verifier.php index f70790a3c..e05464f40 100644 --- a/src/CodeChallengeVerifiers/S256Verifier.php +++ b/src/CodeChallengeVerifiers/S256Verifier.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Lukáš Unger @@ -7,16 +8,23 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\CodeChallengeVerifiers; +use function base64_encode; +use function hash; +use function hash_equals; +use function rtrim; +use function strtr; + class S256Verifier implements CodeChallengeVerifierInterface { /** * Return code challenge method. * - * @return string */ - public function getMethod() + public function getMethod(): string { return 'S256'; } @@ -24,15 +32,12 @@ public function getMethod() /** * Verify the code challenge. * - * @param string $codeVerifier - * @param string $codeChallenge * - * @return bool */ - public function verifyCodeChallenge($codeVerifier, $codeChallenge) + public function verifyCodeChallenge(string $codeVerifier, string $codeChallenge): bool { - return \hash_equals( - \strtr(\rtrim(\base64_encode(\hash('sha256', $codeVerifier, true)), '='), '+/', '-_'), + return hash_equals( + strtr(rtrim(base64_encode(hash('sha256', $codeVerifier, true)), '='), '+/', '-_'), $codeChallenge ); } diff --git a/src/CryptKey.php b/src/CryptKey.php index 351bf9cf0..f0a4464ae 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -1,4 +1,5 @@ passPhrase = $passPhrase; - if (\strpos($keyPath, self::FILE_PREFIX) !== 0 && $this->isValidKey($keyPath, $this->passPhrase ?? '')) { + if (strpos($keyPath, self::FILE_PREFIX) !== 0 && $this->isValidKey($keyPath, $this->passPhrase ?? '')) { $this->keyContents = $keyPath; $this->keyPath = ''; // There's no file, so no need for permission check. $keyPermissionsCheck = false; - } elseif (\is_file($keyPath)) { - if (\strpos($keyPath, self::FILE_PREFIX) !== 0) { + } elseif (is_file($keyPath)) { + if (strpos($keyPath, self::FILE_PREFIX) !== 0) { $keyPath = self::FILE_PREFIX . $keyPath; } - if (!\is_readable($keyPath)) { - throw new LogicException(\sprintf('Key path "%s" does not exist or is not readable', $keyPath)); + if (!is_readable($keyPath)) { + throw new LogicException(sprintf('Key path "%s" does not exist or is not readable', $keyPath)); } $keyContents = file_get_contents($keyPath); @@ -79,10 +87,10 @@ public function __construct($keyPath, $passPhrase = null, $keyPermissionsCheck = if ($keyPermissionsCheck === true) { // Verify the permissions of the key - $keyPathPerms = \decoct(\fileperms($this->keyPath) & 0777); - if (\in_array($keyPathPerms, ['400', '440', '600', '640', '660'], true) === false) { - \trigger_error( - \sprintf( + $keyPathPerms = decoct(fileperms($this->keyPath) & 0777); + if (in_array($keyPathPerms, ['400', '440', '600', '640', '660'], true) === false) { + trigger_error( + sprintf( 'Key file "%s" permissions are not correct, recommend changing to 600 or 660 instead of %s', $this->keyPath, $keyPathPerms @@ -104,20 +112,21 @@ public function getKeyContents(): string /** * Validate key contents. * - * @param string $contents - * @param string $passPhrase * - * @return bool */ - private function isValidKey($contents, $passPhrase) + private function isValidKey(string $contents, string $passPhrase): bool { - $pkey = \openssl_pkey_get_private($contents, $passPhrase) ?: \openssl_pkey_get_public($contents); - if ($pkey === false) { + $privateKey = openssl_pkey_get_private($contents, $passPhrase); + + $key = $privateKey instanceof OpenSSLAsymmetricKey ? $privateKey : openssl_pkey_get_public($contents); + + if ($key === false) { return false; } - $details = \openssl_pkey_get_details($pkey); - return $details !== false && \in_array( + $details = openssl_pkey_get_details($key); + + return $details !== false && in_array( $details['type'] ?? -1, [OPENSSL_KEYTYPE_RSA, OPENSSL_KEYTYPE_EC], true @@ -127,7 +136,7 @@ private function isValidKey($contents, $passPhrase) /** * {@inheritdoc} */ - public function getKeyPath() + public function getKeyPath(): string { return $this->keyPath; } @@ -135,7 +144,7 @@ public function getKeyPath() /** * {@inheritdoc} */ - public function getPassPhrase() + public function getPassPhrase(): ?string { return $this->passPhrase; } diff --git a/src/CryptKeyInterface.php b/src/CryptKeyInterface.php index 15c34b8d7..993ab4d52 100644 --- a/src/CryptKeyInterface.php +++ b/src/CryptKeyInterface.php @@ -1,5 +1,7 @@ encryptionKey instanceof Key) { return Crypto::encrypt($unencryptedData, $this->encryptionKey); } - if (\is_string($this->encryptionKey)) { + if (is_string($this->encryptionKey)) { return Crypto::encryptWithPassword($unencryptedData, $this->encryptionKey); } @@ -52,20 +55,18 @@ protected function encrypt($unencryptedData) /** * Decrypt data with encryptionKey. * - * @param string $encryptedData * * @throws LogicException * - * @return string */ - protected function decrypt($encryptedData) + protected function decrypt(string $encryptedData): string { try { if ($this->encryptionKey instanceof Key) { return Crypto::decrypt($encryptedData, $this->encryptionKey); } - if (\is_string($this->encryptionKey)) { + if (is_string($this->encryptionKey)) { return Crypto::decryptWithPassword($encryptedData, $this->encryptionKey); } diff --git a/src/Entities/AccessTokenEntityInterface.php b/src/Entities/AccessTokenEntityInterface.php index 33306b174..6eb3e7f6d 100644 --- a/src/Entities/AccessTokenEntityInterface.php +++ b/src/Entities/AccessTokenEntityInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities; use League\OAuth2\Server\CryptKeyInterface; @@ -21,5 +24,5 @@ public function setPrivateKey(CryptKeyInterface $privateKey): void; /** * Generate a string representation of the access token. */ - public function __toString(); + public function __toString(): string; } diff --git a/src/Entities/AuthCodeEntityInterface.php b/src/Entities/AuthCodeEntityInterface.php index 40d581245..68c6a2f5b 100644 --- a/src/Entities/AuthCodeEntityInterface.php +++ b/src/Entities/AuthCodeEntityInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities; interface AuthCodeEntityInterface extends TokenInterface diff --git a/src/Entities/ClientEntityInterface.php b/src/Entities/ClientEntityInterface.php index 971c61244..56aa54dfb 100644 --- a/src/Entities/ClientEntityInterface.php +++ b/src/Entities/ClientEntityInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities; interface ClientEntityInterface @@ -14,16 +17,14 @@ interface ClientEntityInterface /** * Get the client's identifier. * - * @return string */ - public function getIdentifier(); + public function getIdentifier(): string; /** * Get the client's name. * - * @return string */ - public function getName(); + public function getName(): string; /** * Returns the registered redirect URI (as a string). @@ -32,12 +33,11 @@ public function getName(); * * @return string|string[] */ - public function getRedirectUri(); + public function getRedirectUri(): string|array; /** * Returns true if the client is confidential. * - * @return bool */ - public function isConfidential(); + public function isConfidential(): bool; } diff --git a/src/Entities/RefreshTokenEntityInterface.php b/src/Entities/RefreshTokenEntityInterface.php index 63f9732c6..9b881216f 100644 --- a/src/Entities/RefreshTokenEntityInterface.php +++ b/src/Entities/RefreshTokenEntityInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities; use DateTimeImmutable; @@ -16,9 +19,8 @@ interface RefreshTokenEntityInterface /** * Get the token's identifier. * - * @return string */ - public function getIdentifier(); + public function getIdentifier(): string; /** * Set the token's identifier. diff --git a/src/Entities/ScopeEntityInterface.php b/src/Entities/ScopeEntityInterface.php index 26748e0c0..653d671ea 100644 --- a/src/Entities/ScopeEntityInterface.php +++ b/src/Entities/ScopeEntityInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities; use JsonSerializable; @@ -16,7 +19,6 @@ interface ScopeEntityInterface extends JsonSerializable /** * Get the scope's identifier. * - * @return string */ - public function getIdentifier(); + public function getIdentifier(): string; } diff --git a/src/Entities/TokenInterface.php b/src/Entities/TokenInterface.php index 75aa261af..22e6fab49 100644 --- a/src/Entities/TokenInterface.php +++ b/src/Entities/TokenInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities; use DateTimeImmutable; @@ -16,9 +19,8 @@ interface TokenInterface /** * Get the token's identifier. * - * @return string */ - public function getIdentifier(); + public function getIdentifier(): string; /** * Set the token's identifier. @@ -28,9 +30,8 @@ public function setIdentifier(mixed $identifier): void; /** * Get the token's expiry date time. * - * @return DateTimeImmutable */ - public function getExpiryDateTime(); + public function getExpiryDateTime(): DateTimeImmutable; /** * Set the date time when the token expires. @@ -67,5 +68,5 @@ public function addScope(ScopeEntityInterface $scope): void; * * @return ScopeEntityInterface[] */ - public function getScopes(); + public function getScopes(): array; } diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index 35300fa4c..48f6f8eca 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities\Traits; use DateTimeImmutable; @@ -60,9 +63,8 @@ public function initJwtConfiguration(): void /** * Generate a JWT from the access token * - * @return Token */ - private function convertToJWT() + private function convertToJWT(): Token { $this->initJwtConfiguration(); @@ -80,33 +82,29 @@ private function convertToJWT() /** * Generate a string representation from the access token */ - public function __toString() + public function __toString(): string { return $this->convertToJWT()->toString(); } /** - * @return ClientEntityInterface */ - abstract public function getClient(); + abstract public function getClient(): ClientEntityInterface; /** - * @return DateTimeImmutable */ - abstract public function getExpiryDateTime(); + abstract public function getExpiryDateTime(): DateTimeImmutable; /** - * @return string|int */ - abstract public function getUserIdentifier(); + abstract public function getUserIdentifier(): string|int|null; /** * @return ScopeEntityInterface[] */ - abstract public function getScopes(); + abstract public function getScopes(): array; /** - * @return string */ - abstract public function getIdentifier(); + abstract public function getIdentifier(): string; } diff --git a/src/Entities/Traits/AuthCodeTrait.php b/src/Entities/Traits/AuthCodeTrait.php index 35cbff295..edc667614 100644 --- a/src/Entities/Traits/AuthCodeTrait.php +++ b/src/Entities/Traits/AuthCodeTrait.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities\Traits; trait AuthCodeTrait diff --git a/src/Entities/Traits/ClientTrait.php b/src/Entities/Traits/ClientTrait.php index a0078d8d7..c779b15a9 100644 --- a/src/Entities/Traits/ClientTrait.php +++ b/src/Entities/Traits/ClientTrait.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities\Traits; trait ClientTrait @@ -29,10 +32,9 @@ trait ClientTrait /** * Get the client's name. * - * @return string * @codeCoverageIgnore */ - public function getName() + public function getName(): string { return $this->name; } @@ -44,7 +46,7 @@ public function getName() * * @return string|string[] */ - public function getRedirectUri() + public function getRedirectUri(): string|array { return $this->redirectUri; } @@ -52,9 +54,8 @@ public function getRedirectUri() /** * Returns true if the client is confidential. * - * @return bool */ - public function isConfidential() + public function isConfidential(): bool { return $this->isConfidential; } diff --git a/src/Entities/Traits/EntityTrait.php b/src/Entities/Traits/EntityTrait.php index 6748aea18..0657a49b8 100644 --- a/src/Entities/Traits/EntityTrait.php +++ b/src/Entities/Traits/EntityTrait.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,27 +8,22 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities\Traits; trait EntityTrait { - /** - * @var string - */ - protected $identifier; + protected string $identifier; - /** - * @return mixed - */ - public function getIdentifier() + public function getIdentifier(): string { return $this->identifier; } /** - * @param mixed $identifier */ - public function setIdentifier($identifier): void + public function setIdentifier(mixed $identifier): void { $this->identifier = $identifier; } diff --git a/src/Entities/Traits/RefreshTokenTrait.php b/src/Entities/Traits/RefreshTokenTrait.php index 568b2a733..a0d4c8885 100644 --- a/src/Entities/Traits/RefreshTokenTrait.php +++ b/src/Entities/Traits/RefreshTokenTrait.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities\Traits; use DateTimeImmutable; diff --git a/src/Entities/Traits/ScopeTrait.php b/src/Entities/Traits/ScopeTrait.php index a132234fc..aeba339de 100644 --- a/src/Entities/Traits/ScopeTrait.php +++ b/src/Entities/Traits/ScopeTrait.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Andrew Millington @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities\Traits; trait ScopeTrait @@ -14,15 +17,13 @@ trait ScopeTrait /** * Serialize the object to the scopes string identifier when using json_encode(). * - * @return string */ - public function jsonSerialize() + public function jsonSerialize(): string { return $this->getIdentifier(); } /** - * @return string */ - abstract public function getIdentifier(); + abstract public function getIdentifier(): string; } diff --git a/src/Entities/Traits/TokenEntityTrait.php b/src/Entities/Traits/TokenEntityTrait.php index d9cfa6fa2..d4a1aabe0 100644 --- a/src/Entities/Traits/TokenEntityTrait.php +++ b/src/Entities/Traits/TokenEntityTrait.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,12 +8,16 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities\Traits; use DateTimeImmutable; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; +use function array_values; + trait TokenEntityTrait { /** @@ -38,7 +43,6 @@ trait TokenEntityTrait /** * Associate a scope with the token. * - * @param ScopeEntityInterface $scope */ public function addScope(ScopeEntityInterface $scope): void { @@ -52,7 +56,7 @@ public function addScope(ScopeEntityInterface $scope): void */ public function getScopes(): array { - return \array_values($this->scopes); + return array_values($this->scopes); } /** @@ -76,7 +80,7 @@ public function setExpiryDateTime(DateTimeImmutable $dateTime): void * * @param string|int|null $identifier The identifier of the user */ - public function setUserIdentifier($identifier): void + public function setUserIdentifier(string|int|null $identifier): void { $this->userIdentifier = $identifier; } @@ -84,7 +88,6 @@ public function setUserIdentifier($identifier): void /** * Get the token user's identifier. * - * @return string|int|null */ public function getUserIdentifier(): string|int|null { diff --git a/src/Entities/UserEntityInterface.php b/src/Entities/UserEntityInterface.php index c71cb9c52..28eed197e 100644 --- a/src/Entities/UserEntityInterface.php +++ b/src/Entities/UserEntityInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Entities; interface UserEntityInterface @@ -14,7 +17,6 @@ interface UserEntityInterface /** * Return the user's identifier. * - * @return mixed */ - public function getIdentifier(); + public function getIdentifier(): mixed; } diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index 32104ef0d..f033fdeb0 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Exception; use Exception; @@ -14,6 +17,12 @@ use Psr\Http\Message\ServerRequestInterface; use Throwable; +use function htmlspecialchars; +use function http_build_query; +use function sprintf; +use function strpos; +use function strstr; + class OAuthServerException extends Exception { /** @@ -57,7 +66,7 @@ class OAuthServerException extends Exception * @param null|string $redirectUri A HTTP URI to redirect the user back to * @param Throwable $previous Previous exception */ - final public function __construct($message, $code, $errorType, $httpStatusCode = 400, $hint = null, $redirectUri = null, Throwable $previous = null) + final public function __construct(string $message, int $code, string $errorType, int $httpStatusCode = 400, ?string $hint = null, ?string $redirectUri = null, Throwable $previous = null) { parent::__construct($message, $code, $previous); $this->httpStatusCode = $httpStatusCode; @@ -104,7 +113,6 @@ public function setPayload(array $payload): void /** * Set the server request that is responsible for generating the exception * - * @param ServerRequestInterface $serverRequest */ public function setServerRequest(ServerRequestInterface $serverRequest): void { @@ -116,7 +124,7 @@ public function setServerRequest(ServerRequestInterface $serverRequest): void * * @return static */ - public static function unsupportedGrantType() + public static function unsupportedGrantType(): static { $errorMessage = 'The authorization grant type is not supported by the authorization server.'; $hint = 'Check that all required parameters have been provided'; @@ -128,16 +136,15 @@ public static function unsupportedGrantType() * Invalid request error. * * @param string $parameter The invalid parameter - * @param null|string $hint * @param Throwable $previous Previous exception * * @return static */ - public static function invalidRequest($parameter, $hint = null, Throwable $previous = null) + public static function invalidRequest(string $parameter, ?string $hint = null, Throwable $previous = null): static { $errorMessage = 'The request is missing a required parameter, includes an invalid parameter value, ' . 'includes a parameter more than once, or is otherwise malformed.'; - $hint = ($hint === null) ? \sprintf('Check the `%s` parameter', $parameter) : $hint; + $hint = ($hint === null) ? sprintf('Check the `%s` parameter', $parameter) : $hint; return new static($errorMessage, 3, 'invalid_request', 400, $hint, null, $previous); } @@ -145,11 +152,10 @@ public static function invalidRequest($parameter, $hint = null, Throwable $previ /** * Invalid client error. * - * @param ServerRequestInterface $serverRequest * * @return static */ - public static function invalidClient(ServerRequestInterface $serverRequest) + public static function invalidClient(ServerRequestInterface $serverRequest): static { $exception = new static('Client authentication failed', 4, 'invalid_client', 401); @@ -159,23 +165,18 @@ public static function invalidClient(ServerRequestInterface $serverRequest) } /** - * Invalid scope error. - * - * @param string $scope The bad scope - * @param null|string $redirectUri A HTTP URI to redirect the user back to - * - * @return static + * Invalid scope error */ - public static function invalidScope($scope, $redirectUri = null) + public static function invalidScope(string $scope, string|null $redirectUri = null): static { $errorMessage = 'The requested scope is invalid, unknown, or malformed'; - if (empty($scope)) { + if ($scope === '') { $hint = 'Specify a scope in the request or set a default scope'; } else { - $hint = \sprintf( + $hint = sprintf( 'Check the `%s` scope', - \htmlspecialchars($scope, ENT_QUOTES, 'UTF-8', false) + htmlspecialchars($scope, ENT_QUOTES, 'UTF-8', false) ); } @@ -187,7 +188,7 @@ public static function invalidScope($scope, $redirectUri = null) * * @return static */ - public static function invalidCredentials() + public static function invalidCredentials(): static { return new static('The user credentials were incorrect.', 6, 'invalid_grant', 400); } @@ -195,14 +196,12 @@ public static function invalidCredentials() /** * Server error. * - * @param string $hint - * @param Throwable $previous * * @return static * * @codeCoverageIgnore */ - public static function serverError($hint, Throwable $previous = null) + public static function serverError(string $hint, Throwable $previous = null): static { return new static( 'The authorization server encountered an unexpected condition which prevented it from fulfilling' @@ -219,12 +218,10 @@ public static function serverError($hint, Throwable $previous = null) /** * Invalid refresh token. * - * @param null|string $hint - * @param Throwable $previous * * @return static */ - public static function invalidRefreshToken($hint = null, Throwable $previous = null) + public static function invalidRefreshToken(?string $hint = null, Throwable $previous = null): static { return new static('The refresh token is invalid.', 8, 'invalid_grant', 400, $hint, null, $previous); } @@ -232,13 +229,10 @@ public static function invalidRefreshToken($hint = null, Throwable $previous = n /** * Access denied. * - * @param null|string $hint - * @param null|string $redirectUri - * @param Throwable $previous * * @return static */ - public static function accessDenied($hint = null, $redirectUri = null, Throwable $previous = null) + public static function accessDenied(?string $hint = null, ?string $redirectUri = null, Throwable $previous = null): static { return new static( 'The resource owner or authorization server denied the request.', @@ -254,11 +248,10 @@ public static function accessDenied($hint = null, $redirectUri = null, Throwable /** * Invalid grant. * - * @param string $hint * * @return static */ - public static function invalidGrant($hint = '') + public static function invalidGrant(string $hint = ''): static { return new static( 'The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token ' @@ -272,9 +265,8 @@ public static function invalidGrant($hint = '') } /** - * @return string */ - public function getErrorType() + public function getErrorType(): string { return $this->errorType; } @@ -282,13 +274,11 @@ public function getErrorType() /** * Generate a HTTP response. * - * @param ResponseInterface $response * @param bool $useFragment True if errors should be in the URI fragment instead of query string * @param int $jsonOptions options passed to json_encode * - * @return ResponseInterface */ - public function generateHttpResponse(ResponseInterface $response, $useFragment = false, $jsonOptions = 0) + public function generateHttpResponse(ResponseInterface $response, bool $useFragment = false, int $jsonOptions = 0): ResponseInterface { $headers = $this->getHttpHeaders(); @@ -296,19 +286,21 @@ public function generateHttpResponse(ResponseInterface $response, $useFragment = if ($this->redirectUri !== null) { if ($useFragment === true) { - $this->redirectUri .= (\strstr($this->redirectUri, '#') === false) ? '#' : '&'; + $this->redirectUri .= (strstr($this->redirectUri, '#') === false) ? '#' : '&'; } else { - $this->redirectUri .= (\strstr($this->redirectUri, '?') === false) ? '?' : '&'; + $this->redirectUri .= (strstr($this->redirectUri, '?') === false) ? '?' : '&'; } - return $response->withStatus(302)->withHeader('Location', $this->redirectUri . \http_build_query($payload)); + return $response->withStatus(302)->withHeader('Location', $this->redirectUri . http_build_query($payload)); } foreach ($headers as $header => $content) { $response = $response->withHeader($header, $content); } - $responseBody = \json_encode($payload, $jsonOptions) ?: 'JSON encoding of payload failed'; + $jsonEncodedPayload = json_encode($payload, $jsonOptions); + + $responseBody = $jsonEncodedPayload === false ? 'JSON encoding of payload failed' : $jsonEncodedPayload; $response->getBody()->write($responseBody); @@ -335,7 +327,7 @@ public function getHttpHeaders(): array // include the "WWW-Authenticate" response header field // matching the authentication scheme used by the client. if ($this->errorType === 'invalid_client' && $this->requestHasAuthorizationHeader()) { - $authScheme = \strpos($this->serverRequest->getHeader('Authorization')[0], 'Bearer') === 0 ? 'Bearer' : 'Basic'; + $authScheme = strpos($this->serverRequest->getHeader('Authorization')[0], 'Bearer') === 0 ? 'Bearer' : 'Basic'; $headers['WWW-Authenticate'] = $authScheme . ' realm="OAuth"'; } @@ -351,9 +343,8 @@ public function getHttpHeaders(): array * redirect enabled. This helps when you want to override local * error pages but want to let redirects through. * - * @return bool */ - public function hasRedirect() + public function hasRedirect(): bool { return $this->redirectUri !== null; } @@ -361,9 +352,8 @@ public function hasRedirect() /** * Returns the Redirect URI used for redirecting. * - * @return string|null */ - public function getRedirectUri() + public function getRedirectUri(): ?string { return $this->redirectUri; } @@ -371,17 +361,15 @@ public function getRedirectUri() /** * Returns the HTTP status code to send when the exceptions is output. * - * @return int */ - public function getHttpStatusCode() + public function getHttpStatusCode(): int { return $this->httpStatusCode; } /** - * @return null|string */ - public function getHint() + public function getHint(): ?string { return $this->hint; } @@ -392,9 +380,8 @@ public function getHint() * Returns true if the header is present and not an empty string, false * otherwise. * - * @return bool */ - private function requestHasAuthorizationHeader() + private function requestHasAuthorizationHeader(): bool { if (!$this->serverRequest->hasHeader('Authorization')) { return false; @@ -407,7 +394,7 @@ private function requestHasAuthorizationHeader() // For practical purposes that case should be treated as though the // header isn't present. // See https://github.com/thephpleague/oauth2-server/issues/1162 - if (empty($authorizationHeader) || empty($authorizationHeader[0])) { + if ($authorizationHeader === [] || $authorizationHeader[0] === '') { return false; } diff --git a/src/Exception/UniqueTokenIdentifierConstraintViolationException.php b/src/Exception/UniqueTokenIdentifierConstraintViolationException.php index 175ab3a88..21f9a28ab 100644 --- a/src/Exception/UniqueTokenIdentifierConstraintViolationException.php +++ b/src/Exception/UniqueTokenIdentifierConstraintViolationException.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,14 +8,15 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Exception; class UniqueTokenIdentifierConstraintViolationException extends OAuthServerException { /** - * @return UniqueTokenIdentifierConstraintViolationException */ - public static function create() + public static function create(): UniqueTokenIdentifierConstraintViolationException { $errorMessage = 'Could not create unique access token identifier'; diff --git a/src/Grant/AbstractAuthorizeGrant.php b/src/Grant/AbstractAuthorizeGrant.php index 9a78ae562..d9f2d3f3e 100644 --- a/src/Grant/AbstractAuthorizeGrant.php +++ b/src/Grant/AbstractAuthorizeGrant.php @@ -1,4 +1,5 @@ defaultScope = $scope; } /** - * @param bool $revokeRefreshTokens */ - public function revokeRefreshTokens(bool $revokeRefreshTokens) + public function revokeRefreshTokens(bool $revokeRefreshTokens): void { $this->revokeRefreshTokens = $revokeRefreshTokens; } @@ -188,13 +193,11 @@ public function revokeRefreshTokens(bool $revokeRefreshTokens) /** * Validate the client. * - * @param ServerRequestInterface $request * * @throws OAuthServerException * - * @return ClientEntityInterface */ - protected function validateClient(ServerRequestInterface $request) + protected function validateClient(ServerRequestInterface $request): ClientEntityInterface { [$clientId, $clientSecret] = $this->getClientCredentials($request); @@ -210,7 +213,7 @@ protected function validateClient(ServerRequestInterface $request) $redirectUri = $this->getRequestParameter('redirect_uri', $request, null); if ($redirectUri !== null) { - if (!\is_string($redirectUri)) { + if (!is_string($redirectUri)) { throw OAuthServerException::invalidRequest('redirect_uri'); } @@ -230,12 +233,9 @@ protected function validateClient(ServerRequestInterface $request) * getClientEntity might return null. By contrast, this method will * always either return a ClientEntityInterface or throw. * - * @param string $clientId - * @param ServerRequestInterface $request * - * @return ClientEntityInterface */ - protected function getClientEntityOrFail($clientId, ServerRequestInterface $request) + protected function getClientEntityOrFail(string $clientId, ServerRequestInterface $request): ClientEntityInterface { $client = $this->clientRepository->getClientEntity($clientId); @@ -251,7 +251,6 @@ protected function getClientEntityOrFail($clientId, ServerRequestInterface $requ * Gets the client credentials from the request from the request body or * the Http Basic Authorization header * - * @param ServerRequestInterface $request * * @return string[] */ @@ -261,13 +260,13 @@ protected function getClientCredentials(ServerRequestInterface $request): array $clientId = $this->getRequestParameter('client_id', $request, $basicAuthUser); - if (\is_null($clientId)) { + if (is_null($clientId)) { throw OAuthServerException::invalidRequest('client_id'); } $clientSecret = $this->getRequestParameter('client_secret', $request, $basicAuthPassword); - if ($clientSecret !== null && !\is_string($clientSecret)) { + if ($clientSecret !== null && !is_string($clientSecret)) { throw OAuthServerException::invalidRequest('client_secret'); } @@ -278,9 +277,6 @@ protected function getClientCredentials(ServerRequestInterface $request): array * Validate redirectUri from the request. * If a redirect URI is provided ensure it matches what is pre-registered * - * @param string $redirectUri - * @param ClientEntityInterface $client - * @param ServerRequestInterface $request * * @throws OAuthServerException */ @@ -301,24 +297,19 @@ protected function validateRedirectUri( * Validate scopes in the request. * * @param null|string|string[] $scopes - * @param string $redirectUri * * @throws OAuthServerException * * @return ScopeEntityInterface[] */ - public function validateScopes($scopes, $redirectUri = null): array + public function validateScopes(string|array|null $scopes, string $redirectUri = null): array { if ($scopes === null) { $scopes = []; - } elseif (\is_string($scopes)) { + } elseif (is_string($scopes)) { $scopes = $this->convertScopesQueryStringToArray($scopes); } - if (!\is_array($scopes)) { - throw OAuthServerException::invalidRequest('scope'); - } - $validScopes = []; foreach ($scopes as $scopeItem) { @@ -337,13 +328,12 @@ public function validateScopes($scopes, $redirectUri = null): array /** * Converts a scopes query string to an array to easily iterate for validation. * - * @param string $scopes * * @return string[] */ private function convertScopesQueryStringToArray(string $scopes): array { - return \array_filter(\explode(self::SCOPE_DELIMITER_STRING, \trim($scopes)), function ($scope) { + return array_filter(explode(self::SCOPE_DELIMITER_STRING, trim($scopes)), function ($scope) { return $scope !== ''; }); } @@ -351,13 +341,9 @@ private function convertScopesQueryStringToArray(string $scopes): array /** * Retrieve request parameter. * - * @param string $parameter - * @param ServerRequestInterface $request - * @param mixed $default * - * @return mixed */ - protected function getRequestParameter($parameter, ServerRequestInterface $request, $default = null) + protected function getRequestParameter(string $parameter, ServerRequestInterface $request, mixed $default = null): mixed { $requestParameters = (array) $request->getParsedBody(); @@ -371,42 +357,39 @@ protected function getRequestParameter($parameter, ServerRequestInterface $reque * not exist, or is otherwise an invalid HTTP Basic header, return * [null, null]. * - * @param ServerRequestInterface $request * * @return string[]|null[] */ - protected function getBasicAuthCredentials(ServerRequestInterface $request) + protected function getBasicAuthCredentials(ServerRequestInterface $request): array { if (!$request->hasHeader('Authorization')) { return [null, null]; } $header = $request->getHeader('Authorization')[0]; - if (\strpos($header, 'Basic ') !== 0) { + if (strpos($header, 'Basic ') !== 0) { return [null, null]; } - if (!($decoded = \base64_decode(\substr($header, 6)))) { + $decoded = base64_decode(substr($header, 6), true); + + if ($decoded === false) { return [null, null]; } - if (\strpos($decoded, ':') === false) { + if (strpos($decoded, ':') === false) { return [null, null]; // HTTP Basic header without colon isn't valid } - return \explode(':', $decoded, 2); + return explode(':', $decoded, 2); } /** * Retrieve query string parameter. * - * @param string $parameter - * @param ServerRequestInterface $request - * @param mixed $default * - * @return null|string */ - protected function getQueryStringParameter($parameter, ServerRequestInterface $request, $default = null) + protected function getQueryStringParameter(string $parameter, ServerRequestInterface $request, mixed $default = null): ?string { return isset($request->getQueryParams()[$parameter]) ? $request->getQueryParams()[$parameter] : $default; } @@ -414,13 +397,9 @@ protected function getQueryStringParameter($parameter, ServerRequestInterface $r /** * Retrieve cookie parameter. * - * @param string $parameter - * @param ServerRequestInterface $request - * @param mixed $default * - * @return null|string */ - protected function getCookieParameter($parameter, ServerRequestInterface $request, $default = null) + protected function getCookieParameter(string $parameter, ServerRequestInterface $request, mixed $default = null): ?string { return isset($request->getCookieParams()[$parameter]) ? $request->getCookieParams()[$parameter] : $default; } @@ -428,13 +407,9 @@ protected function getCookieParameter($parameter, ServerRequestInterface $reques /** * Retrieve server parameter. * - * @param string $parameter - * @param ServerRequestInterface $request - * @param mixed $default * - * @return null|string */ - protected function getServerParameter($parameter, ServerRequestInterface $request, $default = null) + protected function getServerParameter(string $parameter, ServerRequestInterface $request, mixed $default = null): ?string { return isset($request->getServerParams()[$parameter]) ? $request->getServerParams()[$parameter] : $default; } @@ -442,22 +417,18 @@ protected function getServerParameter($parameter, ServerRequestInterface $reques /** * Issue an access token. * - * @param DateInterval $accessTokenTTL - * @param ClientEntityInterface $client - * @param string|null $userIdentifier * @param ScopeEntityInterface[] $scopes * * @throws OAuthServerException * @throws UniqueTokenIdentifierConstraintViolationException * - * @return AccessTokenEntityInterface */ protected function issueAccessToken( DateInterval $accessTokenTTL, ClientEntityInterface $client, - $userIdentifier, + string|int|null $userIdentifier, array $scopes = [] - ) { + ): AccessTokenEntityInterface { $maxGenerationAttempts = self::MAX_RANDOM_TOKEN_GENERATION_ATTEMPTS; $accessToken = $this->accessTokenRepository->getNewToken($client, $scopes, $userIdentifier); @@ -481,24 +452,19 @@ protected function issueAccessToken( /** * Issue an auth code. * - * @param DateInterval $authCodeTTL - * @param ClientEntityInterface $client - * @param string $userIdentifier - * @param string|null $redirectUri * @param ScopeEntityInterface[] $scopes * * @throws OAuthServerException * @throws UniqueTokenIdentifierConstraintViolationException * - * @return AuthCodeEntityInterface */ protected function issueAuthCode( DateInterval $authCodeTTL, ClientEntityInterface $client, - $userIdentifier, - $redirectUri, + string $userIdentifier, + ?string $redirectUri, array $scopes = [] - ) { + ): AuthCodeEntityInterface { $maxGenerationAttempts = self::MAX_RANDOM_TOKEN_GENERATION_ATTEMPTS; $authCode = $this->authCodeRepository->getNewAuthCode(); @@ -529,14 +495,12 @@ protected function issueAuthCode( } /** - * @param AccessTokenEntityInterface $accessToken * * @throws OAuthServerException * @throws UniqueTokenIdentifierConstraintViolationException * - * @return RefreshTokenEntityInterface|null */ - protected function issueRefreshToken(AccessTokenEntityInterface $accessToken) + protected function issueRefreshToken(AccessTokenEntityInterface $accessToken): ?RefreshTokenEntityInterface { $refreshToken = $this->refreshTokenRepository->getNewRefreshToken(); @@ -566,13 +530,11 @@ protected function issueRefreshToken(AccessTokenEntityInterface $accessToken) /** * Generate a new unique identifier. * - * @param int $length * * @throws OAuthServerException * - * @return string */ - protected function generateUniqueIdentifier($length = 40) + protected function generateUniqueIdentifier(int $length = 40): string { try { if ($length < 1) { @@ -581,7 +543,7 @@ protected function generateUniqueIdentifier($length = 40) return bin2hex(random_bytes($length)); // @codeCoverageIgnoreStart - } catch (TypeError|Error $e) { + } catch (TypeError | Error $e) { throw OAuthServerException::serverError('An unexpected error has occurred', $e); } catch (Exception $e) { // If you get this message, the CSPRNG failed hard. @@ -593,12 +555,12 @@ protected function generateUniqueIdentifier($length = 40) /** * {@inheritdoc} */ - public function canRespondToAccessTokenRequest(ServerRequestInterface $request) + public function canRespondToAccessTokenRequest(ServerRequestInterface $request): bool { $requestParameters = (array) $request->getParsedBody(); return ( - \array_key_exists('grant_type', $requestParameters) + array_key_exists('grant_type', $requestParameters) && $requestParameters['grant_type'] === $this->getIdentifier() ); } @@ -606,7 +568,7 @@ public function canRespondToAccessTokenRequest(ServerRequestInterface $request) /** * {@inheritdoc} */ - public function canRespondToAuthorizationRequest(ServerRequestInterface $request) + public function canRespondToAuthorizationRequest(ServerRequestInterface $request): bool { return false; } @@ -614,7 +576,7 @@ public function canRespondToAuthorizationRequest(ServerRequestInterface $request /** * {@inheritdoc} */ - public function validateAuthorizationRequest(ServerRequestInterface $request) + public function validateAuthorizationRequest(ServerRequestInterface $request): AuthorizationRequestInterface { throw new LogicException('This grant cannot validate an authorization request'); } @@ -622,7 +584,7 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) /** * {@inheritdoc} */ - public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest) + public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest): ResponseTypeInterface { throw new LogicException('This grant cannot complete an authorization request'); } diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index 6791f96e8..d940c4038 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Grant; use DateInterval; @@ -30,6 +33,22 @@ use Psr\Http\Message\ServerRequestInterface; use stdClass; +use function array_key_exists; +use function array_keys; +use function array_map; +use function count; +use function hash_algos; +use function implode; +use function in_array; +use function is_array; +use function is_string; +use function json_decode; +use function json_encode; +use function preg_match; +use function property_exists; +use function sprintf; +use function time; + class AuthCodeGrant extends AbstractAuthorizeGrant { /** @@ -48,9 +67,6 @@ class AuthCodeGrant extends AbstractAuthorizeGrant private $codeChallengeVerifiers = []; /** - * @param AuthCodeRepositoryInterface $authCodeRepository - * @param RefreshTokenRepositoryInterface $refreshTokenRepository - * @param DateInterval $authCodeTTL * * @throws Exception */ @@ -64,7 +80,7 @@ public function __construct( $this->authCodeTTL = $authCodeTTL; $this->refreshTokenTTL = new DateInterval('P1M'); - if (\in_array('sha256', \hash_algos(), true)) { + if (in_array('sha256', hash_algos(), true)) { $s256Verifier = new S256Verifier(); $this->codeChallengeVerifiers[$s256Verifier->getMethod()] = $s256Verifier; } @@ -84,19 +100,15 @@ public function disableRequireCodeChallengeForPublicClients(): void /** * Respond to an access token request. * - * @param ServerRequestInterface $request - * @param ResponseTypeInterface $responseType - * @param DateInterval $accessTokenTTL * * @throws OAuthServerException * - * @return ResponseTypeInterface */ public function respondToAccessTokenRequest( ServerRequestInterface $request, ResponseTypeInterface $responseType, DateInterval $accessTokenTTL - ) { + ): ResponseTypeInterface { list($clientId) = $this->getClientCredentials($request); $client = $this->getClientEntityOrFail($clientId, $request); @@ -108,12 +120,12 @@ public function respondToAccessTokenRequest( $encryptedAuthCode = $this->getRequestParameter('code', $request, null); - if (!\is_string($encryptedAuthCode)) { + if (!is_string($encryptedAuthCode)) { throw OAuthServerException::invalidRequest('code'); } try { - $authCodePayload = \json_decode($this->decrypt($encryptedAuthCode)); + $authCodePayload = json_decode($this->decrypt($encryptedAuthCode)); $this->validateAuthorizationCode($authCodePayload, $client, $request); @@ -129,7 +141,7 @@ public function respondToAccessTokenRequest( } // Validate code challenge - if (!empty($authCodePayload->code_challenge)) { + if (isset($authCodePayload->code_challenge) && $authCodePayload->code_challenge !== '') { $codeVerifier = $this->getRequestParameter('code_verifier', $request, null); if ($codeVerifier === null) { @@ -138,14 +150,14 @@ public function respondToAccessTokenRequest( // Validate code_verifier according to RFC-7636 // @see: https://tools.ietf.org/html/rfc7636#section-4.1 - if (\preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $codeVerifier) !== 1) { + if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $codeVerifier) !== 1) { throw OAuthServerException::invalidRequest( 'code_verifier', 'Code Verifier must follow the specifications of RFC-7636.' ); } - if (\property_exists($authCodePayload, 'code_challenge_method')) { + if (property_exists($authCodePayload, 'code_challenge_method')) { if (isset($this->codeChallengeVerifiers[$authCodePayload->code_challenge_method])) { $codeChallengeVerifier = $this->codeChallengeVerifiers[$authCodePayload->code_challenge_method]; @@ -154,7 +166,7 @@ public function respondToAccessTokenRequest( } } else { throw OAuthServerException::serverError( - \sprintf( + sprintf( 'Unsupported code challenge method `%s`', $authCodePayload->code_challenge_method ) @@ -185,20 +197,17 @@ public function respondToAccessTokenRequest( /** * Validate the authorization code. * - * @param stdClass $authCodePayload - * @param ClientEntityInterface $client - * @param ServerRequestInterface $request */ private function validateAuthorizationCode( - $authCodePayload, + stdClass $authCodePayload, ClientEntityInterface $client, ServerRequestInterface $request ): void { - if (!\property_exists($authCodePayload, 'auth_code_id')) { + if (!property_exists($authCodePayload, 'auth_code_id')) { throw OAuthServerException::invalidRequest('code', 'Authorization code malformed'); } - if (\time() > $authCodePayload->expire_time) { + if (time() > $authCodePayload->expire_time) { throw OAuthServerException::invalidRequest('code', 'Authorization code has expired'); } @@ -212,7 +221,7 @@ private function validateAuthorizationCode( // The redirect URI is required in this request $redirectUri = $this->getRequestParameter('redirect_uri', $request, null); - if (empty($authCodePayload->redirect_uri) === false && $redirectUri === null) { + if ($authCodePayload->redirect_uri !== '' && $redirectUri === null) { throw OAuthServerException::invalidRequest('redirect_uri'); } @@ -224,9 +233,8 @@ private function validateAuthorizationCode( /** * Return the grant identifier that can be used in matching up requests. * - * @return string */ - public function getIdentifier() + public function getIdentifier(): string { return 'authorization_code'; } @@ -234,10 +242,10 @@ public function getIdentifier() /** * {@inheritdoc} */ - public function canRespondToAuthorizationRequest(ServerRequestInterface $request) + public function canRespondToAuthorizationRequest(ServerRequestInterface $request): bool { return ( - \array_key_exists('response_type', $request->getQueryParams()) + array_key_exists('response_type', $request->getQueryParams()) && $request->getQueryParams()['response_type'] === 'code' && isset($request->getQueryParams()['client_id']) ); @@ -246,7 +254,7 @@ public function canRespondToAuthorizationRequest(ServerRequestInterface $request /** * {@inheritdoc} */ - public function validateAuthorizationRequest(ServerRequestInterface $request) + public function validateAuthorizationRequest(ServerRequestInterface $request): AuthorizationRequestInterface { $clientId = $this->getQueryStringParameter( 'client_id', @@ -263,19 +271,17 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) $redirectUri = $this->getQueryStringParameter('redirect_uri', $request); if ($redirectUri !== null) { - if (!\is_string($redirectUri)) { - throw OAuthServerException::invalidRequest('redirect_uri'); - } - $this->validateRedirectUri($redirectUri, $client, $request); - } elseif (empty($client->getRedirectUri()) || - (\is_array($client->getRedirectUri()) && \count($client->getRedirectUri()) !== 1)) { + } elseif ( + $client->getRedirectUri() === '' || $client->getRedirectUri() === null || + (is_array($client->getRedirectUri()) && count($client->getRedirectUri()) !== 1) + ) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); throw OAuthServerException::invalidClient($request); } - $defaultClientRedirectUri = \is_array($client->getRedirectUri()) + $defaultClientRedirectUri = is_array($client->getRedirectUri()) ? $client->getRedirectUri()[0] : $client->getRedirectUri(); @@ -309,21 +315,21 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) ); } - if (\array_key_exists($codeChallengeMethod, $this->codeChallengeVerifiers) === false) { + if (array_key_exists($codeChallengeMethod, $this->codeChallengeVerifiers) === false) { throw OAuthServerException::invalidRequest( 'code_challenge_method', - 'Code challenge method must be one of ' . \implode(', ', \array_map( + 'Code challenge method must be one of ' . implode(', ', array_map( function ($method) { return '`' . $method . '`'; }, - \array_keys($this->codeChallengeVerifiers) + array_keys($this->codeChallengeVerifiers) )) ); } // Validate code_challenge according to RFC-7636 // @see: https://tools.ietf.org/html/rfc7636#section-4.2 - if (\preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $codeChallenge) !== 1) { + if (preg_match('/^[A-Za-z0-9-._~]{43,128}$/', $codeChallenge) !== 1) { throw OAuthServerException::invalidRequest( 'code_challenge', 'Code challenge must follow the specifications of RFC-7636.' @@ -342,7 +348,7 @@ function ($method) { /** * {@inheritdoc} */ - public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest) + public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest): ResponseTypeInterface { if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) { throw new LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest'); @@ -372,7 +378,7 @@ public function completeAuthorizationRequest(AuthorizationRequestInterface $auth 'code_challenge_method' => $authorizationRequest->getCodeChallengeMethod(), ]; - $jsonPayload = \json_encode($payload); + $jsonPayload = json_encode($payload); if ($jsonPayload === false) { throw new LogicException('An error was encountered when JSON encoding the authorization request response'); @@ -407,13 +413,11 @@ public function completeAuthorizationRequest(AuthorizationRequestInterface $auth /** * Get the client redirect URI if not set in the request. * - * @param AuthorizationRequestInterface $authorizationRequest * - * @return string */ - private function getClientRedirectUri(AuthorizationRequestInterface $authorizationRequest) + private function getClientRedirectUri(AuthorizationRequestInterface $authorizationRequest): string { - return \is_array($authorizationRequest->getClient()->getRedirectUri()) + return is_array($authorizationRequest->getClient()->getRedirectUri()) ? $authorizationRequest->getClient()->getRedirectUri()[0] : $authorizationRequest->getClient()->getRedirectUri(); } diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index d342b269f..bee6abaa1 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -1,4 +1,5 @@ getClientCredentials($request); $client = $this->getClientEntityOrFail($clientId, $request); @@ -64,7 +67,7 @@ public function respondToAccessTokenRequest( /** * {@inheritdoc} */ - public function getIdentifier() + public function getIdentifier(): string { return 'client_credentials'; } diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index f8dffd578..36f2f6050 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Grant; use DateInterval; @@ -20,6 +23,11 @@ use LogicException; use Psr\Http\Message\ServerRequestInterface; +use function count; +use function is_array; +use function is_null; +use function time; + class ImplicitGrant extends AbstractAuthorizeGrant { /** @@ -33,17 +41,14 @@ class ImplicitGrant extends AbstractAuthorizeGrant private $queryDelimiter; /** - * @param DateInterval $accessTokenTTL - * @param string $queryDelimiter */ - public function __construct(DateInterval $accessTokenTTL, $queryDelimiter = '#') + public function __construct(DateInterval $accessTokenTTL, string $queryDelimiter = '#') { $this->accessTokenTTL = $accessTokenTTL; $this->queryDelimiter = $queryDelimiter; } /** - * @param DateInterval $refreshTokenTTL * * @throw LogicException */ @@ -53,7 +58,6 @@ public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void } /** - * @param RefreshTokenRepositoryInterface $refreshTokenRepository * * @throw LogicException */ @@ -73,9 +77,8 @@ public function canRespondToAccessTokenRequest(ServerRequestInterface $request) /** * Return the grant identifier that can be used in matching up requests. * - * @return string */ - public function getIdentifier() + public function getIdentifier(): string { return 'implicit'; } @@ -83,17 +86,13 @@ public function getIdentifier() /** * Respond to an incoming request. * - * @param ServerRequestInterface $request - * @param ResponseTypeInterface $responseType - * @param DateInterval $accessTokenTTL * - * @return ResponseTypeInterface */ public function respondToAccessTokenRequest( ServerRequestInterface $request, ResponseTypeInterface $responseType, DateInterval $accessTokenTTL - ) { + ): ResponseTypeInterface { throw new LogicException('This grant does not used this method'); } @@ -120,7 +119,7 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) $this->getServerParameter('PHP_AUTH_USER', $request) ); - if (\is_null($clientId)) { + if (is_null($clientId)) { throw OAuthServerException::invalidRequest('client_id'); } @@ -129,17 +128,15 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) $redirectUri = $this->getQueryStringParameter('redirect_uri', $request); if ($redirectUri !== null) { - if (!\is_string($redirectUri)) { - throw OAuthServerException::invalidRequest('redirect_uri'); - } - $this->validateRedirectUri($redirectUri, $client, $request); - } elseif (\is_array($client->getRedirectUri()) && \count($client->getRedirectUri()) !== 1 - || empty($client->getRedirectUri())) { + } elseif ( + is_array($client->getRedirectUri()) && count($client->getRedirectUri()) !== 1 + || $client->getRedirectUri() === '' + ) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); throw OAuthServerException::invalidClient($request); } else { - $redirectUri = \is_array($client->getRedirectUri()) + $redirectUri = is_array($client->getRedirectUri()) ? $client->getRedirectUri()[0] : $client->getRedirectUri(); } @@ -175,7 +172,7 @@ public function completeAuthorizationRequest(AuthorizationRequestInterface $auth } $finalRedirectUri = ($authorizationRequest->getRedirectUri() === null) - ? \is_array($authorizationRequest->getClient()->getRedirectUri()) + ? is_array($authorizationRequest->getClient()->getRedirectUri()) ? $authorizationRequest->getClient()->getRedirectUri()[0] : $authorizationRequest->getClient()->getRedirectUri() : $authorizationRequest->getRedirectUri(); @@ -204,7 +201,7 @@ public function completeAuthorizationRequest(AuthorizationRequestInterface $auth [ 'access_token' => (string) $accessToken, 'token_type' => 'Bearer', - 'expires_in' => $accessToken->getExpiryDateTime()->getTimestamp() - \time(), + 'expires_in' => $accessToken->getExpiryDateTime()->getTimestamp() - time(), 'state' => $authorizationRequest->getState(), ], $this->queryDelimiter diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 80f442616..e492d1e61 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -1,4 +1,5 @@ validateClient($request); $scopes = $this->validateScopes($this->getRequestParameter('scope', $request, $this->defaultScope)); @@ -59,7 +62,8 @@ public function respondToAccessTokenRequest( $scopes, $this->getIdentifier(), $client, - $user->getIdentifier()); + $user->getIdentifier() + ); // Issue and persist new access token $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getIdentifier(), $finalizedScopes); @@ -78,24 +82,21 @@ public function respondToAccessTokenRequest( } /** - * @param ServerRequestInterface $request - * @param ClientEntityInterface $client * * @throws OAuthServerException * - * @return UserEntityInterface */ - protected function validateUser(ServerRequestInterface $request, ClientEntityInterface $client) + protected function validateUser(ServerRequestInterface $request, ClientEntityInterface $client): UserEntityInterface { $username = $this->getRequestParameter('username', $request); - if (!\is_string($username)) { + if (!is_string($username)) { throw OAuthServerException::invalidRequest('username'); } $password = $this->getRequestParameter('password', $request); - if (!\is_string($password)) { + if (!is_string($password)) { throw OAuthServerException::invalidRequest('password'); } diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 541faa4ab..8cf4b3272 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -1,4 +1,5 @@ validateClient($request); $oldRefreshToken = $this->validateOldRefreshToken($request, $client->getIdentifier()); @@ -51,14 +59,14 @@ public function respondToAccessTokenRequest( $this->getRequestParameter( 'scope', $request, - \implode(self::SCOPE_DELIMITER_STRING, $oldRefreshToken['scopes']) + implode(self::SCOPE_DELIMITER_STRING, $oldRefreshToken['scopes']) ) ); // The OAuth spec says that a refreshed access token can have the original scopes or fewer so ensure // the request doesn't include any new scopes foreach ($scopes as $scope) { - if (\in_array($scope->getIdentifier(), $oldRefreshToken['scopes'], true) === false) { + if (in_array($scope->getIdentifier(), $oldRefreshToken['scopes'], true) === false) { throw OAuthServerException::invalidScope($scope->getIdentifier()); } } @@ -90,17 +98,15 @@ public function respondToAccessTokenRequest( } /** - * @param ServerRequestInterface $request - * @param string $clientId * * @throws OAuthServerException * * @return array */ - protected function validateOldRefreshToken(ServerRequestInterface $request, $clientId): array + protected function validateOldRefreshToken(ServerRequestInterface $request, string $clientId): array { $encryptedRefreshToken = $this->getRequestParameter('refresh_token', $request); - if (!\is_string($encryptedRefreshToken)) { + if (!is_string($encryptedRefreshToken)) { throw OAuthServerException::invalidRequest('refresh_token'); } @@ -111,13 +117,13 @@ protected function validateOldRefreshToken(ServerRequestInterface $request, $cli throw OAuthServerException::invalidRefreshToken('Cannot decrypt the refresh token', $e); } - $refreshTokenData = \json_decode($refreshToken, true); + $refreshTokenData = json_decode($refreshToken, true); if ($refreshTokenData['client_id'] !== $clientId) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::REFRESH_TOKEN_CLIENT_FAILED, $request)); throw OAuthServerException::invalidRefreshToken('Token is not linked to client'); } - if ($refreshTokenData['expire_time'] < \time()) { + if ($refreshTokenData['expire_time'] < time()) { throw OAuthServerException::invalidRefreshToken('Token has expired'); } diff --git a/src/Middleware/AuthorizationServerMiddleware.php b/src/Middleware/AuthorizationServerMiddleware.php index f1a743af5..913bb9afd 100644 --- a/src/Middleware/AuthorizationServerMiddleware.php +++ b/src/Middleware/AuthorizationServerMiddleware.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Middleware; use Exception; @@ -23,7 +26,6 @@ class AuthorizationServerMiddleware private $server; /** - * @param AuthorizationServer $server */ public function __construct(AuthorizationServer $server) { @@ -31,13 +33,9 @@ public function __construct(AuthorizationServer $server) } /** - * @param ServerRequestInterface $request - * @param ResponseInterface $response - * @param callable $next * - * @return ResponseInterface */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) + public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface { try { $response = $this->server->respondToAccessTokenRequest($request, $response); diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php index 8a5103f3e..61c8dcab0 100644 --- a/src/Middleware/ResourceServerMiddleware.php +++ b/src/Middleware/ResourceServerMiddleware.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Middleware; use Exception; @@ -23,7 +26,6 @@ class ResourceServerMiddleware private $server; /** - * @param ResourceServer $server */ public function __construct(ResourceServer $server) { @@ -31,13 +33,9 @@ public function __construct(ResourceServer $server) } /** - * @param ServerRequestInterface $request - * @param ResponseInterface $response - * @param callable $next * - * @return ResponseInterface */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) + public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface { try { $request = $this->server->validateAuthenticatedRequest($request); diff --git a/src/RedirectUriValidators/RedirectUriValidator.php b/src/RedirectUriValidators/RedirectUriValidator.php index 3efa356d3..af20765ff 100644 --- a/src/RedirectUriValidators/RedirectUriValidator.php +++ b/src/RedirectUriValidators/RedirectUriValidator.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,11 +8,16 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\RedirectUriValidators; use League\Uri\Exceptions\SyntaxError; use League\Uri\Uri; +use function in_array; +use function is_string; + class RedirectUriValidator implements RedirectUriValidatorInterface { /** @@ -26,23 +32,20 @@ class RedirectUriValidator implements RedirectUriValidatorInterface */ public function __construct(array|string $allowedRedirectUris) { - if (\is_string($allowedRedirectUris)) { + if (is_string($allowedRedirectUris)) { $this->allowedRedirectUris = [$allowedRedirectUris]; - } elseif (\is_array($allowedRedirectUris)) { - $this->allowedRedirectUris = $allowedRedirectUris; } else { - $this->allowedRedirectUris = []; + $this->allowedRedirectUris = $allowedRedirectUris; } } /** * Validates the redirect uri. * - * @param string $redirectUri * * @return bool Return true if valid, false otherwise */ - public function validateRedirectUri($redirectUri) + public function validateRedirectUri(string $redirectUri): bool { if ($this->isLoopbackUri($redirectUri)) { return $this->matchUriExcludingPort($redirectUri); @@ -56,11 +59,9 @@ public function validateRedirectUri($redirectUri) * - "http://127.0.0.1:{port}/{path}" for IPv4 * - "http://[::1]:{port}/{path}" for IPv6 * - * @param string $redirectUri * - * @return bool */ - private function isLoopbackUri($redirectUri) + private function isLoopbackUri(string $redirectUri): bool { try { $uri = Uri::createFromString($redirectUri); @@ -69,29 +70,27 @@ private function isLoopbackUri($redirectUri) } return $uri->getScheme() === 'http' - && (\in_array($uri->getHost(), ['127.0.0.1', '[::1]'], true)); + && (in_array($uri->getHost(), ['127.0.0.1', '[::1]'], true)); } /** * Find an exact match among allowed uris * - * @param string $redirectUri * * @return bool Return true if an exact match is found, false otherwise */ - private function matchExactUri($redirectUri) + private function matchExactUri(string $redirectUri): bool { - return \in_array($redirectUri, $this->allowedRedirectUris, true); + return in_array($redirectUri, $this->allowedRedirectUris, true); } /** * Find a match among allowed uris, allowing for different port numbers * - * @param string $redirectUri * * @return bool Return true if a match is found, false otherwise */ - private function matchUriExcludingPort($redirectUri) + private function matchUriExcludingPort(string $redirectUri): bool { $parsedUrl = $this->parseUrlAndRemovePort($redirectUri); @@ -107,11 +106,9 @@ private function matchUriExcludingPort($redirectUri) /** * Parse an url like \parse_url, excluding the port * - * @param string $url * - * @return string */ - private function parseUrlAndRemovePort($url) + private function parseUrlAndRemovePort(string $url): string { $uri = Uri::createFromString($url); diff --git a/src/RedirectUriValidators/RedirectUriValidatorInterface.php b/src/RedirectUriValidators/RedirectUriValidatorInterface.php index d039085ab..0e44830f7 100644 --- a/src/RedirectUriValidators/RedirectUriValidatorInterface.php +++ b/src/RedirectUriValidators/RedirectUriValidatorInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\RedirectUriValidators; interface RedirectUriValidatorInterface @@ -14,9 +17,8 @@ interface RedirectUriValidatorInterface /** * Validates the redirect uri. * - * @param string $redirectUri * * @return bool Return true if valid, false otherwise */ - public function validateRedirectUri($redirectUri); + public function validateRedirectUri(string $redirectUri): bool; } diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index fb1c967ce..e5a4b0c98 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; @@ -23,13 +26,12 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface * Create a new access token * * @param ScopeEntityInterface[] $scopes - * @param mixed $userIdentifier * - * @return AccessTokenEntityInterface */ public function getNewToken( ClientEntityInterface $clientEntity, - array $scopes, $userIdentifier = null + array $scopes, + mixed $userIdentifier = null ): AccessTokenEntityInterface; /** diff --git a/src/Repositories/AuthCodeRepositoryInterface.php b/src/Repositories/AuthCodeRepositoryInterface.php index 64954aaf5..89ff86b87 100644 --- a/src/Repositories/AuthCodeRepositoryInterface.php +++ b/src/Repositories/AuthCodeRepositoryInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\AuthCodeEntityInterface; diff --git a/src/Repositories/ClientRepositoryInterface.php b/src/Repositories/ClientRepositoryInterface.php index 7eef494f4..092a627f2 100644 --- a/src/Repositories/ClientRepositoryInterface.php +++ b/src/Repositories/ClientRepositoryInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\ClientEntityInterface; @@ -21,9 +24,8 @@ interface ClientRepositoryInterface extends RepositoryInterface * * @param string $clientIdentifier The client's identifier * - * @return ClientEntityInterface|null */ - public function getClientEntity($clientIdentifier); + public function getClientEntity(string $clientIdentifier): ?ClientEntityInterface; /** * Validate a client's secret. @@ -32,7 +34,6 @@ public function getClientEntity($clientIdentifier); * @param null|string $clientSecret The client's secret (if sent) * @param null|string $grantType The type of grant the client is using (if sent) * - * @return bool */ - public function validateClient($clientIdentifier, $clientSecret, $grantType); + public function validateClient(string $clientIdentifier, ?string $clientSecret, ?string $grantType): bool; } diff --git a/src/Repositories/RefreshTokenRepositoryInterface.php b/src/Repositories/RefreshTokenRepositoryInterface.php index 106a2ef7d..a25e50133 100644 --- a/src/Repositories/RefreshTokenRepositoryInterface.php +++ b/src/Repositories/RefreshTokenRepositoryInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; diff --git a/src/Repositories/RepositoryInterface.php b/src/Repositories/RepositoryInterface.php index 9c27b4b0a..00b1dc106 100644 --- a/src/Repositories/RepositoryInterface.php +++ b/src/Repositories/RepositoryInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Repositories; /** diff --git a/src/Repositories/ScopeRepositoryInterface.php b/src/Repositories/ScopeRepositoryInterface.php index 9dbc0a896..2ee699ccf 100644 --- a/src/Repositories/ScopeRepositoryInterface.php +++ b/src/Repositories/ScopeRepositoryInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\ClientEntityInterface; @@ -22,27 +25,22 @@ interface ScopeRepositoryInterface extends RepositoryInterface * * @param string $identifier The scope identifier * - * @return ScopeEntityInterface|null */ - public function getScopeEntityByIdentifier($identifier); + public function getScopeEntityByIdentifier(string $identifier): ?ScopeEntityInterface; /** * Given a client, grant type and optional user identifier validate the set of scopes requested are valid and optionally * append additional scopes or remove requested scopes. * * @param ScopeEntityInterface[] $scopes - * @param string $grantType - * @param ClientEntityInterface $clientEntity - * @param null|string $userIdentifier - * @param null|string $authCodeId * * @return ScopeEntityInterface[] */ public function finalizeScopes( array $scopes, - $grantType, + string $grantType, ClientEntityInterface $clientEntity, - $userIdentifier = null, - $authCodeId = null - ); + string|int|null $userIdentifier = null, + ?string $authCodeId = null + ): array; } diff --git a/src/Repositories/UserRepositoryInterface.php b/src/Repositories/UserRepositoryInterface.php index 8ad49aa7c..644e700ad 100644 --- a/src/Repositories/UserRepositoryInterface.php +++ b/src/Repositories/UserRepositoryInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\ClientEntityInterface; @@ -17,17 +20,13 @@ interface UserRepositoryInterface extends RepositoryInterface /** * Get a user entity. * - * @param string $username - * @param string $password * @param string $grantType The grant type used - * @param ClientEntityInterface $clientEntity * - * @return UserEntityInterface|null */ public function getUserEntityByUserCredentials( - $username, - $password, - $grantType, + string $username, + string $password, + string $grantType, ClientEntityInterface $clientEntity - ); + ): ?UserEntityInterface; } diff --git a/src/RequestAccessTokenEvent.php b/src/RequestAccessTokenEvent.php index 99d17bf36..fe723857f 100644 --- a/src/RequestAccessTokenEvent.php +++ b/src/RequestAccessTokenEvent.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; @@ -20,20 +23,17 @@ class RequestAccessTokenEvent extends RequestEvent private $accessToken; /** - * @param string $name - * @param ServerRequestInterface $request */ - public function __construct($name, ServerRequestInterface $request, AccessTokenEntityInterface $accessToken) + public function __construct(string $name, ServerRequestInterface $request, AccessTokenEntityInterface $accessToken) { parent::__construct($name, $request); $this->accessToken = $accessToken; } /** - * @return AccessTokenEntityInterface * @codeCoverageIgnore */ - public function getAccessToken() + public function getAccessToken(): AccessTokenEntityInterface { return $this->accessToken; } diff --git a/src/RequestEvent.php b/src/RequestEvent.php index b1ca3f6b8..11c5bd0fc 100644 --- a/src/RequestEvent.php +++ b/src/RequestEvent.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server; use League\Event\Event; @@ -14,12 +17,12 @@ class RequestEvent extends Event { - const CLIENT_AUTHENTICATION_FAILED = 'client.authentication.failed'; - const USER_AUTHENTICATION_FAILED = 'user.authentication.failed'; - const REFRESH_TOKEN_CLIENT_FAILED = 'refresh_token.client.failed'; + public const CLIENT_AUTHENTICATION_FAILED = 'client.authentication.failed'; + public const USER_AUTHENTICATION_FAILED = 'user.authentication.failed'; + public const REFRESH_TOKEN_CLIENT_FAILED = 'refresh_token.client.failed'; - const REFRESH_TOKEN_ISSUED = 'refresh_token.issued'; - const ACCESS_TOKEN_ISSUED = 'access_token.issued'; + public const REFRESH_TOKEN_ISSUED = 'refresh_token.issued'; + public const ACCESS_TOKEN_ISSUED = 'access_token.issued'; /** * @var ServerRequestInterface @@ -29,20 +32,17 @@ class RequestEvent extends Event /** * RequestEvent constructor. * - * @param string $name - * @param ServerRequestInterface $request */ - public function __construct($name, ServerRequestInterface $request) + public function __construct(string $name, ServerRequestInterface $request) { parent::__construct($name); $this->request = $request; } /** - * @return ServerRequestInterface * @codeCoverageIgnore */ - public function getRequest() + public function getRequest(): ServerRequestInterface { return $this->request; } diff --git a/src/RequestRefreshTokenEvent.php b/src/RequestRefreshTokenEvent.php index 0682e57f5..d5348b961 100644 --- a/src/RequestRefreshTokenEvent.php +++ b/src/RequestRefreshTokenEvent.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; @@ -20,20 +23,17 @@ class RequestRefreshTokenEvent extends RequestEvent private $refreshToken; /** - * @param string $name - * @param ServerRequestInterface $request */ - public function __construct($name, ServerRequestInterface $request, RefreshTokenEntityInterface $refreshToken) + public function __construct(string $name, ServerRequestInterface $request, RefreshTokenEntityInterface $refreshToken) { parent::__construct($name, $request); $this->refreshToken = $refreshToken; } /** - * @return RefreshTokenEntityInterface * @codeCoverageIgnore */ - public function getRefreshToken() + public function getRefreshToken(): RefreshTokenEntityInterface { return $this->refreshToken; } diff --git a/src/RequestTypes/AuthorizationRequest.php b/src/RequestTypes/AuthorizationRequest.php index f9460d0f5..8231ebbfb 100644 --- a/src/RequestTypes/AuthorizationRequest.php +++ b/src/RequestTypes/AuthorizationRequest.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\RequestTypes; use League\OAuth2\Server\Entities\ClientEntityInterface; diff --git a/src/RequestTypes/AuthorizationRequestInterface.php b/src/RequestTypes/AuthorizationRequestInterface.php index 10ea08ace..6ae358439 100644 --- a/src/RequestTypes/AuthorizationRequestInterface.php +++ b/src/RequestTypes/AuthorizationRequestInterface.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server\RequestTypes; use League\OAuth2\Server\Entities\ClientEntityInterface; diff --git a/src/ResourceServer.php b/src/ResourceServer.php index 92a72763e..844d39be5 100644 --- a/src/ResourceServer.php +++ b/src/ResourceServer.php @@ -1,4 +1,5 @@ * @copyright Copyright (c) Alex Bilbie @@ -7,6 +8,8 @@ * @link https://github.com/thephpleague/oauth2-server */ +declare(strict_types=1); + namespace League\OAuth2\Server; use League\OAuth2\Server\AuthorizationValidators\AuthorizationValidatorInterface; @@ -35,13 +38,11 @@ class ResourceServer /** * New server instance. * - * @param AccessTokenRepositoryInterface $accessTokenRepository - * @param CryptKeyInterface|string $publicKey * @param null|AuthorizationValidatorInterface $authorizationValidator */ public function __construct( AccessTokenRepositoryInterface $accessTokenRepository, - $publicKey, + CryptKeyInterface|string $publicKey, AuthorizationValidatorInterface $authorizationValidator = null ) { $this->accessTokenRepository = $accessTokenRepository; @@ -55,9 +56,8 @@ public function __construct( } /** - * @return AuthorizationValidatorInterface */ - protected function getAuthorizationValidator() + protected function getAuthorizationValidator(): AuthorizationValidatorInterface { if ($this->authorizationValidator instanceof AuthorizationValidatorInterface === false) { $this->authorizationValidator = new BearerTokenValidator($this->accessTokenRepository); @@ -73,13 +73,11 @@ protected function getAuthorizationValidator() /** * Determine the access token validity. * - * @param ServerRequestInterface $request * * @throws OAuthServerException * - * @return ServerRequestInterface */ - public function validateAuthenticatedRequest(ServerRequestInterface $request) + public function validateAuthenticatedRequest(ServerRequestInterface $request): ServerRequestInterface { return $this->getAuthorizationValidator()->validateAuthorization($request); } diff --git a/src/ResponseTypes/AbstractResponseType.php b/src/ResponseTypes/AbstractResponseType.php index dd2c15041..1144b59d5 100644 --- a/src/ResponseTypes/AbstractResponseType.php +++ b/src/ResponseTypes/AbstractResponseType.php @@ -1,4 +1,5 @@ 'Bearer', - 'expires_in' => $expireDateTime - \time(), + 'expires_in' => $expireDateTime - time(), 'access_token' => (string) $this->accessToken, ]; - if ($this->refreshToken instanceof RefreshTokenEntityInterface) { - $refreshTokenPayload = \json_encode([ + $refreshTokenPayload = json_encode([ 'client_id' => $this->accessToken->getClient()->getIdentifier(), 'refresh_token_id' => $this->refreshToken->getIdentifier(), 'access_token_id' => $this->accessToken->getIdentifier(), 'scopes' => $this->accessToken->getScopes(), 'user_id' => $this->accessToken->getUserIdentifier(), 'expire_time' => $this->refreshToken->getExpiryDateTime()->getTimestamp(), - ]); + ]); - if ($refreshTokenPayload === false) { - throw new LogicException('Error encountered JSON encoding the refresh token payload'); - } - - $responseParams['refresh_token'] = $this->encrypt($refreshTokenPayload); + if ($refreshTokenPayload === false) { + throw new LogicException('Error encountered JSON encoding the refresh token payload'); } - $responseParams = \json_encode(\array_merge($this->getExtraParams($this->accessToken), $responseParams)); + $responseParams['refresh_token'] = $this->encrypt($refreshTokenPayload); + + $responseParams = json_encode(array_merge($this->getExtraParams($this->accessToken), $responseParams)); if ($responseParams === false) { throw new LogicException('Error encountered JSON encoding response parameters'); diff --git a/src/ResponseTypes/RedirectResponse.php b/src/ResponseTypes/RedirectResponse.php index 2006a8f0d..cff6af6eb 100644 --- a/src/ResponseTypes/RedirectResponse.php +++ b/src/ResponseTypes/RedirectResponse.php @@ -1,4 +1,5 @@ enableGrantType(new GrantType(), new DateInterval('PT1M')); $authRequest = $server->validateAuthorizationRequest($this->createMock(ServerRequestInterface::class)); - $this->assertSame(GrantType::class, $authRequest->getGrantTypeId()); + self::assertSame(GrantType::class, $authRequest->getGrantTypeId()); } */ @@ -66,17 +73,17 @@ public function testRespondToRequestInvalidGrantType(): void $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/Stubs/private.key', - \base64_encode(\random_bytes(36)), + base64_encode(random_bytes(36)), new StubResponseType() ); $server->enableGrantType(new ClientCredentialsGrant(), new DateInterval('PT1M')); try { - $server->respondToAccessTokenRequest(ServerRequestFactory::fromGlobals(), new Response); + $server->respondToAccessTokenRequest(ServerRequestFactory::fromGlobals(), new Response()); } catch (OAuthServerException $e) { - $this->assertEquals('unsupported_grant_type', $e->getErrorType()); - $this->assertEquals(400, $e->getHttpStatusCode()); + self::assertEquals('unsupported_grant_type', $e->getErrorType()); + self::assertEquals(400, $e->getHttpStatusCode()); } } @@ -89,6 +96,7 @@ public function testRespondToRequest(): void $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository->method('getClientEntity')->willReturn($client); + $clientRepository->method('validateClient')->willReturn(true); $scope = new ScopeEntity(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); @@ -103,7 +111,7 @@ public function testRespondToRequest(): void $accessTokenRepositoryMock, $scopeRepositoryMock, 'file://' . __DIR__ . '/Stubs/private.key', - \base64_encode(\random_bytes(36)), + base64_encode(random_bytes(36)), new StubResponseType() ); @@ -113,8 +121,8 @@ public function testRespondToRequest(): void $_POST['grant_type'] = 'client_credentials'; $_POST['client_id'] = 'foo'; $_POST['client_secret'] = 'bar'; - $response = $server->respondToAccessTokenRequest(ServerRequestFactory::fromGlobals(), new Response); - $this->assertEquals(200, $response->getStatusCode()); + $response = $server->respondToAccessTokenRequest(ServerRequestFactory::fromGlobals(), new Response()); + self::assertEquals(200, $response->getStatusCode()); } public function testGetResponseType(): void @@ -129,11 +137,11 @@ public function testGetResponseType(): void 'file://' . __DIR__ . '/Stubs/public.key' ); - $abstractGrantReflection = new \ReflectionClass($server); + $abstractGrantReflection = new ReflectionClass($server); $method = $abstractGrantReflection->getMethod('getResponseType'); $method->setAccessible(true); - $this->assertInstanceOf(BearerTokenResponse::class, $method->invoke($server)); + self::assertInstanceOf(BearerTokenResponse::class, $method->invoke($server)); } public function testGetResponseTypeExtended(): void @@ -150,13 +158,13 @@ public function testGetResponseTypeExtended(): void 'file://' . __DIR__ . '/Stubs/public.key' ); - $abstractGrantReflection = new \ReflectionClass($server); + $abstractGrantReflection = new ReflectionClass($server); $method = $abstractGrantReflection->getMethod('getResponseType'); $method->setAccessible(true); $responseType = $method->invoke($server); - $responseTypeReflection = new \ReflectionClass($responseType); + $responseTypeReflection = new ReflectionClass($responseType); $privateKeyProperty = $responseTypeReflection->getProperty('privateKey'); $privateKeyProperty->setAccessible(true); @@ -165,8 +173,8 @@ public function testGetResponseTypeExtended(): void $encryptionKeyProperty->setAccessible(true); // generated instances should have keys setup - $this->assertSame($privateKey, $privateKeyProperty->getValue($responseType)->getKeyPath()); - $this->assertSame($encryptionKey, $encryptionKeyProperty->getValue($responseType)); + self::assertSame($privateKey, $privateKeyProperty->getValue($responseType)->getKeyPath()); + self::assertSame($encryptionKey, $encryptionKeyProperty->getValue($responseType)); } public function testMultipleRequestsGetDifferentResponseTypeInstances(): void @@ -197,7 +205,7 @@ public function getEncryptionKey(): Key|string|null $responseTypePrototype ); - $abstractGrantReflection = new \ReflectionClass($server); + $abstractGrantReflection = new ReflectionClass($server); $method = $abstractGrantReflection->getMethod('getResponseType'); $method->setAccessible(true); @@ -205,19 +213,19 @@ public function getEncryptionKey(): Key|string|null $responseTypeB = $method->invoke($server); // prototype should not get changed - $this->assertNull($responseTypePrototype->getPrivateKey()); - $this->assertNull($responseTypePrototype->getEncryptionKey()); + self::assertNull($responseTypePrototype->getPrivateKey()); + self::assertNull($responseTypePrototype->getEncryptionKey()); // generated instances should have keys setup - $this->assertSame($privateKey, $responseTypeA->getPrivateKey()->getKeyPath()); - $this->assertSame($encryptionKey, $responseTypeA->getEncryptionKey()); + self::assertSame($privateKey, $responseTypeA->getPrivateKey()->getKeyPath()); + self::assertSame($encryptionKey, $responseTypeA->getEncryptionKey()); // all instances should be different but based on the same prototype - $this->assertSame(\get_class($responseTypePrototype), \get_class($responseTypeA)); - $this->assertSame(\get_class($responseTypePrototype), \get_class($responseTypeB)); - $this->assertNotSame($responseTypePrototype, $responseTypeA); - $this->assertNotSame($responseTypePrototype, $responseTypeB); - $this->assertNotSame($responseTypeA, $responseTypeB); + self::assertSame(get_class($responseTypePrototype), get_class($responseTypeA)); + self::assertSame(get_class($responseTypePrototype), get_class($responseTypeB)); + self::assertNotSame($responseTypePrototype, $responseTypeA); + self::assertNotSame($responseTypePrototype, $responseTypeB); + self::assertNotSame($responseTypeA, $responseTypeB); } public function testCompleteAuthorizationRequest(): void @@ -243,16 +251,23 @@ public function testCompleteAuthorizationRequest(): void $server->enableGrantType($grant); + $client = new ClientEntity(); + + $client->setRedirectUri('http://foo/bar'); + $client->setIdentifier('clientId'); + $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); - $authRequest->setClient(new ClientEntity()); + $authRequest->setClient($client); $authRequest->setGrantTypeId('authorization_code'); $authRequest->setUser(new UserEntity()); - $this->assertInstanceOf( - ResponseInterface::class, - $server->completeAuthorizationRequest($authRequest, new Response) - ); + $response = $server->completeAuthorizationRequest($authRequest, new Response()); + + $locationHeader = $response->getHeader('Location')[0]; + + self::assertStringStartsWith('http://foo/bar', $locationHeader); + self::assertStringContainsString('code=', $locationHeader); } public function testValidateAuthorizationRequest(): void @@ -299,53 +314,7 @@ public function testValidateAuthorizationRequest(): void ] ); - $this->assertInstanceOf(AuthorizationRequest::class, $server->validateAuthorizationRequest($request)); - } - - public function testValidateAuthorizationRequestWithMissingRedirectUri(): void - { - $client = new ClientEntity(); - $client->setConfidential(); - - $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); - $clientRepositoryMock->method('getClientEntity')->willReturn($client); - - $grant = new AuthCodeGrant( - $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), - $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), - new DateInterval('PT10M') - ); - $grant->setClientRepository($clientRepositoryMock); - - $server = new AuthorizationServer( - $clientRepositoryMock, - $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), - $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), - 'file://' . __DIR__ . '/Stubs/private.key', - 'file://' . __DIR__ . '/Stubs/public.key' - ); - $server->enableGrantType($grant); - - $request = new ServerRequest( - [], - [], - null, - null, - 'php://input', - $headers = [], - $cookies = [], - $queryParams = [ - 'response_type' => 'code', - 'client_id' => 'foo', - ] - ); - - try { - $server->validateAuthorizationRequest($request); - } catch (OAuthServerException $e) { - $this->assertEquals('invalid_client', $e->getErrorType()); - $this->assertEquals(401, $e->getHttpStatusCode()); - } + self::assertInstanceOf(AuthorizationRequest::class, $server->validateAuthorizationRequest($request)); } public function testValidateAuthorizationRequestUnregistered(): void @@ -363,7 +332,7 @@ public function testValidateAuthorizationRequestUnregistered(): void 'client_id' => 'foo', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(2); $server->validateAuthorizationRequest($request); diff --git a/tests/AuthorizationValidators/BearerTokenValidatorTest.php b/tests/AuthorizationValidators/BearerTokenValidatorTest.php index 51ab8ecba..ee4f55585 100644 --- a/tests/AuthorizationValidators/BearerTokenValidatorTest.php +++ b/tests/AuthorizationValidators/BearerTokenValidatorTest.php @@ -1,5 +1,7 @@ withClaim('scopes', 'scope1 scope2 scope3 scope4') ->getToken(new Sha256(), InMemory::file(__DIR__ . '/../Stubs/private.key')); - $request = (new ServerRequest())->withHeader('authorization', \sprintf('Bearer %s', $validJwt->toString())); + $request = (new ServerRequest())->withHeader('authorization', sprintf('Bearer %s', $validJwt->toString())); $validRequest = $bearerTokenValidator->validateAuthorization($request); - $this->assertArrayHasKey('authorization', $validRequest->getHeaders()); + self::assertArrayHasKey('authorization', $validRequest->getHeaders()); } public function testBearerTokenValidatorRejectsExpiredToken(): void @@ -64,9 +69,9 @@ public function testBearerTokenValidatorRejectsExpiredToken(): void ->withClaim('scopes', 'scope1 scope2 scope3 scope4') ->getToken(new Sha256(), InMemory::file(__DIR__ . '/../Stubs/private.key')); - $request = (new ServerRequest())->withHeader('authorization', \sprintf('Bearer %s', $expiredJwt->toString())); + $request = (new ServerRequest())->withHeader('authorization', sprintf('Bearer %s', $expiredJwt->toString())); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(9); $bearerTokenValidator->validateAuthorization($request); diff --git a/tests/Bootstrap.php b/tests/Bootstrap.php index b02cb7be4..6445d351e 100644 --- a/tests/Bootstrap.php +++ b/tests/Bootstrap.php @@ -1,5 +1,7 @@ assertEquals('plain', $verifier->getMethod()); + self::assertEquals('plain', $verifier->getMethod()); } public function testVerifyCodeChallenge(): void { $verifier = new PlainVerifier(); - $this->assertTrue($verifier->verifyCodeChallenge('foo', 'foo')); - $this->assertFalse($verifier->verifyCodeChallenge('foo', 'bar')); + self::assertTrue($verifier->verifyCodeChallenge('foo', 'foo')); + self::assertFalse($verifier->verifyCodeChallenge('foo', 'bar')); } } diff --git a/tests/CodeChallengeVerifiers/S256VerifierTest.php b/tests/CodeChallengeVerifiers/S256VerifierTest.php index 14ef1957f..4bcbbe0e3 100644 --- a/tests/CodeChallengeVerifiers/S256VerifierTest.php +++ b/tests/CodeChallengeVerifiers/S256VerifierTest.php @@ -1,17 +1,24 @@ assertEquals('S256', $verifier->getMethod()); + self::assertEquals('S256', $verifier->getMethod()); } public function testVerifyCodeChallengeSucceeds(): void @@ -19,7 +26,7 @@ public function testVerifyCodeChallengeSucceeds(): void $codeChallenge = $this->createCodeChallenge('foo'); $verifier = new S256Verifier(); - $this->assertTrue($verifier->verifyCodeChallenge('foo', $codeChallenge)); + self::assertTrue($verifier->verifyCodeChallenge('foo', $codeChallenge)); } public function testVerifyCodeChallengeFails(): void @@ -27,11 +34,11 @@ public function testVerifyCodeChallengeFails(): void $codeChallenge = $this->createCodeChallenge('bar'); $verifier = new S256Verifier(); - $this->assertFalse($verifier->verifyCodeChallenge('foo', $codeChallenge)); + self::assertFalse($verifier->verifyCodeChallenge('foo', $codeChallenge)); } private function createCodeChallenge(string $codeVerifier): string { - return \strtr(\rtrim(\base64_encode(\hash('sha256', $codeVerifier, true)), '='), '+/', '-_'); + return strtr(rtrim(base64_encode(hash('sha256', $codeVerifier, true)), '='), '+/', '-_'); } } diff --git a/tests/Exception/OAuthServerExceptionTest.php b/tests/Exception/OAuthServerExceptionTest.php index d0d6641b6..27922b427 100644 --- a/tests/Exception/OAuthServerExceptionTest.php +++ b/tests/Exception/OAuthServerExceptionTest.php @@ -1,5 +1,7 @@ generateHttpResponse(new Response()); - $this->assertTrue($response->hasHeader('WWW-Authenticate')); + self::assertTrue($response->hasHeader('WWW-Authenticate')); } } @@ -43,7 +46,7 @@ public function testInvalidClientExceptionSetsBearerAuthenticateHeader(): void } catch (OAuthServerException $e) { $response = $e->generateHttpResponse(new Response()); - $this->assertEquals(['Bearer realm="OAuth"'], $response->getHeader('WWW-Authenticate')); + self::assertEquals(['Bearer realm="OAuth"'], $response->getHeader('WWW-Authenticate')); } } @@ -59,7 +62,7 @@ public function testInvalidClientExceptionOmitsAuthenticateHeader(): void } catch (OAuthServerException $e) { $response = $e->generateHttpResponse(new Response()); - $this->assertFalse($response->hasHeader('WWW-Authenticate')); + self::assertFalse($response->hasHeader('WWW-Authenticate')); } } @@ -76,7 +79,7 @@ public function testInvalidClientExceptionOmitsAuthenticateHeaderGivenEmptyAutho } catch (OAuthServerException $e) { $response = $e->generateHttpResponse(new Response()); - $this->assertFalse($response->hasHeader('WWW-Authenticate')); + self::assertFalse($response->hasHeader('WWW-Authenticate')); } } @@ -93,7 +96,7 @@ private function issueInvalidClientException(ServerRequestInterface $serverReque $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $validateClientMethod = $abstractGrantReflection->getMethod('validateClient'); $validateClientMethod->setAccessible(true); @@ -105,14 +108,14 @@ public function testHasRedirect(): void { $exceptionWithRedirect = OAuthServerException::accessDenied('some hint', 'https://example.com/error'); - $this->assertTrue($exceptionWithRedirect->hasRedirect()); + self::assertTrue($exceptionWithRedirect->hasRedirect()); } public function testDoesNotHaveRedirect(): void { $exceptionWithoutRedirect = OAuthServerException::accessDenied('Some hint'); - $this->assertFalse($exceptionWithoutRedirect->hasRedirect()); + self::assertFalse($exceptionWithoutRedirect->hasRedirect()); } public function testHasPrevious(): void @@ -122,27 +125,27 @@ public function testHasPrevious(): void $previousMessage = $exceptionWithPrevious->getPrevious() !== null ? $exceptionWithPrevious->getPrevious()->getMessage() : null; - $this->assertSame('This is the previous', $previousMessage); + self::assertSame('This is the previous', $previousMessage); } public function testDoesNotHavePrevious(): void { $exceptionWithoutPrevious = OAuthServerException::accessDenied(); - $this->assertNull($exceptionWithoutPrevious->getPrevious()); + self::assertNull($exceptionWithoutPrevious->getPrevious()); } public function testCanGetRedirectionUri(): void { $exceptionWithRedirect = OAuthServerException::accessDenied('some hint', 'https://example.com/error'); - $this->assertSame('https://example.com/error', $exceptionWithRedirect->getRedirectUri()); + self::assertSame('https://example.com/error', $exceptionWithRedirect->getRedirectUri()); } public function testInvalidCredentialsIsInvalidGrant(): void { $exception = OAuthServerException::invalidCredentials(); - $this->assertSame('invalid_grant', $exception->getErrorType()); + self::assertSame('invalid_grant', $exception->getErrorType()); } } diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index 9bf569c66..06856f0e3 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -1,5 +1,7 @@ getMockForAbstractClass(AbstractGrant::class); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); - $serverRequest = (new ServerRequest())->withHeader('Authorization', 'Basic ' . \base64_encode('Open:Sesame')); + $serverRequest = (new ServerRequest())->withHeader('Authorization', 'Basic ' . base64_encode('Open:Sesame')); $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); $basicAuthMethod->setAccessible(true); - $this->assertSame(['Open', 'Sesame'], $basicAuthMethod->invoke($grantMock, $serverRequest)); + self::assertSame(['Open', 'Sesame'], $basicAuthMethod->invoke($grantMock, $serverRequest)); } public function testHttpBasicNoPassword(): void { /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); - $serverRequest = (new ServerRequest())->withHeader('Authorization', 'Basic ' . \base64_encode('Open:')); + $serverRequest = (new ServerRequest())->withHeader('Authorization', 'Basic ' . base64_encode('Open:')); $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); $basicAuthMethod->setAccessible(true); - $this->assertSame(['Open', ''], $basicAuthMethod->invoke($grantMock, $serverRequest)); + self::assertSame(['Open', ''], $basicAuthMethod->invoke($grantMock, $serverRequest)); } public function testHttpBasicNotBasic(): void { /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); - $serverRequest = (new ServerRequest())->withHeader('Authorization', 'Foo ' . \base64_encode('Open:Sesame')); + $serverRequest = (new ServerRequest())->withHeader('Authorization', 'Foo ' . base64_encode('Open:Sesame')); $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); $basicAuthMethod->setAccessible(true); - $this->assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); + self::assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); } public function testHttpBasicNotBase64(): void { /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = (new ServerRequest())->withHeader('Authorization', 'Basic ||'); $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); $basicAuthMethod->setAccessible(true); - $this->assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); + self::assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); } public function testHttpBasicNoColon(): void { /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); - $serverRequest = (new ServerRequest())->withHeader('Authorization', 'Basic ' . \base64_encode('OpenSesame')); + $serverRequest = (new ServerRequest())->withHeader('Authorization', 'Basic ' . base64_encode('OpenSesame')); $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); $basicAuthMethod->setAccessible(true); - $this->assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); + self::assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); } public function testGetClientCredentialsClientSecretNotAString(): void @@ -97,7 +104,7 @@ public function testGetClientCredentialsClientSecretNotAString(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = new ServerRequest( [], @@ -116,7 +123,7 @@ public function testGetClientCredentialsClientSecretNotAString(): void $getClientCredentialsMethod = $abstractGrantReflection->getMethod('getClientCredentials'); $getClientCredentialsMethod->setAccessible(true); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $getClientCredentialsMethod->invoke($grantMock, $serverRequest, true, true); } @@ -127,13 +134,15 @@ public function testValidateClientPublic(): void $client->setRedirectUri('http://foo/bar'); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', @@ -143,7 +152,7 @@ public function testValidateClientPublic(): void $validateClientMethod->setAccessible(true); $result = $validateClientMethod->invoke($grantMock, $serverRequest); - $this->assertEquals($client, $result); + self::assertEquals($client, $result); } public function testValidateClientConfidential(): void @@ -152,13 +161,15 @@ public function testValidateClientConfidential(): void $client->setRedirectUri('http://foo/bar'); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', @@ -170,12 +181,9 @@ public function testValidateClientConfidential(): void $validateClientMethod->setAccessible(true); $result = $validateClientMethod->invoke($grantMock, $serverRequest, true, true); - $this->assertEquals($client, $result); + self::assertEquals($client, $result); } - - public function testValidateClientMissingClientId(): void - { - $client = new ClientEntity(); +public function testValidateClientMissingClientId(): void { $client = new ClientEntity(); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); @@ -183,13 +191,13 @@ public function testValidateClientMissingClientId(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = new ServerRequest(); $validateClientMethod = $abstractGrantReflection->getMethod('validateClient'); $validateClientMethod->setAccessible(true); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } @@ -203,7 +211,7 @@ public function testValidateClientMissingClientSecret(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', @@ -212,7 +220,7 @@ public function testValidateClientMissingClientSecret(): void $validateClientMethod = $abstractGrantReflection->getMethod('validateClient'); $validateClientMethod->setAccessible(true); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } @@ -226,7 +234,7 @@ public function testValidateClientInvalidClientSecret(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', @@ -236,7 +244,7 @@ public function testValidateClientInvalidClientSecret(): void $validateClientMethod = $abstractGrantReflection->getMethod('validateClient'); $validateClientMethod->setAccessible(true); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } @@ -252,7 +260,7 @@ public function testValidateClientInvalidRedirectUri(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', @@ -262,7 +270,7 @@ public function testValidateClientInvalidRedirectUri(): void $validateClientMethod = $abstractGrantReflection->getMethod('validateClient'); $validateClientMethod->setAccessible(true); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } @@ -278,7 +286,7 @@ public function testValidateClientInvalidRedirectUriArray(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', @@ -288,7 +296,7 @@ public function testValidateClientInvalidRedirectUriArray(): void $validateClientMethod = $abstractGrantReflection->getMethod('validateClient'); $validateClientMethod->setAccessible(true); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } @@ -304,7 +312,7 @@ public function testValidateClientMalformedRedirectUri(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', @@ -314,7 +322,7 @@ public function testValidateClientMalformedRedirectUri(): void $validateClientMethod = $abstractGrantReflection->getMethod('validateClient'); $validateClientMethod->setAccessible(true); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $validateClientMethod->invoke($grantMock, $serverRequest, true, true); } @@ -328,7 +336,7 @@ public function testValidateClientBadClient(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setClientRepository($clientRepositoryMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', @@ -338,7 +346,7 @@ public function testValidateClientBadClient(): void $validateClientMethod = $abstractGrantReflection->getMethod('validateClient'); $validateClientMethod->setAccessible(true); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $validateClientMethod->invoke($grantMock, $serverRequest, true); } @@ -352,14 +360,14 @@ public function testCanRespondToRequest(): void 'grant_type' => 'foobar', ]); - $this->assertTrue($grantMock->canRespondToAccessTokenRequest($serverRequest)); + self::assertTrue($grantMock->canRespondToAccessTokenRequest($serverRequest)); } public function testIssueRefreshToken(): void { $refreshTokenRepoMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepoMock - ->expects($this->once()) + ->expects(self::once()) ->method('getNewRefreshToken') ->willReturn(new RefreshTokenEntity()); @@ -368,36 +376,37 @@ public function testIssueRefreshToken(): void $grantMock->setRefreshTokenTTL(new DateInterval('PT1M')); $grantMock->setRefreshTokenRepository($refreshTokenRepoMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $issueRefreshTokenMethod = $abstractGrantReflection->getMethod('issueRefreshToken'); $issueRefreshTokenMethod->setAccessible(true); $accessToken = new AccessTokenEntity(); + /** @var RefreshTokenEntityInterface $refreshToken */ $refreshToken = $issueRefreshTokenMethod->invoke($grantMock, $accessToken); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $refreshToken); - $this->assertEquals($accessToken, $refreshToken->getAccessToken()); + + self::assertEquals($accessToken, $refreshToken->getAccessToken()); } public function testIssueNullRefreshToken(): void { $refreshTokenRepoMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepoMock - ->expects($this->once()) + ->expects(self::once()) ->method('getNewRefreshToken') ->willReturn(null); /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); - $grantMock->setRefreshTokenTTL(new \DateInterval('PT1M')); + $grantMock->setRefreshTokenTTL(new DateInterval('PT1M')); $grantMock->setRefreshTokenRepository($refreshTokenRepoMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $issueRefreshTokenMethod = $abstractGrantReflection->getMethod('issueRefreshToken'); $issueRefreshTokenMethod->setAccessible(true); $accessToken = new AccessTokenEntity(); - $this->assertNull($issueRefreshTokenMethod->invoke($grantMock, $accessToken)); + self::assertNull($issueRefreshTokenMethod->invoke($grantMock, $accessToken)); } public function testIssueAccessToken(): void @@ -410,7 +419,7 @@ public function testIssueAccessToken(): void $grantMock->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grantMock->setAccessTokenRepository($accessTokenRepoMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $issueAccessTokenMethod = $abstractGrantReflection->getMethod('issueAccessToken'); $issueAccessTokenMethod->setAccessible(true); @@ -422,23 +431,27 @@ public function testIssueAccessToken(): void 123, [new ScopeEntity()] ); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $accessToken); + + self::assertNotEmpty($accessToken->getIdentifier()); } public function testIssueAuthCode(): void { $authCodeRepoMock = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(); - $authCodeRepoMock->expects($this->once())->method('getNewAuthCode')->willReturn(new AuthCodeEntity()); + $authCodeRepoMock->expects(self::once())->method('getNewAuthCode')->willReturn(new AuthCodeEntity()); /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setAuthCodeRepository($authCodeRepoMock); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $issueAuthCodeMethod = $abstractGrantReflection->getMethod('issueAuthCode'); $issueAuthCodeMethod->setAccessible(true); - $this->assertInstanceOf( + $scope = new ScopeEntity(); + $scope->setIdentifier('scopeId'); + + self::assertInstanceOf( AuthCodeEntityInterface::class, $issueAuthCodeMethod->invoke( $grantMock, @@ -446,7 +459,7 @@ public function testIssueAuthCode(): void new ClientEntity(), 123, 'http://foo/bar', - [new ScopeEntity()] + [$scope] ) ); } @@ -456,7 +469,7 @@ public function testGetCookieParameter(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->method('getIdentifier')->willReturn('foobar'); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $method = $abstractGrantReflection->getMethod('getCookieParameter'); $method->setAccessible(true); @@ -464,8 +477,8 @@ public function testGetCookieParameter(): void 'foo' => 'bar', ]); - $this->assertEquals('bar', $method->invoke($grantMock, 'foo', $serverRequest)); - $this->assertEquals('foo', $method->invoke($grantMock, 'bar', $serverRequest, 'foo')); + self::assertEquals('bar', $method->invoke($grantMock, 'foo', $serverRequest)); + self::assertEquals('foo', $method->invoke($grantMock, 'bar', $serverRequest, 'foo')); } public function testGetQueryStringParameter(): void @@ -473,7 +486,7 @@ public function testGetQueryStringParameter(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->method('getIdentifier')->willReturn('foobar'); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $method = $abstractGrantReflection->getMethod('getQueryStringParameter'); $method->setAccessible(true); @@ -481,21 +494,21 @@ public function testGetQueryStringParameter(): void 'foo' => 'bar', ]); - $this->assertEquals('bar', $method->invoke($grantMock, 'foo', $serverRequest)); - $this->assertEquals('foo', $method->invoke($grantMock, 'bar', $serverRequest, 'foo')); + self::assertEquals('bar', $method->invoke($grantMock, 'foo', $serverRequest)); + self::assertEquals('foo', $method->invoke($grantMock, 'bar', $serverRequest, 'foo')); } public function testValidateScopes(): void { $scope = new ScopeEntity(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); - $scopeRepositoryMock->expects($this->exactly(3))->method('getScopeEntityByIdentifier')->willReturn($scope); + $scopeRepositoryMock->expects(self::exactly(3))->method('getScopeEntityByIdentifier')->willReturn($scope); /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setScopeRepository($scopeRepositoryMock); - $this->assertEquals([$scope, $scope, $scope], $grantMock->validateScopes('basic test 0 ')); + self::assertEquals([$scope, $scope, $scope], $grantMock->validateScopes('basic test 0 ')); } public function testValidateScopesBadScope(): void @@ -507,7 +520,7 @@ public function testValidateScopesBadScope(): void $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); $grantMock->setScopeRepository($scopeRepositoryMock); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $grantMock->validateScopes('basic '); } @@ -516,24 +529,24 @@ public function testGenerateUniqueIdentifier(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); - $abstractGrantReflection = new \ReflectionClass($grantMock); + $abstractGrantReflection = new ReflectionClass($grantMock); $method = $abstractGrantReflection->getMethod('generateUniqueIdentifier'); $method->setAccessible(true); - $this->assertIsString($method->invoke($grantMock)); + self::assertIsString($method->invoke($grantMock)); } public function testCanRespondToAuthorizationRequest(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); - $this->assertFalse($grantMock->canRespondToAuthorizationRequest(new ServerRequest())); + self::assertFalse($grantMock->canRespondToAuthorizationRequest(new ServerRequest())); } public function testValidateAuthorizationRequest(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $grantMock->validateAuthorizationRequest(new ServerRequest()); } @@ -542,7 +555,7 @@ public function testCompleteAuthorizationRequest(): void { $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $grantMock->completeAuthorizationRequest(new AuthorizationRequest()); } diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index b5843c29b..efeb6ba59 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -1,12 +1,13 @@ assertEquals('authorization_code', $grant->getIdentifier()); + self::assertEquals('authorization_code', $grant->getIdentifier()); } public function testCanRespondToAuthorizationRequest(): void @@ -81,7 +86,7 @@ public function testCanRespondToAuthorizationRequest(): void ] ); - $this->assertTrue($grant->canRespondToAuthorizationRequest($request)); + self::assertTrue($grant->canRespondToAuthorizationRequest($request)); } public function testValidateAuthorizationRequest(): void @@ -121,7 +126,7 @@ public function testValidateAuthorizationRequest(): void ] ); - $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); + self::assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } public function testValidateAuthorizationRequestRedirectUriArray(): void @@ -160,7 +165,7 @@ public function testValidateAuthorizationRequestRedirectUriArray(): void ] ); - $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); + self::assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } public function testValidateAuthorizationRequestWithoutRedirectUri(): void @@ -200,9 +205,9 @@ public function testValidateAuthorizationRequestWithoutRedirectUri(): void ); $authorizationRequest = $grant->validateAuthorizationRequest($request); - $this->assertInstanceOf(AuthorizationRequest::class, $authorizationRequest); + self::assertInstanceOf(AuthorizationRequest::class, $authorizationRequest); - $this->assertEmpty($authorizationRequest->getRedirectUri()); + self::assertEmpty($authorizationRequest->getRedirectUri()); } public function testValidateAuthorizationRequestCodeChallenge(): void @@ -242,7 +247,7 @@ public function testValidateAuthorizationRequestCodeChallenge(): void ] ); - $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); + self::assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooShort(): void @@ -264,10 +269,10 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooSho 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => \str_repeat('A', 42), + 'code_challenge' => str_repeat('A', 42), ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $grant->validateAuthorizationRequest($request); } @@ -291,10 +296,10 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooLon 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => \str_repeat('A', 129), + 'code_challenge' => str_repeat('A', 129), ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $grant->validateAuthorizationRequest($request); } @@ -318,10 +323,10 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidCharacters() 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', - 'code_challenge' => \str_repeat('A', 42) . '!', + 'code_challenge' => str_repeat('A', 42) . '!', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $grant->validateAuthorizationRequest($request); } @@ -341,7 +346,7 @@ public function testValidateAuthorizationRequestMissingClientId(): void 'response_type' => 'code', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(3); $grant->validateAuthorizationRequest($request); @@ -364,7 +369,7 @@ public function testValidateAuthorizationRequestInvalidClientId(): void 'client_id' => 'foo', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(4); $grant->validateAuthorizationRequest($request); @@ -390,7 +395,7 @@ public function testValidateAuthorizationRequestBadRedirectUriString(): void 'redirect_uri' => 'http://bar', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(4); $grant->validateAuthorizationRequest($request); @@ -416,7 +421,7 @@ public function testValidateAuthorizationRequestBadRedirectUriArray(): void 'redirect_uri' => 'http://bar', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(4); $grant->validateAuthorizationRequest($request); @@ -451,7 +456,7 @@ public function testValidateAuthorizationRequestInvalidCodeChallengeMethod(): vo 'code_challenge_method' => 'foo', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(3); $grant->validateAuthorizationRequest($request); @@ -459,9 +464,13 @@ public function testValidateAuthorizationRequestInvalidCodeChallengeMethod(): vo public function testCompleteAuthorizationRequest(): void { + $client = new ClientEntity(); + $client->setIdentifier('clientId'); + $client->setRedirectUri('http://foo/bar'); + $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); - $authRequest->setClient(new ClientEntity()); + $authRequest->setClient($client); $authRequest->setGrantTypeId('authorization_code'); $authRequest->setUser(new UserEntity()); @@ -475,13 +484,15 @@ public function testCompleteAuthorizationRequest(): void ); $grant->setEncryptionKey($this->cryptStub->getKey()); - $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); + self::assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } public function testCompleteAuthorizationRequestWithMultipleRedirectUrisOnClient(): void { $client = new ClientEntity(); + $client->setIdentifier('clientId'); $client->setRedirectUri(['uriOne', 'uriTwo']); + $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); $authRequest->setClient($client); @@ -498,14 +509,17 @@ public function testCompleteAuthorizationRequestWithMultipleRedirectUrisOnClient ); $grant->setEncryptionKey($this->cryptStub->getKey()); - $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); + self::assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } public function testCompleteAuthorizationRequestDenied(): void { + $client = new ClientEntity(); + $client->setRedirectUri('http://foo/bar'); + $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(false); - $authRequest->setClient(new ClientEntity()); + $authRequest->setClient($client); $authRequest->setGrantTypeId('authorization_code'); $authRequest->setUser(new UserEntity()); @@ -519,7 +533,7 @@ public function testCompleteAuthorizationRequestDenied(): void ); $grant->setEncryptionKey($this->cryptStub->getKey()); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(9); $grant->completeAuthorizationRequest($authRequest); @@ -528,11 +542,15 @@ public function testCompleteAuthorizationRequestDenied(): void public function testRespondToAccessTokenRequest(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeEntity = new ScopeEntity(); @@ -574,8 +592,8 @@ public function testRespondToAccessTokenRequest(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -588,8 +606,7 @@ public function testRespondToAccessTokenRequest(): void /** @var StubResponseType $response */ $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } public function testRespondToAccessTokenRequestUsingHttpBasicAuth(): void @@ -613,7 +630,7 @@ public function testRespondToAccessTokenRequestUsingHttpBasicAuth(): void $authCodeGrant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), $refreshTokenRepositoryMock, - new \DateInterval('PT10M') + new DateInterval('PT10M') ); $authCodeGrant->setClientRepository($clientRepositoryMock); @@ -638,9 +655,9 @@ public function testRespondToAccessTokenRequestUsingHttpBasicAuth(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), + 'auth_code_id' => uniqid(), 'client_id' => 'foo', - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, 'user_id' => 123, 'scopes' => ['foo'], 'redirect_uri' => 'http://foo/bar', @@ -650,10 +667,9 @@ public function testRespondToAccessTokenRequestUsingHttpBasicAuth(): void ); /** @var StubResponseType $response */ - $response = $authCodeGrant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M')); + $response = $authCodeGrant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } public function testRespondToAccessTokenRequestForPublicClient(): void @@ -704,8 +720,8 @@ public function testRespondToAccessTokenRequestForPublicClient(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -718,8 +734,7 @@ public function testRespondToAccessTokenRequestForPublicClient(): void /** @var StubResponseType $response */ $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } public function testRespondToAccessTokenRequestNullRefreshToken(): void @@ -746,7 +761,7 @@ public function testRespondToAccessTokenRequestNullRefreshToken(): void $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), $refreshTokenRepositoryMock, - new \DateInterval('PT10M') + new DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -770,8 +785,8 @@ public function testRespondToAccessTokenRequestNullRefreshToken(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -782,20 +797,23 @@ public function testRespondToAccessTokenRequestNullRefreshToken(): void ); /** @var StubResponseType $response */ - $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M')); + $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken()); - $this->assertNull($response->getRefreshToken()); + self::assertNull($response->getRefreshToken()); } public function testRespondToAccessTokenRequestCodeChallengePlain(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeEntity = new ScopeEntity(); @@ -839,8 +857,8 @@ public function testRespondToAccessTokenRequestCodeChallengePlain(): void 'code_verifier' => self::CODE_VERIFIER, 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -855,18 +873,21 @@ public function testRespondToAccessTokenRequestCodeChallengePlain(): void /** @var StubResponseType $response */ $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } public function testRespondToAccessTokenRequestCodeChallengeS256(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeEntity = new ScopeEntity(); @@ -910,8 +931,8 @@ public function testRespondToAccessTokenRequestCodeChallengeS256(): void 'code_verifier' => self::CODE_VERIFIER, 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -926,18 +947,21 @@ public function testRespondToAccessTokenRequestCodeChallengeS256(): void /** @var StubResponseType $response */ $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } public function testRespondToAccessTokenRequestMissingRedirectUri(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setConfidential(); $client->setRedirectUri('http://foo/bar'); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), @@ -961,8 +985,8 @@ public function testRespondToAccessTokenRequestMissingRedirectUri(): void 'grant_type' => 'authorization_code', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', ], JSON_THROW_ON_ERROR) @@ -970,7 +994,7 @@ public function testRespondToAccessTokenRequestMissingRedirectUri(): void ] ); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(3); $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); @@ -979,11 +1003,15 @@ public function testRespondToAccessTokenRequestMissingRedirectUri(): void public function testRespondToAccessTokenRequestRedirectUriMismatch(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setConfidential(); $client->setRedirectUri('http://bar/foo'); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), @@ -1008,8 +1036,8 @@ public function testRespondToAccessTokenRequestRedirectUriMismatch(): void 'redirect_uri' => 'http://bar/foo', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', ], JSON_THROW_ON_ERROR) @@ -1017,7 +1045,7 @@ public function testRespondToAccessTokenRequestRedirectUriMismatch(): void ] ); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(3); $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); @@ -1026,10 +1054,14 @@ public function testRespondToAccessTokenRequestRedirectUriMismatch(): void public function testRespondToAccessTokenRequestMissingCode(): void { $client = new ClientEntity(); + $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); @@ -1061,7 +1093,7 @@ public function testRespondToAccessTokenRequestMissingCode(): void ] ); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(3); /* @var StubResponseType $response */ @@ -1105,7 +1137,7 @@ public function testRespondToAccessTokenRequestWithRefreshTokenInsteadOfAuthCode 'access_token_id' => 'abcdef', 'scopes' => ['foo'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ], JSON_THROW_ON_ERROR) ), ] @@ -1115,7 +1147,7 @@ public function testRespondToAccessTokenRequestWithRefreshTokenInsteadOfAuthCode /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals('Authorization code malformed', $e->getHint()); + self::assertEquals('Authorization code malformed', $e->getHint()); } } @@ -1153,7 +1185,7 @@ public function testRespondToAccessTokenRequestWithAuthCodeNotAString(): void ] ); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } @@ -1189,8 +1221,8 @@ public function testRespondToAccessTokenRequestExpiredCode(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() - 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() - 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -1204,18 +1236,22 @@ public function testRespondToAccessTokenRequestExpiredCode(): void /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals($e->getHint(), 'Authorization code has expired'); + self::assertEquals($e->getHint(), 'Authorization code has expired'); } } public function testRespondToAccessTokenRequestRevokedCode(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); @@ -1251,8 +1287,8 @@ public function testRespondToAccessTokenRequestRevokedCode(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -1266,19 +1302,23 @@ public function testRespondToAccessTokenRequestRevokedCode(): void /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals($e->getHint(), 'Authorization code has been revoked'); - $this->assertEquals($e->getErrorType(), 'invalid_grant'); + self::assertEquals($e->getHint(), 'Authorization code has been revoked'); + self::assertEquals($e->getErrorType(), 'invalid_grant'); } } public function testRespondToAccessTokenRequestClientMismatch(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); @@ -1311,8 +1351,8 @@ public function testRespondToAccessTokenRequestClientMismatch(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'bar', 'user_id' => 123, 'scopes' => ['foo'], @@ -1326,18 +1366,22 @@ public function testRespondToAccessTokenRequestClientMismatch(): void /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals($e->getHint(), 'Authorization code was not issued to this client'); + self::assertEquals($e->getHint(), 'Authorization code was not issued to this client'); } } public function testRespondToAccessTokenRequestBadCodeEncryption(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); @@ -1376,18 +1420,22 @@ public function testRespondToAccessTokenRequestBadCodeEncryption(): void /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals($e->getHint(), 'Cannot decrypt the authorization code'); + self::assertEquals($e->getHint(), 'Cannot decrypt the authorization code'); } } public function testRespondToAccessTokenRequestBadCodeVerifierPlain(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeEntity = new ScopeEntity(); @@ -1430,8 +1478,8 @@ public function testRespondToAccessTokenRequestBadCodeVerifierPlain(): void 'code_verifier' => self::CODE_VERIFIER, 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -1447,18 +1495,22 @@ public function testRespondToAccessTokenRequestBadCodeVerifierPlain(): void /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals($e->getHint(), 'Failed to verify `code_verifier`.'); + self::assertEquals($e->getHint(), 'Failed to verify `code_verifier`.'); } } public function testRespondToAccessTokenRequestBadCodeVerifierS256(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeEntity = new ScopeEntity(); @@ -1501,8 +1553,8 @@ public function testRespondToAccessTokenRequestBadCodeVerifierS256(): void 'code_verifier' => 'nope', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -1518,18 +1570,22 @@ public function testRespondToAccessTokenRequestBadCodeVerifierS256(): void /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals($e->getHint(), 'Code Verifier must follow the specifications of RFC-7636.'); + self::assertEquals($e->getHint(), 'Code Verifier must follow the specifications of RFC-7636.'); } } public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInvalidChars(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeEntity = new ScopeEntity(); @@ -1572,8 +1628,8 @@ public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInva 'code_verifier' => 'dqX7C-RbqjHYtytmhGTigKdZCXfxq-+xbsk9_GxUcaE', // Malformed code. Contains `+`. 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -1589,18 +1645,22 @@ public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInva /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals($e->getHint(), 'Code Verifier must follow the specifications of RFC-7636.'); + self::assertEquals($e->getHint(), 'Code Verifier must follow the specifications of RFC-7636.'); } } public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInvalidLength(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeEntity = new ScopeEntity(); @@ -1643,8 +1703,8 @@ public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInva 'code_verifier' => 'dqX7C-RbqjHY', // Malformed code. Invalid length. 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -1660,18 +1720,22 @@ public function testRespondToAccessTokenRequestMalformedCodeVerifierS256WithInva /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals($e->getHint(), 'Code Verifier must follow the specifications of RFC-7636.'); + self::assertEquals($e->getHint(), 'Code Verifier must follow the specifications of RFC-7636.'); } } public function testRespondToAccessTokenRequestMissingCodeVerifier(): void { $client = new ClientEntity(); + $client->setIdentifier('foo'); $client->setRedirectUri('http://foo/bar'); $client->setConfidential(); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeEntity = new ScopeEntity(); @@ -1713,8 +1777,8 @@ public function testRespondToAccessTokenRequestMissingCodeVerifier(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -1730,27 +1794,31 @@ public function testRespondToAccessTokenRequestMissingCodeVerifier(): void /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); } catch (OAuthServerException $e) { - $this->assertEquals($e->getHint(), 'Check the `code_verifier` parameter'); + self::assertEquals($e->getHint(), 'Check the `code_verifier` parameter'); } } public function testAuthCodeRepositoryUniqueConstraintCheck(): void { + $client = new ClientEntity(); + $client->setIdentifier('clientId'); + $client->setRedirectUri('http://foo/bar'); + $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); - $authRequest->setClient(new ClientEntity()); + $authRequest->setClient($client); $authRequest->setGrantTypeId('authorization_code'); $authRequest->setUser(new UserEntity()); $authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(); $authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity()); - $matcher = $this->exactly(2); + $matcher = self::exactly(2); $authCodeRepository ->expects($matcher) ->method('persistNewAuthCode') - ->willReturnCallback(function () use ($matcher) { + ->willReturnCallback(function () use ($matcher): void { if ($matcher->getInvocationCount() === 1) { throw UniqueTokenIdentifierConstraintViolationException::create(); } @@ -1764,7 +1832,7 @@ public function testAuthCodeRepositoryUniqueConstraintCheck(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); + self::assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } public function testAuthCodeRepositoryFailToPersist(): void @@ -1786,10 +1854,10 @@ public function testAuthCodeRepositoryFailToPersist(): void ); $grant->setEncryptionKey($this->cryptStub->getKey()); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(7); - $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); + self::assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } public function testAuthCodeRepositoryFailToPersistUniqueNoInfiniteLoop(): void @@ -1810,10 +1878,10 @@ public function testAuthCodeRepositoryFailToPersistUniqueNoInfiniteLoop(): void new DateInterval('PT10M') ); - $this->expectException(\League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException::class); + $this->expectException(UniqueTokenIdentifierConstraintViolationException::class); $this->expectExceptionCode(100); - $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); + self::assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } public function testRefreshTokenRepositoryUniqueConstraintCheck(): void @@ -1836,12 +1904,12 @@ public function testRefreshTokenRepositoryUniqueConstraintCheck(): void $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); - $matcher = $this->exactly(2); + $matcher = self::exactly(2); $refreshTokenRepositoryMock ->expects($matcher) ->method('persistNewRefreshToken') - ->willReturnCallback(function () use ($matcher) { + ->willReturnCallback(function () use ($matcher): void { if ($matcher->getInvocationCount() === 1) { throw UniqueTokenIdentifierConstraintViolationException::create(); } @@ -1874,8 +1942,8 @@ public function testRefreshTokenRepositoryUniqueConstraintCheck(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -1888,8 +1956,7 @@ public function testRefreshTokenRepositoryUniqueConstraintCheck(): void /** @var StubResponseType $response */ $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } public function testRefreshTokenRepositoryFailToPersist(): void @@ -1940,8 +2007,8 @@ public function testRefreshTokenRepositoryFailToPersist(): void 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -1951,14 +2018,13 @@ public function testRefreshTokenRepositoryFailToPersist(): void ] ); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(7); /** @var StubResponseType $response */ $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } public function testRefreshTokenRepositoryFailToPersistUniqueNoInfiniteLoop(): void @@ -2009,8 +2075,8 @@ public function testRefreshTokenRepositoryFailToPersistUniqueNoInfiniteLoop(): v 'redirect_uri' => 'http://foo/bar', 'code' => $this->cryptStub->doEncrypt( json_encode([ - 'auth_code_id' => \uniqid(), - 'expire_time' => \time() + 3600, + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, 'client_id' => 'foo', 'user_id' => 123, 'scopes' => ['foo'], @@ -2020,14 +2086,13 @@ public function testRefreshTokenRepositoryFailToPersistUniqueNoInfiniteLoop(): v ] ); - $this->expectException(\League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException::class); + $this->expectException(UniqueTokenIdentifierConstraintViolationException::class); $this->expectExceptionCode(100); /** @var StubResponseType $response */ $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new DateInterval('PT10M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $response->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $response->getRefreshToken()); } public function testCompleteAuthorizationRequestNoUser(): void @@ -2038,7 +2103,7 @@ public function testCompleteAuthorizationRequestNoUser(): void new DateInterval('PT10M') ); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $grant->completeAuthorizationRequest(new AuthorizationRequest()); } @@ -2120,7 +2185,7 @@ public function testUseValidRedirectUriIfScopeCheckFails(): void } catch (OAuthServerException $e) { $response = $e->generateHttpResponse(new Response()); - $this->assertStringStartsWith('http://bar/foo', $response->getHeader('Location')[0]); + self::assertStringStartsWith('http://bar/foo', $response->getHeader('Location')[0]); } } } diff --git a/tests/Grant/ClientCredentialsGrantTest.php b/tests/Grant/ClientCredentialsGrantTest.php index e3d9b9268..e0b67e755 100644 --- a/tests/Grant/ClientCredentialsGrantTest.php +++ b/tests/Grant/ClientCredentialsGrantTest.php @@ -1,11 +1,12 @@ assertEquals('client_credentials', $grant->getIdentifier()); + self::assertEquals('client_credentials', $grant->getIdentifier()); } public function testRespondToRequest(): void @@ -57,8 +58,9 @@ public function testRespondToRequest(): void ]); $responseType = new StubResponseType(); - $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); + $response = $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); + - $this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken()); + self::assertNotEmpty($response->getAccessToken()->getIdentifier()); } } diff --git a/tests/Grant/ImplicitGrantTest.php b/tests/Grant/ImplicitGrantTest.php index 45777b755..64d00de0d 100644 --- a/tests/Grant/ImplicitGrantTest.php +++ b/tests/Grant/ImplicitGrantTest.php @@ -1,5 +1,7 @@ assertEquals('implicit', $grant->getIdentifier()); + self::assertEquals('implicit', $grant->getIdentifier()); } public function testCanRespondToAccessTokenRequest(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); - $this->assertFalse( + self::assertFalse( $grant->canRespondToAccessTokenRequest(new ServerRequest()) ); } @@ -52,7 +55,7 @@ public function testRespondToAccessTokenRequest(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $grant->respondToAccessTokenRequest( new ServerRequest(), @@ -70,7 +73,7 @@ public function testCanRespondToAuthorizationRequest(): void 'client_id' => 'foo', ]); - $this->assertTrue($grant->canRespondToAuthorizationRequest($request)); + self::assertTrue($grant->canRespondToAuthorizationRequest($request)); } public function testValidateAuthorizationRequest(): void @@ -95,7 +98,7 @@ public function testValidateAuthorizationRequest(): void 'redirect_uri' => 'http://foo/bar', ]); - $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); + self::assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } public function testValidateAuthorizationRequestRedirectUriArray(): void @@ -120,7 +123,7 @@ public function testValidateAuthorizationRequestRedirectUriArray(): void 'redirect_uri' => 'http://foo/bar', ]); - $this->assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); + self::assertInstanceOf(AuthorizationRequest::class, $grant->validateAuthorizationRequest($request)); } public function testValidateAuthorizationRequestMissingClientId(): void @@ -132,7 +135,7 @@ public function testValidateAuthorizationRequestMissingClientId(): void $request = (new ServerRequest())->withQueryParams(['response_type' => 'code']); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(3); $grant->validateAuthorizationRequest($request); @@ -151,7 +154,7 @@ public function testValidateAuthorizationRequestInvalidClientId(): void 'client_id' => 'foo', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(4); $grant->validateAuthorizationRequest($request); @@ -173,7 +176,7 @@ public function testValidateAuthorizationRequestBadRedirectUriString(): void 'redirect_uri' => 'http://bar', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(4); $grant->validateAuthorizationRequest($request); @@ -195,7 +198,7 @@ public function testValidateAuthorizationRequestBadRedirectUriArray(): void 'redirect_uri' => 'http://bar', ]); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(4); $grant->validateAuthorizationRequest($request); @@ -205,6 +208,7 @@ public function testCompleteAuthorizationRequest(): void { $client = new ClientEntity(); $client->setIdentifier('identifier'); + $client->setRedirectUri('https://foo/bar'); $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); @@ -222,19 +226,23 @@ public function testCompleteAuthorizationRequest(): void $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); - $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant = new ImplicitGrant(new DateInterval('PT10M')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); - $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); + self::assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } public function testCompleteAuthorizationRequestDenied(): void { + $client = new ClientEntity(); + $client->setIdentifier('clientId'); + $client->setRedirectUri('https://foo/bar'); + $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(false); - $authRequest->setClient(new ClientEntity()); + $authRequest->setClient($client); $authRequest->setGrantTypeId('authorization_code'); $authRequest->setUser(new UserEntity()); @@ -245,12 +253,12 @@ public function testCompleteAuthorizationRequestDenied(): void $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); - $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant = new ImplicitGrant(new DateInterval('PT10M')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(9); $grant->completeAuthorizationRequest($authRequest); @@ -259,7 +267,8 @@ public function testCompleteAuthorizationRequestDenied(): void public function testAccessTokenRepositoryUniqueConstraintCheck(): void { $client = new ClientEntity(); - $client->setIdentifier('identifier'); + $client->setIdentifier('clientId'); + $client->setRedirectUri('https://foo/bar'); $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); @@ -274,12 +283,12 @@ public function testAccessTokenRepositoryUniqueConstraintCheck(): void $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn($accessToken); - $matcher = $this->exactly(2); + $matcher = self::exactly(2); $accessTokenRepositoryMock ->expects($matcher) ->method('persistNewAccessToken') - ->willReturnCallback(function () use ($matcher) { + ->willReturnCallback(function () use ($matcher): void { if ($matcher->getInvocationCount() === 1) { throw UniqueTokenIdentifierConstraintViolationException::create(); } @@ -288,12 +297,12 @@ public function testAccessTokenRepositoryUniqueConstraintCheck(): void $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); - $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant = new ImplicitGrant(new DateInterval('PT10M')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); - $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); + self::assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } public function testAccessTokenRepositoryFailToPersist(): void @@ -312,12 +321,12 @@ public function testAccessTokenRepositoryFailToPersist(): void $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); - $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant = new ImplicitGrant(new DateInterval('PT10M')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(7); $grant->completeAuthorizationRequest($authRequest); @@ -339,12 +348,12 @@ public function testAccessTokenRepositoryFailToPersistUniqueNoInfiniteLoop(): vo $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); - $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant = new ImplicitGrant(new DateInterval('PT10M')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); - $this->expectException(\League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException::class); + $this->expectException(UniqueTokenIdentifierConstraintViolationException::class); $this->expectExceptionCode(100); $grant->completeAuthorizationRequest($authRequest); @@ -354,7 +363,7 @@ public function testSetRefreshTokenTTL(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $grant->setRefreshTokenTTL(new DateInterval('PT10M')); } @@ -365,7 +374,7 @@ public function testSetRefreshTokenRepository(): void $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); } @@ -374,7 +383,7 @@ public function testCompleteAuthorizationRequestNoUser(): void { $grant = new ImplicitGrant(new DateInterval('PT10M')); - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $grant->completeAuthorizationRequest(new AuthorizationRequest()); } diff --git a/tests/Grant/PasswordGrantTest.php b/tests/Grant/PasswordGrantTest.php index 1eb2e0895..42bdc8f95 100644 --- a/tests/Grant/PasswordGrantTest.php +++ b/tests/Grant/PasswordGrantTest.php @@ -1,5 +1,7 @@ getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock); - $this->assertEquals('password', $grant->getIdentifier()); + self::assertEquals('password', $grant->getIdentifier()); } public function testRespondToRequest(): void @@ -76,8 +79,7 @@ public function testRespondToRequest(): void $responseType = new StubResponseType(); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); } public function testRespondToRequestNullRefreshToken(): void @@ -119,10 +121,9 @@ public function testRespondToRequestNullRefreshToken(): void ]); $responseType = new StubResponseType(); - $grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M')); + $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken()); - $this->assertNull($responseType->getRefreshToken()); + self::assertNull($responseType->getRefreshToken()); } public function testRespondToRequestMissingUsername(): void @@ -148,7 +149,7 @@ public function testRespondToRequestMissingUsername(): void $responseType = new StubResponseType(); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } @@ -177,7 +178,7 @@ public function testRespondToRequestMissingPassword(): void $responseType = new StubResponseType(); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); } @@ -210,7 +211,7 @@ public function testRespondToRequestBadCredentials(): void $responseType = new StubResponseType(); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(6); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index aa2bb101e..0f8e243b5 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -1,12 +1,14 @@ getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $grant = new RefreshTokenGrant($refreshTokenRepositoryMock); - $this->assertEquals('refresh_token', $grant->getIdentifier()); + self::assertEquals('refresh_token', $grant->getIdentifier()); } public function testRespondToRequest(): void @@ -58,11 +62,11 @@ public function testRespondToRequest(): void $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); - $accessTokenRepositoryMock->expects($this->once())->method('persistNewAccessToken')->willReturnSelf(); + $accessTokenRepositoryMock->expects(self::once())->method('persistNewAccessToken')->willReturnSelf(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); - $refreshTokenRepositoryMock->expects($this->once())->method('persistNewRefreshToken')->willReturnSelf(); + $refreshTokenRepositoryMock->expects(self::once())->method('persistNewRefreshToken')->willReturnSelf(); $grant = new RefreshTokenGrant($refreshTokenRepositoryMock); $grant->setClientRepository($clientRepositoryMock); @@ -72,19 +76,19 @@ public function testRespondToRequest(): void $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->revokeRefreshTokens(true); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'foo', 'refresh_token_id' => 'zyxwvu', 'access_token_id' => 'abcdef', 'scopes' => ['foo'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( @@ -101,8 +105,7 @@ public function testRespondToRequest(): void $responseType = new StubResponseType(); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); } public function testRespondToRequestNullRefreshToken(): void @@ -123,11 +126,11 @@ public function testRespondToRequestNullRefreshToken(): void $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); - $accessTokenRepositoryMock->expects($this->once())->method('persistNewAccessToken')->willReturnSelf(); + $accessTokenRepositoryMock->expects(self::once())->method('persistNewAccessToken')->willReturnSelf(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(null); - $refreshTokenRepositoryMock->expects($this->never())->method('persistNewRefreshToken'); + $refreshTokenRepositoryMock->expects(self::never())->method('persistNewRefreshToken'); $grant = new RefreshTokenGrant($refreshTokenRepositoryMock); $grant->setClientRepository($clientRepositoryMock); @@ -136,23 +139,23 @@ public function testRespondToRequestNullRefreshToken(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'foo', 'refresh_token_id' => 'zyxwvu', 'access_token_id' => 'abcdef', 'scopes' => ['foo'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( - $oldRefreshToken + $oldRefreshToken ); $serverRequest = (new ServerRequest())->withParsedBody([ @@ -163,10 +166,9 @@ public function testRespondToRequestNullRefreshToken(): void ]); $responseType = new StubResponseType(); - $grant->respondToAccessTokenRequest($serverRequest, $responseType, new \DateInterval('PT5M')); + $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken()); - $this->assertNull($responseType->getRefreshToken()); + self::assertNull($responseType->getRefreshToken()); } public function testRespondToReducedScopes(): void @@ -200,19 +202,19 @@ public function testRespondToReducedScopes(): void $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->revokeRefreshTokens(true); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'foo', 'refresh_token_id' => 'zyxwvu', 'access_token_id' => 'abcdef', 'scopes' => ['foo', 'bar'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( @@ -229,8 +231,7 @@ public function testRespondToReducedScopes(): void $responseType = new StubResponseType(); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); - $this->assertInstanceOf(AccessTokenEntityInterface::class, $responseType->getAccessToken()); - $this->assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); + self::assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); } public function testRespondToUnexpectedScope(): void @@ -260,19 +261,19 @@ public function testRespondToUnexpectedScope(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'foo', 'refresh_token_id' => 'zyxwvu', 'access_token_id' => 'abcdef', 'scopes' => ['foo', 'bar'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( @@ -288,7 +289,7 @@ public function testRespondToUnexpectedScope(): void $responseType = new StubResponseType(); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(5); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); @@ -319,7 +320,7 @@ public function testRespondToRequestMissingOldToken(): void $responseType = new StubResponseType(); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(3); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); @@ -353,7 +354,7 @@ public function testRespondToRequestInvalidOldToken(): void $responseType = new StubResponseType(); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(8); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); @@ -380,19 +381,19 @@ public function testRespondToRequestClientMismatch(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'bar', 'refresh_token_id' => 'zyxwvu', 'access_token_id' => 'abcdef', 'scopes' => ['foo'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( @@ -407,7 +408,7 @@ public function testRespondToRequestClientMismatch(): void $responseType = new StubResponseType(); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(8); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); @@ -431,19 +432,19 @@ public function testRespondToRequestExpiredToken(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'foo', 'refresh_token_id' => 'zyxwvu', 'access_token_id' => 'abcdef', 'scopes' => ['foo'], 'user_id' => 123, - 'expire_time' => \time() - 3600, + 'expire_time' => time() - 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( @@ -458,7 +459,7 @@ public function testRespondToRequestExpiredToken(): void $responseType = new StubResponseType(); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(8); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); @@ -483,19 +484,19 @@ public function testRespondToRequestRevokedToken(): void $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'foo', 'refresh_token_id' => 'zyxwvu', 'access_token_id' => 'abcdef', 'scopes' => ['foo'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( @@ -510,7 +511,7 @@ public function testRespondToRequestRevokedToken(): void $responseType = new StubResponseType(); - $this->expectException(\League\OAuth2\Server\Exception\OAuthServerException::class); + $this->expectException(OAuthServerException::class); $this->expectExceptionCode(8); $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); @@ -554,7 +555,7 @@ public function testRespondToRequestFinalizeScopes(): void $finalizedScopes = [$fooScopeEntity]; $scopeRepositoryMock - ->expects($this->once()) + ->expects(self::once()) ->method('finalizeScopes') ->with($scopes, $grant->getIdentifier(), $client) ->willReturn($finalizedScopes); @@ -564,19 +565,19 @@ public function testRespondToRequestFinalizeScopes(): void ->with($client, $finalizedScopes) ->willReturn(new AccessTokenEntity()); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'foo', 'refresh_token_id' => 'zyxwvu', 'access_token_id' => 'abcdef', 'scopes' => ['foo', 'bar'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( @@ -588,7 +589,7 @@ public function testRespondToRequestFinalizeScopes(): void 'client_secret' => 'bar', 'refresh_token' => $encryptedOldRefreshToken, 'scope' => ['foo', 'bar'], - ]); + ]); $responseType = new StubResponseType(); @@ -615,26 +616,26 @@ public function testRevokedRefreshToken(): void $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); - $accessTokenRepositoryMock->expects($this->once())->method('persistNewAccessToken')->willReturnSelf(); + $accessTokenRepositoryMock->expects(self::once())->method('persistNewAccessToken')->willReturnSelf(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock->method('isRefreshTokenRevoked') - ->will($this->onConsecutiveCalls(false, true)); - $refreshTokenRepositoryMock->expects($this->once())->method('revokeRefreshToken')->with($this->equalTo($refreshTokenId)); + ->will(self::onConsecutiveCalls(false, true)); + $refreshTokenRepositoryMock->expects(self::once())->method('revokeRefreshToken')->with(self::equalTo($refreshTokenId)); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'foo', 'refresh_token_id' => $refreshTokenId, 'access_token_id' => 'abcdef', 'scopes' => ['foo'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( @@ -657,7 +658,7 @@ public function testRevokedRefreshToken(): void $grant->revokeRefreshTokens(true); $grant->respondToAccessTokenRequest($serverRequest, new StubResponseType(), new DateInterval('PT5M')); - Assert::assertTrue($refreshTokenRepositoryMock->isRefreshTokenRevoked($refreshTokenId)); + self::assertTrue($refreshTokenRepositoryMock->isRefreshTokenRevoked($refreshTokenId)); } public function testUnrevokedRefreshToken(): void @@ -680,25 +681,25 @@ public function testUnrevokedRefreshToken(): void $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); - $accessTokenRepositoryMock->expects($this->once())->method('persistNewAccessToken')->willReturnSelf(); + $accessTokenRepositoryMock->expects(self::once())->method('persistNewAccessToken')->willReturnSelf(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock->method('isRefreshTokenRevoked')->willReturn(false); - $refreshTokenRepositoryMock->expects($this->never())->method('revokeRefreshToken'); + $refreshTokenRepositoryMock->expects(self::never())->method('revokeRefreshToken'); - $oldRefreshToken = \json_encode( + $oldRefreshToken = json_encode( [ 'client_id' => 'foo', 'refresh_token_id' => $refreshTokenId, 'access_token_id' => 'abcdef', 'scopes' => ['foo'], 'user_id' => 123, - 'expire_time' => \time() + 3600, + 'expire_time' => time() + 3600, ] ); if ($oldRefreshToken === false) { - $this->fail('json_encode failed'); + self::fail('json_encode failed'); } $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( @@ -720,6 +721,6 @@ public function testUnrevokedRefreshToken(): void $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->respondToAccessTokenRequest($serverRequest, new StubResponseType(), new DateInterval('PT5M')); - Assert::assertFalse($refreshTokenRepositoryMock->isRefreshTokenRevoked($refreshTokenId)); + self::assertFalse($refreshTokenRepositoryMock->isRefreshTokenRevoked($refreshTokenId)); } } diff --git a/tests/Middleware/AuthorizationServerMiddlewareTest.php b/tests/Middleware/AuthorizationServerMiddlewareTest.php index 696b5cfe3..950ace46b 100644 --- a/tests/Middleware/AuthorizationServerMiddlewareTest.php +++ b/tests/Middleware/AuthorizationServerMiddlewareTest.php @@ -1,5 +1,7 @@ getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository->method('getClientEntity')->willReturn($client); - $scopeEntity = new ScopeEntity; + $scopeEntity = new ScopeEntity(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); @@ -44,7 +50,7 @@ public function testValidResponse(): void $accessRepositoryMock, $scopeRepositoryMock, 'file://' . __DIR__ . '/../Stubs/private.key', - \base64_encode(\random_bytes(36)), + base64_encode(random_bytes(36)), new StubResponseType() ); @@ -62,10 +68,10 @@ public function testValidResponse(): void $request, new Response(), function () { - return \func_get_args()[1]; + return func_get_args()[1]; } ); - $this->assertEquals(200, $response->getStatusCode()); + self::assertEquals(200, $response->getStatusCode()); } public function testOAuthErrorResponse(): void @@ -78,7 +84,7 @@ public function testOAuthErrorResponse(): void $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/../Stubs/private.key', - \base64_encode(\random_bytes(36)), + base64_encode(random_bytes(36)), new StubResponseType() ); @@ -96,11 +102,11 @@ public function testOAuthErrorResponse(): void $request, new Response(), function () { - return \func_get_args()[1]; + return func_get_args()[1]; } ); - $this->assertEquals(401, $response->getStatusCode()); + self::assertEquals(401, $response->getStatusCode()); } public function testOAuthErrorResponseRedirectUri(): void @@ -108,8 +114,8 @@ public function testOAuthErrorResponseRedirectUri(): void $exception = OAuthServerException::invalidScope('test', 'http://foo/bar'); $response = $exception->generateHttpResponse(new Response()); - $this->assertEquals(302, $response->getStatusCode()); - $this->assertEquals( + self::assertEquals(302, $response->getStatusCode()); + self::assertEquals( 'http://foo/bar?error=invalid_scope&error_description=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed', $response->getHeader('location')[0] ); @@ -120,8 +126,8 @@ public function testOAuthErrorResponseRedirectUriFragment(): void $exception = OAuthServerException::invalidScope('test', 'http://foo/bar'); $response = $exception->generateHttpResponse(new Response(), true); - $this->assertEquals(302, $response->getStatusCode()); - $this->assertEquals( + self::assertEquals(302, $response->getStatusCode()); + self::assertEquals( 'http://foo/bar#error=invalid_scope&error_description=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed&hint=Check+the+%60test%60+scope&message=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed', $response->getHeader('location')[0] ); diff --git a/tests/Middleware/ResourceServerMiddlewareTest.php b/tests/Middleware/ResourceServerMiddlewareTest.php index 994d5b5d2..119d43ae0 100644 --- a/tests/Middleware/ResourceServerMiddlewareTest.php +++ b/tests/Middleware/ResourceServerMiddlewareTest.php @@ -1,5 +1,7 @@ withHeader('authorization', \sprintf('Bearer %s', $token)); + $request = (new ServerRequest())->withHeader('authorization', sprintf('Bearer %s', $token)); $middleware = new ResourceServerMiddleware($server); $response = $middleware->__invoke( $request, new Response(), function () { - $this->assertEquals('test', \func_get_args()[0]->getAttribute('oauth_access_token_id')); + self::assertEquals('test', func_get_args()[0]->getAttribute('oauth_access_token_id')); - return \func_get_args()[1]; + return func_get_args()[1]; } ); - $this->assertEquals(200, $response->getStatusCode()); + self::assertEquals(200, $response->getStatusCode()); } public function testValidResponseExpiredToken(): void @@ -70,20 +75,20 @@ public function testValidResponseExpiredToken(): void $token = (string) $accessToken; - $request = (new ServerRequest())->withHeader('authorization', \sprintf('Bearer %s', $token)); + $request = (new ServerRequest())->withHeader('authorization', sprintf('Bearer %s', $token)); $middleware = new ResourceServerMiddleware($server); $response = $middleware->__invoke( $request, new Response(), function () { - $this->assertEquals('test', \func_get_args()[0]->getAttribute('oauth_access_token_id')); + self::assertEquals('test', func_get_args()[0]->getAttribute('oauth_access_token_id')); - return \func_get_args()[1]; + return func_get_args()[1]; } ); - $this->assertEquals(401, $response->getStatusCode()); + self::assertEquals(401, $response->getStatusCode()); } public function testErrorResponse(): void @@ -100,10 +105,10 @@ public function testErrorResponse(): void $request, new Response(), function () { - return \func_get_args()[1]; + return func_get_args()[1]; } ); - $this->assertEquals(401, $response->getStatusCode()); + self::assertEquals(401, $response->getStatusCode()); } } diff --git a/tests/PHPStan/AbstractGrantExtension.php b/tests/PHPStan/AbstractGrantExtension.php index 121648e13..f23062d5b 100644 --- a/tests/PHPStan/AbstractGrantExtension.php +++ b/tests/PHPStan/AbstractGrantExtension.php @@ -1,5 +1,6 @@ getName(), [ + return in_array($methodReflection->getName(), [ 'getRequestParameter', 'getQueryStringParameter', 'getCookieParameter', diff --git a/tests/RedirectUriValidators/RedirectUriValidatorTest.php b/tests/RedirectUriValidators/RedirectUriValidatorTest.php index 11e7a07e4..c648d7ab1 100644 --- a/tests/RedirectUriValidators/RedirectUriValidatorTest.php +++ b/tests/RedirectUriValidators/RedirectUriValidatorTest.php @@ -1,5 +1,7 @@ assertFalse( + self::assertFalse( $validator->validateRedirectUri($invalidRedirectUri), 'Non loopback URI must match in every part' ); @@ -31,7 +33,7 @@ public function testValidNonLoopbackUri(): void $validRedirectUri = 'https://example.com:8443/endpoint'; - $this->assertTrue( + self::assertTrue( $validator->validateRedirectUri($validRedirectUri), 'Redirect URI must be valid when matching in every part' ); @@ -43,7 +45,7 @@ public function testInvalidLoopbackUri(): void $invalidRedirectUri = 'http://127.0.0.1:8443/different/endpoint'; - $this->assertFalse( + self::assertFalse( $validator->validateRedirectUri($invalidRedirectUri), 'Valid loopback redirect URI can change only the port number' ); @@ -55,7 +57,7 @@ public function testValidLoopbackUri(): void $validRedirectUri = 'http://127.0.0.1:8080/endpoint'; - $this->assertTrue( + self::assertTrue( $validator->validateRedirectUri($validRedirectUri), 'Loopback redirect URI can change the port number' ); @@ -67,7 +69,7 @@ public function testValidIpv6LoopbackUri(): void $validRedirectUri = 'http://[::1]:8080/endpoint'; - $this->assertTrue( + self::assertTrue( $validator->validateRedirectUri($validRedirectUri), 'Loopback redirect URI can change the port number' ); @@ -77,7 +79,7 @@ public function testCanValidateUrn(): void { $validator = new RedirectUriValidator('urn:ietf:wg:oauth:2.0:oob'); - $this->assertTrue( + self::assertTrue( $validator->validateRedirectUri('urn:ietf:wg:oauth:2.0:oob'), 'An invalid pre-registered urn was provided' ); @@ -87,7 +89,7 @@ public function canValidateCustomSchemeHost(): void { $validator = new RedirectUriValidator('msal://redirect'); - $this->assertTrue( + self::assertTrue( $validator->validateRedirectUri('msal://redirect'), 'An invalid, pre-registered, custom scheme uri was provided' ); @@ -97,7 +99,7 @@ public function canValidateCustomSchemePath(): void { $validator = new RedirectUriValidator('com.example.app:/oauth2redirect/example-provider'); - $this->assertTrue( + self::assertTrue( $validator->validateRedirectUri('com.example.app:/oauth2redirect/example-provider'), 'An invalid, pre-registered, custom scheme uri was provided' ); diff --git a/tests/ResourceServerTest.php b/tests/ResourceServerTest.php index cd622c488..41ac2e854 100644 --- a/tests/ResourceServerTest.php +++ b/tests/ResourceServerTest.php @@ -1,5 +1,6 @@ validateAuthenticatedRequest(ServerRequestFactory::fromGlobals()); } catch (OAuthServerException $e) { - $this->assertEquals('Missing "Authorization" header', $e->getHint()); + self::assertEquals('Missing "Authorization" header', $e->getHint()); } } } diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index 6c8c1fd03..7f0894936 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -1,5 +1,7 @@ setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $responseType->setEncryptionKey(\base64_encode(\random_bytes(36))); + $responseType->setEncryptionKey(base64_encode(random_bytes(36))); $client = new ClientEntity(); $client->setIdentifier('clientName'); @@ -49,25 +56,24 @@ public function testGenerateHttpResponse(): void $response = $responseType->generateHttpResponse(new Response()); - $this->assertInstanceOf(ResponseInterface::class, $response); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('no-cache', $response->getHeader('pragma')[0]); - $this->assertEquals('no-store', $response->getHeader('cache-control')[0]); - $this->assertEquals('application/json; charset=UTF-8', $response->getHeader('content-type')[0]); + self::assertEquals(200, $response->getStatusCode()); + self::assertEquals('no-cache', $response->getHeader('pragma')[0]); + self::assertEquals('no-store', $response->getHeader('cache-control')[0]); + self::assertEquals('application/json; charset=UTF-8', $response->getHeader('content-type')[0]); $response->getBody()->rewind(); - $json = \json_decode($response->getBody()->getContents()); - $this->assertEquals('Bearer', $json->token_type); - $this->assertObjectHasProperty('expires_in', $json); - $this->assertObjectHasProperty('access_token', $json); - $this->assertObjectHasProperty('refresh_token', $json); + $json = json_decode($response->getBody()->getContents()); + self::assertEquals('Bearer', $json->token_type); + self::assertObjectHasProperty('expires_in', $json); + self::assertObjectHasProperty('access_token', $json); + self::assertObjectHasProperty('refresh_token', $json); } public function testGenerateHttpResponseWithExtraParams(): void { $responseType = new BearerTokenResponseWithParams(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $responseType->setEncryptionKey(\base64_encode(\random_bytes(36))); + $responseType->setEncryptionKey(base64_encode(random_bytes(36))); $client = new ClientEntity(); $client->setIdentifier('clientName'); @@ -92,28 +98,27 @@ public function testGenerateHttpResponseWithExtraParams(): void $response = $responseType->generateHttpResponse(new Response()); - $this->assertInstanceOf(ResponseInterface::class, $response); - $this->assertEquals(200, $response->getStatusCode()); - $this->assertEquals('no-cache', $response->getHeader('pragma')[0]); - $this->assertEquals('no-store', $response->getHeader('cache-control')[0]); - $this->assertEquals('application/json; charset=UTF-8', $response->getHeader('content-type')[0]); + self::assertEquals(200, $response->getStatusCode()); + self::assertEquals('no-cache', $response->getHeader('pragma')[0]); + self::assertEquals('no-store', $response->getHeader('cache-control')[0]); + self::assertEquals('application/json; charset=UTF-8', $response->getHeader('content-type')[0]); $response->getBody()->rewind(); - $json = \json_decode($response->getBody()->getContents()); - $this->assertEquals('Bearer', $json->token_type); - $this->assertObjectHasProperty('expires_in', $json); - $this->assertObjectHasProperty('access_token', $json); - $this->assertObjectHasProperty('refresh_token', $json); - - $this->assertObjectHasProperty('foo', $json); - $this->assertEquals('bar', $json->foo); + $json = json_decode($response->getBody()->getContents()); + self::assertEquals('Bearer', $json->token_type); + self::assertObjectHasProperty('expires_in', $json); + self::assertObjectHasProperty('access_token', $json); + self::assertObjectHasProperty('refresh_token', $json); + + self::assertObjectHasProperty('foo', $json); + self::assertEquals('bar', $json->foo); } public function testDetermineAccessTokenInHeaderValidToken(): void { $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $responseType->setEncryptionKey(\base64_encode(\random_bytes(36))); + $responseType->setEncryptionKey(base64_encode(random_bytes(36))); $client = new ClientEntity(); $client->setIdentifier('clientName'); @@ -134,7 +139,7 @@ public function testDetermineAccessTokenInHeaderValidToken(): void $responseType->setRefreshToken($refreshToken); $response = $responseType->generateHttpResponse(new Response()); - $json = \json_decode((string) $response->getBody()); + $json = json_decode((string) $response->getBody()); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(false); @@ -142,14 +147,14 @@ public function testDetermineAccessTokenInHeaderValidToken(): void $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); $authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); - $request = (new ServerRequest())->withHeader('authorization', \sprintf('Bearer %s', $json->access_token)); + $request = (new ServerRequest())->withHeader('authorization', sprintf('Bearer %s', $json->access_token)); $request = $authorizationValidator->validateAuthorization($request); - $this->assertEquals('abcdef', $request->getAttribute('oauth_access_token_id')); - $this->assertEquals('clientName', $request->getAttribute('oauth_client_id')); - $this->assertEquals('123', $request->getAttribute('oauth_user_id')); - $this->assertEquals([], $request->getAttribute('oauth_scopes')); + self::assertEquals('abcdef', $request->getAttribute('oauth_access_token_id')); + self::assertEquals('clientName', $request->getAttribute('oauth_client_id')); + self::assertEquals('123', $request->getAttribute('oauth_user_id')); + self::assertEquals([], $request->getAttribute('oauth_scopes')); } public function testDetermineAccessTokenInHeaderInvalidJWT(): void @@ -158,7 +163,7 @@ public function testDetermineAccessTokenInHeaderInvalidJWT(): void $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $responseType->setEncryptionKey(\base64_encode(\random_bytes(36))); + $responseType->setEncryptionKey(base64_encode(random_bytes(36))); $client = new ClientEntity(); $client->setIdentifier('clientName'); @@ -179,17 +184,17 @@ public function testDetermineAccessTokenInHeaderInvalidJWT(): void $responseType->setRefreshToken($refreshToken); $response = $responseType->generateHttpResponse(new Response()); - $json = \json_decode((string) $response->getBody()); + $json = json_decode((string) $response->getBody()); $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); $authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); - $request = (new ServerRequest())->withHeader('authorization', \sprintf('Bearer %s', $json->access_token)); + $request = (new ServerRequest())->withHeader('authorization', sprintf('Bearer %s', $json->access_token)); try { $authorizationValidator->validateAuthorization($request); } catch (OAuthServerException $e) { - $this->assertEquals( + self::assertEquals( 'Access token could not be verified', $e->getHint() ); @@ -200,7 +205,7 @@ public function testDetermineAccessTokenInHeaderRevokedToken(): void { $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $responseType->setEncryptionKey(\base64_encode(\random_bytes(36))); + $responseType->setEncryptionKey(base64_encode(random_bytes(36))); $client = new ClientEntity(); $client->setIdentifier('clientName'); @@ -221,7 +226,7 @@ public function testDetermineAccessTokenInHeaderRevokedToken(): void $responseType->setRefreshToken($refreshToken); $response = $responseType->generateHttpResponse(new Response()); - $json = \json_decode((string) $response->getBody()); + $json = json_decode((string) $response->getBody()); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(true); @@ -229,12 +234,12 @@ public function testDetermineAccessTokenInHeaderRevokedToken(): void $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); $authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); - $request = (new ServerRequest())->withHeader('authorization', \sprintf('Bearer %s', $json->access_token)); + $request = (new ServerRequest())->withHeader('authorization', sprintf('Bearer %s', $json->access_token)); try { $authorizationValidator->validateAuthorization($request); } catch (OAuthServerException $e) { - $this->assertEquals( + self::assertEquals( 'Access token has been revoked', $e->getHint() ); @@ -245,7 +250,7 @@ public function testDetermineAccessTokenInHeaderInvalidToken(): void { $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $responseType->setEncryptionKey(\base64_encode(\random_bytes(36))); + $responseType->setEncryptionKey(base64_encode(random_bytes(36))); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); @@ -257,7 +262,7 @@ public function testDetermineAccessTokenInHeaderInvalidToken(): void try { $authorizationValidator->validateAuthorization($request); } catch (OAuthServerException $e) { - $this->assertEquals( + self::assertEquals( 'The JWT string must have two dots', $e->getHint() ); @@ -268,7 +273,7 @@ public function testDetermineMissingBearerInHeader(): void { $responseType = new BearerTokenResponse(); $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $responseType->setEncryptionKey(\base64_encode(\random_bytes(36))); + $responseType->setEncryptionKey(base64_encode(random_bytes(36))); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); @@ -280,7 +285,7 @@ public function testDetermineMissingBearerInHeader(): void try { $authorizationValidator->validateAuthorization($request); } catch (OAuthServerException $e) { - $this->assertEquals( + self::assertEquals( 'Error while decoding from JSON', $e->getHint() ); diff --git a/tests/ResponseTypes/BearerTokenResponseWithParams.php b/tests/ResponseTypes/BearerTokenResponseWithParams.php index 71c1665b2..2be1a3272 100644 --- a/tests/ResponseTypes/BearerTokenResponseWithParams.php +++ b/tests/ResponseTypes/BearerTokenResponseWithParams.php @@ -1,5 +1,7 @@ */ diff --git a/tests/Stubs/AccessTokenEntity.php b/tests/Stubs/AccessTokenEntity.php index 77a4d2231..339b29c8b 100644 --- a/tests/Stubs/AccessTokenEntity.php +++ b/tests/Stubs/AccessTokenEntity.php @@ -1,5 +1,7 @@ setEncryptionKey(\base64_encode(\random_bytes(36))); + $this->setEncryptionKey(base64_encode(random_bytes(36))); } public function getKey(): string|Key|null diff --git a/tests/Stubs/GrantType.php b/tests/Stubs/GrantType.php index 37c75fdcd..bd2f95f77 100644 --- a/tests/Stubs/GrantType.php +++ b/tests/Stubs/GrantType.php @@ -47,7 +47,7 @@ public function respondToAccessTokenRequest( ServerRequestInterface $request, ResponseTypeInterface $responseType, DateInterval $accessTokenTTL - ) { + ): ResponseTypeInterface { return $responseType; } @@ -86,7 +86,7 @@ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository): v { } - public function setDefaultScope($scope): void + public function setDefaultScope(string $scope): void { } diff --git a/tests/Stubs/RefreshTokenEntity.php b/tests/Stubs/RefreshTokenEntity.php index f145b7065..9d6d79f27 100644 --- a/tests/Stubs/RefreshTokenEntity.php +++ b/tests/Stubs/RefreshTokenEntity.php @@ -1,5 +1,7 @@ getIdentifier(); } diff --git a/tests/Stubs/StubResponseType.php b/tests/Stubs/StubResponseType.php index f04d44395..9a00490d9 100644 --- a/tests/Stubs/StubResponseType.php +++ b/tests/Stubs/StubResponseType.php @@ -1,5 +1,7 @@ setIdentifier(123); + $this->setIdentifier('123'); } } diff --git a/tests/Utils/CryptKeyTest.php b/tests/Utils/CryptKeyTest.php index 542fdc2b9..a7526c9ea 100644 --- a/tests/Utils/CryptKeyTest.php +++ b/tests/Utils/CryptKeyTest.php @@ -1,15 +1,27 @@ expectException(\LogicException::class); + $this->expectException(LogicException::class); new CryptKey('undefined file'); } @@ -19,34 +31,34 @@ public function testKeyCreation(): void $keyFile = __DIR__ . '/../Stubs/public.key'; $key = new CryptKey($keyFile, 'secret'); - $this->assertEquals('file://' . $keyFile, $key->getKeyPath()); - $this->assertEquals('secret', $key->getPassPhrase()); + self::assertEquals('file://' . $keyFile, $key->getKeyPath()); + self::assertEquals('secret', $key->getPassPhrase()); } public function testKeyString(): void { - $keyContent = \file_get_contents(__DIR__ . '/../Stubs/public.key'); + $keyContent = file_get_contents(__DIR__ . '/../Stubs/public.key'); - if (!\is_string($keyContent)) { - $this->fail('The public key stub is not a string'); + if (!is_string($keyContent)) { + self::fail('The public key stub is not a string'); } $key = new CryptKey($keyContent); - $this->assertEquals( + self::assertEquals( $keyContent, $key->getKeyContents() ); - $keyContent = \file_get_contents(__DIR__ . '/../Stubs/private.key.crlf'); + $keyContent = file_get_contents(__DIR__ . '/../Stubs/private.key.crlf'); - if (!\is_string($keyContent)) { - $this->fail('The private key (crlf) stub is not a string'); + if (!is_string($keyContent)) { + self::fail('The private key (crlf) stub is not a string'); } $key = new CryptKey($keyContent); - $this->assertEquals( + self::assertEquals( $keyContent, $key->getKeyContents() ); @@ -54,29 +66,29 @@ public function testKeyString(): void public function testUnsupportedKeyType(): void { - $this->expectException(\LogicException::class); + $this->expectException(LogicException::class); $this->expectExceptionMessage('Unable to read key'); try { // Create the keypair - $res = \openssl_pkey_new([ + $res = openssl_pkey_new([ 'digest_alg' => 'sha512', 'private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_DSA, ]); if ($res === false) { - $this->fail('The keypair was not created'); + self::fail('The keypair was not created'); } // Get private key - \openssl_pkey_export($res, $keyContent, 'mystrongpassword'); + openssl_pkey_export($res, $keyContent, 'mystrongpassword'); $path = self::generateKeyPath($keyContent); new CryptKey($keyContent, 'mystrongpassword'); } finally { if (isset($path)) { - @\unlink($path); + @unlink($path); } } } @@ -85,25 +97,25 @@ public function testECKeyType(): void { try { // Create the keypair - $res = \openssl_pkey_new([ + $res = openssl_pkey_new([ 'digest_alg' => 'sha512', 'curve_name' => 'prime256v1', 'private_key_type' => OPENSSL_KEYTYPE_EC, ]); if ($res === false) { - $this->fail('The keypair was not created'); + self::fail('The keypair was not created'); } // Get private key - \openssl_pkey_export($res, $keyContent, 'mystrongpassword'); + openssl_pkey_export($res, $keyContent, 'mystrongpassword'); $key = new CryptKey($keyContent, 'mystrongpassword'); - $this->assertEquals('', $key->getKeyPath()); - $this->assertEquals('mystrongpassword', $key->getPassPhrase()); - } catch (\Throwable $e) { - $this->fail('The EC key was not created'); + self::assertEquals('', $key->getKeyPath()); + self::assertEquals('mystrongpassword', $key->getPassPhrase()); + } catch (Throwable $e) { + self::fail('The EC key was not created'); } } @@ -111,35 +123,33 @@ public function testRSAKeyType(): void { try { // Create the keypair - $res = \openssl_pkey_new([ + $res = openssl_pkey_new([ 'digest_alg' => 'sha512', 'private_key_bits' => 2048, 'private_key_type' => OPENSSL_KEYTYPE_RSA, ]); if ($res === false) { - $this->fail('The keypair was not created'); + self::fail('The keypair was not created'); } // Get private key - \openssl_pkey_export($res, $keyContent, 'mystrongpassword'); + openssl_pkey_export($res, $keyContent, 'mystrongpassword'); $key = new CryptKey($keyContent, 'mystrongpassword'); - $this->assertEquals('', $key->getKeyPath()); - $this->assertEquals('mystrongpassword', $key->getPassPhrase()); - } catch (\Throwable $e) { - $this->fail('The RSA key was not created'); + self::assertEquals('', $key->getKeyPath()); + self::assertEquals('mystrongpassword', $key->getPassPhrase()); + } catch (Throwable $e) { + self::fail('The RSA key was not created'); } } /** - * @param string $keyContent * - * @return string */ - private static function generateKeyPath($keyContent) + private static function generateKeyPath(string $keyContent): string { - return 'file://' . \sys_get_temp_dir() . '/' . \sha1($keyContent) . '.key'; + return 'file://' . sys_get_temp_dir() . '/' . sha1($keyContent) . '.key'; } } diff --git a/tests/Utils/CryptTraitTest.php b/tests/Utils/CryptTraitTest.php index 912c4e568..b49b0e9e2 100644 --- a/tests/Utils/CryptTraitTest.php +++ b/tests/Utils/CryptTraitTest.php @@ -1,11 +1,16 @@ cryptStub->setEncryptionKey(\base64_encode(\random_bytes(36))); + $this->cryptStub->setEncryptionKey(base64_encode(random_bytes(36))); $this->encryptDecrypt(); } @@ -35,7 +40,7 @@ private function encryptDecrypt(): void $encrypted = $this->cryptStub->doEncrypt($payload); $plainText = $this->cryptStub->doDecrypt($encrypted); - $this->assertNotEquals($payload, $encrypted); - $this->assertEquals($payload, $plainText); + self::assertNotEquals($payload, $encrypted); + self::assertEquals($payload, $plainText); } } From 8582e358d365a20dcd595fd548d98afd6c906d67 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Thu, 28 Sep 2023 12:45:45 +0100 Subject: [PATCH 39/46] Fix tests --- src/Grant/ImplicitGrant.php | 8 ++++---- src/Grant/PasswordGrant.php | 2 +- src/Grant/RefreshTokenGrant.php | 2 +- tests/Grant/AuthCodeGrantTest.php | 12 ++++++++++-- tests/Grant/ClientCredentialsGrantTest.php | 1 + tests/Grant/ImplicitGrantTest.php | 14 ++++++++++++-- tests/Grant/PasswordGrantTest.php | 3 +++ tests/Grant/RefreshTokenGrantTest.php | 12 ++++++++++++ .../AuthorizationServerMiddlewareTest.php | 1 + 9 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 124915ceb..2fe7b88f9 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -69,7 +69,7 @@ public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refre /** * {@inheritdoc} */ - public function canRespondToAccessTokenRequest(ServerRequestInterface $request) + public function canRespondToAccessTokenRequest(ServerRequestInterface $request): bool { return false; } @@ -99,7 +99,7 @@ public function respondToAccessTokenRequest( /** * {@inheritdoc} */ - public function canRespondToAuthorizationRequest(ServerRequestInterface $request) + public function canRespondToAuthorizationRequest(ServerRequestInterface $request): bool { return ( isset($request->getQueryParams()['response_type']) @@ -111,7 +111,7 @@ public function canRespondToAuthorizationRequest(ServerRequestInterface $request /** * {@inheritdoc} */ - public function validateAuthorizationRequest(ServerRequestInterface $request) + public function validateAuthorizationRequest(ServerRequestInterface $request): AuthorizationRequestInterface { $clientId = $this->getQueryStringParameter( 'client_id', @@ -165,7 +165,7 @@ public function validateAuthorizationRequest(ServerRequestInterface $request) /** * {@inheritdoc} */ - public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest) + public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest): ResponseTypeInterface { if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) { throw new LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest'); diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index e492d1e61..9826ca245 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -119,7 +119,7 @@ protected function validateUser(ServerRequestInterface $request, ClientEntityInt /** * {@inheritdoc} */ - public function getIdentifier() + public function getIdentifier(): string { return 'password'; } diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 8cf4b3272..5beb3ccf6 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -137,7 +137,7 @@ protected function validateOldRefreshToken(ServerRequestInterface $request, stri /** * {@inheritdoc} */ - public function getIdentifier() + public function getIdentifier(): string { return 'refresh_token'; } diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index efeb6ba59..b84980367 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -1837,9 +1837,13 @@ public function testAuthCodeRepositoryUniqueConstraintCheck(): void public function testAuthCodeRepositoryFailToPersist(): void { + $client = new ClientEntity(); + + $client->setRedirectUri('http://foo/bar'); + $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); - $authRequest->setClient(new ClientEntity()); + $authRequest->setClient($client); $authRequest->setGrantTypeId('authorization_code'); $authRequest->setUser(new UserEntity()); @@ -1862,9 +1866,13 @@ public function testAuthCodeRepositoryFailToPersist(): void public function testAuthCodeRepositoryFailToPersistUniqueNoInfiniteLoop(): void { + $client = new ClientEntity(); + + $client->setRedirectUri('http://foo/bar'); + $authRequest = new AuthorizationRequest(); $authRequest->setAuthorizationApproved(true); - $authRequest->setClient(new ClientEntity()); + $authRequest->setClient($client); $authRequest->setGrantTypeId('authorization_code'); $authRequest->setUser(new UserEntity()); diff --git a/tests/Grant/ClientCredentialsGrantTest.php b/tests/Grant/ClientCredentialsGrantTest.php index e0b67e755..fd621bea6 100644 --- a/tests/Grant/ClientCredentialsGrantTest.php +++ b/tests/Grant/ClientCredentialsGrantTest.php @@ -35,6 +35,7 @@ public function testRespondToRequest(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); diff --git a/tests/Grant/ImplicitGrantTest.php b/tests/Grant/ImplicitGrantTest.php index 64d00de0d..201e036d6 100644 --- a/tests/Grant/ImplicitGrantTest.php +++ b/tests/Grant/ImplicitGrantTest.php @@ -307,9 +307,14 @@ public function testAccessTokenRepositoryUniqueConstraintCheck(): void public function testAccessTokenRepositoryFailToPersist(): void { + $client = new ClientEntity(); + + $client->setRedirectUri('https://foo/bar'); + $authRequest = new AuthorizationRequest(); + $authRequest->setAuthorizationApproved(true); - $authRequest->setClient(new ClientEntity()); + $authRequest->setClient($client); $authRequest->setGrantTypeId('authorization_code'); $authRequest->setUser(new UserEntity()); @@ -334,9 +339,14 @@ public function testAccessTokenRepositoryFailToPersist(): void public function testAccessTokenRepositoryFailToPersistUniqueNoInfiniteLoop(): void { + $client = new ClientEntity(); + + $client->setRedirectUri('https://foo/bar'); + $authRequest = new AuthorizationRequest(); + $authRequest->setAuthorizationApproved(true); - $authRequest->setClient(new ClientEntity()); + $authRequest->setClient($client); $authRequest->setGrantTypeId('authorization_code'); $authRequest->setUser(new UserEntity()); diff --git a/tests/Grant/PasswordGrantTest.php b/tests/Grant/PasswordGrantTest.php index 42bdc8f95..3439d00c4 100644 --- a/tests/Grant/PasswordGrantTest.php +++ b/tests/Grant/PasswordGrantTest.php @@ -44,6 +44,7 @@ public function testRespondToRequest(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); @@ -89,6 +90,7 @@ public function testRespondToRequestNullRefreshToken(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); @@ -190,6 +192,7 @@ public function testRespondToRequestBadCredentials(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index 0f8e243b5..20b530192 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -53,6 +53,7 @@ public function testRespondToRequest(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeEntity = new ScopeEntity(); $scopeEntity->setIdentifier('foo'); @@ -116,6 +117,7 @@ public function testRespondToRequestNullRefreshToken(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeEntity = new ScopeEntity(); $scopeEntity->setIdentifier('foo'); @@ -179,6 +181,7 @@ public function testRespondToReducedScopes(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); @@ -242,6 +245,7 @@ public function testRespondToUnexpectedScope(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); @@ -303,6 +307,7 @@ public function testRespondToRequestMissingOldToken(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); @@ -334,6 +339,7 @@ public function testRespondToRequestInvalidOldToken(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); @@ -368,6 +374,7 @@ public function testRespondToRequestClientMismatch(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); @@ -422,6 +429,7 @@ public function testRespondToRequestExpiredToken(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); @@ -473,6 +481,7 @@ public function testRespondToRequestRevokedToken(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); @@ -526,6 +535,7 @@ public function testRespondToRequestFinalizeScopes(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $fooScopeEntity = new ScopeEntity(); $fooScopeEntity->setIdentifier('foo'); @@ -606,6 +616,7 @@ public function testRevokedRefreshToken(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeEntity = new ScopeEntity(); $scopeEntity->setIdentifier('foo'); @@ -671,6 +682,7 @@ public function testUnrevokedRefreshToken(): void $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); $scopeEntity = new ScopeEntity(); $scopeEntity->setIdentifier('foo'); diff --git a/tests/Middleware/AuthorizationServerMiddlewareTest.php b/tests/Middleware/AuthorizationServerMiddlewareTest.php index 950ace46b..3ba692ce2 100644 --- a/tests/Middleware/AuthorizationServerMiddlewareTest.php +++ b/tests/Middleware/AuthorizationServerMiddlewareTest.php @@ -36,6 +36,7 @@ public function testValidResponse(): void $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository->method('getClientEntity')->willReturn($client); + $clientRepository->method('validateClient')->willReturn(true); $scopeEntity = new ScopeEntity(); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); From df850f8504b8d695be396a04d55557e97dd8628c Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Sun, 1 Oct 2023 23:37:49 +0100 Subject: [PATCH 40/46] Fix tests --- .../BearerTokenValidator.php | 15 ++---- src/CryptKey.php | 12 ++--- src/CryptTrait.php | 5 +- src/Entities/Traits/AccessTokenTrait.php | 10 +--- src/Entities/Traits/AuthCodeTrait.php | 5 +- src/Entities/Traits/ClientTrait.php | 12 ++--- src/Entities/Traits/TokenEntityTrait.php | 17 ++----- src/Exception/OAuthServerException.php | 25 ++-------- src/Grant/AbstractGrant.php | 50 ++++--------------- src/Grant/AuthCodeGrant.php | 12 ++--- src/Grant/ImplicitGrant.php | 10 +--- .../AuthorizationServerMiddleware.php | 5 +- src/Middleware/ResourceServerMiddleware.php | 5 +- src/RequestAccessTokenEvent.php | 5 +- src/RequestEvent.php | 5 +- src/RequestRefreshTokenEvent.php | 5 +- src/RequestTypes/AuthorizationRequest.php | 32 +++++------- src/ResourceServer.php | 15 ++---- src/ResponseTypes/AbstractResponseType.php | 19 ++----- tests/AuthorizationServerTest.php | 9 ++-- tests/Grant/AbstractGrantTest.php | 4 +- tests/Grant/AuthCodeGrantTest.php | 14 ++++-- tests/Grant/PasswordGrantTest.php | 5 ++ tests/Grant/RefreshTokenGrantTest.php | 7 ++- tests/Stubs/StubResponseType.php | 2 +- 25 files changed, 88 insertions(+), 217 deletions(-) diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index e7e32700d..8f781824a 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -39,20 +39,11 @@ class BearerTokenValidator implements AuthorizationValidatorInterface { use CryptTrait; - /** - * @var AccessTokenRepositoryInterface - */ - private $accessTokenRepository; + private AccessTokenRepositoryInterface $accessTokenRepository; - /** - * @var CryptKeyInterface - */ - protected $publicKey; + protected CryptKeyInterface $publicKey; - /** - * @var Configuration - */ - private $jwtConfiguration; + private Configuration $jwtConfiguration; /** */ diff --git a/src/CryptKey.php b/src/CryptKey.php index f0a4464ae..2e6b08563 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -37,17 +37,11 @@ class CryptKey implements CryptKeyInterface /** * @var string Key contents */ - protected $keyContents; + protected string $keyContents; - /** - * @var string - */ - protected $keyPath; + protected string $keyPath; - /** - * @var null|string - */ - protected $passPhrase; + protected ?string $passPhrase = null; /** */ diff --git a/src/CryptTrait.php b/src/CryptTrait.php index 6b541a9c3..2119bc34b 100644 --- a/src/CryptTrait.php +++ b/src/CryptTrait.php @@ -23,10 +23,7 @@ trait CryptTrait { - /** - * @var string|Key|null - */ - protected $encryptionKey; + protected string|Key|null $encryptionKey = null; /** * Encrypt data with encryptionKey. diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index 48f6f8eca..69433fad1 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -24,15 +24,9 @@ trait AccessTokenTrait { - /** - * @var CryptKeyInterface - */ - private $privateKey; + private CryptKeyInterface $privateKey; - /** - * @var Configuration - */ - private $jwtConfiguration; + private Configuration $jwtConfiguration; /** * Set the private key used to encrypt this access token. diff --git a/src/Entities/Traits/AuthCodeTrait.php b/src/Entities/Traits/AuthCodeTrait.php index edc667614..403500b62 100644 --- a/src/Entities/Traits/AuthCodeTrait.php +++ b/src/Entities/Traits/AuthCodeTrait.php @@ -14,10 +14,7 @@ trait AuthCodeTrait { - /** - * @var null|string - */ - protected $redirectUri; + protected ?string $redirectUri = null; public function getRedirectUri(): string|null { diff --git a/src/Entities/Traits/ClientTrait.php b/src/Entities/Traits/ClientTrait.php index c779b15a9..5ae6456b8 100644 --- a/src/Entities/Traits/ClientTrait.php +++ b/src/Entities/Traits/ClientTrait.php @@ -14,20 +14,14 @@ trait ClientTrait { - /** - * @var string - */ - protected $name; + protected string $name; /** * @var string|string[] */ - protected $redirectUri; + protected string|array $redirectUri; - /** - * @var bool - */ - protected $isConfidential = false; + protected bool $isConfidential = false; /** * Get the client's name. diff --git a/src/Entities/Traits/TokenEntityTrait.php b/src/Entities/Traits/TokenEntityTrait.php index d4a1aabe0..73c1d152c 100644 --- a/src/Entities/Traits/TokenEntityTrait.php +++ b/src/Entities/Traits/TokenEntityTrait.php @@ -23,22 +23,13 @@ trait TokenEntityTrait /** * @var ScopeEntityInterface[] */ - protected $scopes = []; + protected array $scopes = []; - /** - * @var DateTimeImmutable - */ - protected $expiryDateTime; + protected DateTimeImmutable $expiryDateTime; - /** - * @var string|int|null - */ - protected $userIdentifier; + protected string|int|null $userIdentifier = null; - /** - * @var ClientEntityInterface - */ - protected $client; + protected ClientEntityInterface $client; /** * Associate a scope with the token. diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index f033fdeb0..3bae5b3a8 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -25,35 +25,20 @@ class OAuthServerException extends Exception { - /** - * @var int - */ - private $httpStatusCode; + private int $httpStatusCode; - /** - * @var string - */ - private $errorType; + private string $errorType; - /** - * @var null|string - */ - private $hint; + private ?string $hint = null; - /** - * @var null|string - */ - private $redirectUri; + private ?string $redirectUri = null; /** * @var array */ private array $payload; - /** - * @var ServerRequestInterface - */ - private $serverRequest; + private ServerRequestInterface $serverRequest; /** * Throw a new exception. diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index b6d32cefe..5c7103800 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -67,55 +67,25 @@ abstract class AbstractGrant implements GrantTypeInterface private const MAX_RANDOM_TOKEN_GENERATION_ATTEMPTS = 10; - /** - * @var ClientRepositoryInterface - */ - protected $clientRepository; + protected ClientRepositoryInterface $clientRepository; - /** - * @var AccessTokenRepositoryInterface - */ - protected $accessTokenRepository; + protected AccessTokenRepositoryInterface $accessTokenRepository; - /** - * @var ScopeRepositoryInterface - */ - protected $scopeRepository; + protected ScopeRepositoryInterface $scopeRepository; - /** - * @var AuthCodeRepositoryInterface - */ - protected $authCodeRepository; + protected AuthCodeRepositoryInterface $authCodeRepository; - /** - * @var RefreshTokenRepositoryInterface - */ - protected $refreshTokenRepository; + protected RefreshTokenRepositoryInterface $refreshTokenRepository; - /** - * @var UserRepositoryInterface - */ - protected $userRepository; + protected UserRepositoryInterface $userRepository; - /** - * @var DateInterval - */ - protected $refreshTokenTTL; + protected DateInterval $refreshTokenTTL; - /** - * @var CryptKeyInterface - */ - protected $privateKey; + protected CryptKeyInterface $privateKey; - /** - * @var string - */ - protected $defaultScope; + protected string $defaultScope; - /** - * @var bool - */ - protected $revokeRefreshTokens; + protected bool $revokeRefreshTokens = true; /** */ diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index d940c4038..e9d14e36d 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -51,20 +51,14 @@ class AuthCodeGrant extends AbstractAuthorizeGrant { - /** - * @var DateInterval - */ - private $authCodeTTL; + private DateInterval $authCodeTTL; - /** - * @var bool - */ - private $requireCodeChallengeForPublicClients = true; + private bool $requireCodeChallengeForPublicClients = true; /** * @var CodeChallengeVerifierInterface[] */ - private $codeChallengeVerifiers = []; + private array $codeChallengeVerifiers = []; /** * diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 2fe7b88f9..226621d13 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -30,15 +30,9 @@ class ImplicitGrant extends AbstractAuthorizeGrant { - /** - * @var DateInterval - */ - private $accessTokenTTL; + private DateInterval $accessTokenTTL; - /** - * @var string - */ - private $queryDelimiter; + private string $queryDelimiter; /** */ diff --git a/src/Middleware/AuthorizationServerMiddleware.php b/src/Middleware/AuthorizationServerMiddleware.php index 913bb9afd..95beef721 100644 --- a/src/Middleware/AuthorizationServerMiddleware.php +++ b/src/Middleware/AuthorizationServerMiddleware.php @@ -20,10 +20,7 @@ class AuthorizationServerMiddleware { - /** - * @var AuthorizationServer - */ - private $server; + private AuthorizationServer $server; /** */ diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php index 61c8dcab0..0607c3e09 100644 --- a/src/Middleware/ResourceServerMiddleware.php +++ b/src/Middleware/ResourceServerMiddleware.php @@ -20,10 +20,7 @@ class ResourceServerMiddleware { - /** - * @var ResourceServer - */ - private $server; + private ResourceServer $server; /** */ diff --git a/src/RequestAccessTokenEvent.php b/src/RequestAccessTokenEvent.php index fe723857f..007252f19 100644 --- a/src/RequestAccessTokenEvent.php +++ b/src/RequestAccessTokenEvent.php @@ -17,10 +17,7 @@ class RequestAccessTokenEvent extends RequestEvent { - /** - * @var AccessTokenEntityInterface - */ - private $accessToken; + private AccessTokenEntityInterface $accessToken; /** */ diff --git a/src/RequestEvent.php b/src/RequestEvent.php index 11c5bd0fc..5c8d09784 100644 --- a/src/RequestEvent.php +++ b/src/RequestEvent.php @@ -24,10 +24,7 @@ class RequestEvent extends Event public const REFRESH_TOKEN_ISSUED = 'refresh_token.issued'; public const ACCESS_TOKEN_ISSUED = 'access_token.issued'; - /** - * @var ServerRequestInterface - */ - private $request; + private ServerRequestInterface $request; /** * RequestEvent constructor. diff --git a/src/RequestRefreshTokenEvent.php b/src/RequestRefreshTokenEvent.php index d5348b961..af67efe3e 100644 --- a/src/RequestRefreshTokenEvent.php +++ b/src/RequestRefreshTokenEvent.php @@ -17,10 +17,7 @@ class RequestRefreshTokenEvent extends RequestEvent { - /** - * @var RefreshTokenEntityInterface - */ - private $refreshToken; + private RefreshTokenEntityInterface $refreshToken; /** */ diff --git a/src/RequestTypes/AuthorizationRequest.php b/src/RequestTypes/AuthorizationRequest.php index 8231ebbfb..07ece0f10 100644 --- a/src/RequestTypes/AuthorizationRequest.php +++ b/src/RequestTypes/AuthorizationRequest.php @@ -21,65 +21,57 @@ class AuthorizationRequest implements AuthorizationRequestInterface /** * The grant type identifier * - * @var string */ - protected $grantTypeId; + protected string $grantTypeId; /** * The client identifier * - * @var ClientEntityInterface */ - protected $client; + protected ClientEntityInterface $client; /** * The user identifier * - * @var UserEntityInterface */ - protected $user; + protected UserEntityInterface $user; /** * An array of scope identifiers * * @var ScopeEntityInterface[] */ - protected $scopes = []; + protected array $scopes = []; /** * Has the user authorized the authorization request * - * @var bool */ - protected $authorizationApproved = false; + protected bool $authorizationApproved = false; /** * The redirect URI used in the request * - * @var string|null */ - protected $redirectUri; + protected ?string $redirectUri = null; /** * The state parameter on the authorization request * - * @var string|null */ - protected $state; + protected ?string $state = null; /** * The code challenge (if provided) * - * @var string */ - protected $codeChallenge; + protected string $codeChallenge; /** * The code challenge method (if provided) * - * @var string */ - protected $codeChallengeMethod; + protected string $codeChallengeMethod; public function getGrantTypeId(): string { @@ -103,7 +95,7 @@ public function setClient(ClientEntityInterface $client): void public function getUser(): ?UserEntityInterface { - return $this->user; + return $this->user ?? null; } public function setUser(UserEntityInterface $user): void @@ -159,7 +151,7 @@ public function setState(string $state): void public function getCodeChallenge(): ?string { - return $this->codeChallenge; + return $this->codeChallenge ?? null; } public function setCodeChallenge(string $codeChallenge): void @@ -169,7 +161,7 @@ public function setCodeChallenge(string $codeChallenge): void public function getCodeChallengeMethod(): ?string { - return $this->codeChallengeMethod; + return $this->codeChallengeMethod ?? null; } public function setCodeChallengeMethod(string $codeChallengeMethod): void diff --git a/src/ResourceServer.php b/src/ResourceServer.php index 844d39be5..95833be4f 100644 --- a/src/ResourceServer.php +++ b/src/ResourceServer.php @@ -20,20 +20,11 @@ class ResourceServer { - /** - * @var AccessTokenRepositoryInterface - */ - private $accessTokenRepository; + private AccessTokenRepositoryInterface $accessTokenRepository; - /** - * @var CryptKeyInterface - */ - private $publicKey; + private CryptKeyInterface $publicKey; - /** - * @var null|AuthorizationValidatorInterface - */ - private $authorizationValidator; + private ?AuthorizationValidatorInterface $authorizationValidator = null; /** * New server instance. diff --git a/src/ResponseTypes/AbstractResponseType.php b/src/ResponseTypes/AbstractResponseType.php index 1144b59d5..2af00e224 100644 --- a/src/ResponseTypes/AbstractResponseType.php +++ b/src/ResponseTypes/AbstractResponseType.php @@ -23,20 +23,11 @@ abstract class AbstractResponseType implements ResponseTypeInterface { use CryptTrait; - /** - * @var AccessTokenEntityInterface - */ - protected $accessToken; - - /** - * @var RefreshTokenEntityInterface - */ - protected $refreshToken; - - /** - * @var CryptKeyInterface - */ - protected $privateKey; + protected AccessTokenEntityInterface $accessToken; + + protected RefreshTokenEntityInterface $refreshToken; + + protected CryptKeyInterface $privateKey; public function setAccessToken(AccessTokenEntityInterface $accessToken): void { diff --git a/tests/AuthorizationServerTest.php b/tests/AuthorizationServerTest.php index 8b35eea6c..fafdd8aae 100644 --- a/tests/AuthorizationServerTest.php +++ b/tests/AuthorizationServerTest.php @@ -183,7 +183,10 @@ public function testMultipleRequestsGetDifferentResponseTypeInstances(): void $encryptionKey = 'file://' . __DIR__ . '/Stubs/public.key'; $responseTypePrototype = new class extends BearerTokenResponse { - public function getPrivateKey(): CryptKeyInterface|null + protected CryptKeyInterface $privateKey; + protected Key|string|null $encryptionKey = null; + + public function getPrivateKey(): CryptKeyInterface { return $this->privateKey; } @@ -212,10 +215,6 @@ public function getEncryptionKey(): Key|string|null $responseTypeA = $method->invoke($server); $responseTypeB = $method->invoke($server); - // prototype should not get changed - self::assertNull($responseTypePrototype->getPrivateKey()); - self::assertNull($responseTypePrototype->getEncryptionKey()); - // generated instances should have keys setup self::assertSame($privateKey, $responseTypeA->getPrivateKey()->getKeyPath()); self::assertSame($encryptionKey, $responseTypeA->getEncryptionKey()); diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index 06856f0e3..37ff51c4d 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -183,7 +183,9 @@ public function testValidateClientConfidential(): void $result = $validateClientMethod->invoke($grantMock, $serverRequest, true, true); self::assertEquals($client, $result); } -public function testValidateClientMissingClientId(): void { $client = new ClientEntity(); + public function testValidateClientMissingClientId(): void + { + $client = new ClientEntity(); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index b84980367..536379274 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -39,10 +39,7 @@ class AuthCodeGrantTest extends TestCase { private const DEFAULT_SCOPE = 'basic'; - /** - * @var CryptTraitStub - */ - protected $cryptStub; + protected CryptTraitStub $cryptStub; private const CODE_VERIFIER = 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk'; @@ -256,6 +253,7 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooSho $client->setRedirectUri('http://foo/bar'); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), @@ -263,7 +261,9 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooSho new DateInterval('PT10M') ); + $grant->setDefaultScope(self::DEFAULT_SCOPE); $grant->setClientRepository($clientRepositoryMock); + $grant->setScopeRepository($scopeRepositoryMock); $request = (new ServerRequest())->withQueryParams([ 'response_type' => 'code', @@ -283,6 +283,7 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooLon $client->setRedirectUri('http://foo/bar'); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), @@ -291,6 +292,8 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidLengthTooLon ); $grant->setClientRepository($clientRepositoryMock); + $grant->setDefaultScope(self::DEFAULT_SCOPE); + $grant->setScopeRepository($scopeRepositoryMock); $request = (new ServerRequest())->withQueryParams([ 'response_type' => 'code', @@ -310,6 +313,7 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidCharacters() $client->setRedirectUri('http://foo/bar'); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), @@ -318,6 +322,8 @@ public function testValidateAuthorizationRequestCodeChallengeInvalidCharacters() ); $grant->setClientRepository($clientRepositoryMock); + $grant->setDefaultScope(self::DEFAULT_SCOPE); + $grant->setScopeRepository($scopeRepositoryMock); $request = (new ServerRequest())->withQueryParams([ 'response_type' => 'code', diff --git a/tests/Grant/PasswordGrantTest.php b/tests/Grant/PasswordGrantTest.php index 3439d00c4..494e1d28c 100644 --- a/tests/Grant/PasswordGrantTest.php +++ b/tests/Grant/PasswordGrantTest.php @@ -201,9 +201,14 @@ public function testRespondToRequestBadCredentials(): void $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); + $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn(new ScopeEntity()); + $grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock); $grant->setClientRepository($clientRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock); + $grant->setDefaultScope(self::DEFAULT_SCOPE); + $grant->setScopeRepository($scopeRepositoryMock); $serverRequest = (new ServerRequest())->withParsedBody([ 'client_id' => 'foo', diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index 20b530192..747ba5ead 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -27,10 +27,7 @@ class RefreshTokenGrantTest extends TestCase { - /** - * @var CryptTraitStub - */ - protected $cryptStub; + protected CryptTraitStub $cryptStub; public function setUp(): void { @@ -731,6 +728,8 @@ public function testUnrevokedRefreshToken(): void $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $grant->revokeRefreshTokens(false); + $grant->respondToAccessTokenRequest($serverRequest, new StubResponseType(), new DateInterval('PT5M')); self::assertFalse($refreshTokenRepositoryMock->isRefreshTokenRevoked($refreshTokenId)); diff --git a/tests/Stubs/StubResponseType.php b/tests/Stubs/StubResponseType.php index 9a00490d9..6acc1562b 100644 --- a/tests/Stubs/StubResponseType.php +++ b/tests/Stubs/StubResponseType.php @@ -25,7 +25,7 @@ public function getAccessToken(): AccessTokenEntityInterface public function getRefreshToken(): RefreshTokenEntityInterface|null { - return $this->refreshToken; + return $this->refreshToken ?? null; } public function setAccessToken(AccessTokenEntityInterface $accessToken): void From 953316901d338dc0803705cc6f03fb9ecba8a4ad Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 2 Oct 2023 11:44:58 +0100 Subject: [PATCH 41/46] PHP CS fixes --- tests/AuthorizationServerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/AuthorizationServerTest.php b/tests/AuthorizationServerTest.php index fafdd8aae..1f6ea7d59 100644 --- a/tests/AuthorizationServerTest.php +++ b/tests/AuthorizationServerTest.php @@ -24,11 +24,13 @@ use LeagueTests\Stubs\AccessTokenEntity; use LeagueTests\Stubs\AuthCodeEntity; use LeagueTests\Stubs\ClientEntity; +use LeagueTests\Stubs\GrantType; use LeagueTests\Stubs\ScopeEntity; use LeagueTests\Stubs\StubResponseType; use LeagueTests\Stubs\UserEntity; use PHPUnit\Framework\TestCase; use ReflectionClass; +use Psr\Http\Message\ServerRequestInterface; use function base64_encode; use function chmod; @@ -47,7 +49,6 @@ public function setUp(): void chmod(__DIR__ . '/Stubs/private.key.crlf', 0600); } - /* public function testGrantTypeGetsEnabled() { $server = new AuthorizationServer( @@ -64,7 +65,6 @@ public function testGrantTypeGetsEnabled() $authRequest = $server->validateAuthorizationRequest($this->createMock(ServerRequestInterface::class)); self::assertSame(GrantType::class, $authRequest->getGrantTypeId()); } - */ public function testRespondToRequestInvalidGrantType(): void { From 6720d77487acf96a03692e28ec2328526c315c06 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 2 Oct 2023 11:53:29 +0100 Subject: [PATCH 42/46] Remove empty comments --- .../AuthorizationValidatorInterface.php | 1 - .../BearerTokenValidator.php | 2 -- src/CryptKey.php | 2 -- src/Entities/Traits/AccessTokenTrait.php | 8 -------- src/Entities/Traits/EntityTrait.php | 2 -- src/Entities/Traits/ScopeTrait.php | 2 -- src/Exception/OAuthServerException.php | 4 ---- ...kenIdentifierConstraintViolationException.php | 2 -- src/Grant/AbstractAuthorizeGrant.php | 2 -- src/Grant/AbstractGrant.php | 16 ---------------- src/Grant/ImplicitGrant.php | 2 -- src/Grant/PasswordGrant.php | 2 -- src/Grant/RefreshTokenGrant.php | 2 -- src/Middleware/AuthorizationServerMiddleware.php | 5 ----- src/Middleware/ResourceServerMiddleware.php | 5 ----- src/RequestAccessTokenEvent.php | 2 -- src/RequestRefreshTokenEvent.php | 2 -- src/ResourceServer.php | 2 -- tests/AuthorizationServerTest.php | 6 +++--- tests/Utils/CryptKeyTest.php | 3 --- 20 files changed, 3 insertions(+), 69 deletions(-) diff --git a/src/AuthorizationValidators/AuthorizationValidatorInterface.php b/src/AuthorizationValidators/AuthorizationValidatorInterface.php index 275853409..05d9fb88c 100644 --- a/src/AuthorizationValidators/AuthorizationValidatorInterface.php +++ b/src/AuthorizationValidators/AuthorizationValidatorInterface.php @@ -19,7 +19,6 @@ interface AuthorizationValidatorInterface /** * Determine the access token in the authorization header and append OAUth * properties to the request as attributes. - * */ public function validateAuthorization(ServerRequestInterface $request): ServerRequestInterface; } diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index 8f781824a..c3e9ed719 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -45,8 +45,6 @@ class BearerTokenValidator implements AuthorizationValidatorInterface private Configuration $jwtConfiguration; - /** - */ public function __construct(AccessTokenRepositoryInterface $accessTokenRepository) { $this->accessTokenRepository = $accessTokenRepository; diff --git a/src/CryptKey.php b/src/CryptKey.php index 2e6b08563..cca82adc2 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -43,8 +43,6 @@ class CryptKey implements CryptKeyInterface protected ?string $passPhrase = null; - /** - */ public function __construct(string $keyPath, ?string $passPhrase = null, bool $keyPermissionsCheck = true) { $this->passPhrase = $passPhrase; diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index 69433fad1..a3bce4804 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -81,16 +81,10 @@ public function __toString(): string return $this->convertToJWT()->toString(); } - /** - */ abstract public function getClient(): ClientEntityInterface; - /** - */ abstract public function getExpiryDateTime(): DateTimeImmutable; - /** - */ abstract public function getUserIdentifier(): string|int|null; /** @@ -98,7 +92,5 @@ abstract public function getUserIdentifier(): string|int|null; */ abstract public function getScopes(): array; - /** - */ abstract public function getIdentifier(): string; } diff --git a/src/Entities/Traits/EntityTrait.php b/src/Entities/Traits/EntityTrait.php index 0657a49b8..8b3db91d4 100644 --- a/src/Entities/Traits/EntityTrait.php +++ b/src/Entities/Traits/EntityTrait.php @@ -21,8 +21,6 @@ public function getIdentifier(): string return $this->identifier; } - /** - */ public function setIdentifier(mixed $identifier): void { $this->identifier = $identifier; diff --git a/src/Entities/Traits/ScopeTrait.php b/src/Entities/Traits/ScopeTrait.php index aeba339de..790fb02f3 100644 --- a/src/Entities/Traits/ScopeTrait.php +++ b/src/Entities/Traits/ScopeTrait.php @@ -23,7 +23,5 @@ public function jsonSerialize(): string return $this->getIdentifier(); } - /** - */ abstract public function getIdentifier(): string; } diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index 3bae5b3a8..29c195359 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -249,8 +249,6 @@ public static function invalidGrant(string $hint = ''): static ); } - /** - */ public function getErrorType(): string { return $this->errorType; @@ -352,8 +350,6 @@ public function getHttpStatusCode(): int return $this->httpStatusCode; } - /** - */ public function getHint(): ?string { return $this->hint; diff --git a/src/Exception/UniqueTokenIdentifierConstraintViolationException.php b/src/Exception/UniqueTokenIdentifierConstraintViolationException.php index 21f9a28ab..4c2f281f6 100644 --- a/src/Exception/UniqueTokenIdentifierConstraintViolationException.php +++ b/src/Exception/UniqueTokenIdentifierConstraintViolationException.php @@ -14,8 +14,6 @@ class UniqueTokenIdentifierConstraintViolationException extends OAuthServerException { - /** - */ public static function create(): UniqueTokenIdentifierConstraintViolationException { $errorMessage = 'Could not create unique access token identifier'; diff --git a/src/Grant/AbstractAuthorizeGrant.php b/src/Grant/AbstractAuthorizeGrant.php index d9f2d3f3e..2bcf27242 100644 --- a/src/Grant/AbstractAuthorizeGrant.php +++ b/src/Grant/AbstractAuthorizeGrant.php @@ -33,8 +33,6 @@ public function makeRedirectUri(string $uri, array $params = [], string $queryDe return $uri . http_build_query($params); } - /** - */ protected function createAuthorizationRequest(): AuthorizationRequestInterface { return new AuthorizationRequest(); diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 5c7103800..595f5a097 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -87,43 +87,31 @@ abstract class AbstractGrant implements GrantTypeInterface protected bool $revokeRefreshTokens = true; - /** - */ public function setClientRepository(ClientRepositoryInterface $clientRepository): void { $this->clientRepository = $clientRepository; } - /** - */ public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository): void { $this->accessTokenRepository = $accessTokenRepository; } - /** - */ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository): void { $this->scopeRepository = $scopeRepository; } - /** - */ public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository): void { $this->refreshTokenRepository = $refreshTokenRepository; } - /** - */ public function setAuthCodeRepository(AuthCodeRepositoryInterface $authCodeRepository): void { $this->authCodeRepository = $authCodeRepository; } - /** - */ public function setUserRepository(UserRepositoryInterface $userRepository): void { $this->userRepository = $userRepository; @@ -146,15 +134,11 @@ public function setPrivateKey(CryptKeyInterface $key): void $this->privateKey = $key; } - /** - */ public function setDefaultScope(string $scope): void { $this->defaultScope = $scope; } - /** - */ public function revokeRefreshTokens(bool $revokeRefreshTokens): void { $this->revokeRefreshTokens = $revokeRefreshTokens; diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 226621d13..d071adc40 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -34,8 +34,6 @@ class ImplicitGrant extends AbstractAuthorizeGrant private string $queryDelimiter; - /** - */ public function __construct(DateInterval $accessTokenTTL, string $queryDelimiter = '#') { $this->accessTokenTTL = $accessTokenTTL; diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 9826ca245..1a1759aa0 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -33,8 +33,6 @@ */ class PasswordGrant extends AbstractGrant { - /** - */ public function __construct( UserRepositoryInterface $userRepository, RefreshTokenRepositoryInterface $refreshTokenRepository diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 5beb3ccf6..4cb8ab475 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -35,8 +35,6 @@ */ class RefreshTokenGrant extends AbstractGrant { - /** - */ public function __construct(RefreshTokenRepositoryInterface $refreshTokenRepository) { $this->setRefreshTokenRepository($refreshTokenRepository); diff --git a/src/Middleware/AuthorizationServerMiddleware.php b/src/Middleware/AuthorizationServerMiddleware.php index 95beef721..bf5387c71 100644 --- a/src/Middleware/AuthorizationServerMiddleware.php +++ b/src/Middleware/AuthorizationServerMiddleware.php @@ -22,16 +22,11 @@ class AuthorizationServerMiddleware { private AuthorizationServer $server; - /** - */ public function __construct(AuthorizationServer $server) { $this->server = $server; } - /** - * - */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface { try { diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php index 0607c3e09..4bed11c66 100644 --- a/src/Middleware/ResourceServerMiddleware.php +++ b/src/Middleware/ResourceServerMiddleware.php @@ -22,16 +22,11 @@ class ResourceServerMiddleware { private ResourceServer $server; - /** - */ public function __construct(ResourceServer $server) { $this->server = $server; } - /** - * - */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface { try { diff --git a/src/RequestAccessTokenEvent.php b/src/RequestAccessTokenEvent.php index 007252f19..ddffa4636 100644 --- a/src/RequestAccessTokenEvent.php +++ b/src/RequestAccessTokenEvent.php @@ -19,8 +19,6 @@ class RequestAccessTokenEvent extends RequestEvent { private AccessTokenEntityInterface $accessToken; - /** - */ public function __construct(string $name, ServerRequestInterface $request, AccessTokenEntityInterface $accessToken) { parent::__construct($name, $request); diff --git a/src/RequestRefreshTokenEvent.php b/src/RequestRefreshTokenEvent.php index af67efe3e..28802951f 100644 --- a/src/RequestRefreshTokenEvent.php +++ b/src/RequestRefreshTokenEvent.php @@ -19,8 +19,6 @@ class RequestRefreshTokenEvent extends RequestEvent { private RefreshTokenEntityInterface $refreshToken; - /** - */ public function __construct(string $name, ServerRequestInterface $request, RefreshTokenEntityInterface $refreshToken) { parent::__construct($name, $request); diff --git a/src/ResourceServer.php b/src/ResourceServer.php index 95833be4f..7ae657715 100644 --- a/src/ResourceServer.php +++ b/src/ResourceServer.php @@ -46,8 +46,6 @@ public function __construct( $this->authorizationValidator = $authorizationValidator; } - /** - */ protected function getAuthorizationValidator(): AuthorizationValidatorInterface { if ($this->authorizationValidator instanceof AuthorizationValidatorInterface === false) { diff --git a/tests/AuthorizationServerTest.php b/tests/AuthorizationServerTest.php index 1f6ea7d59..45dd363cc 100644 --- a/tests/AuthorizationServerTest.php +++ b/tests/AuthorizationServerTest.php @@ -29,8 +29,8 @@ use LeagueTests\Stubs\StubResponseType; use LeagueTests\Stubs\UserEntity; use PHPUnit\Framework\TestCase; -use ReflectionClass; use Psr\Http\Message\ServerRequestInterface; +use ReflectionClass; use function base64_encode; use function chmod; @@ -49,14 +49,14 @@ public function setUp(): void chmod(__DIR__ . '/Stubs/private.key.crlf', 0600); } - public function testGrantTypeGetsEnabled() + public function testGrantTypeGetsEnabled(): void { $server = new AuthorizationServer( $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(), $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/Stubs/private.key', - \base64_encode(\random_bytes(36)), + base64_encode(random_bytes(36)), new StubResponseType() ); diff --git a/tests/Utils/CryptKeyTest.php b/tests/Utils/CryptKeyTest.php index a7526c9ea..3b45e3afc 100644 --- a/tests/Utils/CryptKeyTest.php +++ b/tests/Utils/CryptKeyTest.php @@ -145,9 +145,6 @@ public function testRSAKeyType(): void } } - /** - * - */ private static function generateKeyPath(string $keyContent): string { return 'file://' . sys_get_temp_dir() . '/' . sha1($keyContent) . '.key'; From abfa828e67388588c17854157065b32b7c702b44 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Fri, 13 Oct 2023 22:24:07 +0100 Subject: [PATCH 43/46] Fix styling --- CHANGELOG.md | 3 + phpstan.neon.dist | 4 ++ src/AuthorizationServer.php | 15 +---- .../BearerTokenValidator.php | 9 +-- .../CodeChallengeVerifierInterface.php | 3 - src/CodeChallengeVerifiers/PlainVerifier.php | 3 - src/CodeChallengeVerifiers/S256Verifier.php | 3 - src/CryptKey.php | 7 +- src/CryptTrait.php | 4 -- src/Entities/ClientEntityInterface.php | 8 +-- src/Entities/RefreshTokenEntityInterface.php | 1 - src/Entities/ScopeEntityInterface.php | 1 - src/Entities/TokenInterface.php | 2 - src/Entities/Traits/AccessTokenTrait.php | 3 +- src/Entities/Traits/ClientTrait.php | 6 +- src/Entities/Traits/ScopeTrait.php | 1 - src/Entities/Traits/TokenEntityTrait.php | 2 - src/Entities/UserEntityInterface.php | 1 - src/Exception/OAuthServerException.php | 65 +------------------ src/Grant/AbstractAuthorizeGrant.php | 1 - src/Grant/AbstractGrant.php | 26 +------- src/Grant/AuthCodeGrant.php | 14 +--- src/Grant/GrantTypeInterface.php | 19 ------ src/Grant/ImplicitGrant.php | 18 ++--- src/Grant/PasswordGrant.php | 2 - src/Grant/RefreshTokenGrant.php | 1 - .../AuthorizationServerMiddleware.php | 6 +- src/Middleware/ResourceServerMiddleware.php | 6 +- .../RedirectUriValidator.php | 11 ---- .../RedirectUriValidatorInterface.php | 3 - .../AccessTokenRepositoryInterface.php | 1 - .../ClientRepositoryInterface.php | 8 --- src/Repositories/ScopeRepositoryInterface.php | 1 - src/Repositories/UserRepositoryInterface.php | 3 - src/RequestAccessTokenEvent.php | 5 +- src/RequestEvent.php | 9 +-- src/RequestRefreshTokenEvent.php | 5 +- src/RequestTypes/AuthorizationRequest.php | 9 --- src/ResourceServer.php | 12 +--- src/ResponseTypes/BearerTokenResponse.php | 1 - tests/Grant/ClientCredentialsGrantTest.php | 1 - tests/Grant/PasswordGrantTest.php | 1 - .../ResponseTypes/BearerResponseTypeTest.php | 1 - tests/Stubs/StubResponseType.php | 4 -- 44 files changed, 38 insertions(+), 271 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29548493f..12e305c38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Authorization Request objects are now created through the factory method, `createAuthorizationRequest()` (PR #1111) - Changed parameters for `finalizeScopes()` to allow a reference to an auth code ID (PR #1112) +### Removed +- Removed message property from OAuthException HTTP response. Now just use error_description as per the OAuth 2 spec (PR #1375) + ### [8.3.6] - released 2022-11-14 ### Fixed - Use LooseValidAt instead of StrictValidAt so that users aren't forced to use claims such as NBF in their JWT tokens (PR #1312) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 44d720f86..177d40a90 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -4,6 +4,10 @@ parameters: - src - tests ignoreErrors: + - + message: '#Call to an undefined method League\\OAuth2\\Server\\ResponseTypes\\ResponseTypeInterface::getAccessToken\(\)\.#' + path: tests/Grant/ClientCredentialsGrantTest.php + - '#Return type \(League\\Event\\EmitterInterface\|null\) of method LeagueTests\\Stubs\\GrantType::getEmitter\(\) should be covariant with return type \(League\\Event\\EmitterInterface\) of method League\\Event\\EmitterAwareInterface::getEmitter\(\)#' - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAccessToken\(\) should return League\\OAuth2\\Server\\Entities\\AccessTokenEntityInterface but return statement is missing\.#' - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueAuthCode\(\) should return League\\OAuth2\\Server\\Entities\\AuthCodeEntityInterface but return statement is missing\.#' - '#Method League\\OAuth2\\Server\\Grant\\AbstractGrant::issueRefreshToken\(\) should return League\\OAuth2\\Server\\Entities\\RefreshTokenEntityInterface\|null but return statement is missing\.#' diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index 05e32060a..fbdf99228 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -48,12 +48,6 @@ class AuthorizationServer implements EmitterAwareInterface protected ResponseTypeInterface $responseType; - private ClientRepositoryInterface $clientRepository; - - private AccessTokenRepositoryInterface $accessTokenRepository; - - private ScopeRepositoryInterface $scopeRepository; - private string|Key $encryptionKey; private string $defaultScope = ''; @@ -64,16 +58,13 @@ class AuthorizationServer implements EmitterAwareInterface * New server instance */ public function __construct( - ClientRepositoryInterface $clientRepository, - AccessTokenRepositoryInterface $accessTokenRepository, - ScopeRepositoryInterface $scopeRepository, + private ClientRepositoryInterface $clientRepository, + private AccessTokenRepositoryInterface $accessTokenRepository, + private ScopeRepositoryInterface $scopeRepository, CryptKeyInterface|string $privateKey, Key|string $encryptionKey, ResponseTypeInterface|null $responseType = null ) { - $this->clientRepository = $clientRepository; - $this->accessTokenRepository = $accessTokenRepository; - $this->scopeRepository = $scopeRepository; if ($privateKey instanceof CryptKeyInterface === false) { $privateKey = new CryptKey($privateKey); diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index c3e9ed719..a12e2726f 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -39,20 +39,16 @@ class BearerTokenValidator implements AuthorizationValidatorInterface { use CryptTrait; - private AccessTokenRepositoryInterface $accessTokenRepository; - protected CryptKeyInterface $publicKey; private Configuration $jwtConfiguration; - public function __construct(AccessTokenRepositoryInterface $accessTokenRepository) + public function __construct(private AccessTokenRepositoryInterface $accessTokenRepository) { - $this->accessTokenRepository = $accessTokenRepository; } /** * Set the public key - * */ public function setPublicKey(CryptKeyInterface $key): void { @@ -113,7 +109,7 @@ public function validateAuthorization(ServerRequestInterface $request): ServerRe throw OAuthServerException::accessDenied('Access token could not be verified'); } - if (! $token instanceof UnencryptedToken) { + if (!$token instanceof UnencryptedToken) { throw OAuthServerException::accessDenied('Access token is not an instance of UnencryptedToken'); } @@ -135,6 +131,7 @@ public function validateAuthorization(ServerRequestInterface $request): ServerRe /** * Convert single record arrays into strings to ensure backwards compatibility between v4 and v3.x of lcobucci/jwt * + * TODO: Investigate as I don't think we need this any more * * @return array|string */ diff --git a/src/CodeChallengeVerifiers/CodeChallengeVerifierInterface.php b/src/CodeChallengeVerifiers/CodeChallengeVerifierInterface.php index f358b5c17..1417acf10 100644 --- a/src/CodeChallengeVerifiers/CodeChallengeVerifierInterface.php +++ b/src/CodeChallengeVerifiers/CodeChallengeVerifierInterface.php @@ -16,14 +16,11 @@ interface CodeChallengeVerifierInterface { /** * Return code challenge method. - * */ public function getMethod(): string; /** * Verify the code challenge. - * - * */ public function verifyCodeChallenge(string $codeVerifier, string $codeChallenge): bool; } diff --git a/src/CodeChallengeVerifiers/PlainVerifier.php b/src/CodeChallengeVerifiers/PlainVerifier.php index 34a60615c..53d669459 100644 --- a/src/CodeChallengeVerifiers/PlainVerifier.php +++ b/src/CodeChallengeVerifiers/PlainVerifier.php @@ -18,7 +18,6 @@ class PlainVerifier implements CodeChallengeVerifierInterface { /** * Return code challenge method. - * */ public function getMethod(): string { @@ -27,8 +26,6 @@ public function getMethod(): string /** * Verify the code challenge. - * - * */ public function verifyCodeChallenge(string $codeVerifier, string $codeChallenge): bool { diff --git a/src/CodeChallengeVerifiers/S256Verifier.php b/src/CodeChallengeVerifiers/S256Verifier.php index e05464f40..7f99ead5f 100644 --- a/src/CodeChallengeVerifiers/S256Verifier.php +++ b/src/CodeChallengeVerifiers/S256Verifier.php @@ -22,7 +22,6 @@ class S256Verifier implements CodeChallengeVerifierInterface { /** * Return code challenge method. - * */ public function getMethod(): string { @@ -31,8 +30,6 @@ public function getMethod(): string /** * Verify the code challenge. - * - * */ public function verifyCodeChallenge(string $codeVerifier, string $codeChallenge): bool { diff --git a/src/CryptKey.php b/src/CryptKey.php index cca82adc2..206583783 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -41,11 +41,8 @@ class CryptKey implements CryptKeyInterface protected string $keyPath; - protected ?string $passPhrase = null; - - public function __construct(string $keyPath, ?string $passPhrase = null, bool $keyPermissionsCheck = true) + public function __construct(string $keyPath, protected ?string $passPhrase = null, bool $keyPermissionsCheck = true) { - $this->passPhrase = $passPhrase; if (strpos($keyPath, self::FILE_PREFIX) !== 0 && $this->isValidKey($keyPath, $this->passPhrase ?? '')) { $this->keyContents = $keyPath; @@ -103,8 +100,6 @@ public function getKeyContents(): string /** * Validate key contents. - * - * */ private function isValidKey(string $contents, string $passPhrase): bool { diff --git a/src/CryptTrait.php b/src/CryptTrait.php index 2119bc34b..8b1946fc4 100644 --- a/src/CryptTrait.php +++ b/src/CryptTrait.php @@ -28,9 +28,7 @@ trait CryptTrait /** * Encrypt data with encryptionKey. * - * * @throws LogicException - * */ protected function encrypt(string $unencryptedData): string { @@ -52,9 +50,7 @@ protected function encrypt(string $unencryptedData): string /** * Decrypt data with encryptionKey. * - * * @throws LogicException - * */ protected function decrypt(string $encryptedData): string { diff --git a/src/Entities/ClientEntityInterface.php b/src/Entities/ClientEntityInterface.php index 56aa54dfb..9b1656679 100644 --- a/src/Entities/ClientEntityInterface.php +++ b/src/Entities/ClientEntityInterface.php @@ -16,20 +16,17 @@ interface ClientEntityInterface { /** * Get the client's identifier. - * */ public function getIdentifier(): string; /** * Get the client's name. - * */ public function getName(): string; /** - * Returns the registered redirect URI (as a string). - * - * Alternatively return an indexed array of redirect URIs. + * Returns the registered redirect URI (as a string). Alternatively return + * an indexed array of redirect URIs. * * @return string|string[] */ @@ -37,7 +34,6 @@ public function getRedirectUri(): string|array; /** * Returns true if the client is confidential. - * */ public function isConfidential(): bool; } diff --git a/src/Entities/RefreshTokenEntityInterface.php b/src/Entities/RefreshTokenEntityInterface.php index 9b881216f..f377cd9e1 100644 --- a/src/Entities/RefreshTokenEntityInterface.php +++ b/src/Entities/RefreshTokenEntityInterface.php @@ -18,7 +18,6 @@ interface RefreshTokenEntityInterface { /** * Get the token's identifier. - * */ public function getIdentifier(): string; diff --git a/src/Entities/ScopeEntityInterface.php b/src/Entities/ScopeEntityInterface.php index 653d671ea..37c40bf55 100644 --- a/src/Entities/ScopeEntityInterface.php +++ b/src/Entities/ScopeEntityInterface.php @@ -18,7 +18,6 @@ interface ScopeEntityInterface extends JsonSerializable { /** * Get the scope's identifier. - * */ public function getIdentifier(): string; } diff --git a/src/Entities/TokenInterface.php b/src/Entities/TokenInterface.php index 22e6fab49..5434ff00e 100644 --- a/src/Entities/TokenInterface.php +++ b/src/Entities/TokenInterface.php @@ -18,7 +18,6 @@ interface TokenInterface { /** * Get the token's identifier. - * */ public function getIdentifier(): string; @@ -29,7 +28,6 @@ public function setIdentifier(mixed $identifier): void; /** * Get the token's expiry date time. - * */ public function getExpiryDateTime(): DateTimeImmutable; diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index a3bce4804..9d9fe4a65 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -56,7 +56,6 @@ public function initJwtConfiguration(): void /** * Generate a JWT from the access token - * */ private function convertToJWT(): Token { @@ -75,6 +74,8 @@ private function convertToJWT(): Token /** * Generate a string representation from the access token + * + * TODO: Want to remove this function. */ public function __toString(): string { diff --git a/src/Entities/Traits/ClientTrait.php b/src/Entities/Traits/ClientTrait.php index 5ae6456b8..a5a357258 100644 --- a/src/Entities/Traits/ClientTrait.php +++ b/src/Entities/Traits/ClientTrait.php @@ -34,9 +34,8 @@ public function getName(): string } /** - * Returns the registered redirect URI (as a string). - * - * Alternatively return an indexed array of redirect URIs. + * Returns the registered redirect URI (as a string). Alternatively return + * an indexed array of redirect URIs. * * @return string|string[] */ @@ -47,7 +46,6 @@ public function getRedirectUri(): string|array /** * Returns true if the client is confidential. - * */ public function isConfidential(): bool { diff --git a/src/Entities/Traits/ScopeTrait.php b/src/Entities/Traits/ScopeTrait.php index 790fb02f3..71bedac76 100644 --- a/src/Entities/Traits/ScopeTrait.php +++ b/src/Entities/Traits/ScopeTrait.php @@ -16,7 +16,6 @@ trait ScopeTrait { /** * Serialize the object to the scopes string identifier when using json_encode(). - * */ public function jsonSerialize(): string { diff --git a/src/Entities/Traits/TokenEntityTrait.php b/src/Entities/Traits/TokenEntityTrait.php index 73c1d152c..06ef15fb1 100644 --- a/src/Entities/Traits/TokenEntityTrait.php +++ b/src/Entities/Traits/TokenEntityTrait.php @@ -33,7 +33,6 @@ trait TokenEntityTrait /** * Associate a scope with the token. - * */ public function addScope(ScopeEntityInterface $scope): void { @@ -78,7 +77,6 @@ public function setUserIdentifier(string|int|null $identifier): void /** * Get the token user's identifier. - * */ public function getUserIdentifier(): string|int|null { diff --git a/src/Entities/UserEntityInterface.php b/src/Entities/UserEntityInterface.php index 28eed197e..ef88a84d2 100644 --- a/src/Entities/UserEntityInterface.php +++ b/src/Entities/UserEntityInterface.php @@ -16,7 +16,6 @@ interface UserEntityInterface { /** * Return the user's identifier. - * */ public function getIdentifier(): mixed; } diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index 29c195359..08bbb9538 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -25,14 +25,6 @@ class OAuthServerException extends Exception { - private int $httpStatusCode; - - private string $errorType; - - private ?string $hint = null; - - private ?string $redirectUri = null; - /** * @var array */ @@ -42,26 +34,15 @@ class OAuthServerException extends Exception /** * Throw a new exception. - * - * @param string $message Error message - * @param int $code Error code - * @param string $errorType Error type - * @param int $httpStatusCode HTTP status code to send (default = 400) - * @param null|string $hint A helper hint - * @param null|string $redirectUri A HTTP URI to redirect the user back to - * @param Throwable $previous Previous exception */ - final public function __construct(string $message, int $code, string $errorType, int $httpStatusCode = 400, ?string $hint = null, ?string $redirectUri = null, Throwable $previous = null) + final public function __construct(string $message, int $code, private string $errorType, private int $httpStatusCode = 400, private ?string $hint = null, private ?string $redirectUri = null, Throwable $previous = null) { parent::__construct($message, $code, $previous); - $this->httpStatusCode = $httpStatusCode; - $this->errorType = $errorType; - $this->hint = $hint; - $this->redirectUri = $redirectUri; $this->payload = [ 'error' => $errorType, 'error_description' => $message, ]; + if ($hint !== null) { $this->payload['hint'] = $hint; } @@ -74,15 +55,7 @@ final public function __construct(string $message, int $code, string $errorType, */ public function getPayload(): array { - $payload = $this->payload; - - // The "message" property is deprecated and replaced by "error_description" - // TODO: remove "message" property - if (isset($payload['error_description']) && !isset($payload['message'])) { - $payload['message'] = $payload['error_description']; - } - - return $payload; + return $this->payload; } /** @@ -97,7 +70,6 @@ public function setPayload(array $payload): void /** * Set the server request that is responsible for generating the exception - * */ public function setServerRequest(ServerRequestInterface $serverRequest): void { @@ -106,8 +78,6 @@ public function setServerRequest(ServerRequestInterface $serverRequest): void /** * Unsupported grant type error. - * - * @return static */ public static function unsupportedGrantType(): static { @@ -119,11 +89,6 @@ public static function unsupportedGrantType(): static /** * Invalid request error. - * - * @param string $parameter The invalid parameter - * @param Throwable $previous Previous exception - * - * @return static */ public static function invalidRequest(string $parameter, ?string $hint = null, Throwable $previous = null): static { @@ -136,9 +101,6 @@ public static function invalidRequest(string $parameter, ?string $hint = null, T /** * Invalid client error. - * - * - * @return static */ public static function invalidClient(ServerRequestInterface $serverRequest): static { @@ -170,8 +132,6 @@ public static function invalidScope(string $scope, string|null $redirectUri = nu /** * Invalid credentials error. - * - * @return static */ public static function invalidCredentials(): static { @@ -181,9 +141,6 @@ public static function invalidCredentials(): static /** * Server error. * - * - * @return static - * * @codeCoverageIgnore */ public static function serverError(string $hint, Throwable $previous = null): static @@ -202,9 +159,6 @@ public static function serverError(string $hint, Throwable $previous = null): st /** * Invalid refresh token. - * - * - * @return static */ public static function invalidRefreshToken(?string $hint = null, Throwable $previous = null): static { @@ -213,9 +167,6 @@ public static function invalidRefreshToken(?string $hint = null, Throwable $prev /** * Access denied. - * - * - * @return static */ public static function accessDenied(?string $hint = null, ?string $redirectUri = null, Throwable $previous = null): static { @@ -232,9 +183,6 @@ public static function accessDenied(?string $hint = null, ?string $redirectUri = /** * Invalid grant. - * - * - * @return static */ public static function invalidGrant(string $hint = ''): static { @@ -256,10 +204,6 @@ public function getErrorType(): string /** * Generate a HTTP response. - * - * @param bool $useFragment True if errors should be in the URI fragment instead of query string - * @param int $jsonOptions options passed to json_encode - * */ public function generateHttpResponse(ResponseInterface $response, bool $useFragment = false, int $jsonOptions = 0): ResponseInterface { @@ -325,7 +269,6 @@ public function getHttpHeaders(): array * getHttpStatusCode() doesn't return a 302 when there's a * redirect enabled. This helps when you want to override local * error pages but want to let redirects through. - * */ public function hasRedirect(): bool { @@ -334,7 +277,6 @@ public function hasRedirect(): bool /** * Returns the Redirect URI used for redirecting. - * */ public function getRedirectUri(): ?string { @@ -343,7 +285,6 @@ public function getRedirectUri(): ?string /** * Returns the HTTP status code to send when the exceptions is output. - * */ public function getHttpStatusCode(): int { diff --git a/src/Grant/AbstractAuthorizeGrant.php b/src/Grant/AbstractAuthorizeGrant.php index 2bcf27242..27d39982b 100644 --- a/src/Grant/AbstractAuthorizeGrant.php +++ b/src/Grant/AbstractAuthorizeGrant.php @@ -24,7 +24,6 @@ abstract class AbstractAuthorizeGrant extends AbstractGrant { /** * @param mixed[] $params - * */ public function makeRedirectUri(string $uri, array $params = [], string $queryDelimiter = '?'): string { diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 595f5a097..0bef8209c 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -127,7 +127,6 @@ public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void /** * Set the private key - * */ public function setPrivateKey(CryptKeyInterface $key): void { @@ -147,9 +146,7 @@ public function revokeRefreshTokens(bool $revokeRefreshTokens): void /** * Validate the client. * - * * @throws OAuthServerException - * */ protected function validateClient(ServerRequestInterface $request): ClientEntityInterface { @@ -187,7 +184,7 @@ protected function validateClient(ServerRequestInterface $request): ClientEntity * getClientEntity might return null. By contrast, this method will * always either return a ClientEntityInterface or throw. * - * + * TODO: Check if we still need this */ protected function getClientEntityOrFail(string $clientId, ServerRequestInterface $request): ClientEntityInterface { @@ -205,7 +202,6 @@ protected function getClientEntityOrFail(string $clientId, ServerRequestInterfac * Gets the client credentials from the request from the request body or * the Http Basic Authorization header * - * * @return string[] */ protected function getClientCredentials(ServerRequestInterface $request): array @@ -228,9 +224,8 @@ protected function getClientCredentials(ServerRequestInterface $request): array } /** - * Validate redirectUri from the request. - * If a redirect URI is provided ensure it matches what is pre-registered - * + * Validate redirectUri from the request. If a redirect URI is provided + * ensure it matches what is pre-registered * * @throws OAuthServerException */ @@ -282,7 +277,6 @@ public function validateScopes(string|array|null $scopes, string $redirectUri = /** * Converts a scopes query string to an array to easily iterate for validation. * - * * @return string[] */ private function convertScopesQueryStringToArray(string $scopes): array @@ -294,8 +288,6 @@ private function convertScopesQueryStringToArray(string $scopes): array /** * Retrieve request parameter. - * - * */ protected function getRequestParameter(string $parameter, ServerRequestInterface $request, mixed $default = null): mixed { @@ -311,7 +303,6 @@ protected function getRequestParameter(string $parameter, ServerRequestInterface * not exist, or is otherwise an invalid HTTP Basic header, return * [null, null]. * - * * @return string[]|null[] */ protected function getBasicAuthCredentials(ServerRequestInterface $request): array @@ -340,8 +331,6 @@ protected function getBasicAuthCredentials(ServerRequestInterface $request): arr /** * Retrieve query string parameter. - * - * */ protected function getQueryStringParameter(string $parameter, ServerRequestInterface $request, mixed $default = null): ?string { @@ -350,8 +339,6 @@ protected function getQueryStringParameter(string $parameter, ServerRequestInter /** * Retrieve cookie parameter. - * - * */ protected function getCookieParameter(string $parameter, ServerRequestInterface $request, mixed $default = null): ?string { @@ -360,8 +347,6 @@ protected function getCookieParameter(string $parameter, ServerRequestInterface /** * Retrieve server parameter. - * - * */ protected function getServerParameter(string $parameter, ServerRequestInterface $request, mixed $default = null): ?string { @@ -410,7 +395,6 @@ protected function issueAccessToken( * * @throws OAuthServerException * @throws UniqueTokenIdentifierConstraintViolationException - * */ protected function issueAuthCode( DateInterval $authCodeTTL, @@ -449,10 +433,8 @@ protected function issueAuthCode( } /** - * * @throws OAuthServerException * @throws UniqueTokenIdentifierConstraintViolationException - * */ protected function issueRefreshToken(AccessTokenEntityInterface $accessToken): ?RefreshTokenEntityInterface { @@ -484,9 +466,7 @@ protected function issueRefreshToken(AccessTokenEntityInterface $accessToken): ? /** * Generate a new unique identifier. * - * * @throws OAuthServerException - * */ protected function generateUniqueIdentifier(int $length = 40): string { diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index e9d14e36d..3eb1a8fca 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -51,8 +51,6 @@ class AuthCodeGrant extends AbstractAuthorizeGrant { - private DateInterval $authCodeTTL; - private bool $requireCodeChallengeForPublicClients = true; /** @@ -61,17 +59,15 @@ class AuthCodeGrant extends AbstractAuthorizeGrant private array $codeChallengeVerifiers = []; /** - * * @throws Exception */ public function __construct( AuthCodeRepositoryInterface $authCodeRepository, RefreshTokenRepositoryInterface $refreshTokenRepository, - DateInterval $authCodeTTL + private DateInterval $authCodeTTL ) { $this->setAuthCodeRepository($authCodeRepository); $this->setRefreshTokenRepository($refreshTokenRepository); - $this->authCodeTTL = $authCodeTTL; $this->refreshTokenTTL = new DateInterval('P1M'); if (in_array('sha256', hash_algos(), true)) { @@ -94,9 +90,7 @@ public function disableRequireCodeChallengeForPublicClients(): void /** * Respond to an access token request. * - * * @throws OAuthServerException - * */ public function respondToAccessTokenRequest( ServerRequestInterface $request, @@ -190,7 +184,6 @@ public function respondToAccessTokenRequest( /** * Validate the authorization code. - * */ private function validateAuthorizationCode( stdClass $authCodePayload, @@ -226,7 +219,6 @@ private function validateAuthorizationCode( /** * Return the grant identifier that can be used in matching up requests. - * */ public function getIdentifier(): string { @@ -267,7 +259,7 @@ public function validateAuthorizationRequest(ServerRequestInterface $request): A if ($redirectUri !== null) { $this->validateRedirectUri($redirectUri, $client, $request); } elseif ( - $client->getRedirectUri() === '' || $client->getRedirectUri() === null || + $client->getRedirectUri() === '' || (is_array($client->getRedirectUri()) && count($client->getRedirectUri()) !== 1) ) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); @@ -406,8 +398,6 @@ public function completeAuthorizationRequest(AuthorizationRequestInterface $auth /** * Get the client redirect URI if not set in the request. - * - * */ private function getClientRedirectUri(AuthorizationRequestInterface $authorizationRequest): string { diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index 36f2f6050..a2fda3734 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -32,20 +32,16 @@ interface GrantTypeInterface extends EmitterAwareInterface { /** * Set refresh token TTL. - * */ public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void; /** * Return the grant identifier that can be used in matching up requests. - * */ public function getIdentifier(): string; /** * Respond to an incoming request. - * - * */ public function respondToAccessTokenRequest( ServerRequestInterface $request, @@ -55,8 +51,6 @@ public function respondToAccessTokenRequest( /** * The grant type should return true if it is able to response to an authorization request - * - * */ public function canRespondToAuthorizationRequest(ServerRequestInterface $request): bool; @@ -66,8 +60,6 @@ public function canRespondToAuthorizationRequest(ServerRequestInterface $request * * If the validation is successful an AuthorizationRequest object will be returned. This object can be safely * serialized in a user's session, and can be used during user authentication and authorization. - * - * */ public function validateAuthorizationRequest(ServerRequestInterface $request): AuthorizationRequestInterface; @@ -75,8 +67,6 @@ public function validateAuthorizationRequest(ServerRequestInterface $request): A * Once a user has authenticated and authorized the client the grant can complete the authorization request. * The AuthorizationRequest object's $userId property must be set to the authenticated user and the * $authorizationApproved property must reflect their desire to authorize or deny the client. - * - * */ public function completeAuthorizationRequest(AuthorizationRequestInterface $authorizationRequest): ResponseTypeInterface; @@ -84,38 +74,31 @@ public function completeAuthorizationRequest(AuthorizationRequestInterface $auth * The grant type should return true if it is able to respond to this request. * * For example most grant types will check that the $_POST['grant_type'] property matches it's identifier property. - * - * */ public function canRespondToAccessTokenRequest(ServerRequestInterface $request): bool; /** * Set the client repository. - * */ public function setClientRepository(ClientRepositoryInterface $clientRepository): void; /** * Set the access token repository. - * */ public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository): void; /** * Set the scope repository. - * */ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository): void; /** * Set the default scope. - * */ public function setDefaultScope(string $scope): void; /** * Set the path to the private key. - * */ public function setPrivateKey(CryptKeyInterface $privateKey): void; @@ -123,8 +106,6 @@ public function setEncryptionKey(Key|string|null $key = null): void; /** * Enable or prevent the revocation of refresh tokens upon usage. - * - * */ public function revokeRefreshTokens(bool $willRevoke): void; } diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index d071adc40..d081ba8e5 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -30,19 +30,12 @@ class ImplicitGrant extends AbstractAuthorizeGrant { - private DateInterval $accessTokenTTL; - - private string $queryDelimiter; - - public function __construct(DateInterval $accessTokenTTL, string $queryDelimiter = '#') + public function __construct(private DateInterval $accessTokenTTL, private string $queryDelimiter = '#') { - $this->accessTokenTTL = $accessTokenTTL; - $this->queryDelimiter = $queryDelimiter; } /** - * - * @throw LogicException + * @throws LogicException */ public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void { @@ -50,8 +43,7 @@ public function setRefreshTokenTTL(DateInterval $refreshTokenTTL): void } /** - * - * @throw LogicException + * @throws LogicException */ public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository): void { @@ -68,7 +60,6 @@ public function canRespondToAccessTokenRequest(ServerRequestInterface $request): /** * Return the grant identifier that can be used in matching up requests. - * */ public function getIdentifier(): string { @@ -77,8 +68,6 @@ public function getIdentifier(): string /** * Respond to an incoming request. - * - * */ public function respondToAccessTokenRequest( ServerRequestInterface $request, @@ -163,6 +152,7 @@ public function completeAuthorizationRequest(AuthorizationRequestInterface $auth throw new LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest'); } + // TODO: Need to tidy up the nested ternary expressions $finalRedirectUri = ($authorizationRequest->getRedirectUri() === null) ? is_array($authorizationRequest->getClient()->getRedirectUri()) ? $authorizationRequest->getClient()->getRedirectUri()[0] diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 1a1759aa0..1b92dc1da 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -80,9 +80,7 @@ public function respondToAccessTokenRequest( } /** - * * @throws OAuthServerException - * */ protected function validateUser(ServerRequestInterface $request, ClientEntityInterface $client): UserEntityInterface { diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 4cb8ab475..5a5b55e30 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -96,7 +96,6 @@ public function respondToAccessTokenRequest( } /** - * * @throws OAuthServerException * * @return array diff --git a/src/Middleware/AuthorizationServerMiddleware.php b/src/Middleware/AuthorizationServerMiddleware.php index bf5387c71..e59d35590 100644 --- a/src/Middleware/AuthorizationServerMiddleware.php +++ b/src/Middleware/AuthorizationServerMiddleware.php @@ -12,7 +12,6 @@ namespace League\OAuth2\Server\Middleware; -use Exception; use League\OAuth2\Server\AuthorizationServer; use League\OAuth2\Server\Exception\OAuthServerException; use Psr\Http\Message\ResponseInterface; @@ -20,11 +19,8 @@ class AuthorizationServerMiddleware { - private AuthorizationServer $server; - - public function __construct(AuthorizationServer $server) + public function __construct(private AuthorizationServer $server) { - $this->server = $server; } public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php index 4bed11c66..460e77712 100644 --- a/src/Middleware/ResourceServerMiddleware.php +++ b/src/Middleware/ResourceServerMiddleware.php @@ -12,7 +12,6 @@ namespace League\OAuth2\Server\Middleware; -use Exception; use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\ResourceServer; use Psr\Http\Message\ResponseInterface; @@ -20,11 +19,8 @@ class ResourceServerMiddleware { - private ResourceServer $server; - - public function __construct(ResourceServer $server) + public function __construct(private ResourceServer $server) { - $this->server = $server; } public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface diff --git a/src/RedirectUriValidators/RedirectUriValidator.php b/src/RedirectUriValidators/RedirectUriValidator.php index af20765ff..cbc530adf 100644 --- a/src/RedirectUriValidators/RedirectUriValidator.php +++ b/src/RedirectUriValidators/RedirectUriValidator.php @@ -42,7 +42,6 @@ public function __construct(array|string $allowedRedirectUris) /** * Validates the redirect uri. * - * * @return bool Return true if valid, false otherwise */ public function validateRedirectUri(string $redirectUri): bool @@ -58,8 +57,6 @@ public function validateRedirectUri(string $redirectUri): bool * According to section 7.3 of rfc8252, loopback uris are: * - "http://127.0.0.1:{port}/{path}" for IPv4 * - "http://[::1]:{port}/{path}" for IPv6 - * - * */ private function isLoopbackUri(string $redirectUri): bool { @@ -75,9 +72,6 @@ private function isLoopbackUri(string $redirectUri): bool /** * Find an exact match among allowed uris - * - * - * @return bool Return true if an exact match is found, false otherwise */ private function matchExactUri(string $redirectUri): bool { @@ -86,9 +80,6 @@ private function matchExactUri(string $redirectUri): bool /** * Find a match among allowed uris, allowing for different port numbers - * - * - * @return bool Return true if a match is found, false otherwise */ private function matchUriExcludingPort(string $redirectUri): bool { @@ -105,8 +96,6 @@ private function matchUriExcludingPort(string $redirectUri): bool /** * Parse an url like \parse_url, excluding the port - * - * */ private function parseUrlAndRemovePort(string $url): string { diff --git a/src/RedirectUriValidators/RedirectUriValidatorInterface.php b/src/RedirectUriValidators/RedirectUriValidatorInterface.php index 0e44830f7..df64a219c 100644 --- a/src/RedirectUriValidators/RedirectUriValidatorInterface.php +++ b/src/RedirectUriValidators/RedirectUriValidatorInterface.php @@ -16,9 +16,6 @@ interface RedirectUriValidatorInterface { /** * Validates the redirect uri. - * - * - * @return bool Return true if valid, false otherwise */ public function validateRedirectUri(string $redirectUri): bool; } diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index e5a4b0c98..d392716ed 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -26,7 +26,6 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface * Create a new access token * * @param ScopeEntityInterface[] $scopes - * */ public function getNewToken( ClientEntityInterface $clientEntity, diff --git a/src/Repositories/ClientRepositoryInterface.php b/src/Repositories/ClientRepositoryInterface.php index 092a627f2..63134ca9d 100644 --- a/src/Repositories/ClientRepositoryInterface.php +++ b/src/Repositories/ClientRepositoryInterface.php @@ -21,19 +21,11 @@ interface ClientRepositoryInterface extends RepositoryInterface { /** * Get a client. - * - * @param string $clientIdentifier The client's identifier - * */ public function getClientEntity(string $clientIdentifier): ?ClientEntityInterface; /** * Validate a client's secret. - * - * @param string $clientIdentifier The client's identifier - * @param null|string $clientSecret The client's secret (if sent) - * @param null|string $grantType The type of grant the client is using (if sent) - * */ public function validateClient(string $clientIdentifier, ?string $clientSecret, ?string $grantType): bool; } diff --git a/src/Repositories/ScopeRepositoryInterface.php b/src/Repositories/ScopeRepositoryInterface.php index 2ee699ccf..95bfdbb9a 100644 --- a/src/Repositories/ScopeRepositoryInterface.php +++ b/src/Repositories/ScopeRepositoryInterface.php @@ -24,7 +24,6 @@ interface ScopeRepositoryInterface extends RepositoryInterface * Return information about a scope. * * @param string $identifier The scope identifier - * */ public function getScopeEntityByIdentifier(string $identifier): ?ScopeEntityInterface; diff --git a/src/Repositories/UserRepositoryInterface.php b/src/Repositories/UserRepositoryInterface.php index 644e700ad..b8cf53d09 100644 --- a/src/Repositories/UserRepositoryInterface.php +++ b/src/Repositories/UserRepositoryInterface.php @@ -19,9 +19,6 @@ interface UserRepositoryInterface extends RepositoryInterface { /** * Get a user entity. - * - * @param string $grantType The grant type used - * */ public function getUserEntityByUserCredentials( string $username, diff --git a/src/RequestAccessTokenEvent.php b/src/RequestAccessTokenEvent.php index ddffa4636..1200c44c5 100644 --- a/src/RequestAccessTokenEvent.php +++ b/src/RequestAccessTokenEvent.php @@ -17,12 +17,9 @@ class RequestAccessTokenEvent extends RequestEvent { - private AccessTokenEntityInterface $accessToken; - - public function __construct(string $name, ServerRequestInterface $request, AccessTokenEntityInterface $accessToken) + public function __construct(string $name, ServerRequestInterface $request, private AccessTokenEntityInterface $accessToken) { parent::__construct($name, $request); - $this->accessToken = $accessToken; } /** diff --git a/src/RequestEvent.php b/src/RequestEvent.php index 5c8d09784..642d9ab60 100644 --- a/src/RequestEvent.php +++ b/src/RequestEvent.php @@ -24,16 +24,9 @@ class RequestEvent extends Event public const REFRESH_TOKEN_ISSUED = 'refresh_token.issued'; public const ACCESS_TOKEN_ISSUED = 'access_token.issued'; - private ServerRequestInterface $request; - - /** - * RequestEvent constructor. - * - */ - public function __construct(string $name, ServerRequestInterface $request) + public function __construct(string $name, private ServerRequestInterface $request) { parent::__construct($name); - $this->request = $request; } /** diff --git a/src/RequestRefreshTokenEvent.php b/src/RequestRefreshTokenEvent.php index 28802951f..f2ac556cd 100644 --- a/src/RequestRefreshTokenEvent.php +++ b/src/RequestRefreshTokenEvent.php @@ -17,12 +17,9 @@ class RequestRefreshTokenEvent extends RequestEvent { - private RefreshTokenEntityInterface $refreshToken; - - public function __construct(string $name, ServerRequestInterface $request, RefreshTokenEntityInterface $refreshToken) + public function __construct(string $name, ServerRequestInterface $request, private RefreshTokenEntityInterface $refreshToken) { parent::__construct($name, $request); - $this->refreshToken = $refreshToken; } /** diff --git a/src/RequestTypes/AuthorizationRequest.php b/src/RequestTypes/AuthorizationRequest.php index 07ece0f10..276396722 100644 --- a/src/RequestTypes/AuthorizationRequest.php +++ b/src/RequestTypes/AuthorizationRequest.php @@ -20,56 +20,47 @@ class AuthorizationRequest implements AuthorizationRequestInterface { /** * The grant type identifier - * */ protected string $grantTypeId; /** * The client identifier - * */ protected ClientEntityInterface $client; /** * The user identifier - * */ protected UserEntityInterface $user; /** * An array of scope identifiers - * * @var ScopeEntityInterface[] */ protected array $scopes = []; /** * Has the user authorized the authorization request - * */ protected bool $authorizationApproved = false; /** * The redirect URI used in the request - * */ protected ?string $redirectUri = null; /** * The state parameter on the authorization request - * */ protected ?string $state = null; /** * The code challenge (if provided) - * */ protected string $codeChallenge; /** * The code challenge method (if provided) - * */ protected string $codeChallengeMethod; diff --git a/src/ResourceServer.php b/src/ResourceServer.php index 7ae657715..0ffbf889a 100644 --- a/src/ResourceServer.php +++ b/src/ResourceServer.php @@ -20,23 +20,15 @@ class ResourceServer { - private AccessTokenRepositoryInterface $accessTokenRepository; - private CryptKeyInterface $publicKey; private ?AuthorizationValidatorInterface $authorizationValidator = null; - /** - * New server instance. - * - * @param null|AuthorizationValidatorInterface $authorizationValidator - */ public function __construct( - AccessTokenRepositoryInterface $accessTokenRepository, + private AccessTokenRepositoryInterface $accessTokenRepository, CryptKeyInterface|string $publicKey, AuthorizationValidatorInterface $authorizationValidator = null ) { - $this->accessTokenRepository = $accessTokenRepository; if ($publicKey instanceof CryptKeyInterface === false) { $publicKey = new CryptKey($publicKey); @@ -62,9 +54,7 @@ protected function getAuthorizationValidator(): AuthorizationValidatorInterface /** * Determine the access token validity. * - * * @throws OAuthServerException - * */ public function validateAuthenticatedRequest(ServerRequestInterface $request): ServerRequestInterface { diff --git a/src/ResponseTypes/BearerTokenResponse.php b/src/ResponseTypes/BearerTokenResponse.php index 4761d02d6..f738a4e27 100644 --- a/src/ResponseTypes/BearerTokenResponse.php +++ b/src/ResponseTypes/BearerTokenResponse.php @@ -15,7 +15,6 @@ namespace League\OAuth2\Server\ResponseTypes; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; -use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use LogicException; use Psr\Http\Message\ResponseInterface; diff --git a/tests/Grant/ClientCredentialsGrantTest.php b/tests/Grant/ClientCredentialsGrantTest.php index fd621bea6..264e026e2 100644 --- a/tests/Grant/ClientCredentialsGrantTest.php +++ b/tests/Grant/ClientCredentialsGrantTest.php @@ -61,7 +61,6 @@ public function testRespondToRequest(): void $responseType = new StubResponseType(); $response = $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); - self::assertNotEmpty($response->getAccessToken()->getIdentifier()); } } diff --git a/tests/Grant/PasswordGrantTest.php b/tests/Grant/PasswordGrantTest.php index 494e1d28c..8c60a8c78 100644 --- a/tests/Grant/PasswordGrantTest.php +++ b/tests/Grant/PasswordGrantTest.php @@ -7,7 +7,6 @@ use DateInterval; use Laminas\Diactoros\ServerRequest; use League\OAuth2\Server\CryptKey; -use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\Grant\PasswordGrant; diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index 7f0894936..64c040f57 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -18,7 +18,6 @@ use LeagueTests\Stubs\RefreshTokenEntity; use LeagueTests\Stubs\ScopeEntity; use PHPUnit\Framework\TestCase; -use Psr\Http\Message\ResponseInterface; use function base64_encode; use function json_decode; diff --git a/tests/Stubs/StubResponseType.php b/tests/Stubs/StubResponseType.php index 6acc1562b..0f8f371a1 100644 --- a/tests/Stubs/StubResponseType.php +++ b/tests/Stubs/StubResponseType.php @@ -14,10 +14,6 @@ class StubResponseType extends AbstractResponseType { - public function __construct() - { - } - public function getAccessToken(): AccessTokenEntityInterface { return $this->accessToken; From d780f13f9a532c4c85151954b30849b98ed5dd1a Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Tue, 17 Oct 2023 22:40:17 +0100 Subject: [PATCH 44/46] Update minimum PHPUnit version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a1422afad..4f6012f0e 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "lcobucci/clock": "^2.2 || ^3.0" }, "require-dev": { - "phpunit/phpunit": "^9.6.6", + "phpunit/phpunit": "^9.6.11", "laminas/laminas-diactoros": "^3.0.0", "phpstan/phpstan": "^1.10.26", "phpstan/phpstan-phpunit": "^1.3.14", From b0528f7dbf0140422d15e405aa2758bf843b63eb Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 25 Oct 2023 21:04:55 +0100 Subject: [PATCH 45/46] Tidy up ternary operator --- src/Grant/ImplicitGrant.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index d081ba8e5..8c2328b60 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -152,12 +152,11 @@ public function completeAuthorizationRequest(AuthorizationRequestInterface $auth throw new LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest'); } - // TODO: Need to tidy up the nested ternary expressions - $finalRedirectUri = ($authorizationRequest->getRedirectUri() === null) - ? is_array($authorizationRequest->getClient()->getRedirectUri()) + $clientRegisteredRedirectUri = is_array($authorizationRequest->getClient()->getRedirectUri()) ? $authorizationRequest->getClient()->getRedirectUri()[0] - : $authorizationRequest->getClient()->getRedirectUri() - : $authorizationRequest->getRedirectUri(); + : $authorizationRequest->getClient()->getRedirectUri(); + + $finalRedirectUri = $authorizationRequest->getRedirectUri() ?? $clientRegisteredRedirectUri; // The user approved the client, redirect them back with an access token if ($authorizationRequest->isAuthorizationApproved() === true) { From a11685608e5b2d485e418996eec78d36f5775d93 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 25 Oct 2023 21:29:34 +0100 Subject: [PATCH 46/46] Update changelog with PR number --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d4ad3ab5..2d4a4dfde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added -- GrantTypeInterface has a new function, `revokeRefreshTokens()` for enabling or disabling refresh tokens after use (PR #XXXX) +- GrantTypeInterface has a new function, `revokeRefreshTokens()` for enabling or disabling refresh tokens after use (PR #1375) - A CryptKeyInterface to allow developers to change the CryptKey implementation with greater ease (PR #1044) - The authorization server can now finalize scopes when a client uses a refresh token (PR #1094) - An AuthorizationRequestInterface to make it easier to extend the AuthorizationRequest (PR #1110) -- Added function `getKeyContents()` to the `CryptKeyInterface` (PR #XXXX) +- Added function `getKeyContents()` to the `CryptKeyInterface` (PR #1375) ### Fixed - If a refresh token has expired, been revoked, cannot be decrypted, or does not belong to the correct client, the server will now issue an `invalid_grant` error and a HTTP 400 response. In previous versions the server incorrectly issued an `invalid_request` and HTTP 401 response (PR #1042) (PR #1082)