diff --git a/.gitignore b/.gitignore index 454e2ee..30e934c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ -.idea -vendor -build -composer.lock -.php_cs.cache -.phpunit.result.cache +/.phpcs-cache +/.phpunit.result.cache +/clover.xml +/composer.lock +/coveralls-upload.json +/docs/html/ +/laminas-mkdoc-theme.tgz +/laminas-mkdoc-theme/ +/phpunit.xml +/vendor/ diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 2091c3a..0000000 --- a/.php_cs +++ /dev/null @@ -1,110 +0,0 @@ -setRiskyAllowed(true); - } - - public function getRules(): array - { - return [ - '@PSR2' => true, - 'array_syntax' => ['syntax' => 'short'], - 'binary_operator_spaces' => [ - 'default' => 'single_space', - ], - 'blank_line_after_opening_tag' => true, - 'blank_line_after_namespace' => true, - 'blank_line_before_return' => true, - 'braces' => true, - 'cast_spaces' => true, - 'class_definition' => true, - 'combine_consecutive_unsets' => true, - 'concat_space' => false, - 'declare_strict_types' => true, - 'elseif' => true, - 'encoding' => true, - 'full_opening_tag' => true, - 'function_declaration' => true, - 'function_typehint_space' => true, - 'hash_to_slash_comment' => true, - 'header_comment' => false, - 'include' => true, - 'indentation_type' => true, - 'linebreak_after_opening_tag' => true, - 'line_ending' => true, - 'lowercase_constants' => true, - 'lowercase_keywords' => true, - 'method_argument_space' => true, - 'method_separation' => true, - 'modernize_types_casting' => true, - 'native_function_casing' => true, - 'new_with_braces' => true, - 'no_alias_functions' => true, - 'no_blank_lines_after_class_opening' => true, - 'no_closing_tag' => true, - 'no_empty_statement' => true, - 'no_extra_consecutive_blank_lines' => true, - 'no_leading_import_slash' => true, - 'no_leading_namespace_whitespace' => true, - 'no_multiline_whitespace_around_double_arrow' => true, - 'no_multiline_whitespace_before_semicolons' => true, - 'no_short_bool_cast' => true, - 'no_short_echo_tag' => true, - 'no_singleline_whitespace_before_semicolons' => true, - 'no_spaces_around_offset' => true, - 'no_trailing_comma_in_list_call' => true, - 'no_trailing_comma_in_singleline_array' => true, - 'no_unneeded_control_parentheses' => true, - 'no_unreachable_default_argument_value' => true, - 'no_unused_imports' => true, - 'no_useless_else' => true, - 'no_useless_return' => true, - 'no_spaces_inside_parenthesis' => true, - 'no_trailing_whitespace_in_comment' => true, - 'no_whitespace_before_comma_in_array' => true, - 'no_whitespace_in_blank_line' => true, - 'normalize_index_brace' => true, - 'not_operator_with_successor_space' => true, - 'object_operator_without_whitespace' => true, - 'ordered_imports' => true, - 'phpdoc_indent' => true, - 'phpdoc_inline_tag' => true, - 'psr4' => true, - 'return_type_declaration' => true, - 'semicolon_after_instruction' => true, - 'short_scalar_cast' => true, - 'simplified_null_return' => false, - 'single_blank_line_at_eof' => true, - 'single_class_element_per_statement' => true, - 'single_import_per_statement' => true, - 'single_line_after_imports' => true, - 'single_quote' => true, - 'standardize_not_equals' => true, - 'strict_comparison' => true, - 'switch_case_semicolon_to_colon' => true, - 'switch_case_space' => true, - 'ternary_operator_spaces' => true, - 'trailing_comma_in_multiline_array' => true, - 'trim_array_spaces' => true, - 'unary_operator_spaces' => true, - 'visibility_required' => true, - 'whitespace_after_comma_in_array' => true, - ]; - } -} - -$config = new Config(); -$config->getFinder()->in(__DIR__); - -$cacheDir = getenv('TRAVIS') ? getenv('HOME') . '/.php-cs-fixer' : __DIR__; - -$config->setCacheFile($cacheDir . '/.php_cs.cache'); - -return $config; diff --git a/README.md b/README.md index 7eca17e..b582877 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ZfrOAuth2Server -[![Build Status](https://travis-ci.org/zf-fr/zfr-oauth2-server.png)](https://travis-ci.org/zf-fr/zfr-oauth2-server) +[![Continuous Integration](https://github.com/zf-fr/zfr-oauth2-server/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/zf-fr/zfr-oauth2-server/actions/workflows/continuous-integration.yml) [![Latest Stable Version](https://poser.pugx.org/zfr/zfr-oauth2-server/v/stable.png)](https://packagist.org/packages/zfr/zfr-oauth2-server) [![Coverage Status](https://coveralls.io/repos/github/zf-fr/zfr-oauth2-server/badge.svg?branch=master)](https://coveralls.io/github/zf-fr/zfr-oauth2-server?branch=master) [![Total Downloads](https://poser.pugx.org/zfr/zfr-oauth2-server/downloads.png)](https://packagist.org/packages/zfr/zfr-oauth2-server) @@ -22,7 +22,7 @@ Here are other OAuth2 library you can use: ## Requirements -- PHP 7.2 or higher +- PHP 7.4 or higher ## To-do diff --git a/composer.json b/composer.json index edaa7f3..4662319 100644 --- a/composer.json +++ b/composer.json @@ -21,19 +21,26 @@ "homepage": "https://baskamer.nl" } ], + "config": { + "sort-packages": true, + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, "require": { - "php": "^7.3", + "php": "^7.4 || ^8.0", "laminas/laminas-diactoros": "^2.6", + "nesbot/carbon": "^2.62", "psr/container": "^1.0 || ^2.0", + "psr/http-server-middleware": "^1.0", "ramsey/uuid": "^3.1 || ^4.0", - "roave/security-advisories": "dev-master", - "psr/http-server-middleware": "^1.0" + "roave/security-advisories": "dev-master" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.1", - "phpunit/phpunit": "^8.5", - "satooshi/php-coveralls": "^1.0", - "php-mock/php-mock-phpunit": "^2.5" + "laminas/laminas-coding-standard": "^2.4", + "php-mock/php-mock-phpunit": "^2.6", + "phpunit/phpunit": "^9.5.5" }, "autoload": { "psr-4": { @@ -42,12 +49,22 @@ }, "autoload-dev": { "psr-4": { - "ZfrOAuth2Test\\Server\\": "tests/src/" + "ZfrOAuth2Test\\Server\\": "test/src/" } }, "extra": { "branch-alias": { "dev-master": "0.10.x-dev" } + }, + "scripts": { + "check": [ + "@cs-check", + "@test" + ], + "cs-check": "phpcs", + "cs-fix": "phpcbf", + "test": "phpunit --colors=always", + "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..7f391d8 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + src + test + + + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist index f0569ed..8da3e05 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,20 +1,24 @@ - - - - ./tests - - - + + + + + ./test/ + + + + + + disable + + + + + ./src - - + + + + + + diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index 48b91a3..e5230f5 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -1,6 +1,6 @@ * @licence MIT */ class AuthorizationServer implements AuthorizationServerInterface { - /** - * @var ClientService - */ - private $clientService; + private ClientService $clientService; /** * A list of grant * * @var GrantInterface[] */ - private $grants = []; + private array $grants = []; /** * A list of grant that can answer to an authorization request * * @var GrantInterface[] */ - private $responseTypes = []; + private array $responseTypes = []; - /** - * @var AccessTokenService - */ - private $accessTokenService; + private AccessTokenService $accessTokenService; - /** - * @var RefreshTokenService - */ - private $refreshTokenService; + private RefreshTokenService $refreshTokenService; /** - * @param ClientService $clientService * @param GrantInterface[] $grants - * @param AccessTokenService $accessTokenService - * @param RefreshTokenService $refreshTokenService */ public function __construct( ClientService $clientService, @@ -83,8 +75,8 @@ public function __construct( AccessTokenService $accessTokenService, RefreshTokenService $refreshTokenService ) { - $this->clientService = $clientService; - $this->accessTokenService = $accessTokenService; + $this->clientService = $clientService; + $this->accessTokenService = $accessTokenService; $this->refreshTokenService = $refreshTokenService; foreach ($grants as $grant) { @@ -111,7 +103,7 @@ public function hasGrant(string $grantType): bool /** * Get the grant by its name * - * @throws OAuth2Exception (unsupported_grant_type) When grant type is not registered + * @throws OAuth2Exception (unsupported_grant_type) When grant type is not registered. */ public function getGrant(string $grantType): GrantInterface { @@ -137,7 +129,7 @@ public function hasResponseType(string $responseType): bool /** * Get the response type by its name * - * @throws OAuth2Exception (unsupported_grant_type) When response type is not registered + * @throws OAuth2Exception (unsupported_grant_type) When response type is not registered. */ public function getResponseType(string $responseType): GrantInterface { @@ -153,15 +145,15 @@ public function getResponseType(string $responseType): GrantInterface } /** - * @throws OAuth2Exception (invalid_request) If no "response_type" could be found in the GET parameters - * @throws OAuth2Exception (invalid_clientt) If no client could be authenticated + * @throws OAuth2Exception (invalid_request) If no "response_type" could be found in the GET parameters. + * @throws OAuth2Exception (invalid_clientt) If no client could be authenticated. */ public function handleAuthorizationRequest( ServerRequestInterface $request, - TokenOwnerInterface $owner = null + ?TokenOwnerInterface $owner = null ): ResponseInterface { try { - $queryParams = $request->getQueryParams(); + $queryParams = $request->getQueryParams(); $responseType = $queryParams['response_type'] ?? null; if (null === $responseType) { @@ -169,7 +161,7 @@ public function handleAuthorizationRequest( } $responseType = $this->getResponseType((string) $responseType); - $client = $this->getClient($request, $responseType->allowPublicClients()); + $client = $this->getClient($request, $responseType->allowPublicClients()); if (null === $client) { throw OAuth2Exception::invalidClient('No client could be authenticated'); @@ -184,11 +176,11 @@ public function handleAuthorizationRequest( } /** - * @throws OAuth2Exception (invalid_request) If no "grant_type" could be found in the POST parameters + * @throws OAuth2Exception (invalid_request) If no "grant_type" could be found in the POST parameters. */ public function handleTokenRequest( ServerRequestInterface $request, - TokenOwnerInterface $owner = null + ?TokenOwnerInterface $owner = null ): ResponseInterface { $postParams = $request->getParsedBody(); @@ -199,7 +191,7 @@ public function handleTokenRequest( throw OAuth2Exception::invalidRequest('No grant type was found in the request'); } - $grant = $this->getGrant((string) $grant); + $grant = $this->getGrant((string) $grant); $client = $this->getClient($request, $grant->allowPublicClients()); $response = $grant->createTokenResponse($request, $client, $owner); @@ -214,15 +206,15 @@ public function handleTokenRequest( } /** - * @throws OAuth2Exception (invalid_request) If no "token" is present - * @throws OAuth2Exception (unsupported_token_type) If "token" is unsupported - * @throws OAuth2Exception (invalid_client) If "token" was issued for another client and cannot be revoked + * @throws OAuth2Exception (invalid_request) If no "token" is present. + * @throws OAuth2Exception (unsupported_token_type) If "token" is unsupported. + * @throws OAuth2Exception (invalid_client) If "token" was issued for another client and cannot be revoked. */ public function handleRevocationRequest(ServerRequestInterface $request): ResponseInterface { $postParams = $request->getParsedBody(); - $token = $postParams['token'] ?? null; + $token = $postParams['token'] ?? null; $tokenHint = $postParams['token_type_hint'] ?? null; if (null === $token || null === $tokenHint) { @@ -281,11 +273,11 @@ public function handleRevocationRequest(ServerRequestInterface $request): Respon * According to the spec (http://tools.ietf.org/html/rfc6749#section-2.3), for public clients we do * not need to authenticate them * - * @throws OAuth2Exception (invalid_client) When a client secret is missing or client authentication failed + * @throws OAuth2Exception (invalid_client) When a client secret is missing or client authentication failed. */ private function getClient(ServerRequestInterface $request, bool $allowPublicClients): ?Client { - list($id, $secret) = $this->extractClientCredentials($request); + [$id, $secret] = $this->extractClientCredentials($request); // If the grant type we are issuing does not allow public clients, and that the secret is // missing, then we have an error... @@ -316,7 +308,7 @@ private function getClient(ServerRequestInterface $request, bool $allowPublicCli private function createResponseFromOAuthException(OAuth2Exception $exception): ResponseInterface { $payload = [ - 'error' => $exception->getCode(), + 'error' => $exception->getCode(), 'error_description' => $exception->getMessage(), ]; @@ -334,11 +326,11 @@ private function extractClientCredentials(ServerRequestInterface $request): arra $parts = explode(' ', $request->getHeaderLine('Authorization')); $value = base64_decode(end($parts)); - list($id, $secret) = explode(':', $value); + [$id, $secret] = explode(':', $value); } else { $postParams = $request->getParsedBody(); - $id = $postParams['client_id'] ?? null; + $id = $postParams['client_id'] ?? null; $secret = $postParams['client_secret'] ?? null; } diff --git a/src/AuthorizationServerInterface.php b/src/AuthorizationServerInterface.php index f0bd995..79a50d8 100644 --- a/src/AuthorizationServerInterface.php +++ b/src/AuthorizationServerInterface.php @@ -1,6 +1,6 @@ * @licence MIT */ class AccessTokenServiceFactory @@ -41,7 +40,7 @@ public function __invoke(ContainerInterface $container): AccessTokenService /** @var AccessTokenRepositoryInterface $tokenRepository */ $tokenRepository = $container->get(AccessTokenRepositoryInterface::class); - /* @var ScopeService $scopeService */ + /** @var ScopeService $scopeService */ $scopeService = $container->get(ScopeService::class); return new AccessTokenService($tokenRepository, $scopeService, $serverOptions); diff --git a/src/Container/AuthorizationCodeServiceFactory.php b/src/Container/AuthorizationCodeServiceFactory.php index d850427..fe76734 100644 --- a/src/Container/AuthorizationCodeServiceFactory.php +++ b/src/Container/AuthorizationCodeServiceFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class AuthorizationCodeServiceFactory @@ -41,7 +40,7 @@ public function __invoke(ContainerInterface $container): AuthorizationCodeServic /** @var AuthorizationCodeRepositoryInterface $tokenRepository */ $tokenRepository = $container->get(AuthorizationCodeRepositoryInterface::class); - /* @var ScopeService $scopeService */ + /** @var ScopeService $scopeService */ $scopeService = $container->get(ScopeService::class); return new AuthorizationCodeService($tokenRepository, $scopeService, $serverOptions); diff --git a/src/Container/AuthorizationGrantFactory.php b/src/Container/AuthorizationGrantFactory.php index 33b9722..f6e0ec5 100644 --- a/src/Container/AuthorizationGrantFactory.php +++ b/src/Container/AuthorizationGrantFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class AuthorizationGrantFactory { public function __invoke(ContainerInterface $container): AuthorizationGrant { - /* @var AuthorizationCodeService $authorizationCodeService */ + /** @var AuthorizationCodeService $authorizationCodeService */ $authorizationCodeService = $container->get(AuthorizationCodeService::class); - /* @var AccessTokenService $accessTokenService */ + /** @var AccessTokenService $accessTokenService */ $accessTokenService = $container->get(AccessTokenService::class); - /* @var RefreshTokenService $refreshTokenService */ + /** @var RefreshTokenService $refreshTokenService */ $refreshTokenService = $container->get(RefreshTokenService::class); return new AuthorizationGrant($authorizationCodeService, $accessTokenService, $refreshTokenService); diff --git a/src/Container/AuthorizationRequestMiddlewareFactory.php b/src/Container/AuthorizationRequestMiddlewareFactory.php index 69f5119..2311c4a 100644 --- a/src/Container/AuthorizationRequestMiddlewareFactory.php +++ b/src/Container/AuthorizationRequestMiddlewareFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class AuthorizationRequestMiddlewareFactory diff --git a/src/Container/AuthorizationServerFactory.php b/src/Container/AuthorizationServerFactory.php index 0ca9a6a..5516aff 100644 --- a/src/Container/AuthorizationServerFactory.php +++ b/src/Container/AuthorizationServerFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class AuthorizationServerFactory { public function __invoke(ContainerInterface $container): AuthorizationServer { - /* @var ClientService $clientService */ + /** @var ClientService $clientService */ $clientService = $container->get(ClientService::class); - /* @var ServerOptions $serverOptions */ + /** @var ServerOptions $serverOptions */ $serverOptions = $container->get(ServerOptions::class); $grants = []; diff --git a/src/Container/ClientCredentialsGrantFactory.php b/src/Container/ClientCredentialsGrantFactory.php index 6c2f9f6..87c9738 100644 --- a/src/Container/ClientCredentialsGrantFactory.php +++ b/src/Container/ClientCredentialsGrantFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class ClientCredentialsGrantFactory { public function __invoke(ContainerInterface $container): ClientCredentialsGrant { - /* @var AccessTokenService $accessTokenService */ + /** @var AccessTokenService $accessTokenService */ $accessTokenService = $container->get(AccessTokenService::class); return new ClientCredentialsGrant($accessTokenService); diff --git a/src/Container/ClientServiceFactory.php b/src/Container/ClientServiceFactory.php index 18562ba..1b52e54 100644 --- a/src/Container/ClientServiceFactory.php +++ b/src/Container/ClientServiceFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class ClientServiceFactory diff --git a/src/Container/PasswordGrantFactory.php b/src/Container/PasswordGrantFactory.php index 2939f55..7b85da7 100644 --- a/src/Container/PasswordGrantFactory.php +++ b/src/Container/PasswordGrantFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class PasswordGrantFactory { public function __invoke(ContainerInterface $container): PasswordGrant { - /* @var ServerOptions $options */ + /** @var ServerOptions $options */ $options = $container->get(ServerOptions::class); $ownerCallable = $options->getOwnerCallable(); $ownerCallable = is_string($ownerCallable) ? $container->get($ownerCallable) : $ownerCallable; - /* @var AccessTokenService $accessTokenService */ + /** @var AccessTokenService $accessTokenService */ $accessTokenService = $container->get(AccessTokenService::class); - /* @var RefreshTokenService $refreshTokenService */ + /** @var RefreshTokenService $refreshTokenService */ $refreshTokenService = $container->get(RefreshTokenService::class); return new PasswordGrant($accessTokenService, $refreshTokenService, $ownerCallable); diff --git a/src/Container/RefreshTokenGrantFactory.php b/src/Container/RefreshTokenGrantFactory.php index 72b6a7e..308016c 100644 --- a/src/Container/RefreshTokenGrantFactory.php +++ b/src/Container/RefreshTokenGrantFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class RefreshTokenGrantFactory @@ -38,10 +37,10 @@ public function __invoke(ContainerInterface $container): RefreshTokenGrant /** @var ServerOptions $serverOptions */ $serverOptions = $container->get(ServerOptions::class); - /* @var AccessTokenService $accessTokenService */ + /** @var AccessTokenService $accessTokenService */ $accessTokenService = $container->get(AccessTokenService::class); - /* @var RefreshTokenService $refreshTokenService */ + /** @var RefreshTokenService $refreshTokenService */ $refreshTokenService = $container->get(RefreshTokenService::class); return new RefreshTokenGrant($accessTokenService, $refreshTokenService, $serverOptions); diff --git a/src/Container/RefreshTokenServiceFactory.php b/src/Container/RefreshTokenServiceFactory.php index d02d4b4..d125380 100644 --- a/src/Container/RefreshTokenServiceFactory.php +++ b/src/Container/RefreshTokenServiceFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class RefreshTokenServiceFactory @@ -42,7 +41,7 @@ public function __invoke(ContainerInterface $container): RefreshTokenService /** @var AuthorizationCodeRepositoryInterface $tokenRepository */ $tokenRepository = $container->get(RefreshTokenRepositoryInterface::class); - /* @var ScopeService $scopeService */ + /** @var ScopeService $scopeService */ $scopeService = $container->get(ScopeService::class); return new RefreshTokenService($tokenRepository, $scopeService, $serverOptions); diff --git a/src/Container/ResourceServerFactory.php b/src/Container/ResourceServerFactory.php index dc9bf16..a97730f 100644 --- a/src/Container/ResourceServerFactory.php +++ b/src/Container/ResourceServerFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class ResourceServerFactory diff --git a/src/Container/ResourceServerMiddlewareFactory.php b/src/Container/ResourceServerMiddlewareFactory.php index eba6be7..a039f82 100644 --- a/src/Container/ResourceServerMiddlewareFactory.php +++ b/src/Container/ResourceServerMiddlewareFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class ResourceServerMiddlewareFactory diff --git a/src/Container/RevocationRequestMiddlewareFactory.php b/src/Container/RevocationRequestMiddlewareFactory.php index d96701c..7264234 100644 --- a/src/Container/RevocationRequestMiddlewareFactory.php +++ b/src/Container/RevocationRequestMiddlewareFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class RevocationRequestMiddlewareFactory diff --git a/src/Container/ScopeServiceFactory.php b/src/Container/ScopeServiceFactory.php index 47b94ea..a125d02 100644 --- a/src/Container/ScopeServiceFactory.php +++ b/src/Container/ScopeServiceFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class ScopeServiceFactory { public function __invoke(ContainerInterface $container): ScopeService { - /** @var ScopeRepositoryInterface $clientRepository */ + /** @var ScopeRepositoryInterface $scopeRepository */ $scopeRepository = $container->get(ScopeRepositoryInterface::class); return new ScopeService($scopeRepository); diff --git a/src/Container/ServerOptionsFactory.php b/src/Container/ServerOptionsFactory.php index 1077247..4a3d4d9 100644 --- a/src/Container/ServerOptionsFactory.php +++ b/src/Container/ServerOptionsFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class ServerOptionsFactory { public function __invoke(ContainerInterface $container): ServerOptions { - $config = $container->get('config'); + $config = $container->get('config'); $options = $config['zfr_oauth2_server'] ?? []; return ServerOptions::fromArray($options); diff --git a/src/Container/TokenRequestMiddlewareFactory.php b/src/Container/TokenRequestMiddlewareFactory.php index 7cdcf33..652dc32 100644 --- a/src/Container/TokenRequestMiddlewareFactory.php +++ b/src/Container/TokenRequestMiddlewareFactory.php @@ -1,6 +1,6 @@ * @licence MIT */ class TokenRequestMiddlewareFactory diff --git a/src/Exception/ExceptionInterface.php b/src/Exception/ExceptionInterface.php index 0371062..61ef48d 100644 --- a/src/Exception/ExceptionInterface.php +++ b/src/Exception/ExceptionInterface.php @@ -1,6 +1,6 @@ * @licence MIT */ interface ExceptionInterface diff --git a/src/Exception/InvalidAccessTokenException.php b/src/Exception/InvalidAccessTokenException.php index 250c691..573a1f5 100644 --- a/src/Exception/InvalidAccessTokenException.php +++ b/src/Exception/InvalidAccessTokenException.php @@ -1,6 +1,6 @@ - * @author Bas Kamer * @licence MIT */ class InvalidAccessTokenException extends InvalidArgumentException implements ExceptionInterface diff --git a/src/Exception/OAuth2Exception.php b/src/Exception/OAuth2Exception.php index 5426e00..849ad35 100644 --- a/src/Exception/OAuth2Exception.php +++ b/src/Exception/OAuth2Exception.php @@ -1,6 +1,6 @@ + * * @licence MIT */ class OAuth2Exception extends Exception implements ExceptionInterface @@ -126,7 +126,6 @@ public static function unsupportedResponseType(string $description): OAuth2Excep /** * @link https://tools.ietf.org/html/rfc7009#section-2.2.1 - * @return OAuth2Exception */ public static function unsupportedTokenType(string $description): OAuth2Exception { diff --git a/src/Exception/RuntimeException.php b/src/Exception/RuntimeException.php index 58fb040..36fdd17 100644 --- a/src/Exception/RuntimeException.php +++ b/src/Exception/RuntimeException.php @@ -1,6 +1,6 @@ * @licence MIT */ class RuntimeException extends BaseRuntimeException implements ExceptionInterface diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index cf8868f..21dc2d0 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -1,6 +1,6 @@ * @licence MIT */ abstract class AbstractGrant implements GrantInterface @@ -47,18 +49,18 @@ public function getResponseType(): string */ protected function prepareTokenResponse( AccessToken $accessToken, - RefreshToken $refreshToken = null, + ?RefreshToken $refreshToken = null, bool $useRefreshTokenScopes = false ): ResponseInterface { - $owner = $accessToken->getOwner(); + $owner = $accessToken->getOwner(); $scopes = $useRefreshTokenScopes ? $refreshToken->getScopes() : $accessToken->getScopes(); $responseBody = [ 'access_token' => $accessToken->getToken(), - 'token_type' => 'Bearer', - 'expires_in' => $accessToken->getExpiresIn(), - 'scope' => implode(' ', $scopes), - 'owner_id' => $owner ? $owner->getTokenOwnerId() : null, + 'token_type' => 'Bearer', + 'expires_in' => $accessToken->getExpiresIn(), + 'scope' => implode(' ', $scopes), + 'owner_id' => $owner ? $owner->getTokenOwnerId() : null, ]; if (null !== $refreshToken) { diff --git a/src/Grant/AuthorizationGrant.php b/src/Grant/AuthorizationGrant.php index 7a60eb8..b06b03c 100644 --- a/src/Grant/AuthorizationGrant.php +++ b/src/Grant/AuthorizationGrant.php @@ -1,6 +1,6 @@ * @licence MIT */ class AuthorizationGrant extends AbstractGrant implements AuthorizationServerAwareInterface { - const GRANT_TYPE = 'authorization_code'; - const GRANT_RESPONSE_TYPE = 'code'; + public const GRANT_TYPE = 'authorization_code'; + public const GRANT_RESPONSE_TYPE = 'code'; - /** - * @var AuthorizationCodeService - */ - private $authorizationCodeService; + private AuthorizationCodeService $authorizationCodeService; /** * An AuthorizationServer will inject itself into the grant when it is constructed - * - * @var AuthorizationServerInterface */ - private $authorizationServer; + private ?AuthorizationServerInterface $authorizationServer = null; /** * Access token service (used to create access token) - * - * @var AccessTokenService */ - private $accessTokenService; + private AccessTokenService $accessTokenService; /** * Refresh token service (used to create refresh token) - * - * @var RefreshTokenService */ - private $refreshTokenService; + private RefreshTokenService $refreshTokenService; public function __construct( AuthorizationCodeService $authorizationCodeService, @@ -75,17 +72,17 @@ public function __construct( RefreshTokenService $refreshTokenService ) { $this->authorizationCodeService = $authorizationCodeService; - $this->accessTokenService = $accessTokenService; - $this->refreshTokenService = $refreshTokenService; + $this->accessTokenService = $accessTokenService; + $this->refreshTokenService = $refreshTokenService; } /** - * @throws OAuth2Exception (invalid_request) When grant type was not 'code' + * @throws OAuth2Exception (invalid_request) When grant type was not 'code'. */ public function createAuthorizationResponse( ServerRequestInterface $request, Client $client, - TokenOwnerInterface $owner = null + ?TokenOwnerInterface $owner = null ): ResponseInterface { $queryParams = $request->getQueryParams(); @@ -110,14 +107,14 @@ public function createAuthorizationResponse( } // Scope and state allow to perform additional validation - $scope = $queryParams['scope'] ?? null; - $state = $queryParams['state'] ?? null; + $scope = $queryParams['scope'] ?? null; + $state = $queryParams['state'] ?? null; $scopes = is_string($scope) ? explode(' ', $scope) : []; $authorizationCode = $this->authorizationCodeService->createToken($redirectUri, $owner, $client, $scopes); $uri = http_build_query(array_filter([ - 'code' => $authorizationCode->getToken(), + 'code' => $authorizationCode->getToken(), 'state' => $state, ])); @@ -126,12 +123,13 @@ public function createAuthorizationResponse( /** * {@inheritdoc} + * * @throws OAuth2Exception */ public function createTokenResponse( ServerRequestInterface $request, - Client $client = null, - TokenOwnerInterface $owner = null + ?Client $client = null, + ?TokenOwnerInterface $owner = null ): ResponseInterface { $postParams = $request->getParsedBody(); @@ -141,7 +139,7 @@ public function createTokenResponse( throw OAuth2Exception::invalidRequest('Could not find the authorization code in the request'); } - /* @var \ZfrOAuth2\Server\Model\AuthorizationCode $authorizationCode */ + /** @var AuthorizationCode $authorizationCode */ $authorizationCode = $this->authorizationCodeService->getToken($code); if (null === $authorizationCode || $authorizationCode->isExpired()) { diff --git a/src/Grant/AuthorizationServerAwareInterface.php b/src/Grant/AuthorizationServerAwareInterface.php index 953c793..b053a2d 100644 --- a/src/Grant/AuthorizationServerAwareInterface.php +++ b/src/Grant/AuthorizationServerAwareInterface.php @@ -1,6 +1,6 @@ * @licence MIT */ interface AuthorizationServerAwareInterface diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index a32aa66..9910c03 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -1,6 +1,6 @@ + * * @licence MIT */ class ClientCredentialsGrant extends AbstractGrant { - const GRANT_TYPE = 'client_credentials'; - const GRANT_RESPONSE_TYPE = ''; + public const GRANT_TYPE = 'client_credentials'; + public const GRANT_RESPONSE_TYPE = ''; /** * Access token service (used to create access token) - * - * @var AccessTokenService */ - private $accessTokenService; + private AccessTokenService $accessTokenService; - /** - * @param AccessTokenService $accessTokenService - */ public function __construct(AccessTokenService $accessTokenService) { $this->accessTokenService = $accessTokenService; } /** - * @throws OAuth2Exception (invalid_request) + * @throws OAuth2Exception (invalid_request). */ public function createAuthorizationResponse( ServerRequestInterface $request, Client $client, - TokenOwnerInterface $owner = null + ?TokenOwnerInterface $owner = null ): ResponseInterface { throw OAuth2Exception::invalidRequest('Client credentials grant does not support authorization'); } @@ -74,13 +72,13 @@ public function createAuthorizationResponse( */ public function createTokenResponse( ServerRequestInterface $request, - Client $client = null, - TokenOwnerInterface $owner = null + ?Client $client = null, + ?TokenOwnerInterface $owner = null ): ResponseInterface { $postParams = $request->getParsedBody(); // Everything is okey, we can start tokens generation! - $scope = $postParams['scope'] ?? null; + $scope = $postParams['scope'] ?? null; $scopes = is_string($scope) ? explode(' ', $scope) : []; /** @var AccessToken $accessToken */ diff --git a/src/Grant/GrantInterface.php b/src/Grant/GrantInterface.php index c84e187..56d5690 100644 --- a/src/Grant/GrantInterface.php +++ b/src/Grant/GrantInterface.php @@ -1,6 +1,6 @@ + * * @licence MIT */ interface GrantInterface @@ -42,8 +42,8 @@ interface GrantInterface /** * Constants that need to be overridden for each grant */ - const GRANT_TYPE = ''; - const GRANT_RESPONSE_TYPE = ''; + public const GRANT_TYPE = ''; + public const GRANT_RESPONSE_TYPE = ''; /** * Create an authorization code @@ -53,19 +53,18 @@ interface GrantInterface public function createAuthorizationResponse( ServerRequestInterface $request, Client $client, - TokenOwnerInterface $owner = null + ?TokenOwnerInterface $owner = null ): ResponseInterface; /** * Create a token response according (this is the response to the "token endpoint") * - * @return ResponseInterface * @throws OAuth2Exception */ public function createTokenResponse( ServerRequestInterface $request, - Client $client = null, - TokenOwnerInterface $owner = null + ?Client $client = null, + ?TokenOwnerInterface $owner = null ): ResponseInterface; /** diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 358a0c2..baf8e53 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -1,6 +1,6 @@ + * * @licence MIT */ class PasswordGrant extends AbstractGrant implements AuthorizationServerAwareInterface { - const GRANT_TYPE = 'password'; - const GRANT_RESPONSE_TYPE = ''; + public const GRANT_TYPE = 'password'; + public const GRANT_RESPONSE_TYPE = ''; /** * Access token service (used to create access token) - * - * @var AccessTokenService */ - private $accessTokenService; + private AccessTokenService $accessTokenService; /** * An AuthorizationServer will inject itself into the grant when it is constructed - * - * @var AuthorizationServerInterface */ - private $authorizationServer; + private ?AuthorizationServerInterface $authorizationServer = null; /** * Refresh token service (used to create refresh token) - * - * @var RefreshTokenService */ - private $refreshTokenService; + private RefreshTokenService $refreshTokenService; /** * Callable that is used to verify the username and password @@ -81,18 +78,18 @@ public function __construct( RefreshTokenService $refreshTokenService, callable $callback ) { - $this->accessTokenService = $accessTokenService; + $this->accessTokenService = $accessTokenService; $this->refreshTokenService = $refreshTokenService; - $this->callback = $callback; + $this->callback = $callback; } /** - * @throws OAuth2Exception (invalid_request) + * @throws OAuth2Exception (invalid_request). */ public function createAuthorizationResponse( ServerRequestInterface $request, Client $client, - TokenOwnerInterface $owner = null + ?TokenOwnerInterface $owner = null ): ResponseInterface { throw OAuth2Exception::invalidRequest('Password grant does not support authorization'); } @@ -102,23 +99,23 @@ public function createAuthorizationResponse( */ public function createTokenResponse( ServerRequestInterface $request, - Client $client = null, - TokenOwnerInterface $owner = null + ?Client $client = null, + ?TokenOwnerInterface $owner = null ): ResponseInterface { $postParams = $request->getParsedBody(); // Validate the user using its username and password $username = $postParams['username'] ?? null; $password = $postParams['password'] ?? null; - $scope = $postParams['scope'] ?? null; - $scopes = is_string($scope) ? explode(' ', $scope) : []; + $scope = $postParams['scope'] ?? null; + $scopes = is_string($scope) ? explode(' ', $scope) : []; if (null === $username || null === $password) { throw OAuth2Exception::invalidRequest('Username and/or password is missing'); } $callback = $this->callback; - $owner = $callback($username, $password); + $owner = $callback($username, $password); if (! $owner instanceof TokenOwnerInterface) { throw OAuth2Exception::accessDenied('Either username or password are incorrect'); diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 313917b..005c791 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -1,6 +1,6 @@ * @licence MIT */ class RefreshTokenGrant extends AbstractGrant { - const GRANT_TYPE = 'refresh_token'; - const GRANT_RESPONSE_TYPE = ''; + public const GRANT_TYPE = 'refresh_token'; + public const GRANT_RESPONSE_TYPE = ''; - /** - * @var AccessTokenService - */ - private $accessTokenService; + private AccessTokenService $accessTokenService; - /** - * @var RefreshTokenService - */ - private $refreshTokenService; + private RefreshTokenService $refreshTokenService; - /** - * @var ServerOptions - */ - private $serverOptions; + private ServerOptions $serverOptions; public function __construct( AccessTokenService $accessTokenService, RefreshTokenService $refreshTokenService, ServerOptions $serverOptions ) { - $this->accessTokenService = $accessTokenService; + $this->accessTokenService = $accessTokenService; $this->refreshTokenService = $refreshTokenService; - $this->serverOptions = $serverOptions; + $this->serverOptions = $serverOptions; } /** - * @throws OAuth2Exception (invalid_request) + * @throws OAuth2Exception (invalid_request). */ public function createAuthorizationResponse( ServerRequestInterface $request, Client $client, - TokenOwnerInterface $owner = null + ?TokenOwnerInterface $owner = null ): ResponseInterface { throw OAuth2Exception::invalidRequest('Refresh token grant does not support authorization'); } @@ -81,8 +74,8 @@ public function createAuthorizationResponse( */ public function createTokenResponse( ServerRequestInterface $request, - Client $client = null, - TokenOwnerInterface $owner = null + ?Client $client = null, + ?TokenOwnerInterface $owner = null ): ResponseInterface { $postParams = $request->getParsedBody(); @@ -103,7 +96,7 @@ public function createTokenResponse( // We can now create a new access token! First, we need to make some checks on the asked scopes, // because according to the spec, a refresh token can create an access token with an equal or lesser // scope, but not more - $scope = $postParams['scope'] ?? null; + $scope = $postParams['scope'] ?? null; $scopes = is_string($scope) ? explode(' ', $scope) : $refreshToken->getScopes(); if (! $refreshToken->matchScopes($scopes)) { @@ -112,7 +105,7 @@ public function createTokenResponse( ); } - $owner = $refreshToken->getOwner(); + $owner = $refreshToken->getOwner(); $accessToken = $this->accessTokenService->createToken($owner, $client, $scopes); // We may want to revoke the old refresh token diff --git a/src/Middleware/AuthorizationRequestMiddleware.php b/src/Middleware/AuthorizationRequestMiddleware.php index fb26478..b0a4be2 100644 --- a/src/Middleware/AuthorizationRequestMiddleware.php +++ b/src/Middleware/AuthorizationRequestMiddleware.php @@ -1,6 +1,6 @@ authorizationServer = $authorizationServer; + $this->authorizationServer = $authorizationServer; $this->ownerRequestAttribute = $ownerRequestAttribute; } diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php index 1ece7b0..13012b5 100644 --- a/src/Middleware/ResourceServerMiddleware.php +++ b/src/Middleware/ResourceServerMiddleware.php @@ -40,22 +40,13 @@ */ class ResourceServerMiddleware implements MiddlewareInterface { - /** - * @var ResourceServerInterface - */ - private $resourceServer; + private ResourceServerInterface $resourceServer; - /** - * @var string - */ - private $tokenRequestAttribute; + private string $tokenRequestAttribute; - /** - * @param ResourceServerInterface $resourceServer - */ public function __construct(ResourceServerInterface $resourceServer, string $tokenRequestAttribute = 'oauth_token') { - $this->resourceServer = $resourceServer; + $this->resourceServer = $resourceServer; $this->tokenRequestAttribute = $tokenRequestAttribute; } @@ -66,8 +57,10 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface } catch (InvalidAccessTokenException $exception) { // If we're here, this means that there was an access token, but it's either expired or invalid. If // that's the case we must immediately return - return new JsonResponse(['error' => $exception->getCode(), 'error_description' => $exception->getMessage()], - 401); + return new JsonResponse( + ['error' => $exception->getCode(), 'error_description' => $exception->getMessage()], + 401 + ); } // Otherwise, if we actually have a token and set it as part of the request attribute for next step diff --git a/src/Middleware/RevocationRequestMiddleware.php b/src/Middleware/RevocationRequestMiddleware.php index ee631e9..aee56e2 100644 --- a/src/Middleware/RevocationRequestMiddleware.php +++ b/src/Middleware/RevocationRequestMiddleware.php @@ -32,10 +32,7 @@ */ class RevocationRequestMiddleware implements MiddlewareInterface { - /** - * @var AuthorizationServerInterface - */ - private $authorizationServer; + private AuthorizationServerInterface $authorizationServer; public function __construct(AuthorizationServerInterface $authorizationServer) { diff --git a/src/Middleware/TokenRequestMiddleware.php b/src/Middleware/TokenRequestMiddleware.php index fa9b34e..3976987 100644 --- a/src/Middleware/TokenRequestMiddleware.php +++ b/src/Middleware/TokenRequestMiddleware.php @@ -32,10 +32,7 @@ */ class TokenRequestMiddleware implements MiddlewareInterface { - /** - * @var AuthorizationServerInterface - */ - private $authorizationServer; + private AuthorizationServerInterface $authorizationServer; public function __construct(AuthorizationServerInterface $authorizationServer) { diff --git a/src/Model/AbstractToken.php b/src/Model/AbstractToken.php index 714a907..21956e0 100644 --- a/src/Model/AbstractToken.php +++ b/src/Model/AbstractToken.php @@ -1,6 +1,6 @@ * @licence MIT */ abstract class AbstractToken { - /** - * @var string - */ + /** @var string */ private $token; - /** - * @var Client - */ + /** @var Client */ private $client; - /** - * @var TokenOwnerInterface - */ + /** @var TokenOwnerInterface */ private $owner; - /** - * @var DateTimeInterface - */ + /** @var DateTimeInterface|null */ protected $expiresAt; - /** - * @var array - */ - private $scopes = []; + private array $scopes = []; - /** - * AbstractToken constructor. - */ private function __construct() { } @@ -71,31 +63,26 @@ private function __construct() /** * Create a new AbstractToken * - * @param int $ttl - * @param TokenOwnerInterface $owner - * @param Client $client * @param string[]|Scope[]|null $scopes * @return AbstractToken */ protected static function createNew( int $ttl, - TokenOwnerInterface $owner = null, - Client $client = null, - array $scopes = null + ?TokenOwnerInterface $owner = null, + ?Client $client = null, + ?array $scopes = null ): self { if (is_array($scopes)) { - $scopes = array_map(function ($scope) { - return (string) $scope; - }, $scopes); + $scopes = array_map(fn($scope) => (string) $scope, $scopes); } $token = new static(); - $token->token = bin2hex(random_bytes(20)); - $token->owner = $owner; - $token->client = $client; - $token->scopes = $scopes ?? []; - $token->expiresAt = $ttl ? (new DateTime('@' . time(), new DateTimeZone('UTC')))->modify("+$ttl seconds") : null; + $token->token = bin2hex(random_bytes(20)); + $token->owner = $owner; + $token->client = $client; + $token->scopes = $scopes ?? []; + $token->expiresAt = $ttl ? (Carbon::now('UTC'))->modify("+$ttl seconds") : null; return $token; } @@ -107,11 +94,11 @@ public static function reconstitute(array $data) { $token = new static(); - $token->token = $data['token']; + $token->token = $data['token']; $token->expiresAt = $data['expiresAt']; - $token->owner = $data['owner']; - $token->client = $data['client']; - $token->scopes = (array) $data['scopes']; + $token->owner = $data['owner']; + $token->client = $data['client']; + $token->scopes = (array) $data['scopes']; return $token; } @@ -153,7 +140,7 @@ public function getExpiresAt(): ?DateTimeInterface */ public function getExpiresIn(): int { - return $this->expiresAt->getTimestamp() - (new DateTime('@' . time(), new DateTimeZone('UTC')))->getTimestamp(); + return $this->expiresAt === null ? 0 : $this->expiresAt->getTimestamp() - Carbon::now('UTC')->getTimestamp(); } /** @@ -161,7 +148,7 @@ public function getExpiresIn(): int */ public function isExpired(): bool { - return $this->expiresAt < new DateTime('@' . time(), new DateTimeZone('UTC')); + return $this->expiresAt === null || $this->expiresAt->getTimestamp() <= Carbon::now('UTC')->getTimestamp(); } /** @@ -182,7 +169,7 @@ public function getScopes(): array public function matchScopes($scopes): bool { $scopes = is_string($scopes) ? explode(' ', $scopes) : $scopes; - $diff = array_diff($scopes, $this->scopes); + $diff = array_diff($scopes, $this->scopes); return empty($diff); } diff --git a/src/Model/AccessToken.php b/src/Model/AccessToken.php index ee43f1c..8c23985 100644 --- a/src/Model/AccessToken.php +++ b/src/Model/AccessToken.php @@ -1,6 +1,6 @@ * @licence MIT */ class AccessToken extends AbstractToken @@ -36,8 +35,8 @@ class AccessToken extends AbstractToken */ public static function createNewAccessToken( int $ttl, - TokenOwnerInterface $owner = null, - Client $client = null, + ?TokenOwnerInterface $owner = null, + ?Client $client = null, $scopes = null ): AccessToken { return static::createNew($ttl, $owner, $client, $scopes); diff --git a/src/Model/AuthorizationCode.php b/src/Model/AuthorizationCode.php index f24bc55..791297e 100644 --- a/src/Model/AuthorizationCode.php +++ b/src/Model/AuthorizationCode.php @@ -1,6 +1,6 @@ * @licence MIT */ class AuthorizationCode extends AbstractToken { - /** - * @var string - */ + /** @var string */ private $redirectUri; /** * Create a new AuthorizationCode * - * @param int $ttl - * @param string $redirectUri - * @param TokenOwnerInterface $owner - * @param Client $client * @param string|string[]|Scope[]|null $scopes - * @return AuthorizationCode */ public static function createNewAuthorizationCode( int $ttl, - string $redirectUri = null, - TokenOwnerInterface $owner = null, - Client $client = null, + ?string $redirectUri = null, + ?TokenOwnerInterface $owner = null, + ?Client $client = null, $scopes = null ): AuthorizationCode { $token = static::createNew($ttl, $owner, $client, $scopes); diff --git a/src/Model/Client.php b/src/Model/Client.php index c5f6ce4..68d8a49 100644 --- a/src/Model/Client.php +++ b/src/Model/Client.php @@ -1,6 +1,6 @@ * @licence MIT */ class Client { - /** - * @var string - */ - private $id = ''; + private string $id = ''; - /** - * @var string - */ - private $name = ''; + private string $name = ''; - /** - * @var string - */ - private $secret = ''; + private string $secret = ''; - /** - * @var array - */ - private $redirectUris = []; + private array $redirectUris = []; - /** - * @var array - */ - private $scopes = []; + private array $scopes = []; - /** - * Client constructor. - */ private function __construct() { } @@ -91,10 +84,10 @@ public static function createNewClient(string $name, $redirectUris = null, $scop $client = new static(); - $client->id = (string) Uuid::uuid4(); - $client->name = $name; + $client->id = (string) Uuid::uuid4(); + $client->name = $name; $client->redirectUris = $redirectUris ?? []; - $client->scopes = $scopes ?? []; + $client->scopes = $scopes ?? []; return $client; } @@ -103,11 +96,11 @@ public static function reconstitute(array $data): Client { $client = new static(); - $client->id = $data['id']; - $client->name = $data['name']; - $client->secret = $data['secret']; + $client->id = $data['id']; + $client->name = $data['name']; + $client->secret = $data['secret']; $client->redirectUris = $data['redirectUris']; - $client->scopes = $data['scopes']; + $client->scopes = $data['scopes']; return $client; } @@ -183,7 +176,7 @@ public function authenticate(string $secret): bool */ public function generateSecret(): string { - $secret = bin2hex(random_bytes(20)); + $secret = bin2hex(random_bytes(20)); $this->secret = password_hash($secret, PASSWORD_DEFAULT); return $secret; diff --git a/src/Model/RefreshToken.php b/src/Model/RefreshToken.php index 42f1c5d..7641f0c 100644 --- a/src/Model/RefreshToken.php +++ b/src/Model/RefreshToken.php @@ -1,6 +1,6 @@ * @licence MIT */ class RefreshToken extends AbstractToken @@ -36,8 +35,8 @@ class RefreshToken extends AbstractToken */ public static function createNewRefreshToken( int $ttl, - TokenOwnerInterface $owner = null, - Client $client = null, + ?TokenOwnerInterface $owner = null, + ?Client $client = null, $scopes = null ): RefreshToken { return static::createNew($ttl, $owner, $client, $scopes); diff --git a/src/Model/Scope.php b/src/Model/Scope.php index fae1676..4fcd847 100644 --- a/src/Model/Scope.php +++ b/src/Model/Scope.php @@ -1,6 +1,6 @@ * @licence MIT */ class Scope { - /** - * @var int - */ + /** @var int */ private $id; - /** - * @var string - */ - private $name = ''; + private string $name = ''; - /** - * @var string - */ + /** @var string */ private $description = ''; - /** - * @var bool - */ - private $isDefault = false; + private bool $isDefault = false; - /** - * Scope constructor. - */ private function __construct() { } @@ -62,15 +48,15 @@ private function __construct() public static function createNewScope( int $id, string $name, - string $description = null, + ?string $description = null, bool $isDefault = false ): Scope { $scope = new static(); - $scope->id = $id; - $scope->name = $name; + $scope->id = $id; + $scope->name = $name; $scope->description = $description; - $scope->isDefault = $isDefault; + $scope->isDefault = $isDefault; return $scope; } @@ -79,10 +65,10 @@ public static function reconstitute(array $data): Scope { $scope = new static(); - $scope->id = $data['id']; - $scope->name = $data['name']; + $scope->id = $data['id']; + $scope->name = $data['name']; $scope->description = $data['description']; - $scope->isDefault = $data['isDefault']; + $scope->isDefault = $data['isDefault']; return $scope; } diff --git a/src/Model/TokenOwnerInterface.php b/src/Model/TokenOwnerInterface.php index 80a1d17..b66a7bc 100644 --- a/src/Model/TokenOwnerInterface.php +++ b/src/Model/TokenOwnerInterface.php @@ -1,6 +1,6 @@ * @licence MIT */ interface TokenOwnerInterface diff --git a/src/ModuleConfig.php b/src/ModuleConfig.php index c42078b..6f0f0a9 100644 --- a/src/ModuleConfig.php +++ b/src/ModuleConfig.php @@ -1,6 +1,6 @@ * @licence MIT */ class ModuleConfig diff --git a/src/Options/ServerOptions.php b/src/Options/ServerOptions.php index 81dadbf..1dec110 100644 --- a/src/Options/ServerOptions.php +++ b/src/Options/ServerOptions.php @@ -1,6 +1,6 @@ * @licence MIT */ final class ServerOptions { /** * Authorization code TTL - * - * @var int */ - private $authorizationCodeTtl = 120; + private int $authorizationCodeTtl = 120; /** * Access token TTL - * - * @var int */ - private $accessTokenTtl = 3600; + private int $accessTokenTtl = 3600; /** * Refresh token TTL - * - * @var int */ - private $refreshTokenTtl = 86400; + private int $refreshTokenTtl = 86400; /** * Rotate refresh tokens (for RefreshTokenGrant) - * - * @var bool */ - private $rotateRefreshTokens = false; + private bool $rotateRefreshTokens = false; /** * Revoke rotated refresh tokens (for RefreshTokenGrant) - * - * @var bool */ - private $revokeRotatedRefreshTokens = true; + private bool $revokeRotatedRefreshTokens = true; /** * Set the owner callable @@ -73,25 +62,19 @@ final class ServerOptions /** * Grants that the authorization server must support - * - * @var array */ - private $grants = []; + private array $grants = []; /** * Attribute that the AuthorizationRequestMiddleware expects the ZfrOAuth2\Server\Model\TokenOwnerInterface * to be present on - * - * @var string */ - private $ownerRequestAttribute; + private string $ownerRequestAttribute; /** * Attribute that the ResourceServerMiddleware uses to access the token - * - * @var string */ - private $tokenRequestAttribute; + private string $tokenRequestAttribute; /** * @param callable|string $ownerCallable either a callable or the name of a container service @@ -107,15 +90,15 @@ private function __construct( string $ownerRequestAttribute, string $tokenRequestAttribute ) { - $this->authorizationCodeTtl = $authorizationCodeTtl; - $this->accessTokenTtl = $accessTokenTtl; - $this->refreshTokenTtl = $refreshTokenTtl; - $this->rotateRefreshTokens = $rotateRefreshTokens; + $this->authorizationCodeTtl = $authorizationCodeTtl; + $this->accessTokenTtl = $accessTokenTtl; + $this->refreshTokenTtl = $refreshTokenTtl; + $this->rotateRefreshTokens = $rotateRefreshTokens; $this->revokeRotatedRefreshTokens = $revokeRotatedRefreshTokens; - $this->ownerCallable = $ownerCallable; - $this->grants = $grants; - $this->ownerRequestAttribute = $ownerRequestAttribute; - $this->tokenRequestAttribute = $tokenRequestAttribute; + $this->ownerCallable = $ownerCallable; + $this->grants = $grants; + $this->ownerRequestAttribute = $ownerRequestAttribute; + $this->tokenRequestAttribute = $tokenRequestAttribute; } /** diff --git a/src/Repository/AccessTokenRepositoryInterface.php b/src/Repository/AccessTokenRepositoryInterface.php index ba6b08e..654f933 100644 --- a/src/Repository/AccessTokenRepositoryInterface.php +++ b/src/Repository/AccessTokenRepositoryInterface.php @@ -1,6 +1,6 @@ * @licence MIT */ class ResourceServer implements ResourceServerInterface { - /** - * @var AccessTokenService - */ - private $accessTokenService; + private AccessTokenService $accessTokenService; public function __construct(AccessTokenService $accessTokenService) { @@ -57,9 +57,9 @@ public function __construct(AccessTokenService $accessTokenService) * deleted) or is not valid, then it will trigger an exception * * @link http://tools.ietf.org/html/rfc6750#page-5 + * * @param array|string|Scope[] $scopes - * @return AccessToken|null - * @throws InvalidAccessTokenException If given access token is invalid or expired + * @throws InvalidAccessTokenException If given access token is invalid or expired. */ public function getAccessToken(ServerRequestInterface $request, $scopes = []): ?AccessToken { diff --git a/src/ResourceServerInterface.php b/src/ResourceServerInterface.php index e079694..b479e41 100644 --- a/src/ResourceServerInterface.php +++ b/src/ResourceServerInterface.php @@ -1,6 +1,6 @@ * @licence MIT */ abstract class AbstractTokenService { - /** - * @var TokenRepositoryInterface - */ + /** @var TokenRepositoryInterface */ protected $tokenRepository; - /** - * @var ScopeService - */ + /** @var ScopeService */ protected $scopeService; - /** - * @var ServerOptions - */ + /** @var ServerOptions */ protected $serverOptions; - /** - * @param TokenRepositoryInterface $tokenRepository - * @param ScopeService $scopeService - * @param ServerOptions $serverOptions - */ public function __construct( TokenRepositoryInterface $tokenRepository, ScopeService $scopeService, ServerOptions $serverOptions ) { $this->tokenRepository = $tokenRepository; - $this->scopeService = $scopeService; - $this->serverOptions = $serverOptions; + $this->scopeService = $scopeService; + $this->serverOptions = $serverOptions; } /** @@ -71,7 +66,7 @@ public function __construct( */ public function getToken(string $token): ?AbstractToken { - /* @var \ZfrOAuth2\Server\Model\AbstractToken $tokenFromDb */ + /** @var AbstractToken $tokenFromDb */ $tokenFromDb = $this->tokenRepository->findByToken($token); // Because the collation is most often case insensitive, we need to add a check here to ensure @@ -101,20 +96,15 @@ public function purgeExpiredTokens(): void * * @param string[]|Scope[] $scopes * @param Client|null $client - * - * @throws OAuth2Exception (invalid_scope) When one or more of the given scopes where not registered + * @throws OAuth2Exception (invalid_scope) When one or more of the given scopes where not registered. */ public function validateTokenScopes(array $scopes, $client = null): void { - $scopes = array_map(function ($scope) { - return (string) $scope; - }, $scopes); + $scopes = array_map(fn($scope) => (string) $scope, $scopes); $registeredScopes = $this->scopeService->getAll(); - $registeredScopes = array_map(function ($scope) { - return (string) $scope; - }, $registeredScopes); + $registeredScopes = array_map(fn($scope) => (string) $scope, $registeredScopes); $diff = array_diff($scopes, $registeredScopes); diff --git a/src/Service/AccessTokenService.php b/src/Service/AccessTokenService.php index 1d98864..4809dd9 100644 --- a/src/Service/AccessTokenService.php +++ b/src/Service/AccessTokenService.php @@ -1,6 +1,6 @@ * @licence MIT */ class AccessTokenService extends AbstractTokenService { - /** - * @var AccessTokenRepositoryInterface - */ + /** @var AccessTokenRepositoryInterface */ protected $tokenRepository; /** @@ -47,7 +44,6 @@ class AccessTokenService extends AbstractTokenService * @param TokenOwnerInterface $owner * @param Client $client * @param string[]|Scope[] $scopes - * @return AccessToken * @throws OAuth2Exception */ public function createToken($owner, $client, array $scopes = []): AccessToken diff --git a/src/Service/AuthorizationCodeService.php b/src/Service/AuthorizationCodeService.php index 56e73c0..8929b3c 100644 --- a/src/Service/AuthorizationCodeService.php +++ b/src/Service/AuthorizationCodeService.php @@ -1,6 +1,6 @@ * @licence MIT */ class AuthorizationCodeService extends AbstractTokenService { - /** - * @var AuthorizationCodeRepositoryInterface - */ + /** @var AuthorizationCodeRepositoryInterface */ protected $tokenRepository; /** @@ -48,7 +45,6 @@ class AuthorizationCodeService extends AbstractTokenService * @param TokenOwnerInterface $owner * @param Client $client * @param string[]|Scope[] $scopes - * @return AuthorizationCode * @throws OAuth2Exception */ public function createToken($redirectUri, $owner, $client, array $scopes = []): AuthorizationCode diff --git a/src/Service/ClientService.php b/src/Service/ClientService.php index 3a3137d..516fd71 100644 --- a/src/Service/ClientService.php +++ b/src/Service/ClientService.php @@ -1,6 +1,6 @@ * @licence MIT */ class ClientService { - /** - * @var ClientRepositoryInterface - */ - private $clientRepository; + private ClientRepositoryInterface $clientRepository; - /** - * ClientService constructor. - * - * @param ClientRepositoryInterface $clientRepository - */ public function __construct(ClientRepositoryInterface $clientRepository) { $this->clientRepository = $clientRepository; @@ -54,7 +45,6 @@ public function __construct(ClientRepositoryInterface $clientRepository) * authorize the client. It is returned as a result of this method, as it's already encrypted * in the client object * - * @param string $name * @param array $redirectUris * @param array $scopes * @return array [$client, $secret] @@ -74,7 +64,6 @@ public function registerClient(string $name, array $redirectUris, array $scopes /** * Get the client using its id * - * @param string $id * @return Client|null */ public function getClient(string $id) diff --git a/src/Service/RefreshTokenService.php b/src/Service/RefreshTokenService.php index 4642b02..5b21591 100644 --- a/src/Service/RefreshTokenService.php +++ b/src/Service/RefreshTokenService.php @@ -1,6 +1,6 @@ * @licence MIT */ class RefreshTokenService extends AbstractTokenService { - /** - * @var RefreshTokenRepositoryInterface - */ + /** @var RefreshTokenRepositoryInterface */ protected $tokenRepository; /** @@ -47,7 +44,6 @@ class RefreshTokenService extends AbstractTokenService * @param TokenOwnerInterface $owner * @param Client|null $client * @param string[]|Scope[] $scopes - * @return RefreshToken * @throws OAuth2Exception */ public function createToken($owner, $client = null, array $scopes = []): RefreshToken diff --git a/src/Service/ScopeService.php b/src/Service/ScopeService.php index 09de45e..bc4e579 100644 --- a/src/Service/ScopeService.php +++ b/src/Service/ScopeService.php @@ -1,6 +1,6 @@ * @licence MIT */ class ScopeService { - /** - * @var ScopeRepositoryInterface - */ - private $scopeRepository; + private ScopeRepositoryInterface $scopeRepository; - /** - * @param ScopeRepositoryInterface $scopeRepository - */ public function __construct(ScopeRepositoryInterface $scopeRepository) { $this->scopeRepository = $scopeRepository; @@ -47,9 +40,6 @@ public function __construct(ScopeRepositoryInterface $scopeRepository) /** * Create a new scope - * - * @param Scope $scope - * @return Scope */ public function createScope(Scope $scope): Scope { diff --git a/tests/Bootstrap.php b/test/Bootstrap.php similarity index 89% rename from tests/Bootstrap.php rename to test/Bootstrap.php index 4d76afd..4ee1ada 100644 --- a/tests/Bootstrap.php +++ b/test/Bootstrap.php @@ -1,6 +1,6 @@ add('ZfrOAuth2Test\\', __DIR__); -\phpmock\phpunit\PHPMock::defineFunctionMock('ZfrOAuth2\Server\Model', 'time'); - unset($files, $file, $loader); diff --git a/tests/src/Asset/SomeToken.php b/test/src/Asset/SomeToken.php similarity index 94% rename from tests/src/Asset/SomeToken.php rename to test/src/Asset/SomeToken.php index 19c62ae..bf3ae71 100644 --- a/tests/src/Asset/SomeToken.php +++ b/test/src/Asset/SomeToken.php @@ -1,6 +1,6 @@ * @licence MIT */ class SomeToken extends AbstractToken diff --git a/tests/src/AuthorizationServerTest.php b/test/src/AuthorizationServerTest.php similarity index 54% rename from tests/src/AuthorizationServerTest.php rename to test/src/AuthorizationServerTest.php index bf3954a..e62b5e0 100644 --- a/tests/src/AuthorizationServerTest.php +++ b/test/src/AuthorizationServerTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\AuthorizationServer */ @@ -47,17 +53,22 @@ class AuthorizationServerTest extends TestCase public function testCanCheckAndGetForGrants(): void { $clientService = $this->createMock(ClientService::class); - $grant = new PasswordGrant( + $grant = new PasswordGrant( $this->createMock(AccessTokenService::class), $this->createMock(RefreshTokenService::class), function () { } ); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); $this->assertTrue($authorizationServer->hasGrant(PasswordGrant::GRANT_TYPE)); $this->assertFalse($authorizationServer->hasGrant(ClientCredentialsGrant::GRANT_TYPE)); @@ -71,16 +82,21 @@ function () { public function testCanCheckAndGetForResponseType(): void { $clientService = $this->createMock(ClientService::class); - $grant = new AuthorizationGrant( + $grant = new AuthorizationGrant( $this->createMock(AuthorizationCodeService::class), $this->createMock(AccessTokenService::class), $this->createMock(RefreshTokenService::class) ); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); $this->assertTrue($authorizationServer->hasResponseType(AuthorizationGrant::GRANT_RESPONSE_TYPE)); $this->assertFalse($authorizationServer->hasResponseType(ClientCredentialsGrant::GRANT_RESPONSE_TYPE)); @@ -96,14 +112,19 @@ public function testThrowExceptionIfNoResponseType(): void $request = $this->createMock(ServerRequestInterface::class); $request->expects($this->once())->method('getQueryParams')->willReturn([]); - $clientService = $this->createMock(ClientService::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $clientService = $this->createMock(ClientService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [], + $accessTokenService, + $refreshTokenService + ); $response = $authorizationServer->handleAuthorizationRequest($request); - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); $this->assertEquals(400, $response->getStatusCode()); $this->assertArrayHasKey('error', $body); @@ -118,9 +139,18 @@ public function testThrowExceptionIfNoClientIdAtHandleAuthorisationRequests(): v { $authorizationGrant = $this->createMock(AuthorizationGrant::class); - $authorizationGrant->expects($this->any())->method('getType')->willReturn(AuthorizationGrant::GRANT_TYPE); - $authorizationGrant->expects($this->any())->method('getResponseType')->willReturn(AuthorizationGrant::GRANT_RESPONSE_TYPE); - $authorizationGrant->expects($this->any())->method('allowPublicClients')->willReturn(true); + $authorizationGrant + ->expects($this->any()) + ->method('getType') + ->willReturn(AuthorizationGrant::GRANT_TYPE); + $authorizationGrant + ->expects($this->any()) + ->method('getResponseType') + ->willReturn(AuthorizationGrant::GRANT_RESPONSE_TYPE); + $authorizationGrant + ->expects($this->any()) + ->method('allowPublicClients') + ->willReturn(true); $request = $this->createMock(ServerRequestInterface::class); @@ -129,14 +159,19 @@ public function testThrowExceptionIfNoClientIdAtHandleAuthorisationRequests(): v // use POST vars $request->expects($this->once())->method('getParsedBody')->willReturn(['client_secret' => 'clientsecret']); - $clientService = $this->createMock(ClientService::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $clientService = $this->createMock(ClientService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$authorizationGrant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$authorizationGrant], + $accessTokenService, + $refreshTokenService + ); $response = $authorizationServer->handleAuthorizationRequest($request); - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); $this->assertEquals(400, $response->getStatusCode()); $this->assertArrayHasKey('error', $body); @@ -150,13 +185,18 @@ public function testThrowExceptionIfNoGrantType(): void $clientService = $this->createMock(ClientService::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [], + $accessTokenService, + $refreshTokenService + ); $response = $authorizationServer->handleTokenRequest($request); - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); $this->assertEquals(400, $response->getStatusCode()); $this->assertArrayHasKey('error', $body); @@ -166,19 +206,26 @@ public function testThrowExceptionIfNoGrantType(): void public function testThrowExceptionIfPrivateClientDoesNotHaveSecret(): void { $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->exactly(2))->method('getParsedBody')->willReturn(['grant_type' => 'client_credentials']); + $request->expects($this->exactly(2)) + ->method('getParsedBody') + ->willReturn(['grant_type' => 'client_credentials']); $grant = new ClientCredentialsGrant($this->createMock(AccessTokenService::class)); $clientService = $this->createMock(ClientService::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); $response = $authorizationServer->handleTokenRequest($request); - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); $this->assertEquals(400, $response->getStatusCode()); $this->assertArrayHasKey('error', $body); @@ -189,12 +236,20 @@ public function testThrowExceptionForIncorrectSecret(): void { $grant = $this->createMock(ClientCredentialsGrant::class); - $grant->expects($this->any())->method('getType')->willReturn(ClientCredentialsGrant::GRANT_TYPE); - $grant->expects($this->any())->method('getResponseType')->willReturn(ClientCredentialsGrant::GRANT_RESPONSE_TYPE); - $grant->expects($this->once())->method('allowPublicClients')->willReturn(false); + $grant->expects($this->any()) + ->method('getType') + ->willReturn(ClientCredentialsGrant::GRANT_TYPE); + $grant->expects($this->any()) + ->method('getResponseType') + ->willReturn(ClientCredentialsGrant::GRANT_RESPONSE_TYPE); + $grant->expects($this->once()) + ->method('allowPublicClients') + ->willReturn(false); $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->exactly(1))->method('getParsedBody')->willReturn(['grant_type' => 'client_credentials']); + $request->expects($this->exactly(1)) + ->method('getParsedBody') + ->willReturn(['grant_type' => 'client_credentials']); $request->expects($this->once()) ->method('hasHeader') ->with('Authorization') @@ -206,23 +261,29 @@ public function testThrowExceptionForIncorrectSecret(): void ->willReturn('Authorization Y2xpZW50aWQ6Y2xpZW50c2VjcmV0'); $client = Client::reconstitute([ - 'id' => 'clientid', + 'id' => 'clientid', 'name' => 'clientname', - 'secret' => '$2y$10$ixK8D7rBvEPkX0.d3e93h.lb3wufbavWmIyX0zK1FhP3fGp.rIK1u', // hash of 'incorrectclientsecret' + // hash of 'incorrectclientsecret' + 'secret' => '$2y$10$ixK8D7rBvEPkX0.d3e93h.lb3wufbavWmIyX0zK1FhP3fGp.rIK1u', 'redirectUris' => ['http://example.com'], - 'scopes' => [], + 'scopes' => [], ]); $clientService = $this->createMock(ClientService::class); $clientService->expects($this->once())->method('getClient')->with('clientid')->willReturn($client); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); - $response = $authorizationServer->handleTokenRequest($request); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); + $response = $authorizationServer->handleTokenRequest($request); - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); $this->assertEquals(400, $response->getStatusCode()); $this->assertArrayHasKey('error', $body); @@ -240,24 +301,38 @@ public function revocationProvider(): array /** * @dataProvider revocationProvider */ - public function testCanReturn200IfTokenDoesNotExistForRevocation($tokenType): void + public function testCanReturn200IfTokenDoesNotExistForRevocation(string $tokenType): void { $request = $this->createMock(ServerRequestInterface::class); - $request->expects(static::once())->method('getParsedBody')->willReturn(['token' => 'abc', 'token_type_hint' => $tokenType]); + $request->expects(static::once()) + ->method('getParsedBody') + ->willReturn(['token' => 'abc', 'token_type_hint' => $tokenType]); $clientService = $this->createMock(ClientService::class); - $grant = $this->createMock(GrantInterface::class); + $grant = $this->createMock(GrantInterface::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); if ($tokenType === 'access_token') { - $accessTokenService->expects($this->once())->method('getToken')->with('abc')->will($this->returnValue(null)); - $accessTokenService->expects($this->never())->method('deleteToken'); + $accessTokenService->expects($this->once()) + ->method('getToken') + ->with('abc') + ->will($this->returnValue(null)); + $accessTokenService->expects($this->never()) + ->method('deleteToken'); } elseif ($tokenType === 'refresh_token') { - $refreshTokenService->expects($this->once())->method('getToken')->with('abc')->will($this->returnValue(null)); + $refreshTokenService->expects($this->once()) + ->method('getToken') + ->with('abc') + ->will($this->returnValue(null)); $refreshTokenService->expects($this->never())->method('deleteToken'); } @@ -270,29 +345,58 @@ public function testCanReturn200IfTokenDoesNotExistForRevocation($tokenType): vo /** * @dataProvider revocationProvider */ - public function testCanRevokeToken($tokenType): void + public function testCanRevokeToken(string $tokenType): void { $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getParsedBody')->willReturn(['token' => 'abc', 'token_type_hint' => $tokenType]); + $request->expects($this->once()) + ->method('getParsedBody') + ->willReturn(['token' => 'abc', 'token_type_hint' => $tokenType]); $clientService = $this->createMock(ClientService::class); - $grant = $this->createMock(GrantInterface::class); + $grant = $this->createMock(GrantInterface::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); if ($tokenType === 'access_token') { - $token = AccessToken::reconstitute(['token' => 'abc', 'owner' => null, 'client' => null, 'scopes' => [], 'expiresAt' => new \DateTimeImmutable()]); + $token = AccessToken::reconstitute([ + 'token' => 'abc', + 'owner' => null, + 'client' => null, + 'scopes' => [], + 'expiresAt' => new DateTimeImmutable(), + ]); - $accessTokenService->expects($this->once())->method('getToken')->with('abc')->will($this->returnValue($token)); - $accessTokenService->expects($this->once())->method('deleteToken')->with($token); + $accessTokenService->expects($this->once()) + ->method('getToken') + ->with('abc') + ->will($this->returnValue($token)); + $accessTokenService->expects($this->once()) + ->method('deleteToken') + ->with($token); } elseif ($tokenType === 'refresh_token') { - $token = RefreshToken::reconstitute(['token' => 'abc', 'owner' => null, 'client' => null, 'scopes' => [], 'expiresAt' => new \DateTimeImmutable()]); + $token = RefreshToken::reconstitute([ + 'token' => 'abc', + 'owner' => null, + 'client' => null, + 'scopes' => [], + 'expiresAt' => new DateTimeImmutable(), + ]); - $refreshTokenService->expects($this->once())->method('getToken')->with('abc')->will($this->returnValue($token)); - $refreshTokenService->expects($this->once())->method('deleteToken')->with($token); + $refreshTokenService->expects($this->once()) + ->method('getToken') + ->with('abc') + ->will($this->returnValue($token)); + $refreshTokenService->expects($this->once()) + ->method('deleteToken') + ->with($token); } $response = $authorizationServer->handleRevocationRequest($request); @@ -304,35 +408,61 @@ public function testCanRevokeToken($tokenType): void /** * @dataProvider revocationProvider */ - public function testReturn503IfCannotRevoke($tokenType): void + public function testReturn503IfCannotRevoke(string $tokenType): void { $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getParsedBody')->willReturn(['token' => 'abc', 'token_type_hint' => $tokenType]); + $request->expects($this->once()) + ->method('getParsedBody') + ->willReturn(['token' => 'abc', 'token_type_hint' => $tokenType]); $clientService = $this->createMock(ClientService::class); - $grant = $this->createMock(GrantInterface::class); + $grant = $this->createMock(GrantInterface::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); if ($tokenType === 'access_token') { - $token = AccessToken::reconstitute(['token' => 'abc', 'owner' => null, 'client' => null, 'scopes' => [], 'expiresAt' => new \DateTimeImmutable()]); + $token = AccessToken::reconstitute([ + 'token' => 'abc', + 'owner' => null, + 'client' => null, + 'scopes' => [], + 'expiresAt' => new DateTimeImmutable(), + ]); - $accessTokenService->expects($this->once())->method('getToken')->with('abc')->will($this->returnValue($token)); $accessTokenService->expects($this->once()) - ->method('deleteToken') - ->with($token) - ->will($this->throwException(new \RuntimeException())); + ->method('getToken') + ->with('abc') + ->will($this->returnValue($token)); + $accessTokenService->expects($this->once()) + ->method('deleteToken') + ->with($token) + ->will($this->throwException(new RuntimeException())); } elseif ($tokenType === 'refresh_token') { - $token = RefreshToken::reconstitute(['token' => 'abc', 'owner' => null, 'client' => null, 'scopes' => [], 'expiresAt' => new \DateTimeImmutable()]); + $token = RefreshToken::reconstitute([ + 'token' => 'abc', + 'owner' => null, + 'client' => null, + 'scopes' => [], + 'expiresAt' => new DateTimeImmutable(), + ]); + + $refreshTokenService->expects($this->once()) + ->method('getToken') + ->with('abc') + ->will($this->returnValue($token)); - $refreshTokenService->expects($this->once())->method('getToken')->with('abc')->will($this->returnValue($token)); $refreshTokenService->expects($this->once()) ->method('deleteToken') ->with($token) - ->will($this->throwException(new \RuntimeException())); + ->will($this->throwException(new RuntimeException())); } $response = $authorizationServer->handleRevocationRequest($request); @@ -347,15 +477,22 @@ public function testRevocationRequestWithoutTokenThrowsException(): void $request->expects($this->once())->method('getParsedBody')->willReturn(['token_type_hint' => 'access_token']); $clientService = $this->createMock(ClientService::class); - $grant = $this->createMock(GrantInterface::class); + $grant = $this->createMock(GrantInterface::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); $this->expectException(OAuth2Exception::class); - $this->expectExceptionMessage('Cannot revoke a token as the "token" and/or "token_type_hint" parameters are missing'); + $this->expectExceptionMessage( + 'Cannot revoke a token as the "token" and/or "token_type_hint" parameters are missing' + ); $authorizationServer->handleRevocationRequest($request); } @@ -366,15 +503,22 @@ public function testRevocationRequestWithoutTokenHintTypeThrowsException(): void $request->expects($this->once())->method('getParsedBody')->willReturn(['token' => '123']); $clientService = $this->createMock(ClientService::class); - $grant = $this->createMock(GrantInterface::class); + $grant = $this->createMock(GrantInterface::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); $this->expectException(OAuth2Exception::class); - $this->expectExceptionMessage('Cannot revoke a token as the "token" and/or "token_type_hint" parameters are missing'); + $this->expectExceptionMessage( + 'Cannot revoke a token as the "token" and/or "token_type_hint" parameters are missing' + ); $authorizationServer->handleRevocationRequest($request); } @@ -382,18 +526,27 @@ public function testRevocationRequestWithoutTokenHintTypeThrowsException(): void public function testRevocationRequestWithInvalidTokenTypeHintThrowsException(): void { $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getParsedBody')->willReturn(['token' => '123', 'token_type_hint' => 'invalid_token_hint']); + $request->expects($this->once()) + ->method('getParsedBody') + ->willReturn(['token' => '123', 'token_type_hint' => 'invalid_token_hint']); $clientService = $this->createMock(ClientService::class); - $grant = $this->createMock(GrantInterface::class); + $grant = $this->createMock(GrantInterface::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); $this->expectException(OAuth2Exception::class); - $this->expectExceptionMessage('Authorization server does not support revocation of token of type "invalid_token_hint"'); + $this->expectExceptionMessage( + 'Authorization server does not support revocation of token of type "invalid_token_hint"' + ); $authorizationServer->handleRevocationRequest($request); } @@ -401,22 +554,29 @@ public function testRevocationRequestWithInvalidTokenTypeHintThrowsException(): public function testRevocationRequestWithInvalidOtherNonPublicClientThrowsException(): void { $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getParsedBody')->willReturn(['token' => '123', 'token_type_hint' => 'access_token']); + $request->expects($this->once()) + ->method('getParsedBody') + ->willReturn(['token' => '123', 'token_type_hint' => 'access_token']); $clientService = $this->createMock(ClientService::class); - $grant = $this->createMock(GrantInterface::class); + $grant = $this->createMock(GrantInterface::class); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); $client = Client::reconstitute([ - 'id' => 'clientid', - 'name' => 'clientname', - 'secret' => '$2y$10$Nhc3Wlyez2lOM3U7vGZIBOIJOi14HxZB7CWEf2ymyIWKrDEs0OCRW', // hash of 'clientsecret' + 'id' => 'clientid', + 'name' => 'clientname', + 'secret' => '$2y$10$Nhc3Wlyez2lOM3U7vGZIBOIJOi14HxZB7CWEf2ymyIWKrDEs0OCRW', // hash of 'clientsecret' 'redirectUris' => [], - 'scopes' => [], + 'scopes' => [], ]); $clientService->expects($this->once())->method('getClient')->with('clientid')->willReturn($client); @@ -433,16 +593,25 @@ public function testRevocationRequestWithInvalidOtherNonPublicClientThrowsExcept // client has been changed since issuing $client = Client::reconstitute([ - 'id' => 'clientid', - 'name' => 'clientname', - 'secret' => '$2y$10$Nhc3Wlyez2lOM3U7vGZIBOIJOi14HxZB7CWEf2ymyIWKrDEs0OCRW', // hash of 'clientsecret' + 'id' => 'clientid', + 'name' => 'clientname', + 'secret' => '$2y$10$Nhc3Wlyez2lOM3U7vGZIBOIJOi14HxZB7CWEf2ymyIWKrDEs0OCRW', // hash of 'clientsecret' 'redirectUris' => ['http://example.com'], - 'scopes' => [], + 'scopes' => [], ]); - $token = AccessToken::reconstitute(['token' => '123', 'owner' => null, 'client' => $client, 'scopes' => [], 'expiresAt' => new \DateTimeImmutable()]); + $token = AccessToken::reconstitute([ + 'token' => '123', + 'owner' => null, + 'client' => $client, + 'scopes' => [], + 'expiresAt' => new DateTimeImmutable(), + ]); - $accessTokenService->expects($this->once())->method('getToken')->with('123')->will($this->returnValue($token)); + $accessTokenService->expects($this->once()) + ->method('getToken') + ->with('123') + ->will($this->returnValue($token)); $this->expectException(OAuth2Exception::class); $this->expectExceptionMessage('Token was issued for another client and cannot be revoked'); @@ -478,33 +647,45 @@ public function testHandleAuthorizationRequest(string $credentialsmethod): void $request->expects($this->once()) ->method('getParsedBody') ->willReturn([ - 'client_id' => 'clientid', + 'client_id' => 'clientid', 'client_secret' => 'clientsecret', ]); } $authorizationGrant = $this->createMock(AuthorizationGrant::class); - $authorizationGrant->expects($this->any())->method('getType')->willReturn(AuthorizationGrant::GRANT_TYPE); - $authorizationGrant->expects($this->any())->method('getResponseType')->willReturn(AuthorizationGrant::GRANT_RESPONSE_TYPE); - $authorizationGrant->expects($this->any())->method('allowPublicClients')->willReturn(true); + $authorizationGrant->expects($this->any()) + ->method('getType') + ->willReturn(AuthorizationGrant::GRANT_TYPE); + + $authorizationGrant->expects($this->any()) + ->method('getResponseType') + ->willReturn(AuthorizationGrant::GRANT_RESPONSE_TYPE); + + $authorizationGrant->expects($this->any()) + ->method('allowPublicClients') + ->willReturn(true); $client = Client::reconstitute([ - 'id' => 'clientid', - 'name' => 'clientname', - 'secret' => 'clientsecret', + 'id' => 'clientid', + 'name' => 'clientname', + 'secret' => 'clientsecret', 'redirectUris' => ['http://example.com'], - 'scopes' => [], + 'scopes' => [], ]); $clientService = $this->createMock(ClientService::class); $clientService->expects($this->once())->method('getClient')->with('clientid')->willReturn($client); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$authorizationGrant], $accessTokenService, - $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$authorizationGrant], + $accessTokenService, + $refreshTokenService + ); $response = $this->createMock(ResponseInterface::class); $response->expects($this->once()) @@ -535,19 +716,35 @@ public function testHandleTokenRequest(): void { $grant = $this->createMock(ClientCredentialsGrant::class); - $grant->expects($this->any())->method('getType')->willReturn(ClientCredentialsGrant::GRANT_TYPE); - $grant->expects($this->any())->method('getResponseType')->willReturn(ClientCredentialsGrant::GRANT_RESPONSE_TYPE); - $grant->expects($this->once())->method('allowPublicClients')->willReturn(false); + $grant->expects($this->any()) + ->method('getType') + ->willReturn(ClientCredentialsGrant::GRANT_TYPE); + + $grant->expects($this->any()) + ->method('getResponseType') + ->willReturn(ClientCredentialsGrant::GRANT_RESPONSE_TYPE); + + $grant->expects($this->once()) + ->method('allowPublicClients') + ->willReturn(false); $response = $this->createMock(ResponseInterface::class); - $response->expects($this->at(0))->method('withHeader')->with('Content-Type', 'application/json')->willReturn($response); - $response->expects($this->at(1))->method('withHeader')->with('Cache-Control', 'no-store')->willReturn($response); - $response->expects($this->at(2))->method('withHeader')->with('Pragma', 'no-cache')->willReturn($response); + $response->expects($this->exactly(3)) + ->method('withHeader') + ->withConsecutive( + ['Content-Type', 'application/json'], + ['Cache-Control', 'no-store'], + ['Pragma', 'no-cache'] + )->willReturn($response); $grant->expects($this->once())->method('createTokenResponse')->willReturn($response); $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->exactly(1))->method('getParsedBody')->willReturn(['grant_type' => 'client_credentials']); + + $request->expects($this->exactly(1)) + ->method('getParsedBody') + ->willReturn(['grant_type' => 'client_credentials']); + $request->expects($this->once()) ->method('hasHeader') ->with('Authorization') @@ -558,20 +755,25 @@ public function testHandleTokenRequest(): void ->with('Authorization') ->willReturn('Authorization Y2xpZW50aWQ6Y2xpZW50c2VjcmV0'); - $client = Client::reconstitute([ - 'id' => 'clientid', - 'name' => 'clientname', - 'secret' => '$2y$10$Nhc3Wlyez2lOM3U7vGZIBOIJOi14HxZB7CWEf2ymyIWKrDEs0OCRW', // hash of 'clientsecret' + $client = Client::reconstitute([ + 'id' => 'clientid', + 'name' => 'clientname', + 'secret' => '$2y$10$Nhc3Wlyez2lOM3U7vGZIBOIJOi14HxZB7CWEf2ymyIWKrDEs0OCRW', // hash of 'clientsecret' 'redirectUris' => ['http://example.com'], - 'scopes' => [], + 'scopes' => [], ]); $clientService = $this->createMock(ClientService::class); $clientService->expects($this->once())->method('getClient')->with('clientid')->willReturn($client); - $accessTokenService = $this->createMock(AccessTokenService::class); + $accessTokenService = $this->createMock(AccessTokenService::class); $refreshTokenService = $this->createMock(RefreshTokenService::class); - $authorizationServer = new AuthorizationServer($clientService, [$grant], $accessTokenService, $refreshTokenService); + $authorizationServer = new AuthorizationServer( + $clientService, + [$grant], + $accessTokenService, + $refreshTokenService + ); $authorizationServer->handleTokenRequest($request); } diff --git a/tests/src/Container/AccessTokenServiceFactoryTest.php b/test/src/Container/AccessTokenServiceFactoryTest.php similarity index 76% rename from tests/src/Container/AccessTokenServiceFactoryTest.php rename to test/src/Container/AccessTokenServiceFactoryTest.php index 0eff180..ad11c99 100644 --- a/tests/src/Container/AccessTokenServiceFactoryTest.php +++ b/test/src/Container/AccessTokenServiceFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Container\AccessTokenServiceFactory */ @@ -41,20 +41,17 @@ public function testCanCreateFromFactory(): void $serverOptions = ServerOptions::fromArray(); - $container->expects($this->at(0)) - ->method('get') - ->with(ServerOptions::class) - ->willReturn($serverOptions); - - $container->expects($this->at(1)) - ->method('get') - ->with(AccessTokenRepositoryInterface::class) - ->willReturn($this->createMock(AccessTokenRepositoryInterface::class)); - - $container->expects($this->at(2)) + $container + ->expects($this->exactly(3)) ->method('get') - ->with(ScopeService::class) - ->willReturn($this->createMock(ScopeService::class)); + ->withConsecutive([ServerOptions::class], [AccessTokenRepositoryInterface::class], [ScopeService::class]) + ->will( + $this->onConsecutiveCalls( + $serverOptions, + $this->createMock(AccessTokenRepositoryInterface::class), + $this->createMock(ScopeService::class), + ) + ); $factory = new AccessTokenServiceFactory(); $service = $factory($container); diff --git a/tests/src/Container/AuthorizationCodeServiceFactoryTest.php b/test/src/Container/AuthorizationCodeServiceFactoryTest.php similarity index 76% rename from tests/src/Container/AuthorizationCodeServiceFactoryTest.php rename to test/src/Container/AuthorizationCodeServiceFactoryTest.php index eec088f..16f13d3 100644 --- a/tests/src/Container/AuthorizationCodeServiceFactoryTest.php +++ b/test/src/Container/AuthorizationCodeServiceFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Container\AuthorizationCodeServiceFactory */ @@ -41,20 +41,21 @@ public function testCanCreateFromFactory(): void $serverOptions = ServerOptions::fromArray(); - $container->expects($this->at(0)) - ->method('get') - ->with(ServerOptions::class) - ->willReturn($serverOptions); - - $container->expects($this->at(1)) - ->method('get') - ->with(AuthorizationCodeRepositoryInterface::class) - ->willReturn($this->createMock(AuthorizationCodeRepositoryInterface::class)); - - $container->expects($this->at(2)) + $container + ->expects($this->exactly(3)) ->method('get') - ->with(ScopeService::class) - ->willReturn($this->createMock(ScopeService::class)); + ->withConsecutive( + [ServerOptions::class], + [AuthorizationCodeRepositoryInterface::class], + [ScopeService::class] + ) + ->will( + $this->onConsecutiveCalls( + $serverOptions, + $this->createMock(AuthorizationCodeRepositoryInterface::class), + $this->createMock(ScopeService::class), + ) + ); $factory = new AuthorizationCodeServiceFactory(); $service = $factory($container); diff --git a/tests/src/Container/AuthorizationGrantFactoryTest.php b/test/src/Container/AuthorizationGrantFactoryTest.php similarity index 74% rename from tests/src/Container/AuthorizationGrantFactoryTest.php rename to test/src/Container/AuthorizationGrantFactoryTest.php index 7c2f11d..bce54e5 100644 --- a/tests/src/Container/AuthorizationGrantFactoryTest.php +++ b/test/src/Container/AuthorizationGrantFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\AuthorizationGrantFactory */ class AuthorizationGrantFactoryTest extends TestCase @@ -40,20 +39,21 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) - ->method('get') - ->with(AuthorizationCodeService::class) - ->willReturn($this->createMock(AuthorizationCodeService::class)); - - $container->expects($this->at(1)) - ->method('get') - ->with(AccessTokenService::class) - ->willReturn($this->createMock(AccessTokenService::class)); - - $container->expects($this->at(2)) + $container + ->expects($this->exactly(3)) ->method('get') - ->with(RefreshTokenService::class) - ->willReturn($this->createMock(RefreshTokenService::class)); + ->withConsecutive( + [AuthorizationCodeService::class], + [AccessTokenService::class], + [RefreshTokenService::class] + ) + ->will( + $this->onConsecutiveCalls( + $this->createMock(AuthorizationCodeService::class), + $this->createMock(AccessTokenService::class), + $this->createMock(RefreshTokenService::class), + ) + ); $factory = new AuthorizationGrantFactory(); $service = $factory($container); diff --git a/tests/src/Container/AuthorizationRequestMiddlewareFactoryTest.php b/test/src/Container/AuthorizationRequestMiddlewareFactoryTest.php similarity index 82% rename from tests/src/Container/AuthorizationRequestMiddlewareFactoryTest.php rename to test/src/Container/AuthorizationRequestMiddlewareFactoryTest.php index a01c312..4bdeb1e 100644 --- a/tests/src/Container/AuthorizationRequestMiddlewareFactoryTest.php +++ b/test/src/Container/AuthorizationRequestMiddlewareFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Container\AuthorizationRequestMiddlewareFactory */ @@ -38,14 +38,16 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) - ->method('get') - ->with(AuthorizationServerInterface::class) - ->willReturn($this->createMock(AuthorizationServerInterface::class)); - $container->expects($this->at(1)) + $container + ->expects($this->exactly(2)) ->method('get') - ->with(ServerOptions::class) - ->willReturn(ServerOptions::fromArray()); + ->withConsecutive([AuthorizationServerInterface::class], [ServerOptions::class]) + ->will( + $this->onConsecutiveCalls( + $this->createMock(AuthorizationServerInterface::class), + ServerOptions::fromArray(), + ) + ); $factory = new AuthorizationRequestMiddlewareFactory(); $service = $factory($container); diff --git a/tests/src/Container/AuthorizationServerFactoryTest.php b/test/src/Container/AuthorizationServerFactoryTest.php similarity index 65% rename from tests/src/Container/AuthorizationServerFactoryTest.php rename to test/src/Container/AuthorizationServerFactoryTest.php index 05d4514..8e30804 100644 --- a/tests/src/Container/AuthorizationServerFactoryTest.php +++ b/test/src/Container/AuthorizationServerFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\AuthorizationServerFactory */ class AuthorizationServerFactoryTest extends TestCase { public function testCanCreateFromFactory(): void { - $container = $this->createMock(ContainerInterface::class); + $container = $this->createMock(ContainerInterface::class); $serverOptions = ServerOptions::fromArray(['grants' => ['MyGrant']]); - $container->expects($this->at(0)) - ->method('get') - ->with(ClientService::class) - ->willReturn($this->createMock(ClientService::class)); - - $container->expects($this->at(1)) - ->method('get') - ->with(ServerOptions::class) - ->willReturn($serverOptions); - - $container->expects($this->at(2)) - ->method('get') - ->with('MyGrant') - ->willReturn($this->createMock(GrantInterface::class)); - - $container->expects($this->at(3)) - ->method('get') - ->with(AccessTokenService::class) - ->willReturn($this->createMock(AccessTokenService::class)); - - $container->expects($this->at(4)) + $container + ->expects($this->exactly(5)) ->method('get') - ->with(RefreshTokenService::class) - ->willReturn($this->createMock(RefreshTokenService::class)); + ->withConsecutive( + [ClientService::class], + [ServerOptions::class], + ['MyGrant'], + [AccessTokenService::class], + [RefreshTokenService::class] + ) + ->will( + $this->onConsecutiveCalls( + $this->createMock(ClientService::class), + $serverOptions, + $this->createMock(GrantInterface::class), + $this->createMock(AccessTokenService::class), + $this->createMock(RefreshTokenService::class), + ) + ); $factory = new AuthorizationServerFactory(); $service = $factory($container); diff --git a/tests/src/Container/ClientCredentialsGrantFactoryTest.php b/test/src/Container/ClientCredentialsGrantFactoryTest.php similarity index 94% rename from tests/src/Container/ClientCredentialsGrantFactoryTest.php rename to test/src/Container/ClientCredentialsGrantFactoryTest.php index 25b8db5..68b8c20 100644 --- a/tests/src/Container/ClientCredentialsGrantFactoryTest.php +++ b/test/src/Container/ClientCredentialsGrantFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\ClientCredentialsGrantFactory */ class ClientCredentialsGrantFactoryTest extends TestCase @@ -38,7 +37,7 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) + $container->expects($this->once()) ->method('get') ->with(AccessTokenService::class) ->willReturn($this->createMock(AccessTokenService::class)); diff --git a/tests/src/Container/ClientServiceFactoryTest.php b/test/src/Container/ClientServiceFactoryTest.php similarity index 94% rename from tests/src/Container/ClientServiceFactoryTest.php rename to test/src/Container/ClientServiceFactoryTest.php index 7282e88..814b1ab 100644 --- a/tests/src/Container/ClientServiceFactoryTest.php +++ b/test/src/Container/ClientServiceFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\ClientServiceFactory */ class ClientServiceFactoryTest extends TestCase @@ -38,7 +37,7 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) + $container->expects($this->once()) ->method('get') ->with(ClientRepositoryInterface::class) ->willReturn($this->createMock(ClientRepositoryInterface::class)); diff --git a/tests/src/Container/PasswordGrantFactoryTest.php b/test/src/Container/PasswordGrantFactoryTest.php similarity index 59% rename from tests/src/Container/PasswordGrantFactoryTest.php rename to test/src/Container/PasswordGrantFactoryTest.php index afb6214..4378d82 100644 --- a/tests/src/Container/PasswordGrantFactoryTest.php +++ b/test/src/Container/PasswordGrantFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\PasswordGrantFactory */ class PasswordGrantFactoryTest extends TestCase @@ -39,24 +38,21 @@ class PasswordGrantFactoryTest extends TestCase public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $callable = function () { + $callable = function () { }; - $options = ServerOptions::fromArray(['owner_callable' => $callable]); - - $container->expects($this->at(0)) - ->method('get') - ->with(ServerOptions::class) - ->willReturn($options); - - $container->expects($this->at(1)) - ->method('get') - ->with(AccessTokenService::class) - ->willReturn($this->createMock(AccessTokenService::class)); + $options = ServerOptions::fromArray(['owner_callable' => $callable]); - $container->expects($this->at(2)) + $container + ->expects($this->exactly(3)) ->method('get') - ->with(RefreshTokenService::class) - ->willReturn($this->createMock(RefreshTokenService::class)); + ->withConsecutive([ServerOptions::class], [AccessTokenService::class], [RefreshTokenService::class]) + ->will( + $this->onConsecutiveCalls( + $options, + $this->createMock(AccessTokenService::class), + $this->createMock(RefreshTokenService::class) + ) + ); $factory = new PasswordGrantFactory(); $service = $factory($container); @@ -67,29 +63,27 @@ public function testCanCreateFromFactory(): void public function testCanCreateFromFactoryOwnerCallableOptionsIsString(): void { $container = $this->createMock(ContainerInterface::class); - $callable = function () { + $callable = function () { }; - $options = ServerOptions::fromArray(['owner_callable' => 'service_name']); - - $container->expects($this->at(0)) - ->method('get') - ->with(ServerOptions::class) - ->willReturn($options); - - $container->expects($this->at(1)) - ->method('get') - ->with('service_name') - ->willReturn($callable); - - $container->expects($this->at(2)) - ->method('get') - ->with(AccessTokenService::class) - ->willReturn($this->createMock(AccessTokenService::class)); + $options = ServerOptions::fromArray(['owner_callable' => 'service_name']); - $container->expects($this->at(3)) + $container + ->expects($this->exactly(4)) ->method('get') - ->with(RefreshTokenService::class) - ->willReturn($this->createMock(RefreshTokenService::class)); + ->withConsecutive( + [ServerOptions::class], + ['service_name'], + [AccessTokenService::class], + [RefreshTokenService::class] + ) + ->will( + $this->onConsecutiveCalls( + $options, + $callable, + $this->createMock(AccessTokenService::class), + $this->createMock(RefreshTokenService::class) + ) + ); $factory = new PasswordGrantFactory(); $service = $factory($container); diff --git a/tests/src/Container/RefreshTokenGrantFactoryTest.php b/test/src/Container/RefreshTokenGrantFactoryTest.php similarity index 75% rename from tests/src/Container/RefreshTokenGrantFactoryTest.php rename to test/src/Container/RefreshTokenGrantFactoryTest.php index 25cbe86..120ee1d 100644 --- a/tests/src/Container/RefreshTokenGrantFactoryTest.php +++ b/test/src/Container/RefreshTokenGrantFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\RefreshTokenGrantFactory */ class RefreshTokenGrantFactoryTest extends TestCase @@ -40,20 +39,17 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) - ->method('get') - ->with(ServerOptions::class) - ->willReturn(ServerOptions::fromArray()); - - $container->expects($this->at(1)) - ->method('get') - ->with(AccessTokenService::class) - ->willReturn($this->createMock(AccessTokenService::class)); - - $container->expects($this->at(2)) + $container + ->expects($this->exactly(3)) ->method('get') - ->with(RefreshTokenService::class) - ->willReturn($this->createMock(RefreshTokenService::class)); + ->withConsecutive([ServerOptions::class], [AccessTokenService::class], [RefreshTokenService::class]) + ->will( + $this->onConsecutiveCalls( + ServerOptions::fromArray(), + $this->createMock(AccessTokenService::class), + $this->createMock(RefreshTokenService::class) + ) + ); $factory = new RefreshTokenGrantFactory(); $service = $factory($container); diff --git a/tests/src/Container/RefreshTokenServiceFactoryTest.php b/test/src/Container/RefreshTokenServiceFactoryTest.php similarity index 76% rename from tests/src/Container/RefreshTokenServiceFactoryTest.php rename to test/src/Container/RefreshTokenServiceFactoryTest.php index a6abbe8..62b4ba1 100644 --- a/tests/src/Container/RefreshTokenServiceFactoryTest.php +++ b/test/src/Container/RefreshTokenServiceFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Container\RefreshTokenServiceFactory */ @@ -41,20 +41,17 @@ public function testCanCreateFromFactory(): void $serverOptions = ServerOptions::fromArray(); - $container->expects($this->at(0)) - ->method('get') - ->with(ServerOptions::class) - ->willReturn($serverOptions); - - $container->expects($this->at(1)) - ->method('get') - ->with(RefreshTokenRepositoryInterface::class) - ->willReturn($this->createMock(RefreshTokenRepositoryInterface::class)); - - $container->expects($this->at(2)) + $container + ->expects($this->exactly(3)) ->method('get') - ->with(ScopeService::class) - ->willReturn($this->createMock(ScopeService::class)); + ->withConsecutive([ServerOptions::class], [RefreshTokenRepositoryInterface::class], [ScopeService::class]) + ->will( + $this->onConsecutiveCalls( + $serverOptions, + $this->createMock(RefreshTokenRepositoryInterface::class), + $this->createMock(ScopeService::class) + ) + ); $factory = new RefreshTokenServiceFactory(); $service = $factory($container); diff --git a/tests/src/Container/ResourceServerFactoryTest.php b/test/src/Container/ResourceServerFactoryTest.php similarity index 93% rename from tests/src/Container/ResourceServerFactoryTest.php rename to test/src/Container/ResourceServerFactoryTest.php index 0456d2b..512e285 100644 --- a/tests/src/Container/ResourceServerFactoryTest.php +++ b/test/src/Container/ResourceServerFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\ResourceServerFactory */ class ResourceServerFactoryTest extends TestCase { public function testCanCreateFromFactory(): void { - $container = $this->createMock(ContainerInterface::class); + $container = $this->createMock(ContainerInterface::class); $tokenService = $this->createMock(AccessTokenService::class); $container->expects($this->once()) diff --git a/tests/src/Container/ResourceServerMiddlewareFactoryTest.php b/test/src/Container/ResourceServerMiddlewareFactoryTest.php similarity index 82% rename from tests/src/Container/ResourceServerMiddlewareFactoryTest.php rename to test/src/Container/ResourceServerMiddlewareFactoryTest.php index 7117253..2d06e40 100644 --- a/tests/src/Container/ResourceServerMiddlewareFactoryTest.php +++ b/test/src/Container/ResourceServerMiddlewareFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Container\ResourceServerMiddlewareFactory */ @@ -38,15 +38,16 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) - ->method('get') - ->with(ResourceServerInterface::class) - ->willReturn($this->createMock(ResourceServerInterface::class)); - - $container->expects($this->at(1)) + $container + ->expects($this->exactly(2)) ->method('get') - ->with(ServerOptions::class) - ->willReturn(ServerOptions::fromArray()); + ->withConsecutive([ResourceServerInterface::class], [ServerOptions::class]) + ->will( + $this->onConsecutiveCalls( + $this->createMock(ResourceServerInterface::class), + ServerOptions::fromArray() + ) + ); $factory = new ResourceServerMiddlewareFactory(); $service = $factory($container); diff --git a/tests/src/Container/RevocationRequestMiddlewareFactoryTest.php b/test/src/Container/RevocationRequestMiddlewareFactoryTest.php similarity index 95% rename from tests/src/Container/RevocationRequestMiddlewareFactoryTest.php rename to test/src/Container/RevocationRequestMiddlewareFactoryTest.php index 4658496..40c08aa 100644 --- a/tests/src/Container/RevocationRequestMiddlewareFactoryTest.php +++ b/test/src/Container/RevocationRequestMiddlewareFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Container\RevocationRequestMiddlewareFactory */ @@ -37,7 +37,7 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) + $container->expects($this->once()) ->method('get') ->with(AuthorizationServerInterface::class) ->willReturn($this->createMock(AuthorizationServerInterface::class)); diff --git a/tests/src/Container/ScopeServiceFactoryTest.php b/test/src/Container/ScopeServiceFactoryTest.php similarity index 94% rename from tests/src/Container/ScopeServiceFactoryTest.php rename to test/src/Container/ScopeServiceFactoryTest.php index 6fb9c6e..d1435aa 100644 --- a/tests/src/Container/ScopeServiceFactoryTest.php +++ b/test/src/Container/ScopeServiceFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\ScopeServiceFactory */ class ScopeServiceFactoryTest extends TestCase @@ -38,7 +37,7 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) + $container->expects($this->once()) ->method('get') ->with(ScopeRepositoryInterface::class) ->willReturn($this->createMock(ScopeRepositoryInterface::class)); diff --git a/tests/src/Container/ServerOptionsFactoryTest.php b/test/src/Container/ServerOptionsFactoryTest.php similarity index 94% rename from tests/src/Container/ServerOptionsFactoryTest.php rename to test/src/Container/ServerOptionsFactoryTest.php index 8e183a5..b0358a4 100644 --- a/tests/src/Container/ServerOptionsFactoryTest.php +++ b/test/src/Container/ServerOptionsFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\ServerOptionsFactory */ class ServerOptionsFactoryTest extends TestCase @@ -37,7 +36,7 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) + $container->expects($this->once()) ->method('get') ->with('config') ->willReturn(['zfr_oauth2_server' => []]); diff --git a/tests/src/Container/TokenRequestMiddlewareFactoryTest.php b/test/src/Container/TokenRequestMiddlewareFactoryTest.php similarity index 95% rename from tests/src/Container/TokenRequestMiddlewareFactoryTest.php rename to test/src/Container/TokenRequestMiddlewareFactoryTest.php index 871bea9..265ebf2 100644 --- a/tests/src/Container/TokenRequestMiddlewareFactoryTest.php +++ b/test/src/Container/TokenRequestMiddlewareFactoryTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Container\TokenRequestMiddlewareFactory */ class TokenRequestMiddlewareFactoryTest extends TestCase @@ -38,7 +37,7 @@ public function testCanCreateFromFactory(): void { $container = $this->createMock(ContainerInterface::class); - $container->expects($this->at(0)) + $container->expects($this->once()) ->method('get') ->with(AuthorizationServerInterface::class) ->willReturn($this->createMock(AuthorizationServerInterface::class)); diff --git a/tests/src/Exception/InvalidAccessTokenExceptionTest.php b/test/src/Exception/InvalidAccessTokenExceptionTest.php similarity index 97% rename from tests/src/Exception/InvalidAccessTokenExceptionTest.php rename to test/src/Exception/InvalidAccessTokenExceptionTest.php index 7227b88..5d41046 100644 --- a/tests/src/Exception/InvalidAccessTokenExceptionTest.php +++ b/test/src/Exception/InvalidAccessTokenExceptionTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Exception\InvalidAccessTokenException */ diff --git a/tests/src/Exception/OAuth2ExceptionTest.php b/test/src/Exception/OAuth2ExceptionTest.php similarity index 98% rename from tests/src/Exception/OAuth2ExceptionTest.php rename to test/src/Exception/OAuth2ExceptionTest.php index 0d16443..514f9e3 100644 --- a/tests/src/Exception/OAuth2ExceptionTest.php +++ b/test/src/Exception/OAuth2ExceptionTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Exception\OAuth2Exception */ diff --git a/tests/src/Grant/AbstractGrantTest.php b/test/src/Grant/AbstractGrantTest.php similarity index 84% rename from tests/src/Grant/AbstractGrantTest.php rename to test/src/Grant/AbstractGrantTest.php index d20e5bb..08caba8 100644 --- a/tests/src/Grant/AbstractGrantTest.php +++ b/test/src/Grant/AbstractGrantTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Grant\AbstractGrant */ @@ -49,10 +49,13 @@ public function testMethodGetResponseType(): void /** * @dataProvider dpMethodPrepareTokenResponse */ - public function testMethodPrepareTokenResponse(?RefreshToken $refreshToken, bool $useRefreshTokenScopes, ?TokenOwnerInterface $getOwner): void - { + public function testMethodPrepareTokenResponse( + ?RefreshToken $refreshToken, + bool $useRefreshTokenScopes, + ?TokenOwnerInterface $getOwner + ): void { $abstractGrant = $this->getMockForAbstractClass(AbstractGrant::class); - $accessToken = $this->createMock(AccessToken::class); + $accessToken = $this->createMock(AccessToken::class); $accessToken->expects($this->once())->method('getOwner')->willReturn($getOwner); $accessToken->expects($this->once())->method('getExpiresIn'); @@ -72,11 +75,14 @@ public function testMethodPrepareTokenResponse(?RefreshToken $refreshToken, bool } // calling protected method from abstract token scope - $protectedBound = (function ($accessToken, $refreshToken, $useRefreshTokenScopes) { - return $this->prepareTokenResponse($accessToken, $refreshToken, $useRefreshTokenScopes); - })->bindTo($abstractGrant, $abstractGrant); + $protectedBound = (fn ($accessToken, $refreshToken, $useRefreshTokenScopes) + => $this->prepareTokenResponse($accessToken, $refreshToken, $useRefreshTokenScopes)) + ->bindTo($abstractGrant, $abstractGrant); - $this->assertInstanceOf(ResponseInterface::class, $protectedBound($accessToken, $refreshToken, $useRefreshTokenScopes)); + $this->assertInstanceOf( + ResponseInterface::class, + $protectedBound($accessToken, $refreshToken, $useRefreshTokenScopes) + ); } public function dpMethodPrepareTokenResponse(): array diff --git a/tests/src/Grant/AuthorizationGrantTest.php b/test/src/Grant/AuthorizationGrantTest.php similarity index 64% rename from tests/src/Grant/AuthorizationGrantTest.php rename to test/src/Grant/AuthorizationGrantTest.php index de59d6c..21a9f36 100644 --- a/tests/src/Grant/AuthorizationGrantTest.php +++ b/test/src/Grant/AuthorizationGrantTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Grant\AuthorizationGrant */ @@ -46,33 +53,34 @@ class AuthorizationGrantTest extends TestCase { use PHPMock; - /** - * @var AuthorizationCodeService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var AuthorizationCodeService|MockObject */ protected $authorizationCodeService; - /** - * @var AccessTokenService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var AccessTokenService|MockObject */ protected $accessTokenService; - /** - * @var RefreshTokenService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var RefreshTokenService|MockObject */ protected $refreshTokenService; - /** - * @var AuthorizationGrant - */ + /** @var AuthorizationGrant */ protected $grant; public function setUp(): void { $this->authorizationCodeService = $this->createMock(AuthorizationCodeService::class); - $this->accessTokenService = $this->createMock(AccessTokenService::class); - $this->refreshTokenService = $this->createMock(RefreshTokenService::class); + $this->accessTokenService = $this->createMock(AccessTokenService::class); + $this->refreshTokenService = $this->createMock(RefreshTokenService::class); + + $this->grant = new AuthorizationGrant( + $this->authorizationCodeService, + $this->accessTokenService, + $this->refreshTokenService + ); + } - $this->grant = new AuthorizationGrant($this->authorizationCodeService, $this->accessTokenService, $this->refreshTokenService); + public function tearDown(): void + { + Carbon::setTestNow(); } public function testAssertInvalidIfWrongResponseType(): void @@ -80,7 +88,9 @@ public function testAssertInvalidIfWrongResponseType(): void $this->expectException(OAuth2Exception::class, null, 'invalid_request'); $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getQueryParams')->will($this->returnValue(['response_type' => 'foo'])); + $request->expects($this->once()) + ->method('getQueryParams') + ->will($this->returnValue(['response_type' => 'foo'])); $this->grant->createAuthorizationResponse($request, Client::createNewClient('id', 'http://www.example.com')); } @@ -90,12 +100,20 @@ public function testCanCreateAuthorizationCodeUsingClientRedirectUri(): void $queryParams = ['response_type' => 'code', 'scope' => '', 'state' => 'xyz']; $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getQueryParams')->will($this->returnValue($queryParams)); + $request->expects($this->once()) + ->method('getQueryParams') + ->will($this->returnValue($queryParams)); $token = $this->getValidAuthorizationCode(); - $this->authorizationCodeService->expects($this->once())->method('createToken')->will($this->returnValue($token)); + $this->authorizationCodeService + ->expects($this->once()) + ->method('createToken') + ->will($this->returnValue($token)); - $response = $this->grant->createAuthorizationResponse($request, Client::createNewClient('name', 'http://www.example.com')); + $response = $this->grant->createAuthorizationResponse( + $request, + Client::createNewClient('name', 'http://www.example.com') + ); $location = $response->getHeaderLine('Location'); $this->assertEquals('http://www.example.com?code=azerty_auth&state=xyz', $location); @@ -105,24 +123,27 @@ public function testCanCreateAuthorizationCodeUsingOverriddenRedirectUriInList() { $queryParams = [ 'response_type' => 'code', - 'scope' => '', - 'state' => 'xyz', - 'redirect_uri' => 'http://www.custom-example.com', + 'scope' => '', + 'state' => 'xyz', + 'redirect_uri' => 'http://www.custom-example.com', ]; $request = $this->createMock(ServerRequestInterface::class); $request->expects($this->once())->method('getQueryParams')->will($this->returnValue($queryParams)); $token = $this->getValidAuthorizationCode(); - $this->authorizationCodeService->expects($this->once())->method('createToken')->will($this->returnValue($token)); + $this->authorizationCodeService + ->expects($this->once()) + ->method('createToken') + ->will($this->returnValue($token)); $client = Client::reconstitute( [ - 'id' => 'id', - 'name' => 'name', - 'secret' => '', + 'id' => 'id', + 'name' => 'name', + 'secret' => '', 'redirectUris' => ['http://www.example.com', 'http://www.custom-example.com'], - 'scopes' => [], + 'scopes' => [], ] ); @@ -138,16 +159,21 @@ public function testTriggerExceptionIfCustomRedirectUriIsNotAuthorized(): void $queryParams = [ 'response_type' => 'code', - 'scope' => '', - 'state' => 'xyz', - 'redirect_uri' => 'http://www.custom-example.com', + 'scope' => '', + 'state' => 'xyz', + 'redirect_uri' => 'http://www.custom-example.com', ]; $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getQueryParams')->will($this->returnValue($queryParams)); + $request->expects($this->once()) + ->method('getQueryParams') + ->will($this->returnValue($queryParams)); $token = $this->getValidAuthorizationCode(); - $this->authorizationCodeService->expects($this->never())->method('createToken')->will($this->returnValue($token)); + $this->authorizationCodeService + ->expects($this->never()) + ->method('createToken') + ->will($this->returnValue($token)); $this->grant->createAuthorizationResponse($request, Client::createNewClient('name', 'http://www.example.com')); } @@ -198,14 +224,14 @@ public function testInvalidRequestIfAuthClientIsNotSame(): void $request = $this->createMock(ServerRequestInterface::class); $request->expects($this->once())->method('getParsedBody')->willReturn(['code' => '123', 'client_id' => 'foo']); - $token = $this->getValidAuthorizationCode(null, null, CLient::createNewClient('id', 'http://www.example.com')); + $token = $this->getValidAuthorizationCode(null, null, Client::createNewClient('id', 'http://www.example.com')); $this->authorizationCodeService->expects($this->once()) ->method('getToken') ->with('123') ->will($this->returnValue($token)); - $this->grant->createTokenResponse($request, CLient::createNewClient('id', 'http://www.example.com')); + $this->grant->createTokenResponse($request, Client::createNewClient('id', 'http://www.example.com')); } public function hasRefreshGrant(): array @@ -221,24 +247,24 @@ public function hasRefreshGrant(): array */ public function testCanCreateTokenResponse(bool $hasRefreshGrant): void { - $time = $this->getFunctionMock('ZfrOAuth2\Server\Model', 'time'); - $time->expects($this->any())->willReturn(10000); + Carbon::setTestNow('1970-01-01 02:46:40'); $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getParsedBody')->willReturn(['code' => '123', - 'client_id' => 'client_123', + $request->expects($this->once())->method('getParsedBody')->willReturn([ + 'code' => '123', + 'client_id' => 'client_123', ]); $client = Client::reconstitute( [ - 'id' => 'client_123', - 'name' => 'name', - 'secret' => '', + 'id' => 'client_123', + 'name' => 'name', + 'secret' => '', 'redirectUris' => [], - 'scopes' => [], + 'scopes' => [], ] ); - $token = $this->getValidAuthorizationCode(null, null, $client); + $token = $this->getValidAuthorizationCode(null, null, $client); $this->authorizationCodeService->expects($this->once()) ->method('getToken') @@ -249,11 +275,17 @@ public function testCanCreateTokenResponse(bool $hasRefreshGrant): void $owner->expects($this->once())->method('getTokenOwnerId')->will($this->returnValue(1)); $accessToken = $this->getValidAccessToken($owner); - $this->accessTokenService->expects($this->once())->method('createToken')->will($this->returnValue($accessToken)); + $this->accessTokenService + ->expects($this->once()) + ->method('createToken') + ->will($this->returnValue($accessToken)); if ($hasRefreshGrant) { $refreshToken = $this->getValidRefreshToken(); - $this->refreshTokenService->expects($this->once())->method('createToken')->will($this->returnValue($refreshToken)); + $this->refreshTokenService + ->expects($this->once()) + ->method('createToken') + ->will($this->returnValue($refreshToken)); } $authorizationServer = $this->createMock(AuthorizationServer::class); @@ -271,7 +303,7 @@ public function testCanCreateTokenResponse(bool $hasRefreshGrant): void $response = $this->grant->createTokenResponse($request, $client, $owner); - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); $this->assertEquals('azerty_access', $body['access_token']); $this->assertEquals('Bearer', $body['token_type']); @@ -284,62 +316,62 @@ public function testCanCreateTokenResponse(bool $hasRefreshGrant): void } } - private function getValidRefreshToken(TokenOwnerInterface $owner = null, array $scopes = null): RefreshToken + private function getValidRefreshToken(?TokenOwnerInterface $owner = null, ?array $scopes = null): RefreshToken { - $validDate = (new \DateTimeImmutable('@10000'))->add(new DateInterval('P1D')); - $token = RefreshToken::reconstitute([ - 'token' => 'azerty_refresh', - 'owner' => $owner, - 'client' => null, - 'scopes' => $scopes ?? ['read'], + $validDate = (new DateTimeImmutable('@10000'))->add(new DateInterval('P1D')); + return RefreshToken::reconstitute([ + 'token' => 'azerty_refresh', + 'owner' => $owner, + 'client' => null, + 'scopes' => $scopes ?? ['read'], 'expiresAt' => $validDate, ]); - - return $token; } - private function getValidAccessToken(TokenOwnerInterface $owner = null, array $scopes = null): AccessToken + private function getValidAccessToken(?TokenOwnerInterface $owner = null, ?array $scopes = null): AccessToken { - $validDate = (new \DateTimeImmutable('@10000'))->add(new DateInterval('PT1H')); - $token = AccessToken::reconstitute([ - 'token' => 'azerty_access', - 'owner' => $owner, - 'client' => null, - 'scopes' => $scopes ?? ['read'], + $validDate = (new DateTimeImmutable('@10000'))->add(new DateInterval('PT1H')); + return AccessToken::reconstitute([ + 'token' => 'azerty_access', + 'owner' => $owner, + 'client' => null, + 'scopes' => $scopes ?? ['read'], 'expiresAt' => $validDate, ]); - - return $token; } - private function getInvalidAuthorizationCode($redirectUri = null, $owner = null, $client = null, $scopes = null): AuthorizationCode - { - $invalidDate = (new \DateTimeImmutable('@10000'))->sub(new DateInterval('PT1H')); - $token = AuthorizationCode::reconstitute([ - 'token' => 'azerty_auth', - 'owner' => $owner, - 'client' => $client, - 'scopes' => $scopes ?? ['read'], - 'expiresAt' => $invalidDate, + private function getInvalidAuthorizationCode( + ?string $redirectUri = null, + ?string $owner = null, + ?string $client = null, + ?array $scopes = null + ): AuthorizationCode { + $invalidDate = (new DateTimeImmutable('@10000'))->sub(new DateInterval('PT1H')); + return AuthorizationCode::reconstitute([ + 'token' => 'azerty_auth', + 'owner' => $owner, + 'client' => $client, + 'scopes' => $scopes ?? ['read'], + 'expiresAt' => $invalidDate, 'redirectUri' => $redirectUri ?? '', ]); - - return $token; } - private function getValidAuthorizationCode($redirectUri = null, $owner = null, $client = null, $scopes = null): AuthorizationCode - { - $validDate = (new \DateTimeImmutable('@10000'))->add(new DateInterval('PT1H')); - $token = AuthorizationCode::reconstitute([ - 'token' => 'azerty_auth', - 'owner' => $owner, - 'client' => $client, - 'scopes' => $scopes ?? ['read'], - 'expiresAt' => $validDate, + private function getValidAuthorizationCode( + ?string $redirectUri = null, + ?string $owner = null, + ?Client $client = null, + ?array $scopes = null + ): AuthorizationCode { + $validDate = (new DateTimeImmutable('@10000'))->add(new DateInterval('PT1H')); + return AuthorizationCode::reconstitute([ + 'token' => 'azerty_auth', + 'owner' => $owner, + 'client' => $client, + 'scopes' => $scopes ?? ['read'], + 'expiresAt' => $validDate, 'redirectUri' => $redirectUri ?? '', ]); - - return $token; } public function testMethodGetType(): void diff --git a/tests/src/Grant/ClientCredentialsGrantTest.php b/test/src/Grant/ClientCredentialsGrantTest.php similarity index 79% rename from tests/src/Grant/ClientCredentialsGrantTest.php rename to test/src/Grant/ClientCredentialsGrantTest.php index bc5994b..431fce2 100644 --- a/tests/src/Grant/ClientCredentialsGrantTest.php +++ b/test/src/Grant/ClientCredentialsGrantTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Grant\ClientCredentialsGrant */ @@ -40,20 +47,21 @@ class ClientCredentialsGrantTest extends TestCase { use PHPMock; - /** - * @var AccessTokenService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var AccessTokenService|MockObject */ protected $tokenService; - /** - * @var ClientCredentialsGrant - */ + /** @var ClientCredentialsGrant */ protected $grant; public function setUp(): void { $this->tokenService = $this->createMock(AccessTokenService::class); - $this->grant = new ClientCredentialsGrant($this->tokenService); + $this->grant = new ClientCredentialsGrant($this->tokenService); + } + + public function tearDown(): void + { + Carbon::setTestNow(); } public function testAssertDoesNotImplementAuthorization() @@ -67,28 +75,27 @@ public function testAssertDoesNotImplementAuthorization() public function testCanCreateTokenResponse(): void { - $time = $this->getFunctionMock('ZfrOAuth2\Server\Model', 'time'); - $time->expects($this->any())->willReturn(10000); + Carbon::setTestNow('1970-01-01 02:46:40'); $request = $this->createMock(ServerRequestInterface::class); $client = Client::createNewClient('name', 'http://www.example.com'); - $owner = $this->createMock(TokenOwnerInterface::class); + $owner = $this->createMock(TokenOwnerInterface::class); $owner->expects($this->once())->method('getTokenOwnerId')->will($this->returnValue(1)); $token = AccessToken::reconstitute([ - 'token' => 'azerty', - 'owner' => $owner, - 'client' => null, - 'expiresAt' => (new \DateTimeImmutable('@10000'))->add(new DateInterval('PT1H')), - 'scopes' => [], + 'token' => 'azerty', + 'owner' => $owner, + 'client' => null, + 'expiresAt' => (new DateTimeImmutable('@10000'))->add(new DateInterval('PT1H')), + 'scopes' => [], ]); $this->tokenService->expects($this->once())->method('createToken')->will($this->returnValue($token)); $response = $this->grant->createTokenResponse($request, $client, $owner); - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); $this->assertEquals('azerty', $body['access_token']); $this->assertEquals('Bearer', $body['token_type']); diff --git a/tests/src/Grant/PasswordGrantTest.php b/test/src/Grant/PasswordGrantTest.php similarity index 69% rename from tests/src/Grant/PasswordGrantTest.php rename to test/src/Grant/PasswordGrantTest.php index 857d29d..ef4739a 100644 --- a/tests/src/Grant/PasswordGrantTest.php +++ b/test/src/Grant/PasswordGrantTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Grant\PasswordGrant */ @@ -45,40 +51,40 @@ class PasswordGrantTest extends TestCase { use PHPMock; - /** - * @var AccessTokenService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var AccessTokenService|MockObject */ protected $accessTokenService; - /** - * @var RefreshTokenService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var RefreshTokenService|MockObject */ protected $refreshTokenService; - /** - * @var callable - */ + /** @var callable */ protected $callback; - /** - * @var PasswordGrant - */ + /** @var PasswordGrant */ protected $grant; public function setUp(): void { - $this->accessTokenService = $this->createMock(AccessTokenService::class); + $this->accessTokenService = $this->createMock(AccessTokenService::class); $this->refreshTokenService = $this->createMock(RefreshTokenService::class); - $callable = function () { + $callable = function () { }; $this->grant = new PasswordGrant($this->accessTokenService, $this->refreshTokenService, $callable); } + public function tearDown(): void + { + Carbon::setTestNow(); + } + public function testAssertDoesNotImplementAuthorization(): void { $this->expectException(OAuth2Exception::class, null, 'invalid_request'); - $this->grant->createAuthorizationResponse($this->createMock(ServerRequestInterface::class), Client::createNewClient('id', 'http://www.example.com')); + $this->grant->createAuthorizationResponse( + $this->createMock(ServerRequestInterface::class), + Client::createNewClient('id', 'http://www.example.com') + ); } public function testAssertInvalidIfNoUsernameNorPasswordIsFound(): void @@ -95,7 +101,9 @@ public function testAssertInvalidIfWrongCredentials(): void $this->expectException(OAuth2Exception::class, null, 'access_denied'); $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getParsedBody')->willReturn(['username' => 'michael', 'password' => 'azerty']); + $request->expects($this->once()) + ->method('getParsedBody') + ->willReturn(['username' => 'michael', 'password' => 'azerty']); $callable = function ($username, $password) { $this->assertEquals('michael', $username); @@ -122,25 +130,32 @@ public function hasRefreshGrant(): array */ public function testCanCreateTokenResponse(bool $hasRefreshGrant) { - $time = $this->getFunctionMock('ZfrOAuth2\Server\Model', 'time'); - $time->expects($this->any())->willReturn(10000); + Carbon::setTestNow('1970-01-01 02:46:40'); $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('getParsedBody')->willReturn(['username' => 'michael', 'password' => 'azerty', 'scope' => 'read']); + $request->expects($this->once()) + ->method('getParsedBody') + ->willReturn(['username' => 'michael', 'password' => 'azerty', 'scope' => 'read']); $owner = $this->createMock(TokenOwnerInterface::class); - $owner->expects($this->once())->method('getTokenOwnerId')->will($this->returnValue(1)); + $owner->expects($this->once()) + ->method('getTokenOwnerId') + ->will($this->returnValue(1)); - $callable = function ($username, $password) use ($owner) { - return $owner; - }; + $callable = fn($username, $password) => $owner; $accessToken = $this->getValidAccessToken($owner); - $this->accessTokenService->expects($this->once())->method('createToken')->will($this->returnValue($accessToken)); + $this->accessTokenService + ->expects($this->once()) + ->method('createToken') + ->will($this->returnValue($accessToken)); if ($hasRefreshGrant) { $refreshToken = $this->getValidRefreshToken(); - $this->refreshTokenService->expects($this->once())->method('createToken')->will($this->returnValue($refreshToken)); + $this->refreshTokenService + ->expects($this->once()) + ->method('createToken') + ->will($this->returnValue($refreshToken)); } $authorizationServer = $this->createMock(AuthorizationServer::class); @@ -152,9 +167,12 @@ public function testCanCreateTokenResponse(bool $hasRefreshGrant) $this->grant = new PasswordGrant($this->accessTokenService, $this->refreshTokenService, $callable); $this->grant->setAuthorizationServer($authorizationServer); - $response = $this->grant->createTokenResponse($request, Client::createNewClient('id', 'http://www.example.com')); + $response = $this->grant->createTokenResponse( + $request, + Client::createNewClient('id', 'http://www.example.com') + ); - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); $this->assertEquals('azerty_access', $body['access_token']); $this->assertEquals('Bearer', $body['token_type']); @@ -167,32 +185,28 @@ public function testCanCreateTokenResponse(bool $hasRefreshGrant) } } - private function getValidRefreshToken(TokenOwnerInterface $owner = null, array $scopes = null): RefreshToken + private function getValidRefreshToken(?TokenOwnerInterface $owner = null, ?array $scopes = null): RefreshToken { $validDate = (new DateTimeImmutable('@10000'))->add(new DateInterval('P1D')); - $token = RefreshToken::reconstitute([ - 'token' => 'azerty_refresh', - 'owner' => $owner, - 'client' => null, - 'scopes' => $scopes ?? ['read'], + return RefreshToken::reconstitute([ + 'token' => 'azerty_refresh', + 'owner' => $owner, + 'client' => null, + 'scopes' => $scopes ?? ['read'], 'expiresAt' => $validDate, ]); - - return $token; } - private function getValidAccessToken(TokenOwnerInterface $owner = null, array $scopes = null): AccessToken + private function getValidAccessToken(?TokenOwnerInterface $owner = null, ?array $scopes = null): AccessToken { $validDate = (new DateTimeImmutable('@10000'))->add(new DateInterval('PT1H')); - $token = AccessToken::reconstitute([ - 'token' => 'azerty_access', - 'owner' => $owner, - 'client' => null, - 'scopes' => $scopes ?? ['read'], + return AccessToken::reconstitute([ + 'token' => 'azerty_access', + 'owner' => $owner, + 'client' => null, + 'scopes' => $scopes ?? ['read'], 'expiresAt' => $validDate, ]); - - return $token; } public function testMethodGetType(): void diff --git a/tests/src/Grant/RefreshTokenGrantTest.php b/test/src/Grant/RefreshTokenGrantTest.php similarity index 66% rename from tests/src/Grant/RefreshTokenGrantTest.php rename to test/src/Grant/RefreshTokenGrantTest.php index 5529d6b..fd1e65e 100644 --- a/tests/src/Grant/RefreshTokenGrantTest.php +++ b/test/src/Grant/RefreshTokenGrantTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Grant\RefreshTokenGrant */ @@ -43,30 +50,33 @@ class RefreshTokenGrantTest extends TestCase { use PHPMock; - /** - * @var AccessTokenService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var AccessTokenService|MockObject */ protected $accessTokenService; - /** - * @var RefreshTokenService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var RefreshTokenService|MockObject */ protected $refreshTokenService; - /** - * @var RefreshTokenGrant - */ + /** @var RefreshTokenGrant */ protected $grant; public function setUp(): void { - $this->accessTokenService = $this->createMock(AccessTokenService::class); + $this->accessTokenService = $this->createMock(AccessTokenService::class); $this->refreshTokenService = $this->createMock(RefreshTokenService::class); } + public function tearDown(): void + { + Carbon::setTestNow(); + } + public function testAssertDoesNotImplementAuthorization(): void { - $grant = new RefreshTokenGrant($this->accessTokenService, $this->refreshTokenService, ServerOptions::fromArray()); + $grant = new RefreshTokenGrant( + $this->accessTokenService, + $this->refreshTokenService, + ServerOptions::fromArray() + ); $this->expectException(OAuth2Exception::class, null, 'invalid_request'); $grant->createAuthorizationResponse( @@ -77,7 +87,11 @@ public function testAssertDoesNotImplementAuthorization(): void public function testAssertInvalidIfNoRefreshTokenIsFound(): void { - $grant = new RefreshTokenGrant($this->accessTokenService, $this->refreshTokenService, ServerOptions::fromArray()); + $grant = new RefreshTokenGrant( + $this->accessTokenService, + $this->refreshTokenService, + ServerOptions::fromArray() + ); $request = $this->createMock(ServerRequestInterface::class); $request->expects($this->once())->method('getParsedBody')->willReturn([]); @@ -88,8 +102,6 @@ public function testAssertInvalidIfNoRefreshTokenIsFound(): void public function testAssertInvalidIfRefreshTokenIsExpired(): void { - $grant = new RefreshTokenGrant($this->accessTokenService, $this->refreshTokenService, ServerOptions::fromArray()); - $this->expectException(OAuth2Exception::class, null, 'invalid_grant'); $request = $this->createMock(ServerRequestInterface::class); @@ -102,22 +114,30 @@ public function testAssertInvalidIfRefreshTokenIsExpired(): void ->with('123') ->will($this->returnValue($refreshToken)); + $grant = new RefreshTokenGrant( + $this->accessTokenService, + $this->refreshTokenService, + ServerOptions::fromArray() + ); $grant->createTokenResponse($request, Client::createNewClient('name', [])); } public function testAssertExceptionIfAskedScopeIsSuperiorToRefreshToken(): void { - $time = $this->getFunctionMock('ZfrOAuth2\Server\Model', 'time'); - $time->expects($this->any())->willReturn(10000); + Carbon::setTestNow('1970-01-01 02:46:40'); - $grant = new RefreshTokenGrant($this->accessTokenService, $this->refreshTokenService, ServerOptions::fromArray()); + $grant = new RefreshTokenGrant( + $this->accessTokenService, + $this->refreshTokenService, + ServerOptions::fromArray() + ); $this->expectException(OAuth2Exception::class, null, 'invalid_scope'); $request = $this->createMock(ServerRequestInterface::class); $request->expects($this->once())->method('getParsedBody')->willReturn([ 'refresh_token' => '123', - 'scope' => 'read write', + 'scope' => 'read write', ]); $refreshToken = $this->getValidRefreshToken(null, ['read']); @@ -145,18 +165,17 @@ public function grantOptions(): array */ public function testCanCreateTokenResponse(bool $rotateRefreshToken, bool $revokeRotatedRefreshToken): void { - $time = $this->getFunctionMock('ZfrOAuth2\Server\Model', 'time'); - $time->expects($this->any())->willReturn(10000); + Carbon::setTestNow('1970-01-01 02:46:40'); $grant = new RefreshTokenGrant($this->accessTokenService, $this->refreshTokenService, ServerOptions::fromArray([ - 'rotate_refresh_tokens' => $rotateRefreshToken, + 'rotate_refresh_tokens' => $rotateRefreshToken, 'revoke_rotated_refresh_tokens' => $revokeRotatedRefreshToken, ])); $request = $this->createMock(ServerRequestInterface::class); $request->expects($this->once())->method('getParsedBody')->willReturn([ 'refresh_token' => '123', - 'scope' => 'read', + 'scope' => 'read', ]); $owner = $this->createMock(TokenOwnerInterface::class); @@ -174,15 +193,21 @@ public function testCanCreateTokenResponse(bool $rotateRefreshToken, bool $revok ->with($refreshToken); $refreshToken = $this->getValidRefreshToken(); - $this->refreshTokenService->expects($this->once())->method('createToken')->will($this->returnValue($refreshToken)); + $this->refreshTokenService + ->expects($this->once()) + ->method('createToken') + ->will($this->returnValue($refreshToken)); } $accessToken = $this->getValidAccessToken($owner); - $this->accessTokenService->expects($this->once())->method('createToken')->will($this->returnValue($accessToken)); + $this->accessTokenService + ->expects($this->once()) + ->method('createToken') + ->will($this->returnValue($accessToken)); $response = $grant->createTokenResponse($request, Client::createNewClient('name', [])); - $body = json_decode((string) $response->getBody(), true); + $body = json_decode((string) $response->getBody(), true, 512, JSON_THROW_ON_ERROR); $this->assertEquals('azerty_access', $body['access_token']); $this->assertEquals('Bearer', $body['token_type']); @@ -194,61 +219,67 @@ public function testCanCreateTokenResponse(bool $rotateRefreshToken, bool $revok private function getExpiredRefreshToken(): RefreshToken { - $validDate = (new \DateTimeImmutable('@10000'))->sub(new DateInterval('P1D')); - $token = RefreshToken::reconstitute([ - 'token' => 'azerty_refresh', - 'owner' => null, - 'client' => null, - 'scopes' => [], + $validDate = (new DateTimeImmutable('@10000'))->sub(new DateInterval('P1D')); + return RefreshToken::reconstitute([ + 'token' => 'azerty_refresh', + 'owner' => null, + 'client' => null, + 'scopes' => [], 'expiresAt' => $validDate, ]); - - return $token; } - private function getValidRefreshToken(TokenOwnerInterface $owner = null, array $scopes = null): RefreshToken + private function getValidRefreshToken(?TokenOwnerInterface $owner = null, ?array $scopes = null): RefreshToken { - $validDate = (new \DateTimeImmutable('@10000'))->add(new DateInterval('P1D')); - $token = RefreshToken::reconstitute([ - 'token' => 'azerty_refresh', - 'owner' => $owner, - 'client' => null, - 'scopes' => $scopes ?? ['read'], + $validDate = (new DateTimeImmutable('@10000'))->add(new DateInterval('P1D')); + return RefreshToken::reconstitute([ + 'token' => 'azerty_refresh', + 'owner' => $owner, + 'client' => null, + 'scopes' => $scopes ?? ['read'], 'expiresAt' => $validDate, ]); - - return $token; } - private function getValidAccessToken(TokenOwnerInterface $owner = null, array $scopes = null): AccessToken + private function getValidAccessToken(?TokenOwnerInterface $owner = null, ?array $scopes = null): AccessToken { - $validDate = (new \DateTimeImmutable('@10000'))->add(new DateInterval('PT1H')); - $token = AccessToken::reconstitute([ - 'token' => 'azerty_access', - 'owner' => $owner, - 'client' => null, - 'scopes' => $scopes ?? ['read'], + $validDate = (new DateTimeImmutable('@10000'))->add(new DateInterval('PT1H')); + return AccessToken::reconstitute([ + 'token' => 'azerty_access', + 'owner' => $owner, + 'client' => null, + 'scopes' => $scopes ?? ['read'], 'expiresAt' => $validDate, ]); - - return $token; } public function testMethodGetType(): void { - $grant = new RefreshTokenGrant($this->accessTokenService, $this->refreshTokenService, ServerOptions::fromArray()); + $grant = new RefreshTokenGrant( + $this->accessTokenService, + $this->refreshTokenService, + ServerOptions::fromArray() + ); $this->assertSame('refresh_token', $grant->getType()); } public function testMethodGetResponseType(): void { - $grant = new RefreshTokenGrant($this->accessTokenService, $this->refreshTokenService, ServerOptions::fromArray()); + $grant = new RefreshTokenGrant( + $this->accessTokenService, + $this->refreshTokenService, + ServerOptions::fromArray() + ); $this->assertSame('', $grant->getResponseType()); } public function testMethodAllowPublicClients(): void { - $grant = new RefreshTokenGrant($this->accessTokenService, $this->refreshTokenService, ServerOptions::fromArray()); + $grant = new RefreshTokenGrant( + $this->accessTokenService, + $this->refreshTokenService, + ServerOptions::fromArray() + ); $this->assertTrue($grant->allowPublicClients()); } } diff --git a/tests/src/Middleware/AuthorizationRequestMiddlewareTest.php b/test/src/Middleware/AuthorizationRequestMiddlewareTest.php similarity index 93% rename from tests/src/Middleware/AuthorizationRequestMiddlewareTest.php rename to test/src/Middleware/AuthorizationRequestMiddlewareTest.php index 48f8189..5c3bf16 100644 --- a/tests/src/Middleware/AuthorizationRequestMiddlewareTest.php +++ b/test/src/Middleware/AuthorizationRequestMiddlewareTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Middleware\AuthorizationRequestMiddleware */ @@ -37,7 +37,7 @@ class AuthorizationRequestMiddlewareTest extends TestCase public function testWillHandleAuthorizationRequest(): void { $authorizationServer = $this->createMock(AuthorizationServerInterface::class); - $middleware = new AuthorizationRequestMiddleware($authorizationServer, 'owner'); + $middleware = new AuthorizationRequestMiddleware($authorizationServer, 'owner'); $request = $this->createMock(RequestInterface::class); $handler = $this->createMock(RequestHandlerInterface::class); diff --git a/tests/src/Middleware/ResourceServerMiddlewareTest.php b/test/src/Middleware/ResourceServerMiddlewareTest.php similarity index 79% rename from tests/src/Middleware/ResourceServerMiddlewareTest.php rename to test/src/Middleware/ResourceServerMiddlewareTest.php index 233d4fc..4b0b78b 100644 --- a/tests/src/Middleware/ResourceServerMiddlewareTest.php +++ b/test/src/Middleware/ResourceServerMiddlewareTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Middleware\ResourceServerMiddleware */ @@ -40,11 +40,11 @@ class ResourceServerMiddlewareTest extends TestCase public function testWillGetAccessTokenWithAccessTokenAsResult(): void { $resourceServer = $this->createMock(ResourceServer::class); - $middleware = new ResourceServerMiddleware($resourceServer, 'oauth_token'); - $accessToken = $this->createMock(AccessToken::class); - $request = $this->createMock(RequestInterface::class); - $response = $this->createMock(ResponseInterface::class); - $handler = $this->createMock(RequestHandlerInterface::class); + $middleware = new ResourceServerMiddleware($resourceServer, 'oauth_token'); + $accessToken = $this->createMock(AccessToken::class); + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); + $handler = $this->createMock(RequestHandlerInterface::class); $handler->expects($this->once()) ->method('handle') @@ -70,11 +70,11 @@ public function testWillGetAccessTokenWithAccessTokenAsResult(): void public function testWillGetAccessTokenWithNullAsResult(): void { $resourceServer = $this->createMock(ResourceServer::class); - $middleware = new ResourceServerMiddleware($resourceServer, 'oauth_token'); - $accessToken = null; - $request = $this->createMock(RequestInterface::class); - $response = $this->createMock(ResponseInterface::class); - $handler = $this->createMock(RequestHandlerInterface::class); + $middleware = new ResourceServerMiddleware($resourceServer, 'oauth_token'); + $accessToken = null; + $request = $this->createMock(RequestInterface::class); + $response = $this->createMock(ResponseInterface::class); + $handler = $this->createMock(RequestHandlerInterface::class); $handler->expects($this->once()) ->method('handle') @@ -100,9 +100,9 @@ public function testWillGetAccessTokenWithNullAsResult(): void public function testWillCallGetAccessTokenWithException(): void { $resourceServer = $this->createMock(ResourceServer::class); - $middleware = new ResourceServerMiddleware($resourceServer, 'oauth_token'); - $request = $this->createMock(RequestInterface::class); - $handler = $this->createMock(RequestHandlerInterface::class); + $middleware = new ResourceServerMiddleware($resourceServer, 'oauth_token'); + $request = $this->createMock(RequestInterface::class); + $handler = $this->createMock(RequestHandlerInterface::class); $resourceServer->expects($this->once()) ->method('getAccessToken') diff --git a/tests/src/Middleware/RevocationRequestMiddlewareTest.php b/test/src/Middleware/RevocationRequestMiddlewareTest.php similarity index 84% rename from tests/src/Middleware/RevocationRequestMiddlewareTest.php rename to test/src/Middleware/RevocationRequestMiddlewareTest.php index a2d456d..c4927e0 100644 --- a/tests/src/Middleware/RevocationRequestMiddlewareTest.php +++ b/test/src/Middleware/RevocationRequestMiddlewareTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Middleware\RevocationRequestMiddleware */ class RevocationRequestMiddlewareTest extends TestCase { - /** - * @var \PHPUnit\Framework\MockObject\MockObject|AuthorizationServerInterface - */ + /** @var MockObject|AuthorizationServerInterface */ private $authorizationServer; - /** - * @var RevocationRequestMiddleware - */ - private $middleware; + private RevocationRequestMiddleware $middleware; public function setUp(): void { $this->authorizationServer = $this->createMock(AuthorizationServerInterface::class); - $this->middleware = new RevocationRequestMiddleware($this->authorizationServer); + $this->middleware = new RevocationRequestMiddleware($this->authorizationServer); } public function testCanHandleRevocationRequest(): void { - $request = $this->createMock(RequestInterface::class); + $request = $this->createMock(RequestInterface::class); $delegate = $this->createMock(RequestHandlerInterface::class); $this->authorizationServer->expects($this->once()) diff --git a/tests/src/Middleware/TokenRequestMiddlewareTest.php b/test/src/Middleware/TokenRequestMiddlewareTest.php similarity index 86% rename from tests/src/Middleware/TokenRequestMiddlewareTest.php rename to test/src/Middleware/TokenRequestMiddlewareTest.php index c9a5b87..794ec28 100644 --- a/tests/src/Middleware/TokenRequestMiddlewareTest.php +++ b/test/src/Middleware/TokenRequestMiddlewareTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Middleware\TokenRequestMiddleware */ class TokenRequestMiddlewareTest extends TestCase { - /** - * @var \PHPUnit\Framework\MockObject\MockObject|AuthorizationServerInterface - */ + /** @var MockObject|AuthorizationServerInterface */ private $authorizationServer; - /** - * @var TokenRequestMiddleware - */ - private $middleware; + private TokenRequestMiddleware $middleware; public function setUp(): void { $this->authorizationServer = $this->createMock(AuthorizationServerInterface::class); - $this->middleware = new TokenRequestMiddleware($this->authorizationServer); + $this->middleware = new TokenRequestMiddleware($this->authorizationServer); } public function testCanHandleTokenRequest(): void diff --git a/tests/src/Model/AbstractTokenTest.php b/test/src/Model/AbstractTokenTest.php similarity index 78% rename from tests/src/Model/AbstractTokenTest.php rename to test/src/Model/AbstractTokenTest.php index 0bae771..c740fe0 100644 --- a/tests/src/Model/AbstractTokenTest.php +++ b/test/src/Model/AbstractTokenTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Model\AbstractToken */ @@ -34,17 +35,17 @@ class AbstractTokenTest extends TestCase { public function setUp(): void { - $this->owner = $this->createMock(TokenOwnerInterface::class); - $this->client = $this->createMock(Client::class); - $this->expiresAt = (new \DateTime())->modify('+60 seconds'); - $this->scopes = ['somescope', 'otherscope']; + $this->owner = $this->createMock(TokenOwnerInterface::class); + $this->client = $this->createMock(Client::class); + $this->expiresAt = (new DateTime())->modify('+60 seconds'); + $this->scopes = ['somescope', 'otherscope']; $this->token = SomeToken::reconstitute([ - 'token' => 'a token', + 'token' => 'a token', 'expiresAt' => $this->expiresAt, - 'owner' => $this->owner, - 'client' => $this->client, - 'scopes' => $this->scopes, + 'owner' => $this->owner, + 'client' => $this->client, + 'scopes' => $this->scopes, ]); } @@ -65,7 +66,10 @@ public function testMethodGetClient(): void public function testMethodGetExpiresAt(): void { - $this->assertSame($this->expiresAt->format(\DateTime::ATOM), $this->token->getExpiresAt()->format(\DateTime::ATOM)); + $this->assertSame( + $this->expiresAt->format(DateTime::ATOM), + $this->token->getExpiresAt()->format(DateTime::ATOM) + ); } public function testMethodGetExpiresIn(): void @@ -102,14 +106,14 @@ public function testMethodIsValid(): void public function testMethodIsValidWithExpired(): void { // expired - $this->expiresAt = (new \DateTime())->modify('-60 seconds'); + $this->expiresAt = (new DateTime())->modify('-60 seconds'); $this->token = SomeToken::reconstitute([ - 'token' => 'a token', + 'token' => 'a token', 'expiresAt' => $this->expiresAt, - 'owner' => $this->owner, - 'client' => $this->client, - 'scopes' => $this->scopes, + 'owner' => $this->owner, + 'client' => $this->client, + 'scopes' => $this->scopes, ]); $this->assertFalse($this->token->isValid('somescope')); diff --git a/tests/src/Model/AccessTokenTest.php b/test/src/Model/AccessTokenTest.php similarity index 87% rename from tests/src/Model/AccessTokenTest.php rename to test/src/Model/AccessTokenTest.php index 512ecd8..c9f75f7 100644 --- a/tests/src/Model/AccessTokenTest.php +++ b/test/src/Model/AccessTokenTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Model\AbstractToken * @covers \ZfrOAuth2\Server\Model\AccessToken @@ -40,8 +44,12 @@ class AccessTokenTest extends TestCase /** * @dataProvider providerGenerateNewAccessToken */ - public function testGenerateNewAccessToken($ttl, $owner, $client, $scopes): void - { + public function testGenerateNewAccessToken( + int $ttl, + ?TokenOwnerInterface $owner, + ?Client $client, + ?array $scopes + ): void { /** @var AccessToken $accessToken */ $accessToken = AccessToken::createNewAccessToken($ttl, $owner, $client, $scopes); @@ -113,21 +121,21 @@ public function providerReconstitute(): array return [ [ [ - 'token' => 'token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), + 'token' => 'token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), 'expiresAt' => new DateTimeImmutable(), - 'scopes' => ['scope1', 'scope2'], + 'scopes' => ['scope1', 'scope2'], ], ], [ // test set - null values - [ - 'token' => 'token', - 'owner' => null, - 'client' => null, - 'expiresAt' => null, - 'scopes' => [], - ], + [ + 'token' => 'token', + 'owner' => null, + 'client' => null, + 'expiresAt' => null, + 'scopes' => [], + ], ], ]; } diff --git a/tests/src/Model/AuthorizationCodeTest.php b/test/src/Model/AuthorizationCodeTest.php similarity index 77% rename from tests/src/Model/AuthorizationCodeTest.php rename to test/src/Model/AuthorizationCodeTest.php index 63351ff..ba2eb8a 100644 --- a/tests/src/Model/AuthorizationCodeTest.php +++ b/test/src/Model/AuthorizationCodeTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Model\AbstractToken * @covers \ZfrOAuth2\Server\Model\AuthorizationCode @@ -58,7 +58,7 @@ public function providerGenerateNewAuthorizationCode(): array /** * @dataProvider providerReconstitute */ - public function testReconstitute($data) + public function testReconstitute(array $data) { /** @var AuthorizationCode $authorizationCode */ $authorizationCode = AuthorizationCode::reconstitute($data); @@ -66,26 +66,26 @@ public function testReconstitute($data) $this->assertSame($data['redirectUri'], $authorizationCode->getRedirectUri()); } - public function providerReconstitute() + public function providerReconstitute(): array { return [ [ [ - 'token' => 'token', - 'owner' => null, - 'client' => null, - 'expiresAt' => null, - 'scopes' => [], + 'token' => 'token', + 'owner' => null, + 'client' => null, + 'expiresAt' => null, + 'scopes' => [], 'redirectUri' => 'http://www.example.com', ], ], [ [ - 'token' => 'token', - 'owner' => null, - 'client' => null, - 'expiresAt' => null, - 'scopes' => [], + 'token' => 'token', + 'owner' => null, + 'client' => null, + 'expiresAt' => null, + 'scopes' => [], 'redirectUri' => '', ], ], @@ -115,13 +115,31 @@ public function testSupportLongLiveToken() public function testIsValid() { - $authorizationCode = AuthorizationCode::createNewAuthorizationCode(60, 'http://www.example.com', null, null, ['read', 'write']); + $authorizationCode = AuthorizationCode::createNewAuthorizationCode( + 60, + 'http://www.example.com', + null, + null, + ['read', 'write'] + ); $this->assertTrue($authorizationCode->isValid('read')); - $authorizationCode = AuthorizationCode::createNewAuthorizationCode(-60, 'http://www.example.com', null, null, ['read', 'write']); + $authorizationCode = AuthorizationCode::createNewAuthorizationCode( + -60, + 'http://www.example.com', + null, + null, + ['read', 'write'] + ); $this->assertFalse($authorizationCode->isValid('read')); - $authorizationCode = AuthorizationCode::createNewAuthorizationCode(60, 'http://www.example.com', null, null, ['read', 'write']); + $authorizationCode = AuthorizationCode::createNewAuthorizationCode( + 60, + 'http://www.example.com', + null, + null, + ['read', 'write'] + ); $this->assertFalse($authorizationCode->isValid('delete')); } @@ -130,7 +148,13 @@ public function testIsValid() */ public function testDoNotSupportLongLiveToken() { - $authorizationCode = AuthorizationCode::createNewAuthorizationCode(0, 'http://www.example.com', null, null, ['read', 'write']); + $authorizationCode = AuthorizationCode::createNewAuthorizationCode( + 0, + 'http://www.example.com', + null, + null, + ['read', 'write'] + ); $this->assertTrue($authorizationCode->isExpired()); } } diff --git a/tests/src/Model/ClientTest.php b/test/src/Model/ClientTest.php similarity index 85% rename from tests/src/Model/ClientTest.php rename to test/src/Model/ClientTest.php index bf1a258..b7162a6 100644 --- a/tests/src/Model/ClientTest.php +++ b/test/src/Model/ClientTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Model\Client */ @@ -33,8 +40,13 @@ class ClientTest extends TestCase /** * @dataProvider providerGenerateNewClient */ - public function testGenerateNewAccessToken($id, $name, $secret, $redirectUris, $scopes): void - { + public function testGenerateNewAccessToken( + int $id, + string $name, + ?string $secret, + ?string $redirectUris, + array $scopes + ): void { /** @var Client $client */ $client = Client::createNewClient($name, $redirectUris); @@ -103,18 +115,19 @@ public function providerReconstitute(): array return [ [ [ - 'id' => '325e4ffc-ff89-4558-971a-6c6a4c13e718', - 'name' => 'name', - 'secret' => 'secret', + 'id' => '325e4ffc-ff89-4558-971a-6c6a4c13e718', + 'name' => 'name', + 'secret' => 'secret', 'redirectUris' => ['http://www.example.com'], - 'scopes' => [], + 'scopes' => [], ], [ - 'id' => '29432c0c-fd08-46bb-a9a5-c55ccaf9ccda', - 'name' => 'name', - 'secret' => '', + 'id' => '29432c0c-fd08-46bb-a9a5-c55ccaf9ccda', + 'name' => 'name', + 'secret' => '', 'redirectUris' => [], - 'scopes' => [], ], + 'scopes' => [], + ], ], ]; } @@ -176,11 +189,11 @@ public function testAuthenticate(): void { $client = Client::reconstitute( [ - 'id' => '325e4ffc-ff89-4558-971a-6c6a4c13e718', - 'name' => 'name', - 'secret' => '$2y$10$LHAy5E0b1Fie9NpV6KeOWeAmVdA6UnaXP82TNoMGiVl0Sy/E6PUs6', + 'id' => '325e4ffc-ff89-4558-971a-6c6a4c13e718', + 'name' => 'name', + 'secret' => '$2y$10$LHAy5E0b1Fie9NpV6KeOWeAmVdA6UnaXP82TNoMGiVl0Sy/E6PUs6', 'redirectUris' => [], - 'scopes' => [], + 'scopes' => [], ] ); diff --git a/tests/src/Model/RefreshTokenTest.php b/test/src/Model/RefreshTokenTest.php similarity index 83% rename from tests/src/Model/RefreshTokenTest.php rename to test/src/Model/RefreshTokenTest.php index 2ccb557..dabf234 100644 --- a/tests/src/Model/RefreshTokenTest.php +++ b/test/src/Model/RefreshTokenTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Model\AbstractToken * @covers \ZfrOAuth2\Server\Model\RefreshToken @@ -38,8 +43,12 @@ class RefreshTokenTest extends TestCase /** * @dataProvider providerGenerateNewRefreshToken */ - public function testGenerateNewAccessToken($ttl, $owner, $client, $scopes): void - { + public function testGenerateNewAccessToken( + int $ttl, + ?TokenOwnerInterface $owner, + ?Client $client, + ?array $scopes + ): void { /** @var RefreshToken $refreshToken */ $refreshToken = RefreshToken::createNewRefreshToken($ttl, $owner, $client, $scopes); @@ -55,10 +64,10 @@ public function testGenerateNewAccessToken($ttl, $owner, $client, $scopes): void if ($ttl === 0) { $this->assertNull($refreshToken->getExpiresAt()); } else { - $this->assertInstanceOf(\DateTimeInterface::class, $refreshToken->getExpiresAt()); + $this->assertInstanceOf(DateTimeInterface::class, $refreshToken->getExpiresAt()); $this->assertEquals( (new DateTimeImmutable())->modify("+$ttl seconds")->format(DateTime::ATOM), - $refreshToken->getExpiresAt()->format(\DateTime::ATOM) + $refreshToken->getExpiresAt()->format(DateTime::ATOM) ); } } @@ -86,7 +95,7 @@ public function providerGenerateNewRefreshToken(): array /** * @dataProvider providerReconstitute */ - public function testReconstitute($data): void + public function testReconstitute(array $data): void { /** @var RefreshToken $refreshToken */ $refreshToken = RefreshToken::reconstitute($data); @@ -111,21 +120,21 @@ public function providerReconstitute(): array return [ [ [ - 'token' => 'token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), + 'token' => 'token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), 'expiresAt' => new DateTimeImmutable(), - 'scopes' => ['scope1', 'scope2'], + 'scopes' => ['scope1', 'scope2'], ], ], [ // test set - null values - [ - 'token' => 'token', - 'owner' => null, - 'client' => null, - 'expiresAt' => null, - 'scopes' => [], - ], + [ + 'token' => 'token', + 'owner' => null, + 'client' => null, + 'expiresAt' => null, + 'scopes' => [], + ], ], ]; } diff --git a/tests/src/Model/ScopeTest.php b/test/src/Model/ScopeTest.php similarity index 93% rename from tests/src/Model/ScopeTest.php rename to test/src/Model/ScopeTest.php index 57f1758..82ab2de 100644 --- a/tests/src/Model/ScopeTest.php +++ b/test/src/Model/ScopeTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Model\Scope */ @@ -33,7 +33,7 @@ class ScopeTest extends TestCase /** * @dataProvider providerGenerateNewScope */ - public function testGenerateNewScope($id, $name, $description, $isDefault): void + public function testGenerateNewScope(int $id, string $name, string $description, bool $isDefault): void { /** @var Scope $scope */ $scope = Scope::createNewScope($id, $name, $description, $isDefault); @@ -55,7 +55,7 @@ public function providerGenerateNewScope(): array /** * @dataProvider providerReconstitute */ - public function testReconstitute($data): void + public function testReconstitute(array $data): void { $scope = Scope::reconstitute($data); diff --git a/tests/src/ModuleConfigTest.php b/test/src/ModuleConfigTest.php similarity index 94% rename from tests/src/ModuleConfigTest.php rename to test/src/ModuleConfigTest.php index 2d3e0a2..caaec20 100644 --- a/tests/src/ModuleConfigTest.php +++ b/test/src/ModuleConfigTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\ModuleConfig */ @@ -40,7 +42,7 @@ public function testCanBeInvoked(): void public function testGetArrayWith(): void { $moduleConfig = new ModuleConfig(); - $config = $moduleConfig->__invoke(); + $config = $moduleConfig->__invoke(); $this->assertIsArray($config); $this->assertArrayHasKey('zfr_oauth2_server', $config); diff --git a/tests/src/Options/ServerOptionsTest.php b/test/src/Options/ServerOptionsTest.php similarity index 85% rename from tests/src/Options/ServerOptionsTest.php rename to test/src/Options/ServerOptionsTest.php index ba2ec93..ad7c1fe 100644 --- a/tests/src/Options/ServerOptionsTest.php +++ b/test/src/Options/ServerOptionsTest.php @@ -1,6 +1,7 @@ * @licence MIT - * * @covers \ZfrOAuth2\Server\Options\ServerOptions */ class ServerOptionsTest extends TestCase @@ -53,15 +52,15 @@ public function testGetters(): void }; $options = ServerOptions::fromArray([ - 'authorization_code_ttl' => 300, - 'access_token_ttl' => 3000, - 'refresh_token_ttl' => 30000, - 'rotate_refresh_tokens' => true, + 'authorization_code_ttl' => 300, + 'access_token_ttl' => 3000, + 'refresh_token_ttl' => 30000, + 'rotate_refresh_tokens' => true, 'revoke_rotated_refresh_tokens' => false, - 'owner_callable' => $callable, - 'grants' => [ClientCredentialsGrant::class], - 'owner_request_attribute' => 'something', - 'token_request_attribute' => 'else', + 'owner_callable' => $callable, + 'grants' => [ClientCredentialsGrant::class], + 'owner_request_attribute' => 'something', + 'token_request_attribute' => 'else', ]); $this->assertEquals(300, $options->getAuthorizationCodeTtl()); diff --git a/tests/src/ResourceServerTest.php b/test/src/ResourceServerTest.php similarity index 82% rename from tests/src/ResourceServerTest.php rename to test/src/ResourceServerTest.php index 6fe2aae..2a91bbc 100644 --- a/tests/src/ResourceServerTest.php +++ b/test/src/ResourceServerTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\ResourceServer */ class ResourceServerTest extends TestCase { - /** - * @var AccessTokenService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var AccessTokenService|MockObject */ protected $tokenService; - /** - * @var ResourceServer - */ + /** @var ResourceServer */ protected $resourceServer; public function setUp(): void { - $this->tokenService = $this->createMock(AccessTokenService::class); + $this->tokenService = $this->createMock(AccessTokenService::class); $this->resourceServer = new ResourceServer($this->tokenService); } @@ -70,11 +69,23 @@ public function testCanExtractAccessTokenFromAuthorizationHeader(): void public function testCanExtractAccessTokenFromQueryString(): void { $request = $this->createMock(ServerRequestInterface::class); - $request->expects($this->once())->method('hasHeader')->with('Authorization')->will($this->returnValue(false)); - $request->expects($this->once())->method('getQueryParams')->will($this->returnValue(['access_token' => 'token'])); + + $request + ->expects($this->once()) + ->method('hasHeader') + ->with('Authorization')->will($this->returnValue(false)); + + $request + ->expects($this->once()) + ->method('getQueryParams') + ->will($this->returnValue(['access_token' => 'token'])); $token = $this->createMock(AccessToken::class); - $token->expects($this->once())->method('isValid')->will($this->returnValue(true)); + + $token + ->expects($this->once()) + ->method('isValid') + ->will($this->returnValue(true)); $this->tokenService->expects($this->once()) ->method('getToken') @@ -115,25 +126,25 @@ public function requestProvider(): array // Should return false because the token is expired [ 'expired_token' => true, - 'token_scope' => 'read', + 'token_scope' => 'read', 'desired_scope' => 'read write', - 'match' => false, + 'match' => false, ], // Should return false because we are asking more permissions than the token scope [ 'expired_token' => false, - 'token_scope' => 'read', + 'token_scope' => 'read', 'desired_scope' => 'read write', - 'match' => false, + 'match' => false, ], // Should return true [ 'expired_token' => false, - 'token_scope' => 'read', + 'token_scope' => 'read', 'desired_scope' => 'read', - 'match' => true, + 'match' => true, ], ]; } @@ -141,10 +152,14 @@ public function requestProvider(): array /** * @dataProvider requestProvider */ - public function testCanValidateAccessToResource($expiredToken, $tokenScope, $desiredScope, $match): void - { + public function testCanValidateAccessToResource( + bool $expiredToken, + string $tokenScope, + string $desiredScope, + bool $match + ): void { $tokenScope = explode(' ', $tokenScope); - $request = $this->createMock(ServerRequestInterface::class); + $request = $this->createMock(ServerRequestInterface::class); $request->expects($this->once())->method('hasHeader')->with('Authorization')->will($this->returnValue(true)); $request->expects($this->once())->method('getHeaderLine')->will($this->returnValue('Bearer token')); diff --git a/tests/src/Service/AbstractTokenServiceTest.php b/test/src/Service/AbstractTokenServiceTest.php similarity index 77% rename from tests/src/Service/AbstractTokenServiceTest.php rename to test/src/Service/AbstractTokenServiceTest.php index 1005c3e..2abc7d2 100644 --- a/tests/src/Service/AbstractTokenServiceTest.php +++ b/test/src/Service/AbstractTokenServiceTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Service\AbstractTokenService */ class AbstractTokenServiceTest extends TestCase { - /** - * @var AccessTokenRepositoryInterface - */ + /** @var AccessTokenRepositoryInterface */ protected $tokenRepository; - /** - * @var ScopeService - */ + /** @var ScopeService */ protected $scopeService; - /** - * @var AccessTokenService - */ + /** @var AccessTokenService */ protected $abstractTokenService; public function setUp(): void { - $this->tokenRepository = $this->createMock(AccessTokenRepositoryInterface::class); - $this->scopeService = $this->createMock(ScopeService::class); + $this->tokenRepository = $this->createMock(AccessTokenRepositoryInterface::class); + $this->scopeService = $this->createMock(ScopeService::class); $this->abstractTokenService = $this->getMockForAbstractClass(AbstractTokenService::class, [ $this->tokenRepository, $this->scopeService, @@ -68,11 +63,11 @@ public function testCanCallGetTokenWithTokenFound(): void { $token = SomeToken::reconstitute( [ - 'token' => 'token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), - 'expiresAt' => new \DateTimeImmutable(), - 'scopes' => [], + 'token' => 'token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), + 'expiresAt' => new DateTimeImmutable(), + 'scopes' => [], ] ); @@ -90,11 +85,11 @@ public function testCanCallGetTokenButRetrievedTokenHashDiffers(): void { $token = SomeToken::reconstitute( [ - 'token' => 'token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), - 'expiresAt' => new \DateTimeImmutable(), - 'scopes' => [], + 'token' => 'token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), + 'expiresAt' => new DateTimeImmutable(), + 'scopes' => [], ] ); @@ -120,11 +115,11 @@ public function testCanDeleteToken(): void { $token = SomeToken::reconstitute( [ - 'token' => 'token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), - 'expiresAt' => new \DateTimeImmutable(), - 'scopes' => [], + 'token' => 'token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), + 'expiresAt' => new DateTimeImmutable(), + 'scopes' => [], ] ); @@ -159,9 +154,8 @@ public function testCanValidateScopes(array $registeredScopes, array $scopes, bo } // calling protected method from abstract scope service - $protectedBound = (function ($token) { - return $this->validateTokenScopes($token); - })->bindTo($this->abstractTokenService, $this->abstractTokenService); + $protectedBound = (fn ($token) => $this->validateTokenScopes($token)) + ->bindTo($this->abstractTokenService, $this->abstractTokenService); $protectedBound($scopes); } diff --git a/tests/src/Service/AccessTokenServiceTest.php b/test/src/Service/AccessTokenServiceTest.php similarity index 73% rename from tests/src/Service/AccessTokenServiceTest.php rename to test/src/Service/AccessTokenServiceTest.php index 75cc921..dd5925b 100644 --- a/tests/src/Service/AccessTokenServiceTest.php +++ b/test/src/Service/AccessTokenServiceTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Service\AccessTokenService */ class AccessTokenServiceTest extends TestCase { - /** - * @var AccessTokenRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var AccessTokenRepositoryInterface|MockObject */ protected $tokenRepository; - /** - * @var ScopeService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var ScopeService|MockObject */ protected $scopeService; - /** - * @var AccessTokenService - */ + /** @var AccessTokenService */ protected $tokenService; public function setUp(): void { $this->tokenRepository = $this->createMock(AccessTokenRepositoryInterface::class); - $this->scopeService = $this->createMock(ScopeService::class); - $this->tokenService = new AccessTokenService( + $this->scopeService = $this->createMock(ScopeService::class); + $this->tokenService = new AccessTokenService( $this->tokenRepository, $this->scopeService, ServerOptions::fromArray() @@ -68,11 +66,11 @@ public function testCanGetToken(): void { $token = AccessToken::reconstitute( [ - 'token' => 'token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), - 'expiresAt' => new \DateTimeImmutable(), - 'scopes' => [], + 'token' => 'token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), + 'expiresAt' => new DateTimeImmutable(), + 'scopes' => [], ] ); @@ -98,11 +96,11 @@ public function testDoesCaseSensitiveTest(): void { $token = AccessToken::reconstitute( [ - 'token' => 'Token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), - 'expiresAt' => new \DateTimeImmutable(), - 'scopes' => [], + 'token' => 'Token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), + 'expiresAt' => new DateTimeImmutable(), + 'scopes' => [], ] ); @@ -120,37 +118,37 @@ public function scopeProvider(): array // With no scope [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => [], - 'throw_exception' => false, + 'client_scopes' => ['read', 'write'], + 'token_scope' => [], + 'throw_exception' => false, ], // With less permissions [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => ['read'], - 'throw_exception' => false, + 'client_scopes' => ['read', 'write'], + 'token_scope' => ['read'], + 'throw_exception' => false, ], // With same permissions [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => ['read', 'write'], - 'throw_exception' => false, + 'client_scopes' => ['read', 'write'], + 'token_scope' => ['read', 'write'], + 'throw_exception' => false, ], // With too much permissions [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => ['read', 'write', 'delete'], - 'throw_exception' => true, + 'client_scopes' => ['read', 'write'], + 'token_scope' => ['read', 'write', 'delete'], + 'throw_exception' => true, ], // With too little scopes on the client [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read'], - 'token_scope' => ['write'], - 'throw_exception' => true, + 'client_scopes' => ['read'], + 'token_scope' => ['write'], + 'throw_exception' => true, ], ]; } @@ -158,13 +156,17 @@ public function scopeProvider(): array /** * @dataProvider scopeProvider */ - public function testCanSaveToken($registeredScopes, $clientScopes, $tokenScope, $throwException): void - { + public function testCanSaveToken( + array $registeredScopes, + array $clientScopes, + array $tokenScope, + bool $throwException + ): void { if ($throwException) { $this->expectException(OAuth2Exception::class, null, 'invalid_scope'); } - $owner = $this->createMock(TokenOwnerInterface::class); + $owner = $this->createMock(TokenOwnerInterface::class); $client = $this->createMock(Client::class); $client->expects($this->any()) @@ -213,21 +215,22 @@ public function testCreateNewTokenUntilOneDoesNotExist(): void Scope::reconstitute(['id' => 1, 'name' => 'read', 'description' => 'desc', 'isDefault' => false]), ])); - $this->tokenRepository->expects($this->at(0)) - ->method('tokenExists') - ->with($this->isType('string')) - ->willReturn(true); - - $this->tokenRepository->expects($this->at(1)) + $this->tokenRepository + ->expects($this->exactly(2)) ->method('tokenExists') ->with($this->isType('string')) - ->willReturn(false); + ->will( + $this->onConsecutiveCalls( + true, + false + ) + ); $this->tokenRepository->expects($this->once()) ->method('save') ->will($this->returnArgument(0)); - $owner = $this->createMock(TokenOwnerInterface::class); + $owner = $this->createMock(TokenOwnerInterface::class); $client = $this->createMock(Client::class); $client->expects($this->once()) diff --git a/tests/src/Service/AuthorizationCodeServiceTest.php b/test/src/Service/AuthorizationCodeServiceTest.php similarity index 71% rename from tests/src/Service/AuthorizationCodeServiceTest.php rename to test/src/Service/AuthorizationCodeServiceTest.php index b35a124..c16c2df 100644 --- a/tests/src/Service/AuthorizationCodeServiceTest.php +++ b/test/src/Service/AuthorizationCodeServiceTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Service\AuthorizationCodeService */ class AuthorizationCodeServiceTest extends TestCase { - /** - * @var AuthorizationCodeRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var AuthorizationCodeRepositoryInterface|MockObject */ protected $tokenRepository; - /** - * @var ScopeService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var ScopeService|MockObject */ protected $scopeService; - /** - * @var AuthorizationCodeService - */ + /** @var AuthorizationCodeService */ protected $tokenService; public function setUp(): void { $this->tokenRepository = $this->createMock(AuthorizationCodeRepositoryInterface::class); - $this->scopeService = $this->createMock(ScopeService::class); - $this->tokenService = new AuthorizationCodeService( + $this->scopeService = $this->createMock(ScopeService::class); + $this->tokenService = new AuthorizationCodeService( $this->tokenRepository, $this->scopeService, ServerOptions::fromArray() @@ -69,11 +67,11 @@ public function testCanGetToken(): void { $token = AccessToken::reconstitute( [ - 'token' => 'token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), - 'expiresAt' => new \DateTimeImmutable(), - 'scopes' => [], + 'token' => 'token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), + 'expiresAt' => new DateTimeImmutable(), + 'scopes' => [], ] ); @@ -99,11 +97,11 @@ public function testDoesCaseSensitiveTest(): void { $token = AccessToken::reconstitute( [ - 'token' => 'Token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), - 'expiresAt' => new \DateTimeImmutable(), - 'scopes' => [], + 'token' => 'Token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), + 'expiresAt' => new DateTimeImmutable(), + 'scopes' => [], ] ); @@ -121,37 +119,37 @@ public function scopeProvider(): array // With no scope [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => [], - 'throw_exception' => false, + 'client_scopes' => ['read', 'write'], + 'token_scope' => [], + 'throw_exception' => false, ], // With less permissions [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => ['read'], - 'throw_exception' => false, + 'client_scopes' => ['read', 'write'], + 'token_scope' => ['read'], + 'throw_exception' => false, ], // With same permissions [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => ['read', 'write'], - 'throw_exception' => false, + 'client_scopes' => ['read', 'write'], + 'token_scope' => ['read', 'write'], + 'throw_exception' => false, ], // With too much permissions [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => ['read', 'write', 'delete'], - 'throw_exception' => true, + 'client_scopes' => ['read', 'write'], + 'token_scope' => ['read', 'write', 'delete'], + 'throw_exception' => true, ], // With too little scopes on the client [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read'], - 'token_scope' => ['write'], - 'throw_exception' => true, + 'client_scopes' => ['read'], + 'token_scope' => ['write'], + 'throw_exception' => true, ], ]; } @@ -159,13 +157,17 @@ public function scopeProvider(): array /** * @dataProvider scopeProvider */ - public function testCanSaveToken($registeredScopes, $clientScopes, $tokenScope, $throwException): void - { + public function testCanSaveToken( + array $registeredScopes, + array $clientScopes, + array $tokenScope, + bool $throwException + ): void { if ($throwException) { $this->expectException(OAuth2Exception::class, null, 'invalid_scope'); } - $owner = $this->createMock(TokenOwnerInterface::class); + $owner = $this->createMock(TokenOwnerInterface::class); $client = $this->createMock(Client::class); $client->expects($this->any()) @@ -214,26 +216,28 @@ public function testCreateNewTokenUntilOneDoesNotExist(): void Scope::reconstitute(['id' => 1, 'name' => 'read', 'description' => 'desc', 'isDefault' => false]), ])); - $this->tokenRepository->expects($this->at(0)) - ->method('tokenExists') - ->with($this->isType('string')) - ->willReturn(true); - - $this->tokenRepository->expects($this->at(1)) + $this->tokenRepository + ->expects($this->exactly(2)) ->method('tokenExists') ->with($this->isType('string')) - ->willReturn(false); + ->will( + $this->onConsecutiveCalls( + true, + false + ) + ); - $this->tokenRepository->expects($this->once()) - ->method('save') - ->will($this->returnArgument(0)); + $this->tokenRepository + ->expects($this->once()) + ->method('save') + ->will($this->returnArgument(0)); - $owner = $this->createMock(TokenOwnerInterface::class); + $owner = $this->createMock(TokenOwnerInterface::class); $client = $this->createMock(Client::class); $client->expects($this->once()) - ->method('getScopes') - ->will($this->returnValue(['read'])); + ->method('getScopes') + ->will($this->returnValue(['read'])); $token = $this->tokenService->createToken('http://www.example.com', $owner, $client, []); $this->assertEquals(40, strlen($token->getToken())); diff --git a/tests/src/Service/ClientServiceTest.php b/test/src/Service/ClientServiceTest.php similarity index 81% rename from tests/src/Service/ClientServiceTest.php rename to test/src/Service/ClientServiceTest.php index a2546ed..3eb7b1a 100644 --- a/tests/src/Service/ClientServiceTest.php +++ b/test/src/Service/ClientServiceTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Service\ClientService */ class ClientServiceTest extends TestCase { - /** - * @var ClientRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var ClientRepositoryInterface|MockObject */ protected $clientRepository; - /** - * @var ClientService - */ + /** @var ClientService */ protected $clientService; public function setUp(): void { $this->clientRepository = $this->createMock(ClientRepositoryInterface::class); - $this->clientService = new ClientService($this->clientRepository); + $this->clientService = new ClientService($this->clientRepository); } public function testCanGetClient(): void { $client = Client::reconstitute([ - 'id' => 'client_id', - 'name' => 'name', - 'secret' => '', - 'redirectUris' => [], - 'scopes' => [], + 'id' => 'client_id', + 'name' => 'name', + 'secret' => '', + 'redirectUris' => [], + 'scopes' => [], ]); $this->clientRepository->expects($this->once()) @@ -76,7 +75,7 @@ public function testRegisterClient(): void ->method('save') ->will($this->returnArgument(0)); - list($client, $secret) = $this->clientService->registerClient('name', ['http://www.example.com']); + [$client, $secret] = $this->clientService->registerClient('name', ['http://www.example.com']); $this->assertEquals(60, strlen($client->getSecret())); $this->assertEquals(40, strlen($secret)); diff --git a/tests/src/Service/RefreshTokenServiceTest.php b/test/src/Service/RefreshTokenServiceTest.php similarity index 71% rename from tests/src/Service/RefreshTokenServiceTest.php rename to test/src/Service/RefreshTokenServiceTest.php index f7daa81..304088b 100644 --- a/tests/src/Service/RefreshTokenServiceTest.php +++ b/test/src/Service/RefreshTokenServiceTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Service\RefreshTokenService */ class RefreshTokenServiceTest extends TestCase { - /** - * @var RefreshTokenRepositoryInterface|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var RefreshTokenRepositoryInterface|MockObject */ protected $tokenRepository; - /** - * @var ScopeService|\PHPUnit\Framework\MockObject\MockObject - */ + /** @var ScopeService|MockObject */ protected $scopeService; - /** - * @var RefreshTokenService - */ + /** @var RefreshTokenService */ protected $tokenService; public function setUp(): void { $this->tokenRepository = $this->createMock(RefreshTokenRepositoryInterface::class); - $this->scopeService = $this->createMock(ScopeService::class); - $this->tokenService = new RefreshTokenService( + $this->scopeService = $this->createMock(ScopeService::class); + $this->tokenService = new RefreshTokenService( $this->tokenRepository, $this->scopeService, ServerOptions::fromArray() @@ -69,11 +67,11 @@ public function testCanGetToken(): void { $token = AccessToken::reconstitute( [ - 'token' => 'token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), - 'expiresAt' => new \DateTimeImmutable(), - 'scopes' => [], + 'token' => 'token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), + 'expiresAt' => new DateTimeImmutable(), + 'scopes' => [], ] ); @@ -99,11 +97,11 @@ public function testDoesCaseSensitiveTest(): void { $token = AccessToken::reconstitute( [ - 'token' => 'Token', - 'owner' => $this->createMock(TokenOwnerInterface::class), - 'client' => $this->createMock(Client::class), - 'expiresAt' => new \DateTimeImmutable(), - 'scopes' => [], + 'token' => 'Token', + 'owner' => $this->createMock(TokenOwnerInterface::class), + 'client' => $this->createMock(Client::class), + 'expiresAt' => new DateTimeImmutable(), + 'scopes' => [], ] ); @@ -121,37 +119,37 @@ public function scopeProvider(): array // With no scope [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => [], - 'throw_exception' => false, + 'client_scopes' => ['read', 'write'], + 'token_scope' => [], + 'throw_exception' => false, ], // With less permissions [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => ['read'], - 'throw_exception' => false, + 'client_scopes' => ['read', 'write'], + 'token_scope' => ['read'], + 'throw_exception' => false, ], // With same permissions [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => ['read', 'write'], - 'throw_exception' => false, + 'client_scopes' => ['read', 'write'], + 'token_scope' => ['read', 'write'], + 'throw_exception' => false, ], // With too much permissions [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read', 'write'], - 'token_scope' => ['read', 'write', 'delete'], - 'throw_exception' => true, + 'client_scopes' => ['read', 'write'], + 'token_scope' => ['read', 'write', 'delete'], + 'throw_exception' => true, ], // With too little scopes on the client [ 'registered_scopes' => ['read', 'write'], - 'client_scopes' => ['read'], - 'token_scope' => ['write'], - 'throw_exception' => true, + 'client_scopes' => ['read'], + 'token_scope' => ['write'], + 'throw_exception' => true, ], ]; } @@ -159,13 +157,17 @@ public function scopeProvider(): array /** * @dataProvider scopeProvider */ - public function testCanSaveToken($registeredScopes, $clientScopes, $tokenScope, $throwException): void - { + public function testCanSaveToken( + array $registeredScopes, + array $clientScopes, + array $tokenScope, + bool $throwException + ): void { if ($throwException) { $this->expectException(OAuth2Exception::class, null, 'invalid_scope'); } - $owner = $this->createMock(TokenOwnerInterface::class); + $owner = $this->createMock(TokenOwnerInterface::class); $client = $this->createMock(Client::class); $client->expects($this->any()) @@ -214,26 +216,28 @@ public function testCreateNewTokenUntilOneDoesNotExist(): void Scope::reconstitute(['id' => 1, 'name' => 'read', 'description' => 'desc', 'isDefault' => false]), ])); - $this->tokenRepository->expects($this->at(0)) - ->method('tokenExists') - ->with($this->isType('string')) - ->willReturn(true); - - $this->tokenRepository->expects($this->at(1)) + $this->tokenRepository + ->expects($this->exactly(2)) ->method('tokenExists') ->with($this->isType('string')) - ->willReturn(false); + ->will( + $this->onConsecutiveCalls( + true, + false + ) + ); - $this->tokenRepository->expects($this->once()) + $this->tokenRepository + ->expects($this->once()) ->method('save') ->will($this->returnArgument(0)); - $owner = $this->createMock(TokenOwnerInterface::class); + $owner = $this->createMock(TokenOwnerInterface::class); $client = $this->createMock(Client::class); $client->expects($this->once()) - ->method('getScopes') - ->will($this->returnValue(['read'])); + ->method('getScopes') + ->will($this->returnValue(['read'])); $token = $this->tokenService->createToken($owner, $client, []); $this->assertEquals(40, strlen($token->getToken())); diff --git a/tests/src/Service/ScopeServiceTest.php b/test/src/Service/ScopeServiceTest.php similarity index 93% rename from tests/src/Service/ScopeServiceTest.php rename to test/src/Service/ScopeServiceTest.php index d68b84c..51e9834 100644 --- a/tests/src/Service/ScopeServiceTest.php +++ b/test/src/Service/ScopeServiceTest.php @@ -1,6 +1,7 @@ * @licence MIT * @covers \ZfrOAuth2\Server\Service\ScopeService */ class ScopeServiceTest extends TestCase { - /** - * @var ScopeRepositoryInterface - */ + /** @var ScopeRepositoryInterface */ protected $scopeRepository; public function setUp(): void { $this->scopeRepository = $this->createMock(ScopeRepositoryInterface::class); - $this->tokenService = new ScopeService($this->scopeRepository); + $this->tokenService = new ScopeService($this->scopeRepository); } public function testCanCreateScope(): void