From bb82651bec28e5a92fa7c6a8561e0f2452c0af37 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Tue, 10 May 2016 08:10:50 +0100 Subject: [PATCH 01/36] First commit of update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5b5bf68..a32fd239 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.1.0 (released 2016-05-XX) + +* Implemented RFC7636 (Issue #574) + ## 5.0.3 (released 2016-05-04) * Fix hints in PasswordGrant (Issue #560) From c0936cc320adb97119c44706eabe4265c9ddf2d2 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Tue, 10 May 2016 13:23:56 +0100 Subject: [PATCH 02/36] Updated commercial support statement --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2cb8349d..de5f3471 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,7 @@ If you have any questions about OAuth _please_ open a ticket here; please **don' ## Commercial Support -If you would like help implementing this library into your existing platform, or would like to - some advice or training for you and your team please email Alex Bilbie at `hello@glyndelabs.com`. +If you would like help implementing this library into your existing platform, or would be interested in OAuth advice or training for you and your team please get in touch with [Glynde Labs](https://glyndelabs.com). ## Security From 22e6a350dd266cd0d266b92dcc380788b44a1c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Guti=C3=A9rrez?= Date: Wed, 11 May 2016 14:13:58 +0200 Subject: [PATCH 03/36] unify middleware exception responses --- src/Middleware/AuthorizationServerMiddleware.php | 5 ++--- src/Middleware/ResourceServerMiddleware.php | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Middleware/AuthorizationServerMiddleware.php b/src/Middleware/AuthorizationServerMiddleware.php index d33cbd31..6c2d08b2 100644 --- a/src/Middleware/AuthorizationServerMiddleware.php +++ b/src/Middleware/AuthorizationServerMiddleware.php @@ -46,9 +46,8 @@ class AuthorizationServerMiddleware return $exception->generateHttpResponse($response); // @codeCoverageIgnoreStart } catch (\Exception $exception) { - $response->getBody()->write($exception->getMessage()); - - return $response->withStatus(500); + return (new OAuthServerException($exception->getMessage(), 0, 'unknown_error', 500)) + ->generateHttpResponse($response); // @codeCoverageIgnoreEnd } diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php index 6d67cb68..9e235c35 100644 --- a/src/Middleware/ResourceServerMiddleware.php +++ b/src/Middleware/ResourceServerMiddleware.php @@ -46,9 +46,8 @@ class ResourceServerMiddleware return $exception->generateHttpResponse($response); // @codeCoverageIgnoreStart } catch (\Exception $exception) { - $response->getBody()->write($exception->getMessage()); - - return $response->withStatus(500); + return (new OAuthServerException($exception->getMessage(), 0, 'unknown_error', 500)) + ->generateHttpResponse($response); // @codeCoverageIgnoreEnd } From 64a0fcb3a66b0b1e6040c56c0a92f88ea5ced72c Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Thu, 2 Jun 2016 09:35:27 +0100 Subject: [PATCH 04/36] Updated examples. Fixes #589 --- examples/src/Repositories/ScopeRepository.php | 7 +++++++ examples/src/Repositories/UserRepository.php | 5 ----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/src/Repositories/ScopeRepository.php b/examples/src/Repositories/ScopeRepository.php index fbd64b3e..f9879850 100644 --- a/examples/src/Repositories/ScopeRepository.php +++ b/examples/src/Repositories/ScopeRepository.php @@ -48,6 +48,13 @@ class ScopeRepository implements ScopeRepositoryInterface ClientEntityInterface $clientEntity, $userIdentifier = null ) { + // Example of programatically modifying the final scope of the access token + if ((int) $userIdentifier === 1) { + $scope = new ScopeEntity(); + $scope->setIdentifier('email'); + $scopes[] = $scope; + } + return $scopes; } } diff --git a/examples/src/Repositories/UserRepository.php b/examples/src/Repositories/UserRepository.php index 86f99970..88836cd6 100644 --- a/examples/src/Repositories/UserRepository.php +++ b/examples/src/Repositories/UserRepository.php @@ -11,7 +11,6 @@ namespace OAuth2ServerExamples\Repositories; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Repositories\UserRepositoryInterface; -use OAuth2ServerExamples\Entities\ScopeEntity; use OAuth2ServerExamples\Entities\UserEntity; class UserRepository implements UserRepositoryInterface @@ -26,10 +25,6 @@ class UserRepository implements UserRepositoryInterface ClientEntityInterface $clientEntity ) { if ($username === 'alex' && $password === 'whisky') { - $scope = new ScopeEntity(); - $scope->setIdentifier('email'); - $scopes[] = $scope; - return new UserEntity(); } From 6b88cbeb137187687a50c2ec27d162fea56b7eb1 Mon Sep 17 00:00:00 2001 From: Ivan Kurnosov Date: Fri, 17 Jun 2016 19:50:04 +1200 Subject: [PATCH 05/36] Removed isExpired() from interfaces and traits --- src/Entities/RefreshTokenEntityInterface.php | 7 ------- src/Entities/TokenInterface.php | 7 ------- src/Entities/Traits/RefreshTokenTrait.php | 10 ---------- src/Entities/Traits/TokenEntityTrait.php | 10 ---------- tests/Grant/AbstractGrantTest.php | 2 -- 5 files changed, 36 deletions(-) diff --git a/src/Entities/RefreshTokenEntityInterface.php b/src/Entities/RefreshTokenEntityInterface.php index 8b7d587d..c0e7bc4f 100644 --- a/src/Entities/RefreshTokenEntityInterface.php +++ b/src/Entities/RefreshTokenEntityInterface.php @@ -52,11 +52,4 @@ interface RefreshTokenEntityInterface * @return \League\OAuth2\Server\Entities\AccessTokenEntityInterface */ public function getAccessToken(); - - /** - * Has the token expired? - * - * @return bool - */ - public function isExpired(); } diff --git a/src/Entities/TokenInterface.php b/src/Entities/TokenInterface.php index 7d7c6d33..f9e5992e 100644 --- a/src/Entities/TokenInterface.php +++ b/src/Entities/TokenInterface.php @@ -80,11 +80,4 @@ interface TokenInterface * @return ScopeEntityInterface[] */ public function getScopes(); - - /** - * Has the token expired? - * - * @return bool - */ - public function isExpired(); } diff --git a/src/Entities/Traits/RefreshTokenTrait.php b/src/Entities/Traits/RefreshTokenTrait.php index 28d31a02..0734daf1 100644 --- a/src/Entities/Traits/RefreshTokenTrait.php +++ b/src/Entities/Traits/RefreshTokenTrait.php @@ -59,14 +59,4 @@ trait RefreshTokenTrait { $this->expiryDateTime = $dateTime; } - - /** - * Has the token expired? - * - * @return bool - */ - public function isExpired() - { - return (new DateTime()) > $this->getExpiryDateTime(); - } } diff --git a/src/Entities/Traits/TokenEntityTrait.php b/src/Entities/Traits/TokenEntityTrait.php index 87fdd2f4..61c1ef3c 100644 --- a/src/Entities/Traits/TokenEntityTrait.php +++ b/src/Entities/Traits/TokenEntityTrait.php @@ -114,14 +114,4 @@ trait TokenEntityTrait { $this->client = $client; } - - /** - * Has the token expired? - * - * @return bool - */ - public function isExpired() - { - return (new DateTime()) > $this->getExpiryDateTime(); - } } diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index 0c4f6ae7..6e516409 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -275,7 +275,6 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase /** @var RefreshTokenEntityInterface $refreshToken */ $refreshToken = $issueRefreshTokenMethod->invoke($grantMock, $accessToken); $this->assertTrue($refreshToken instanceof RefreshTokenEntityInterface); - $this->assertFalse($refreshToken->isExpired()); $this->assertEquals($accessToken, $refreshToken->getAccessToken()); } @@ -301,7 +300,6 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase [new ScopeEntity()] ); $this->assertTrue($accessToken instanceof AccessTokenEntityInterface); - $this->assertFalse($accessToken->isExpired()); } public function testIssueAuthCode() From b68ef973df721c89dfe4e0b9f83ecc1573b2f14c Mon Sep 17 00:00:00 2001 From: Ivan Kurnosov Date: Mon, 20 Jun 2016 20:18:53 +1200 Subject: [PATCH 06/36] Added a check for unique access token constraint violation --- ...IdentifierConstraintViolationException.php | 21 ++ src/Grant/AbstractGrant.php | 54 +++- tests/Grant/AuthCodeGrantTest.php | 298 +++++++++++++++++- tests/Grant/ImplicitGrantTest.php | 74 +++++ 4 files changed, 434 insertions(+), 13 deletions(-) create mode 100644 src/Exception/UniqueTokenIdentifierConstraintViolationException.php diff --git a/src/Exception/UniqueTokenIdentifierConstraintViolationException.php b/src/Exception/UniqueTokenIdentifierConstraintViolationException.php new file mode 100644 index 00000000..816c249f --- /dev/null +++ b/src/Exception/UniqueTokenIdentifierConstraintViolationException.php @@ -0,0 +1,21 @@ + + * @copyright Copyright (c) Alex Bilbie + * @license http://mit-license.org/ + * + * @link https://github.com/thephpleague/oauth2-server + */ + +namespace League\OAuth2\Server\Exception; + + +class UniqueTokenIdentifierConstraintViolationException extends OAuthServerException +{ + public static function create() + { + $errorMessage = 'Could not create unique access token identifier'; + + return new static($errorMessage, 100, 'access_token_duplicate', 500); + } +} diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 9c72a9a1..473e21ed 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -16,6 +16,7 @@ use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; use League\OAuth2\Server\Exception\OAuthServerException; +use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; @@ -35,6 +36,8 @@ abstract class AbstractGrant implements GrantTypeInterface const SCOPE_DELIMITER_STRING = ' '; + const MAX_RANDOM_TOKEN_GENERATION_ATTEMPTS = 10; + /** * @var ClientRepositoryInterface */ @@ -295,19 +298,28 @@ abstract class AbstractGrant implements GrantTypeInterface $userIdentifier, array $scopes = [] ) { + $maxGenerationAttempts = self::MAX_RANDOM_TOKEN_GENERATION_ATTEMPTS; + $accessToken = $this->accessTokenRepository->getNewToken($client, $scopes, $userIdentifier); $accessToken->setClient($client); $accessToken->setUserIdentifier($userIdentifier); - $accessToken->setIdentifier($this->generateUniqueIdentifier()); $accessToken->setExpiryDateTime((new \DateTime())->add($accessTokenTTL)); foreach ($scopes as $scope) { $accessToken->addScope($scope); } - $this->accessTokenRepository->persistNewAccessToken($accessToken); - - return $accessToken; + while ($maxGenerationAttempts-- > 0) { + $accessToken->setIdentifier($this->generateUniqueIdentifier()); + try { + $this->accessTokenRepository->persistNewAccessToken($accessToken); + return $accessToken; + } catch (UniqueTokenIdentifierConstraintViolationException $e) { + if ($maxGenerationAttempts === 0) { + throw $e; + } + } + } } /** @@ -328,8 +340,9 @@ abstract class AbstractGrant implements GrantTypeInterface $redirectUri, array $scopes = [] ) { + $maxGenerationAttempts = self::MAX_RANDOM_TOKEN_GENERATION_ATTEMPTS; + $authCode = $this->authCodeRepository->getNewAuthCode(); - $authCode->setIdentifier($this->generateUniqueIdentifier()); $authCode->setExpiryDateTime((new \DateTime())->add($authCodeTTL)); $authCode->setClient($client); $authCode->setUserIdentifier($userIdentifier); @@ -339,9 +352,17 @@ abstract class AbstractGrant implements GrantTypeInterface $authCode->addScope($scope); } - $this->authCodeRepository->persistNewAuthCode($authCode); - - return $authCode; + while ($maxGenerationAttempts-- > 0) { + $authCode->setIdentifier($this->generateUniqueIdentifier()); + try { + $this->authCodeRepository->persistNewAuthCode($authCode); + return $authCode; + } catch (UniqueTokenIdentifierConstraintViolationException $e) { + if ($maxGenerationAttempts === 0) { + throw $e; + } + } + } } /** @@ -351,14 +372,23 @@ abstract class AbstractGrant implements GrantTypeInterface */ protected function issueRefreshToken(AccessTokenEntityInterface $accessToken) { + $maxGenerationAttempts = self::MAX_RANDOM_TOKEN_GENERATION_ATTEMPTS; + $refreshToken = $this->refreshTokenRepository->getNewRefreshToken(); - $refreshToken->setIdentifier($this->generateUniqueIdentifier()); $refreshToken->setExpiryDateTime((new \DateTime())->add($this->refreshTokenTTL)); $refreshToken->setAccessToken($accessToken); - $this->refreshTokenRepository->persistNewRefreshToken($refreshToken); - - return $refreshToken; + while ($maxGenerationAttempts-- > 0) { + $refreshToken->setIdentifier($this->generateUniqueIdentifier()); + try { + $this->refreshTokenRepository->persistNewRefreshToken($refreshToken); + return $refreshToken; + } catch (UniqueTokenIdentifierConstraintViolationException $e) { + if ($maxGenerationAttempts === 0) { + throw $e; + } + } + } } /** diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index 09ea03e6..8537a1af 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -6,6 +6,7 @@ use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Exception\OAuthServerException; +use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException; use League\OAuth2\Server\Grant\AuthCodeGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface; @@ -1183,4 +1184,299 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $this->assertEquals($e->getHint(), 'Check the `code_verifier` parameter'); } } -} \ No newline at end of file + + public function testAuthCodeRepositoryUniqueConstraintCheck() + { + $authRequest = new AuthorizationRequest(); + $authRequest->setAuthorizationApproved(true); + $authRequest->setClient(new ClientEntity()); + $authRequest->setGrantTypeId('authorization_code'); + $authRequest->setUser(new UserEntity()); + + $authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(); + $authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity()); + + $authCodeRepository->expects($this->at(0))->method('persistNewAuthCode')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create()); + $authCodeRepository->expects($this->at(1))->method('persistNewAuthCode'); + + $grant = new AuthCodeGrant( + $authCodeRepository, + $this->getMock(RefreshTokenRepositoryInterface::class), + new \DateInterval('PT10M') + ); + + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + + $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse); + } + + /** + * @expectedException \League\OAuth2\Server\Exception\OAuthServerException + * @expectedExceptionCode 7 + */ + public function testAuthCodeRepositoryFailToPersist() + { + $authRequest = new AuthorizationRequest(); + $authRequest->setAuthorizationApproved(true); + $authRequest->setClient(new ClientEntity()); + $authRequest->setGrantTypeId('authorization_code'); + $authRequest->setUser(new UserEntity()); + + $authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(); + $authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity()); + $authCodeRepository->method('persistNewAuthCode')->willThrowException(OAuthServerException::serverError('something bad happened')); + + $grant = new AuthCodeGrant( + $authCodeRepository, + $this->getMock(RefreshTokenRepositoryInterface::class), + new \DateInterval('PT10M') + ); + + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + + $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse); + } + + /** + * @expectedException \League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException + * @expectedExceptionCode 100 + */ + public function testAuthCodeRepositoryFailToPersistUniqueNoInfiniteLoop() + { + $authRequest = new AuthorizationRequest(); + $authRequest->setAuthorizationApproved(true); + $authRequest->setClient(new ClientEntity()); + $authRequest->setGrantTypeId('authorization_code'); + $authRequest->setUser(new UserEntity()); + + $authCodeRepository = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(); + $authCodeRepository->method('getNewAuthCode')->willReturn(new AuthCodeEntity()); + $authCodeRepository->method('persistNewAuthCode')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create()); + + $grant = new AuthCodeGrant( + $authCodeRepository, + $this->getMock(RefreshTokenRepositoryInterface::class), + new \DateInterval('PT10M') + ); + + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + + $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse); + } + + public function testRefreshTokenRepositoryUniqueConstraintCheck() + { + $client = new ClientEntity(); + $client->setIdentifier('foo'); + $client->setRedirectUri('http://foo/bar'); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); + $scopeEntity = new ScopeEntity(); + $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); + $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); + + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + + $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); + $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); + $refreshTokenRepositoryMock->expects($this->at(0))->method('persistNewRefreshToken')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create()); + $refreshTokenRepositoryMock->expects($this->at(1))->method('persistNewRefreshToken'); + + $grant = new AuthCodeGrant( + $this->getMock(AuthCodeRepositoryInterface::class), + $this->getMock(RefreshTokenRepositoryInterface::class), + new \DateInterval('PT10M') + ); + $grant->setClientRepository($clientRepositoryMock); + $grant->setScopeRepository($scopeRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); + $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + + $request = new ServerRequest( + [], + [], + null, + 'POST', + 'php://input', + [], + [], + [], + [ + 'grant_type' => 'authorization_code', + 'client_id' => 'foo', + 'redirect_uri' => 'http://foo/bar', + 'code' => $this->cryptStub->doEncrypt( + json_encode( + [ + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ] + ) + ), + ] + ); + + /** @var StubResponseType $response */ + $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M')); + + $this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface); + $this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface); + } + + /** + * @expectedException \League\OAuth2\Server\Exception\OAuthServerException + * @expectedExceptionCode 7 + */ + public function testRefreshTokenRepositoryFailToPersist() + { + $client = new ClientEntity(); + $client->setIdentifier('foo'); + $client->setRedirectUri('http://foo/bar'); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); + $scopeEntity = new ScopeEntity(); + $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); + $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); + + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + + $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); + $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); + $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willThrowException(OAuthServerException::serverError('something bad happened')); + + $grant = new AuthCodeGrant( + $this->getMock(AuthCodeRepositoryInterface::class), + $this->getMock(RefreshTokenRepositoryInterface::class), + new \DateInterval('PT10M') + ); + $grant->setClientRepository($clientRepositoryMock); + $grant->setScopeRepository($scopeRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); + $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + + $request = new ServerRequest( + [], + [], + null, + 'POST', + 'php://input', + [], + [], + [], + [ + 'grant_type' => 'authorization_code', + 'client_id' => 'foo', + 'redirect_uri' => 'http://foo/bar', + 'code' => $this->cryptStub->doEncrypt( + json_encode( + [ + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ] + ) + ), + ] + ); + + /** @var StubResponseType $response */ + $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M')); + + $this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface); + $this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface); + } + + /** + * @expectedException \League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException + * @expectedExceptionCode 100 + */ + public function testRefreshTokenRepositoryFailToPersistUniqueNoInfiniteLoop() + { + $client = new ClientEntity(); + $client->setIdentifier('foo'); + $client->setRedirectUri('http://foo/bar'); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); + $scopeEntity = new ScopeEntity(); + $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); + $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); + + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + + $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); + $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); + $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create()); + + $grant = new AuthCodeGrant( + $this->getMock(AuthCodeRepositoryInterface::class), + $this->getMock(RefreshTokenRepositoryInterface::class), + new \DateInterval('PT10M') + ); + $grant->setClientRepository($clientRepositoryMock); + $grant->setScopeRepository($scopeRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); + $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + + $request = new ServerRequest( + [], + [], + null, + 'POST', + 'php://input', + [], + [], + [], + [ + 'grant_type' => 'authorization_code', + 'client_id' => 'foo', + 'redirect_uri' => 'http://foo/bar', + 'code' => $this->cryptStub->doEncrypt( + json_encode( + [ + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, + 'client_id' => 'foo', + 'user_id' => 123, + 'scopes' => ['foo'], + 'redirect_uri' => 'http://foo/bar', + ] + ) + ), + ] + ); + + /** @var StubResponseType $response */ + $response = $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M')); + + $this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface); + $this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface); + } +} diff --git a/tests/Grant/ImplicitGrantTest.php b/tests/Grant/ImplicitGrantTest.php index fbf60b8c..0600d4c6 100644 --- a/tests/Grant/ImplicitGrantTest.php +++ b/tests/Grant/ImplicitGrantTest.php @@ -3,6 +3,8 @@ namespace LeagueTests\Grant; use League\OAuth2\Server\CryptKey; +use League\OAuth2\Server\Exception\OAuthServerException; +use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException; use League\OAuth2\Server\Grant\ImplicitGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; @@ -295,4 +297,76 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase $grant->completeAuthorizationRequest($authRequest); } + + public function testAccessTokenRepositoryUniqueConstraintCheck() + { + $authRequest = new AuthorizationRequest(); + $authRequest->setAuthorizationApproved(true); + $authRequest->setClient(new ClientEntity()); + $authRequest->setGrantTypeId('authorization_code'); + $authRequest->setUser(new UserEntity()); + + /** @var AccessTokenRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject $accessTokenRepositoryMock */ + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); + $accessTokenRepositoryMock->expects($this->at(0))->method('persistNewAccessToken')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create()); + $accessTokenRepositoryMock->expects($this->at(1))->method('persistNewAccessToken')->willReturnSelf(); + + $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); + + $this->assertTrue($grant->completeAuthorizationRequest($authRequest) instanceof RedirectResponse); + } + + /** + * @expectedException \League\OAuth2\Server\Exception\OAuthServerException + * @expectedExceptionCode 7 + */ + public function testAccessTokenRepositoryFailToPersist() + { + $authRequest = new AuthorizationRequest(); + $authRequest->setAuthorizationApproved(true); + $authRequest->setClient(new ClientEntity()); + $authRequest->setGrantTypeId('authorization_code'); + $authRequest->setUser(new UserEntity()); + + /** @var AccessTokenRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject $accessTokenRepositoryMock */ + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willThrowException(OAuthServerException::serverError('something bad happened')); + + $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); + + $grant->completeAuthorizationRequest($authRequest); + } + + /** + * @expectedException \League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException + * @expectedExceptionCode 100 + */ + public function testAccessTokenRepositoryFailToPersistUniqueNoInfiniteLoop() + { + $authRequest = new AuthorizationRequest(); + $authRequest->setAuthorizationApproved(true); + $authRequest->setClient(new ClientEntity()); + $authRequest->setGrantTypeId('authorization_code'); + $authRequest->setUser(new UserEntity()); + + /** @var AccessTokenRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject $accessTokenRepositoryMock */ + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create()); + + $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); + + $grant->completeAuthorizationRequest($authRequest); + } } From 9775c0076bfb6c24908de29ae198bd2207d809d5 Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Tue, 21 Jun 2016 21:08:38 -0500 Subject: [PATCH 07/36] Look at Authorization header directly for HTTP Basic auth check Should allow for better compatibility with server implementations that aren't sitting on top of a standard SAPI (e.g. persistent web servers building a PSR-7 compatible request from a socket-received message). One catch here is that I've seen Apache hijack the HTTP Authorization header in the past, though that would probably impact the other aspects of the server just as much as it would this, so I think that risk is manageable. Added tests to cover all paths through the new code, so the AbstractGrant type still has 100% coverage :) Did notice that, as of the latest versions of PHPUnit, the mock creation method is deprecated. Maybe that needs to be updated? Haven't checked to see whether the replacements are PHPUnit 4.8 compatible though, so maybe they need to stay in order to test on older PHP versions? --- src/Grant/AbstractGrant.php | 46 +++++++++++++++----- tests/Grant/AbstractGrantTest.php | 70 +++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 10 deletions(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 9c72a9a1..547ab213 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -137,21 +137,15 @@ abstract class AbstractGrant implements GrantTypeInterface */ protected function validateClient(ServerRequestInterface $request) { - $clientId = $this->getRequestParameter( - 'client_id', - $request, - $this->getServerParameter('PHP_AUTH_USER', $request) - ); + list($basicAuthUser, $basicAuthPassword) = $this->getBasicAuthCredentials($request); + + $clientId = $this->getRequestParameter('client_id', $request, $basicAuthUser); if (is_null($clientId)) { throw OAuthServerException::invalidRequest('client_id'); } // If the client is confidential require the client secret - $clientSecret = $this->getRequestParameter( - 'client_secret', - $request, - $this->getServerParameter('PHP_AUTH_PW', $request) - ); + $clientSecret = $this->getRequestParameter('client_secret', $request, $basicAuthPassword); $client = $this->clientRepository->getClientEntity( $clientId, @@ -237,6 +231,38 @@ abstract class AbstractGrant implements GrantTypeInterface return isset($requestParameters[$parameter]) ? $requestParameters[$parameter] : $default; } + /** + * Retrieve HTTP Basic Auth credentials with the Authorization header + * of a request. First index of the returned array is the username, + * second is the password (so list() will work). If the header does + * not exist, or is otherwise an invalid HTTP Basic header, return + * [null, null]. + * + * @param \Psr\Http\Message\ServerRequestInterface $request + * @return string[]|null[] + */ + protected function getBasicAuthCredentials(ServerRequestInterface $request) + { + if (!$request->hasHeader('Authorization')) { + return [null, null]; + } + + $header = $request->getHeader('Authorization')[0]; + if (strpos($header, 'Basic ') !== 0) { + return [null, null]; + } + + if (!($decoded = base64_decode(substr($header, 6)))) { + return [null, null]; + } + + if (strpos($decoded, ':') === false) { + return [null, null]; // HTTP Basic header without colon isn't valid + } + + return explode(':', $decoded, 2); + } + /** * Retrieve query string parameter. * diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index 6e516409..deafbdcd 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -32,6 +32,76 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase $grantMock->setEmitter(new Emitter()); } + public function testHttpBasicWithPassword() + { + /** @var AbstractGrant $grantMock */ + $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); + $abstractGrantReflection = new \ReflectionClass($grantMock); + + $serverRequest = new ServerRequest(); + $serverRequest = $serverRequest->withHeader('Authorization', 'Basic ' . base64_encode('Open:Sesame')); + $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); + $basicAuthMethod->setAccessible(true); + + $this->assertSame(['Open', 'Sesame'], $basicAuthMethod->invoke($grantMock, $serverRequest)); + } + + public function testHttpBasicNoPassword() + { + /** @var AbstractGrant $grantMock */ + $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); + $abstractGrantReflection = new \ReflectionClass($grantMock); + + $serverRequest = new ServerRequest(); + $serverRequest = $serverRequest->withHeader('Authorization', 'Basic ' . base64_encode('Open:')); + $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); + $basicAuthMethod->setAccessible(true); + + $this->assertSame(['Open', ''], $basicAuthMethod->invoke($grantMock, $serverRequest)); + } + + public function testHttpBasicNotBasic() + { + /** @var AbstractGrant $grantMock */ + $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); + $abstractGrantReflection = new \ReflectionClass($grantMock); + + $serverRequest = new ServerRequest(); + $serverRequest = $serverRequest->withHeader('Authorization', 'Foo ' . base64_encode('Open:Sesame')); + $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); + $basicAuthMethod->setAccessible(true); + + $this->assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); + } + + public function testHttpBasicNotBase64() + { + /** @var AbstractGrant $grantMock */ + $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); + $abstractGrantReflection = new \ReflectionClass($grantMock); + + $serverRequest = new ServerRequest(); + $serverRequest = $serverRequest->withHeader('Authorization', 'Basic ||'); + $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); + $basicAuthMethod->setAccessible(true); + + $this->assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); + } + + public function testHttpBasicNoColon() + { + /** @var AbstractGrant $grantMock */ + $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); + $abstractGrantReflection = new \ReflectionClass($grantMock); + + $serverRequest = new ServerRequest(); + $serverRequest = $serverRequest->withHeader('Authorization', 'Basic ' . base64_encode('OpenSesame')); + $basicAuthMethod = $abstractGrantReflection->getMethod('getBasicAuthCredentials'); + $basicAuthMethod->setAccessible(true); + + $this->assertSame([null, null], $basicAuthMethod->invoke($grantMock, $serverRequest)); + } + public function testValidateClientPublic() { $client = new ClientEntity(); From 9eccc40eb6dabedc8c16013a02a7a502d5bcafee Mon Sep 17 00:00:00 2001 From: Jakub Filla Date: Wed, 22 Jun 2016 12:38:03 +0200 Subject: [PATCH 08/36] Added catch Runtime exception when parsing JWT string --- .../BearerTokenValidator.php | 3 +++ .../ResponseTypes/BearerResponseTypeTest.php | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index 88034750..78f2b47c 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -77,6 +77,9 @@ class BearerTokenValidator implements AuthorizationValidatorInterface } catch (\InvalidArgumentException $exception) { // JWT couldn't be parsed so return the request as is throw OAuthServerException::accessDenied($exception->getMessage()); + } catch(\RuntimeException $exception){ + //JWR couldn't be parsed so return the request as is + throw OAuthServerException::accessDenied('Error while decoding to JSON'); } } } diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index 6c84e148..59955397 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -226,4 +226,31 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase ); } } + + public function testDetermineMissingBearerInHeader() + { + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + + $responseType = new BearerTokenResponse($accessTokenRepositoryMock); + $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + + $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); + $authorizationValidator->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $authorizationValidator->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + + $request = new ServerRequest(); + $request = $request->withHeader('authorization', 'Bearer blah.blah.blah'); + + try { + $authorizationValidator->validateAuthorization($request); + } catch (OAuthServerException $e) { + $this->assertEquals( + 'Error while decoding to JSON', + $e->getHint() + ); + } + } } From 84187041bdaaec5f01c0aedda530c0e5eb86c4ee Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Mon, 27 Jun 2016 19:31:35 +0100 Subject: [PATCH 09/36] Allow random compat 2.x --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 5b506f12..64df3ccb 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "ext-openssl": "*", "league/event": "^2.1", "lcobucci/jwt": "^3.1", - "paragonie/random_compat": "^1.1", + "paragonie/random_compat": "^1.1 || ^2.0", "psr/http-message": "^1.0" }, "require-dev": { From 5ee1583c5b4ba9787403470bc6f6aec3843e3144 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Tue, 28 Jun 2016 09:03:01 +0100 Subject: [PATCH 10/36] Ensure state is in access denied redirect. Fixes #597 --- src/Grant/AuthCodeGrant.php | 7 ++++++- src/Grant/ImplicitGrant.php | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index 5f736709..aba20aea 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -335,7 +335,12 @@ class AuthCodeGrant extends AbstractAuthorizeGrant // The user denied the client, redirect them back with an error throw OAuthServerException::accessDenied( 'The user denied the request', - $finalRedirectUri + $this->makeRedirectUri( + $finalRedirectUri, + [ + 'state' => $authorizationRequest->getState(), + ] + ) ); } } diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 976acefb..6f415164 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -207,7 +207,12 @@ class ImplicitGrant extends AbstractAuthorizeGrant // The user denied the client, redirect them back with an error throw OAuthServerException::accessDenied( 'The user denied the request', - $finalRedirectUri + $this->makeRedirectUri( + $finalRedirectUri, + [ + 'state' => $authorizationRequest->getState(), + ] + ) ); } } From 68e4b1d39064ba69af2d2461cb657e8aa053447f Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Tue, 28 Jun 2016 09:03:41 +0100 Subject: [PATCH 11/36] Updated changelog --- CHANGELOG.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a32fd239..49fb51e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,17 @@ # Changelog -## 5.1.0 (released 2016-05-XX) +## 5.1.0 (released 2016-06-28) -* Implemented RFC7636 (Issue #574) +* Implemented RFC7636 (Issue #574) +* Unify middleware exception responses (Issue #578) +* Updated examples (Issue #589) +* Ensure state is in access denied redirect (Issue #597) +* Remove redundant `isExpired()` method from entity interfaces and traits (Issue #600) +* Added a check for unique access token constraint violation (Issue #601) +* Look at Authorization header directly for HTTP Basic auth checks (Issue #604) +* Added catch Runtime exception when parsing JWT string (Issue #605) +* Allow `paragonie/random_compat` 2.x (Issue #606) +* Added `indigophp/hash-compat` to Composer suggestions and `require-dev` for PHP 5.5 support ## 5.0.3 (released 2016-05-04) From 32efd091a18c0ad917e0693aeb619cc25fb26445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Unger?= Date: Fri, 8 Jul 2016 15:29:21 +0200 Subject: [PATCH 12/36] tests: use MockBuilder everywhere --- tests/AuthorizationServerTest.php | 38 +++--- tests/Grant/AbstractGrantTest.php | 6 +- tests/Grant/AuthCodeGrantTest.php | 114 +++++++++--------- tests/Grant/ImplicitGrantTest.php | 1 + tests/Grant/PasswordGrantTest.php | 4 +- tests/Grant/RefreshTokenGrantTest.php | 2 +- .../AuthorizationServerMiddlewareTest.php | 10 +- .../ResourceServerMiddlewareTest.php | 6 +- tests/ResourceServerTest.php | 2 +- 9 files changed, 92 insertions(+), 91 deletions(-) diff --git a/tests/AuthorizationServerTest.php b/tests/AuthorizationServerTest.php index 2303b713..909da159 100644 --- a/tests/AuthorizationServerTest.php +++ b/tests/AuthorizationServerTest.php @@ -29,9 +29,9 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase public function testRespondToRequestInvalidGrantType() { $server = new AuthorizationServer( - $this->getMock(ClientRepositoryInterface::class), - $this->getMock(AccessTokenRepositoryInterface::class), - $this->getMock(ScopeRepositoryInterface::class), + $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), + $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/public.key', new StubResponseType() @@ -49,13 +49,13 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase public function testRespondToRequest() { - $clientRepository = $this->getMock(ClientRepositoryInterface::class); + $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository->method('getClientEntity')->willReturn(new ClientEntity()); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); - $accessTokenRepositoryMock = $this->getMock(AccessTokenRepositoryInterface::class); + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); $server = new AuthorizationServer( @@ -78,12 +78,12 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase public function testGetResponseType() { - $clientRepository = $this->getMock(ClientRepositoryInterface::class); + $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $server = new AuthorizationServer( $clientRepository, - $this->getMock(AccessTokenRepositoryInterface::class), - $this->getMock(ScopeRepositoryInterface::class), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), + $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/public.key' ); @@ -97,12 +97,12 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase public function testCompleteAuthorizationRequest() { - $clientRepository = $this->getMock(ClientRepositoryInterface::class); + $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $server = new AuthorizationServer( $clientRepository, - $this->getMock(AccessTokenRepositoryInterface::class), - $this->getMock(ScopeRepositoryInterface::class), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), + $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/public.key' ); @@ -112,7 +112,7 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase $grant = new AuthCodeGrant( $authCodeRepository, - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); @@ -139,16 +139,16 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock->method('getClientEntity')->willReturn($client); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); $server = new AuthorizationServer( $clientRepositoryMock, - $this->getMock(AccessTokenRepositoryInterface::class), - $this->getMock(ScopeRepositoryInterface::class), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), + $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/public.key' ); @@ -178,9 +178,9 @@ class AuthorizationServerTest extends \PHPUnit_Framework_TestCase public function testValidateAuthorizationRequestUnregistered() { $server = new AuthorizationServer( - $this->getMock(ClientRepositoryInterface::class), - $this->getMock(AccessTokenRepositoryInterface::class), - $this->getMock(ScopeRepositoryInterface::class), + $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), + $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/Stubs/private.key', 'file://' . __DIR__ . '/Stubs/public.key' ); diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index deafbdcd..3ef3f133 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -326,7 +326,7 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase public function testIssueRefreshToken() { - $refreshTokenRepoMock = $this->getMock(RefreshTokenRepositoryInterface::class); + $refreshTokenRepoMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $refreshTokenRepoMock ->expects($this->once()) ->method('getNewRefreshToken') @@ -350,7 +350,7 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase public function testIssueAccessToken() { - $accessTokenRepoMock = $this->getMock(AccessTokenRepositoryInterface::class); + $accessTokenRepoMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepoMock->method('getNewToken')->willReturn(new AccessTokenEntity()); /** @var AbstractGrant $grantMock */ @@ -374,7 +374,7 @@ class AbstractGrantTest extends \PHPUnit_Framework_TestCase public function testIssueAuthCode() { - $authCodeRepoMock = $this->getMock(AuthCodeRepositoryInterface::class); + $authCodeRepoMock = $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(); $authCodeRepoMock->expects($this->once())->method('getNewAuthCode')->willReturn(new AuthCodeEntity()); /** @var AbstractGrant $grantMock */ diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index 8537a1af..ae0f757e 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -40,8 +40,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase public function testGetIdentifier() { $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); @@ -51,8 +51,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase public function testCanRespondToAuthorizationRequest() { $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); @@ -81,8 +81,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock->method('getClientEntity')->willReturn($client); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -113,8 +113,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock->method('getClientEntity')->willReturn($client); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -146,8 +146,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock->method('getClientEntity')->willReturn($client); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->enableCodeExchangeProof(); @@ -181,8 +181,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -213,8 +213,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock->method('getClientEntity')->willReturn(null); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -248,8 +248,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock->method('getClientEntity')->willReturn($client); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -284,8 +284,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock->method('getClientEntity')->willReturn($client); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -320,8 +320,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock->method('getClientEntity')->willReturn($client); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->enableCodeExchangeProof(); @@ -357,8 +357,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock->method('getClientEntity')->willReturn($client); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->enableCodeExchangeProof(); @@ -397,7 +397,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $grant = new AuthCodeGrant( $authCodeRepository, - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); @@ -424,7 +424,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $grant = new AuthCodeGrant( $authCodeRepository, - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); @@ -456,8 +456,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -524,8 +524,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->enableCodeExchangeProof(); @@ -596,8 +596,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->enableCodeExchangeProof(); @@ -657,8 +657,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -700,8 +700,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -746,8 +746,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf(); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -811,7 +811,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $grant = new AuthCodeGrant( $authCodeRepositoryMock, - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -871,8 +871,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf(); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -932,8 +932,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willReturnSelf(); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -989,8 +989,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->enableCodeExchangeProof(); @@ -1039,7 +1039,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $this->assertEquals($e->getHint(), 'Failed to verify `code_verifier`.'); } } - + public function testRespondToAccessTokenRequestBadCodeVerifierS256() { $client = new ClientEntity(); @@ -1062,8 +1062,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->enableCodeExchangeProof(); @@ -1135,8 +1135,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->enableCodeExchangeProof(); @@ -1201,7 +1201,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $grant = new AuthCodeGrant( $authCodeRepository, - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); @@ -1229,7 +1229,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $grant = new AuthCodeGrant( $authCodeRepository, - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); @@ -1257,7 +1257,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $grant = new AuthCodeGrant( $authCodeRepository, - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); @@ -1290,8 +1290,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->expects($this->at(1))->method('persistNewRefreshToken'); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -1362,8 +1362,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willThrowException(OAuthServerException::serverError('something bad happened')); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); @@ -1434,8 +1434,8 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $refreshTokenRepositoryMock->method('persistNewRefreshToken')->willThrowException(UniqueTokenIdentifierConstraintViolationException::create()); $grant = new AuthCodeGrant( - $this->getMock(AuthCodeRepositoryInterface::class), - $this->getMock(RefreshTokenRepositoryInterface::class), + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); diff --git a/tests/Grant/ImplicitGrantTest.php b/tests/Grant/ImplicitGrantTest.php index 0600d4c6..08cb24df 100644 --- a/tests/Grant/ImplicitGrantTest.php +++ b/tests/Grant/ImplicitGrantTest.php @@ -8,6 +8,7 @@ use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationExcep use League\OAuth2\Server\Grant\ImplicitGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; +use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; use League\OAuth2\Server\RequestTypes\AuthorizationRequest; use League\OAuth2\Server\ResponseTypes\RedirectResponse; use LeagueTests\Stubs\AccessTokenEntity; diff --git a/tests/Grant/PasswordGrantTest.php b/tests/Grant/PasswordGrantTest.php index 20f2ce2b..b380bfb2 100644 --- a/tests/Grant/PasswordGrantTest.php +++ b/tests/Grant/PasswordGrantTest.php @@ -21,8 +21,8 @@ class PasswordGrantTest extends \PHPUnit_Framework_TestCase { public function testGetIdentifier() { - $userRepositoryMock = $this->getMock(UserRepositoryInterface::class); - $refreshTokenRepositoryMock = $this->getMock(RefreshTokenRepositoryInterface::class); + $userRepositoryMock = $this->getMockBuilder(UserRepositoryInterface::class)->getMock(); + $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock); $this->assertEquals('password', $grant->getIdentifier()); diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index af3d477f..90a63276 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -32,7 +32,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase public function testGetIdentifier() { - $refreshTokenRepositoryMock = $this->getMock(RefreshTokenRepositoryInterface::class); + $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); $grant = new RefreshTokenGrant($refreshTokenRepositoryMock); $this->assertEquals('refresh_token', $grant->getIdentifier()); diff --git a/tests/Middleware/AuthorizationServerMiddlewareTest.php b/tests/Middleware/AuthorizationServerMiddlewareTest.php index bb068179..affc2a3b 100644 --- a/tests/Middleware/AuthorizationServerMiddlewareTest.php +++ b/tests/Middleware/AuthorizationServerMiddlewareTest.php @@ -19,13 +19,13 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase { public function testValidResponse() { - $clientRepository = $this->getMock(ClientRepositoryInterface::class); + $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository->method('getClientEntity')->willReturn(new ClientEntity()); $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); - $accessRepositoryMock = $this->getMock(AccessTokenRepositoryInterface::class); + $accessRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); $server = new AuthorizationServer( @@ -58,13 +58,13 @@ class AuthorizationServerMiddlewareTest extends \PHPUnit_Framework_TestCase public function testOAuthErrorResponse() { - $clientRepository = $this->getMock(ClientRepositoryInterface::class); + $clientRepository = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepository->method('getClientEntity')->willReturn(null); $server = new AuthorizationServer( $clientRepository, - $this->getMock(AccessTokenRepositoryInterface::class), - $this->getMock(ScopeRepositoryInterface::class), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), + $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/../Stubs/private.key', 'file://' . __DIR__ . '/../Stubs/public.key', new StubResponseType() diff --git a/tests/Middleware/ResourceServerMiddlewareTest.php b/tests/Middleware/ResourceServerMiddlewareTest.php index e91e9b9b..549c8003 100644 --- a/tests/Middleware/ResourceServerMiddlewareTest.php +++ b/tests/Middleware/ResourceServerMiddlewareTest.php @@ -16,7 +16,7 @@ class ResourceServerMiddlewareTest extends \PHPUnit_Framework_TestCase public function testValidResponse() { $server = new ResourceServer( - $this->getMock(AccessTokenRepositoryInterface::class), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/../Stubs/public.key' ); @@ -51,7 +51,7 @@ class ResourceServerMiddlewareTest extends \PHPUnit_Framework_TestCase public function testValidResponseExpiredToken() { $server = new ResourceServer( - $this->getMock(AccessTokenRepositoryInterface::class), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/../Stubs/public.key' ); @@ -86,7 +86,7 @@ class ResourceServerMiddlewareTest extends \PHPUnit_Framework_TestCase public function testErrorResponse() { $server = new ResourceServer( - $this->getMock(AccessTokenRepositoryInterface::class), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/../Stubs/public.key' ); diff --git a/tests/ResourceServerTest.php b/tests/ResourceServerTest.php index c1dafe27..8a3353cc 100644 --- a/tests/ResourceServerTest.php +++ b/tests/ResourceServerTest.php @@ -13,7 +13,7 @@ class ResourceServerTest extends \PHPUnit_Framework_TestCase public function testValidateAuthenticatedRequest() { $server = new ResourceServer( - $this->getMock(AccessTokenRepositoryInterface::class), + $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(), 'file://' . __DIR__ . '/Stubs/public.key' ); From 9899aa1f99f3943beeb01fa9cdc5f980a2eb11d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Unger?= Date: Fri, 8 Jul 2016 15:30:59 +0200 Subject: [PATCH 13/36] tests: ImplicitGrantTest additional tests --- tests/Grant/ImplicitGrantTest.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/Grant/ImplicitGrantTest.php b/tests/Grant/ImplicitGrantTest.php index 08cb24df..f5f1feb2 100644 --- a/tests/Grant/ImplicitGrantTest.php +++ b/tests/Grant/ImplicitGrantTest.php @@ -370,4 +370,32 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase $grant->completeAuthorizationRequest($authRequest); } + + /** + * @expectedException \LogicException + */ + public function testSetRefreshTokenTTL() + { + $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant->setRefreshTokenTTL(new \DateInterval('PT10M')); + } + + /** + * @expectedException \LogicException + */ + public function testSetRefreshTokenRepository() + { + $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); + $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); + } + + /** + * @expectedException \LogicException + */ + public function testCompleteAuthorizationRequestNoUser() + { + $grant = new ImplicitGrant(new \DateInterval('PT10M')); + $grant->completeAuthorizationRequest(new AuthorizationRequest()); + } } From 54422a244faa7110add58302e07585f65ab587d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Unger?= Date: Fri, 8 Jul 2016 15:31:29 +0200 Subject: [PATCH 14/36] tests: AuthCodeGrantTest additional tests --- tests/Grant/AuthCodeGrantTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index ae0f757e..3935dac5 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -1479,4 +1479,18 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $this->assertTrue($response->getAccessToken() instanceof AccessTokenEntityInterface); $this->assertTrue($response->getRefreshToken() instanceof RefreshTokenEntityInterface); } + + /** + * @expectedException \LogicException + */ + public function testCompleteAuthorizationRequestNoUser() + { + $grant = new AuthCodeGrant( + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), + new \DateInterval('PT10M') + ); + + $grant->completeAuthorizationRequest(new AuthorizationRequest()); + } } From 17b6e2a20761395dad0718743ef98c4a6ac56878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Unger?= Date: Fri, 8 Jul 2016 16:04:14 +0200 Subject: [PATCH 15/36] tests: Fix missing redirect uri test, add redirect uri mismatch test --- tests/Grant/AuthCodeGrantTest.php | 110 ++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 27 deletions(-) diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index 3935dac5..18420c16 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -93,9 +93,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase null, null, 'php://input', - $headers = [], - $cookies = [], - $queryParams = [ + [], + [], + [ 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', @@ -125,9 +125,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase null, null, 'php://input', - $headers = [], - $cookies = [], - $queryParams = [ + [], + [], + [ 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', @@ -159,9 +159,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase null, null, 'php://input', - $headers = [], - $cookies = [], - $queryParams = [ + [], + [], + [ 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', @@ -260,9 +260,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase null, null, 'php://input', - $headers = [], - $cookies = [], - $queryParams = [ + [], + [], + [ 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://bar', @@ -296,9 +296,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase null, null, 'php://input', - $headers = [], - $cookies = [], - $queryParams = [ + [], + [], + [ 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://bar', @@ -333,9 +333,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase null, null, 'php://input', - $headers = [], - $cookies = [], - $queryParams = [ + [], + [], + [ 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', @@ -370,9 +370,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase null, null, 'php://input', - $headers = [], - $cookies = [], - $queryParams = [ + [], + [], + [ 'response_type' => 'code', 'client_id' => 'foo', 'redirect_uri' => 'http://foo/bar', @@ -652,9 +652,10 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase */ public function testRespondToAccessTokenRequestMissingRedirectUri() { + $client = new ClientEntity(); + $client->setIdentifier('foo'); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); - $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); - $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); $grant = new AuthCodeGrant( $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), @@ -662,10 +663,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); - $grant->setAccessTokenRepository($accessTokenRepositoryMock); - $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); - $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $request = new ServerRequest( [], @@ -677,11 +675,69 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase [], [], [ + 'client_id' => 'foo', 'grant_type' => 'authorization_code', + 'code' => $this->cryptStub->doEncrypt( + json_encode( + [ + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, + 'client_id' => 'foo', + 'redirect_uri' => 'http://foo/bar', + ] + ) + ), + ] + ); + + $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M')); + } + + /** + * @expectedException \League\OAuth2\Server\Exception\OAuthServerException + * @expectedExceptionCode 3 + */ + public function testRespondToAccessTokenRequestRedirectUriMismatch() + { + $client = new ClientEntity(); + $client->setIdentifier('foo'); + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + + $grant = new AuthCodeGrant( + $this->getMockBuilder(AuthCodeRepositoryInterface::class)->getMock(), + $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(), + new \DateInterval('PT10M') + ); + $grant->setClientRepository($clientRepositoryMock); + $grant->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + + $request = new ServerRequest( + [], + [], + null, + 'POST', + 'php://input', + [], + [], + [], + [ + 'client_id' => 'foo', + 'grant_type' => 'authorization_code', + 'redirect_uri' => 'http://bar/foo', + 'code' => $this->cryptStub->doEncrypt( + json_encode( + [ + 'auth_code_id' => uniqid(), + 'expire_time' => time() + 3600, + 'client_id' => 'foo', + 'redirect_uri' => 'http://foo/bar', + ] + ) + ), ] ); - /* @var StubResponseType $response */ $grant->respondToAccessTokenRequest($request, new StubResponseType(), new \DateInterval('PT10M')); } From c3a4670c1103137df1269e547d2ef460f1e2308f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Unger?= Date: Sat, 9 Jul 2016 01:00:44 +0200 Subject: [PATCH 16/36] Updated PHPDoc --- src/AuthorizationServer.php | 55 ++++++------ .../BearerTokenValidator.php | 6 +- src/CryptKey.php | 3 +- src/CryptTrait.php | 11 ++- src/Entities/AccessTokenEntityInterface.php | 2 +- src/Entities/RefreshTokenEntityInterface.php | 4 +- src/Entities/TokenInterface.php | 4 +- src/Entities/Traits/AccessTokenTrait.php | 2 +- src/Entities/Traits/ClientTrait.php | 6 ++ src/Entities/Traits/RefreshTokenTrait.php | 9 +- src/Entities/Traits/TokenEntityTrait.php | 13 ++- src/Exception/OAuthServerException.php | 15 ++-- src/Grant/AbstractGrant.php | 88 +++++++++++-------- src/Grant/AuthCodeGrant.php | 23 +++-- src/Grant/ClientCredentialsGrant.php | 1 + src/Grant/GrantTypeInterface.php | 29 +++--- src/Grant/ImplicitGrant.php | 14 +-- src/Grant/PasswordGrant.php | 13 +-- src/Grant/RefreshTokenGrant.php | 9 +- .../AuthorizationServerMiddleware.php | 14 ++- src/Middleware/ResourceServerMiddleware.php | 12 ++- .../AccessTokenRepositoryInterface.php | 9 +- .../AuthCodeRepositoryInterface.php | 5 +- .../ClientRepositoryInterface.php | 7 +- .../RefreshTokenRepositoryInterface.php | 3 +- src/Repositories/RepositoryInterface.php | 1 + src/Repositories/ScopeRepositoryInterface.php | 12 +-- src/Repositories/UserRepositoryInterface.php | 11 +-- src/RequestEvent.php | 7 +- src/RequestTypes/AuthorizationRequest.php | 6 +- src/ResourceServer.php | 24 ++--- src/ResponseTypes/AbstractResponseType.php | 5 +- src/ResponseTypes/BearerTokenResponse.php | 3 +- src/ResponseTypes/RedirectResponse.php | 9 ++ src/ResponseTypes/ResponseTypeInterface.php | 5 +- 35 files changed, 240 insertions(+), 200 deletions(-) diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index 6b7a972b..b46a574f 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -9,7 +9,6 @@ namespace League\OAuth2\Server; -use DateInterval; use League\Event\EmitterAwareInterface; use League\Event\EmitterAwareTrait; use League\OAuth2\Server\Exception\OAuthServerException; @@ -28,7 +27,7 @@ class AuthorizationServer implements EmitterAwareInterface use EmitterAwareTrait; /** - * @var \League\OAuth2\Server\Grant\GrantTypeInterface[] + * @var GrantTypeInterface[] */ protected $enabledGrantTypes = []; @@ -38,44 +37,44 @@ class AuthorizationServer implements EmitterAwareInterface protected $grantTypeAccessTokenTTL = []; /** - * @var \League\OAuth2\Server\CryptKey + * @var CryptKey */ protected $privateKey; /** - * @var \League\OAuth2\Server\CryptKey + * @var CryptKey */ protected $publicKey; /** - * @var ResponseTypeInterface + * @var null|ResponseTypeInterface */ protected $responseType; /** - * @var \League\OAuth2\Server\Repositories\ClientRepositoryInterface + * @var ClientRepositoryInterface */ private $clientRepository; /** - * @var \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface + * @var AccessTokenRepositoryInterface */ private $accessTokenRepository; /** - * @var \League\OAuth2\Server\Repositories\ScopeRepositoryInterface + * @var ScopeRepositoryInterface */ private $scopeRepository; /** * New server instance. * - * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository - * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository - * @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository - * @param \League\OAuth2\Server\CryptKey|string $privateKey - * @param \League\OAuth2\Server\CryptKey|string $publicKey - * @param null|\League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType + * @param ClientRepositoryInterface $clientRepository + * @param AccessTokenRepositoryInterface $accessTokenRepository + * @param ScopeRepositoryInterface $scopeRepository + * @param CryptKey|string $privateKey + * @param CryptKey|string $publicKey + * @param null|ResponseTypeInterface $responseType */ public function __construct( ClientRepositoryInterface $clientRepository, @@ -105,12 +104,12 @@ class AuthorizationServer implements EmitterAwareInterface /** * Enable a grant type on the server. * - * @param \League\OAuth2\Server\Grant\GrantTypeInterface $grantType - * @param \DateInterval $accessTokenTTL + * @param GrantTypeInterface $grantType + * @param null|\DateInterval $accessTokenTTL */ - public function enableGrantType(GrantTypeInterface $grantType, DateInterval $accessTokenTTL = null) + public function enableGrantType(GrantTypeInterface $grantType, \DateInterval $accessTokenTTL = null) { - if ($accessTokenTTL instanceof DateInterval === false) { + if (!$accessTokenTTL instanceof \DateInterval) { $accessTokenTTL = new \DateInterval('PT1H'); } @@ -128,11 +127,11 @@ class AuthorizationServer implements EmitterAwareInterface /** * Validate an authorization request * - * @param \Psr\Http\Message\ServerRequestInterface $request + * @param ServerRequestInterface $request * - * @throws \League\OAuth2\Server\Exception\OAuthServerException + * @throws OAuthServerException * - * @return \League\OAuth2\Server\RequestTypes\AuthorizationRequest|null + * @return AuthorizationRequest */ public function validateAuthorizationRequest(ServerRequestInterface $request) { @@ -153,10 +152,10 @@ class AuthorizationServer implements EmitterAwareInterface /** * Complete an authorization request * - * @param \League\OAuth2\Server\RequestTypes\AuthorizationRequest $authRequest - * @param \Psr\Http\Message\ResponseInterface $response + * @param AuthorizationRequest $authRequest + * @param ResponseInterface $response * - * @return \Psr\Http\Message\ResponseInterface + * @return ResponseInterface */ public function completeAuthorizationRequest(AuthorizationRequest $authRequest, ResponseInterface $response) { @@ -168,12 +167,12 @@ class AuthorizationServer implements EmitterAwareInterface /** * Return an access token response. * - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param \Psr\Http\Message\ResponseInterface $response + * @param ServerRequestInterface $request + * @param ResponseInterface $response * - * @throws \League\OAuth2\Server\Exception\OAuthServerException + * @throws OAuthServerException * - * @return \Psr\Http\Message\ResponseInterface + * @return ResponseInterface */ public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response) { diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index 78f2b47c..f24d9abb 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -22,14 +22,12 @@ class BearerTokenValidator implements AuthorizationValidatorInterface use CryptTrait; /** - * @var \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface + * @var AccessTokenRepositoryInterface */ private $accessTokenRepository; /** - * BearerTokenValidator constructor. - * - * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository + * @param AccessTokenRepositoryInterface $accessTokenRepository */ public function __construct(AccessTokenRepositoryInterface $accessTokenRepository) { diff --git a/src/CryptKey.php b/src/CryptKey.php index 4ea05264..e088abcf 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -8,6 +8,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server; class CryptKey @@ -18,7 +19,7 @@ class CryptKey protected $keyPath; /** - * @var string + * @var null|string */ protected $passPhrase; diff --git a/src/CryptTrait.php b/src/CryptTrait.php index 1075ea12..d417e115 100644 --- a/src/CryptTrait.php +++ b/src/CryptTrait.php @@ -8,24 +8,25 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server; trait CryptTrait { /** - * @var \League\OAuth2\Server\CryptKey + * @var CryptKey */ protected $privateKey; /** - * @var \League\OAuth2\Server\CryptKey + * @var CryptKey */ protected $publicKey; /** * Set path to private key. * - * @param \League\OAuth2\Server\CryptKey $privateKey + * @param CryptKey $privateKey */ public function setPrivateKey(CryptKey $privateKey) { @@ -35,7 +36,7 @@ trait CryptTrait /** * Set path to public key. * - * @param \League\OAuth2\Server\CryptKey $publicKey + * @param CryptKey $publicKey */ public function setPublicKey(CryptKey $publicKey) { @@ -47,6 +48,8 @@ trait CryptTrait * * @param string $unencryptedData * + * @throws \LogicException + * * @return string */ protected function encrypt($unencryptedData) diff --git a/src/Entities/AccessTokenEntityInterface.php b/src/Entities/AccessTokenEntityInterface.php index 642cc99f..c297e267 100644 --- a/src/Entities/AccessTokenEntityInterface.php +++ b/src/Entities/AccessTokenEntityInterface.php @@ -16,7 +16,7 @@ interface AccessTokenEntityInterface extends TokenInterface /** * Generate a JWT from the access token * - * @param \League\OAuth2\Server\CryptKey $privateKey + * @param CryptKey $privateKey * * @return string */ diff --git a/src/Entities/RefreshTokenEntityInterface.php b/src/Entities/RefreshTokenEntityInterface.php index c0e7bc4f..05e86e00 100644 --- a/src/Entities/RefreshTokenEntityInterface.php +++ b/src/Entities/RefreshTokenEntityInterface.php @@ -42,14 +42,14 @@ interface RefreshTokenEntityInterface /** * Set the access token that the refresh token was associated with. * - * @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessToken + * @param AccessTokenEntityInterface $accessToken */ public function setAccessToken(AccessTokenEntityInterface $accessToken); /** * Get the access token that the refresh token was originally associated with. * - * @return \League\OAuth2\Server\Entities\AccessTokenEntityInterface + * @return AccessTokenEntityInterface */ public function getAccessToken(); } diff --git a/src/Entities/TokenInterface.php b/src/Entities/TokenInterface.php index f9e5992e..c842b09a 100644 --- a/src/Entities/TokenInterface.php +++ b/src/Entities/TokenInterface.php @@ -63,14 +63,14 @@ interface TokenInterface /** * Set the client that the token was issued to. * - * @param \League\OAuth2\Server\Entities\ClientEntityInterface $client + * @param ClientEntityInterface $client */ public function setClient(ClientEntityInterface $client); /** * Associate a scope with the token. * - * @param \League\OAuth2\Server\Entities\ScopeEntityInterface $scope + * @param ScopeEntityInterface $scope */ public function addScope(ScopeEntityInterface $scope); diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index 31a8eb48..741d6c19 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -21,7 +21,7 @@ trait AccessTokenTrait /** * Generate a JWT from the access token * - * @param \League\OAuth2\Server\CryptKey $privateKey + * @param CryptKey $privateKey * * @return string */ diff --git a/src/Entities/Traits/ClientTrait.php b/src/Entities/Traits/ClientTrait.php index 8e44ce09..fec76a6f 100644 --- a/src/Entities/Traits/ClientTrait.php +++ b/src/Entities/Traits/ClientTrait.php @@ -11,8 +11,14 @@ namespace League\OAuth2\Server\Entities\Traits; trait ClientTrait { + /** + * @var string + */ protected $name; + /** + * @var string|string[] + */ protected $redirectUri; /** diff --git a/src/Entities/Traits/RefreshTokenTrait.php b/src/Entities/Traits/RefreshTokenTrait.php index 0734daf1..fb9dbc68 100644 --- a/src/Entities/Traits/RefreshTokenTrait.php +++ b/src/Entities/Traits/RefreshTokenTrait.php @@ -9,7 +9,6 @@ namespace League\OAuth2\Server\Entities\Traits; -use DateTime; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; trait RefreshTokenTrait @@ -20,7 +19,7 @@ trait RefreshTokenTrait protected $accessToken; /** - * @var DateTime + * @var \DateTime */ protected $expiryDateTime; @@ -43,7 +42,7 @@ trait RefreshTokenTrait /** * Get the token's expiry date time. * - * @return DateTime + * @return \DateTime */ public function getExpiryDateTime() { @@ -53,9 +52,9 @@ trait RefreshTokenTrait /** * Set the date time when the token expires. * - * @param DateTime $dateTime + * @param \DateTime $dateTime */ - public function setExpiryDateTime(DateTime $dateTime) + public function setExpiryDateTime(\DateTime $dateTime) { $this->expiryDateTime = $dateTime; } diff --git a/src/Entities/Traits/TokenEntityTrait.php b/src/Entities/Traits/TokenEntityTrait.php index 61c1ef3c..0b5608cd 100644 --- a/src/Entities/Traits/TokenEntityTrait.php +++ b/src/Entities/Traits/TokenEntityTrait.php @@ -9,7 +9,6 @@ namespace League\OAuth2\Server\Entities\Traits; -use DateTime; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; @@ -21,7 +20,7 @@ trait TokenEntityTrait protected $scopes = []; /** - * @var DateTime + * @var \DateTime */ protected $expiryDateTime; @@ -38,7 +37,7 @@ trait TokenEntityTrait /** * Associate a scope with the token. * - * @param \League\OAuth2\Server\Entities\ScopeEntityInterface $scope + * @param ScopeEntityInterface $scope */ public function addScope(ScopeEntityInterface $scope) { @@ -58,7 +57,7 @@ trait TokenEntityTrait /** * Get the token's expiry date time. * - * @return DateTime + * @return \DateTime */ public function getExpiryDateTime() { @@ -68,9 +67,9 @@ trait TokenEntityTrait /** * Set the date time when the token expires. * - * @param DateTime $dateTime + * @param \DateTime $dateTime */ - public function setExpiryDateTime(DateTime $dateTime) + public function setExpiryDateTime(\DateTime $dateTime) { $this->expiryDateTime = $dateTime; } @@ -108,7 +107,7 @@ trait TokenEntityTrait /** * Set the client that the token was issued to. * - * @param \League\OAuth2\Server\Entities\ClientEntityInterface $client + * @param ClientEntityInterface $client */ public function setClient(ClientEntityInterface $client) { diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index 4a6e1832..1d1336a5 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -69,7 +69,7 @@ class OAuthServerException extends \Exception * Invalid request error. * * @param string $parameter The invalid parameter - * @param string|null $hint + * @param null|string $hint * * @return static */ @@ -143,7 +143,7 @@ class OAuthServerException extends \Exception /** * Invalid refresh token. * - * @param string|null $hint + * @param null|string $hint * * @return static */ @@ -155,8 +155,8 @@ class OAuthServerException extends \Exception /** * Access denied. * - * @param string|null $hint - * @param string|null $redirectUri + * @param null|string $hint + * @param null|string $redirectUri * * @return static */ @@ -203,11 +203,10 @@ class OAuthServerException extends \Exception /** * Generate a HTTP response. * - * @param \Psr\Http\Message\ResponseInterface $response - * @param bool $useFragment True if errors should be in the URI fragment instead of - * query string + * @param ResponseInterface $response + * @param bool $useFragment True if errors should be in the URI fragment instead of query string * - * @return \Psr\Http\Message\ResponseInterface + * @return ResponseInterface */ public function generateHttpResponse(ResponseInterface $response, $useFragment = false) { diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 38336b76..2790e80f 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -13,7 +13,9 @@ namespace League\OAuth2\Server\Grant; use League\Event\EmitterAwareTrait; use League\OAuth2\Server\CryptTrait; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; +use League\OAuth2\Server\Entities\AuthCodeEntityInterface; use League\OAuth2\Server\Entities\ClientEntityInterface; +use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException; @@ -54,17 +56,17 @@ abstract class AbstractGrant implements GrantTypeInterface protected $scopeRepository; /** - * @var \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface + * @var AuthCodeRepositoryInterface */ protected $authCodeRepository; /** - * @var \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface + * @var RefreshTokenRepositoryInterface */ protected $refreshTokenRepository; /** - * @var \League\OAuth2\Server\Repositories\UserRepositoryInterface + * @var UserRepositoryInterface */ protected $userRepository; @@ -98,7 +100,7 @@ abstract class AbstractGrant implements GrantTypeInterface } /** - * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository + * @param RefreshTokenRepositoryInterface $refreshTokenRepository */ public function setRefreshTokenRepository(RefreshTokenRepositoryInterface $refreshTokenRepository) { @@ -106,7 +108,7 @@ abstract class AbstractGrant implements GrantTypeInterface } /** - * @param \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface $authCodeRepository + * @param AuthCodeRepositoryInterface $authCodeRepository */ public function setAuthCodeRepository(AuthCodeRepositoryInterface $authCodeRepository) { @@ -114,7 +116,7 @@ abstract class AbstractGrant implements GrantTypeInterface } /** - * @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository + * @param UserRepositoryInterface $userRepository */ public function setUserRepository(UserRepositoryInterface $userRepository) { @@ -132,11 +134,11 @@ abstract class AbstractGrant implements GrantTypeInterface /** * Validate the client. * - * @param \Psr\Http\Message\ServerRequestInterface $request + * @param ServerRequestInterface $request * - * @throws \League\OAuth2\Server\Exception\OAuthServerException + * @throws OAuthServerException * - * @return \League\OAuth2\Server\Entities\ClientEntityInterface + * @return ClientEntityInterface */ protected function validateClient(ServerRequestInterface $request) { @@ -189,9 +191,9 @@ abstract class AbstractGrant implements GrantTypeInterface * @param string $scopes * @param string $redirectUri * - * @throws \League\OAuth2\Server\Exception\OAuthServerException + * @throws OAuthServerException * - * @return \League\OAuth2\Server\Entities\ScopeEntityInterface[] + * @return ScopeEntityInterface[] */ public function validateScopes( $scopes, @@ -221,9 +223,9 @@ abstract class AbstractGrant implements GrantTypeInterface /** * Retrieve request parameter. * - * @param string $parameter - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param mixed $default + * @param string $parameter + * @param ServerRequestInterface $request + * @param mixed $default * * @return null|string */ @@ -241,7 +243,8 @@ abstract class AbstractGrant implements GrantTypeInterface * not exist, or is otherwise an invalid HTTP Basic header, return * [null, null]. * - * @param \Psr\Http\Message\ServerRequestInterface $request + * @param ServerRequestInterface $request + * * @return string[]|null[] */ protected function getBasicAuthCredentials(ServerRequestInterface $request) @@ -269,9 +272,9 @@ abstract class AbstractGrant implements GrantTypeInterface /** * Retrieve query string parameter. * - * @param string $parameter - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param mixed $default + * @param string $parameter + * @param ServerRequestInterface $request + * @param mixed $default * * @return null|string */ @@ -283,9 +286,9 @@ abstract class AbstractGrant implements GrantTypeInterface /** * Retrieve cookie parameter. * - * @param string $parameter - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param mixed $default + * @param string $parameter + * @param ServerRequestInterface $request + * @param mixed $default * * @return null|string */ @@ -297,9 +300,9 @@ abstract class AbstractGrant implements GrantTypeInterface /** * Retrieve server parameter. * - * @param string $parameter - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param mixed $default + * @param string $parameter + * @param ServerRequestInterface $request + * @param mixed $default * * @return null|string */ @@ -311,12 +314,15 @@ abstract class AbstractGrant implements GrantTypeInterface /** * Issue an access token. * - * @param \DateInterval $accessTokenTTL - * @param \League\OAuth2\Server\Entities\ClientEntityInterface $client - * @param string $userIdentifier - * @param \League\OAuth2\Server\Entities\ScopeEntityInterface[] $scopes + * @param \DateInterval $accessTokenTTL + * @param ClientEntityInterface $client + * @param string $userIdentifier + * @param ScopeEntityInterface[] $scopes * - * @return \League\OAuth2\Server\Entities\AccessTokenEntityInterface + * @throws OAuthServerException + * @throws UniqueTokenIdentifierConstraintViolationException + * + * @return AccessTokenEntityInterface */ protected function issueAccessToken( \DateInterval $accessTokenTTL, @@ -351,13 +357,16 @@ abstract class AbstractGrant implements GrantTypeInterface /** * Issue an auth code. * - * @param \DateInterval $authCodeTTL - * @param \League\OAuth2\Server\Entities\ClientEntityInterface $client - * @param string $userIdentifier - * @param string $redirectUri - * @param \League\OAuth2\Server\Entities\ScopeEntityInterface[] $scopes + * @param \DateInterval $authCodeTTL + * @param ClientEntityInterface $client + * @param string $userIdentifier + * @param string $redirectUri + * @param ScopeEntityInterface[] $scopes * - * @return \League\OAuth2\Server\Entities\AuthCodeEntityInterface + * @throws OAuthServerException + * @throws UniqueTokenIdentifierConstraintViolationException + * + * @return AuthCodeEntityInterface */ protected function issueAuthCode( \DateInterval $authCodeTTL, @@ -392,9 +401,12 @@ abstract class AbstractGrant implements GrantTypeInterface } /** - * @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessToken + * @param AccessTokenEntityInterface $accessToken * - * @return \League\OAuth2\Server\Entities\RefreshTokenEntityInterface + * @throws OAuthServerException + * @throws UniqueTokenIdentifierConstraintViolationException + * + * @return RefreshTokenEntityInterface */ protected function issueRefreshToken(AccessTokenEntityInterface $accessToken) { @@ -422,7 +434,7 @@ abstract class AbstractGrant implements GrantTypeInterface * * @param int $length * - * @throws \League\OAuth2\Server\Exception\OAuthServerException + * @throws OAuthServerException * * @return string */ diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index aba20aea..babf3d56 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -9,7 +9,6 @@ namespace League\OAuth2\Server\Grant; -use DateInterval; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; use League\OAuth2\Server\Entities\UserEntityInterface; @@ -35,9 +34,9 @@ class AuthCodeGrant extends AbstractAuthorizeGrant private $enableCodeExchangeProof = false; /** - * @param \League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface $authCodeRepository - * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository - * @param \DateInterval $authCodeTTL + * @param AuthCodeRepositoryInterface $authCodeRepository + * @param RefreshTokenRepositoryInterface $refreshTokenRepository + * @param \DateInterval $authCodeTTL */ public function __construct( AuthCodeRepositoryInterface $authCodeRepository, @@ -58,18 +57,18 @@ class AuthCodeGrant extends AbstractAuthorizeGrant /** * Respond to an access token request. * - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType - * @param \DateInterval $accessTokenTTL + * @param ServerRequestInterface $request + * @param ResponseTypeInterface $responseType + * @param \DateInterval $accessTokenTTL * - * @throws \League\OAuth2\Server\Exception\OAuthServerException + * @throws OAuthServerException * - * @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface + * @return ResponseTypeInterface */ public function respondToAccessTokenRequest( ServerRequestInterface $request, ResponseTypeInterface $responseType, - DateInterval $accessTokenTTL + \DateInterval $accessTokenTTL ) { // Validate request $client = $this->validateClient($request); @@ -221,7 +220,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant false ); - if ($client instanceof ClientEntityInterface === false) { + if (!$client instanceof ClientEntityInterface) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); throw OAuthServerException::invalidClient(); } @@ -285,7 +284,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant */ public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest) { - if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) { + if (!$authorizationRequest->getUser() instanceof UserEntityInterface) { throw new \LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest'); } diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index c8ff2d52..b5b968d4 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -8,6 +8,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\Grant; use League\OAuth2\Server\ResponseTypes\ResponseTypeInterface; diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index c0ffdd9c..c01a571d 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -8,6 +8,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\Grant; use League\Event\EmitterAwareInterface; @@ -41,11 +42,11 @@ interface GrantTypeInterface extends EmitterAwareInterface /** * Respond to an incoming request. * - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType - * @param \DateInterval $accessTokenTTL + * @param ServerRequestInterface $request + * @param ResponseTypeInterface $responseType + * @param \DateInterval $accessTokenTTL * - * @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface + * @return ResponseTypeInterface */ public function respondToAccessTokenRequest( ServerRequestInterface $request, @@ -56,7 +57,7 @@ interface GrantTypeInterface extends EmitterAwareInterface /** * The grant type should return true if it is able to response to an authorization request * - * @param \Psr\Http\Message\ServerRequestInterface $request + * @param ServerRequestInterface $request * * @return bool */ @@ -69,7 +70,7 @@ interface GrantTypeInterface extends EmitterAwareInterface * If the validation is successful an AuthorizationRequest object will be returned. This object can be safely * serialized in a user's session, and can be used during user authentication and authorization. * - * @param \Psr\Http\Message\ServerRequestInterface $request + * @param ServerRequestInterface $request * * @return AuthorizationRequest */ @@ -80,9 +81,9 @@ interface GrantTypeInterface extends EmitterAwareInterface * The AuthorizationRequest object's $userId property must be set to the authenticated user and the * $authorizationApproved property must reflect their desire to authorize or deny the client. * - * @param \League\OAuth2\Server\RequestTypes\AuthorizationRequest $authorizationRequest + * @param AuthorizationRequest $authorizationRequest * - * @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface + * @return ResponseTypeInterface */ public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest); @@ -91,7 +92,7 @@ interface GrantTypeInterface extends EmitterAwareInterface * * For example most grant types will check that the $_POST['grant_type'] property matches it's identifier property. * - * @param \Psr\Http\Message\ServerRequestInterface $request + * @param ServerRequestInterface $request * * @return bool */ @@ -100,35 +101,35 @@ interface GrantTypeInterface extends EmitterAwareInterface /** * Set the client repository. * - * @param \League\OAuth2\Server\Repositories\ClientRepositoryInterface $clientRepository + * @param ClientRepositoryInterface $clientRepository */ public function setClientRepository(ClientRepositoryInterface $clientRepository); /** * Set the access token repository. * - * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository + * @param AccessTokenRepositoryInterface $accessTokenRepository */ public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessTokenRepository); /** * Set the scope repository. * - * @param \League\OAuth2\Server\Repositories\ScopeRepositoryInterface $scopeRepository + * @param ScopeRepositoryInterface $scopeRepository */ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository); /** * Set the path to the private key. * - * @param \League\OAuth2\Server\CryptKey $privateKey + * @param CryptKey $privateKey */ public function setPrivateKey(CryptKey $privateKey); /** * Set the path to the public key. * - * @param \League\OAuth2\Server\CryptKey $publicKey + * @param CryptKey $publicKey */ public function setPublicKey(CryptKey $publicKey); } diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 6f415164..08585f15 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -45,7 +45,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant } /** - * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository + * @param RefreshTokenRepositoryInterface $refreshTokenRepository * * @throw \LogicException */ @@ -75,11 +75,11 @@ class ImplicitGrant extends AbstractAuthorizeGrant /** * Respond to an incoming request. * - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface $responseType - * @param \DateInterval $accessTokenTTL + * @param ServerRequestInterface $request + * @param ResponseTypeInterface $responseType + * @param \DateInterval $accessTokenTTL * - * @return \League\OAuth2\Server\ResponseTypes\ResponseTypeInterface + * @return ResponseTypeInterface */ public function respondToAccessTokenRequest( ServerRequestInterface $request, @@ -122,7 +122,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant false ); - if ($client instanceof ClientEntityInterface === false) { + if (!$client instanceof ClientEntityInterface) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); throw OAuthServerException::invalidClient(); } @@ -168,7 +168,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant */ public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest) { - if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) { + if (!$authorizationRequest->getUser() instanceof UserEntityInterface) { throw new \LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest'); } diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 86ba1e32..07eba5f1 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -8,6 +8,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\Grant; use League\OAuth2\Server\Entities\ClientEntityInterface; @@ -25,8 +26,8 @@ use Psr\Http\Message\ServerRequestInterface; class PasswordGrant extends AbstractGrant { /** - * @param \League\OAuth2\Server\Repositories\UserRepositoryInterface $userRepository - * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository + * @param UserRepositoryInterface $userRepository + * @param RefreshTokenRepositoryInterface $refreshTokenRepository */ public function __construct( UserRepositoryInterface $userRepository, @@ -66,12 +67,12 @@ class PasswordGrant extends AbstractGrant } /** - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param \League\OAuth2\Server\Entities\ClientEntityInterface $client + * @param ServerRequestInterface $request + * @param ClientEntityInterface $client * - * @throws \League\OAuth2\Server\Exception\OAuthServerException + * @throws OAuthServerException * - * @return \League\OAuth2\Server\Entities\UserEntityInterface + * @return UserEntityInterface */ protected function validateUser(ServerRequestInterface $request, ClientEntityInterface $client) { diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index d4d693a6..600eae8f 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -8,6 +8,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\Grant; use League\OAuth2\Server\Entities\ScopeEntityInterface; @@ -23,7 +24,7 @@ use Psr\Http\Message\ServerRequestInterface; class RefreshTokenGrant extends AbstractGrant { /** - * @param \League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface $refreshTokenRepository + * @param RefreshTokenRepositoryInterface $refreshTokenRepository */ public function __construct(RefreshTokenRepositoryInterface $refreshTokenRepository) { @@ -84,10 +85,10 @@ class RefreshTokenGrant extends AbstractGrant } /** - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param string $clientId + * @param ServerRequestInterface $request + * @param string $clientId * - * @throws \League\OAuth2\Server\Exception\OAuthServerException + * @throws OAuthServerException * * @return array */ diff --git a/src/Middleware/AuthorizationServerMiddleware.php b/src/Middleware/AuthorizationServerMiddleware.php index 6c2d08b2..a5f102fc 100644 --- a/src/Middleware/AuthorizationServerMiddleware.php +++ b/src/Middleware/AuthorizationServerMiddleware.php @@ -17,14 +17,12 @@ use Psr\Http\Message\ServerRequestInterface; class AuthorizationServerMiddleware { /** - * @var \League\OAuth2\Server\AuthorizationServer + * @var AuthorizationServer */ private $server; /** - * AuthorizationServerMiddleware constructor. - * - * @param \League\OAuth2\Server\AuthorizationServer $server + * @param AuthorizationServer $server */ public function __construct(AuthorizationServer $server) { @@ -32,11 +30,11 @@ class AuthorizationServerMiddleware } /** - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param \Psr\Http\Message\ResponseInterface $response - * @param callable $next + * @param ServerRequestInterface $request + * @param ResponseInterface $response + * @param callable $next * - * @return \Psr\Http\Message\ResponseInterface + * @return ResponseInterface */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) { diff --git a/src/Middleware/ResourceServerMiddleware.php b/src/Middleware/ResourceServerMiddleware.php index 9e235c35..56d28aee 100644 --- a/src/Middleware/ResourceServerMiddleware.php +++ b/src/Middleware/ResourceServerMiddleware.php @@ -17,14 +17,12 @@ use Psr\Http\Message\ServerRequestInterface; class ResourceServerMiddleware { /** - * @var \League\OAuth2\Server\ResourceServer + * @var ResourceServer */ private $server; /** - * ResourceServerMiddleware constructor. - * - * @param \League\OAuth2\Server\ResourceServer $server + * @param ResourceServer $server */ public function __construct(ResourceServer $server) { @@ -32,9 +30,9 @@ class ResourceServerMiddleware } /** - * @param \Psr\Http\Message\ServerRequestInterface $request - * @param \Psr\Http\Message\ResponseInterface $response - * @param callable $next + * @param ServerRequestInterface $request + * @param ResponseInterface $response + * @param callable $next * * @return \Psr\Http\Message\ResponseInterface */ diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index aab8eab8..04e98bc6 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -11,6 +11,7 @@ namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\ClientEntityInterface; +use League\OAuth2\Server\Entities\ScopeEntityInterface; /** * Access token interface. @@ -20,9 +21,9 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface /** * Create a new access token * - * @param \League\OAuth2\Server\Entities\ClientEntityInterface $clientEntity - * @param \League\OAuth2\Server\Entities\ScopeEntityInterface[] $scopes - * @param mixed $userIdentifier + * @param ClientEntityInterface $clientEntity + * @param ScopeEntityInterface[] $scopes + * @param mixed $userIdentifier * * @return AccessTokenEntityInterface */ @@ -31,7 +32,7 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface /** * Persists a new access token to permanent storage. * - * @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessTokenEntity + * @param AccessTokenEntityInterface $accessTokenEntity */ public function persistNewAccessToken(AccessTokenEntityInterface $accessTokenEntity); diff --git a/src/Repositories/AuthCodeRepositoryInterface.php b/src/Repositories/AuthCodeRepositoryInterface.php index cfe3b4d8..4d23439a 100644 --- a/src/Repositories/AuthCodeRepositoryInterface.php +++ b/src/Repositories/AuthCodeRepositoryInterface.php @@ -6,6 +6,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\AuthCodeEntityInterface; @@ -18,14 +19,14 @@ interface AuthCodeRepositoryInterface extends RepositoryInterface /** * Creates a new AuthCode * - * @return \League\OAuth2\Server\Entities\AuthCodeEntityInterface + * @return AuthCodeEntityInterface */ public function getNewAuthCode(); /** * Persists a new auth code to permanent storage. * - * @param \League\OAuth2\Server\Entities\AuthCodeEntityInterface $authCodeEntity + * @param AuthCodeEntityInterface $authCodeEntity */ public function persistNewAuthCode(AuthCodeEntityInterface $authCodeEntity); diff --git a/src/Repositories/ClientRepositoryInterface.php b/src/Repositories/ClientRepositoryInterface.php index fc56c2f3..34adf56a 100644 --- a/src/Repositories/ClientRepositoryInterface.php +++ b/src/Repositories/ClientRepositoryInterface.php @@ -6,8 +6,11 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\Repositories; +use League\OAuth2\Server\Entities\ClientEntityInterface; + /** * Client storage interface. */ @@ -19,10 +22,10 @@ interface ClientRepositoryInterface extends RepositoryInterface * @param string $clientIdentifier The client's identifier * @param string $grantType The grant type used * @param null|string $clientSecret The client's secret (if sent) - * @param bool $mustValidateSecret If true the client must attempt to validate the secret unless the client + * @param bool $mustValidateSecret If true the client must attempt to validate the secret if the client * is confidential * - * @return \League\OAuth2\Server\Entities\ClientEntityInterface + * @return ClientEntityInterface */ public function getClientEntity($clientIdentifier, $grantType, $clientSecret = null, $mustValidateSecret = true); } diff --git a/src/Repositories/RefreshTokenRepositoryInterface.php b/src/Repositories/RefreshTokenRepositoryInterface.php index 49d3ea4a..d7e686cc 100644 --- a/src/Repositories/RefreshTokenRepositoryInterface.php +++ b/src/Repositories/RefreshTokenRepositoryInterface.php @@ -6,6 +6,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; @@ -25,7 +26,7 @@ interface RefreshTokenRepositoryInterface extends RepositoryInterface /** * Create a new refresh token_name. * - * @param \League\OAuth2\Server\Entities\RefreshTokenEntityInterface $refreshTokenEntity + * @param RefreshTokenEntityInterface $refreshTokenEntity */ public function persistNewRefreshToken(RefreshTokenEntityInterface $refreshTokenEntity); diff --git a/src/Repositories/RepositoryInterface.php b/src/Repositories/RepositoryInterface.php index 3e50d4de..9c27b4b0 100644 --- a/src/Repositories/RepositoryInterface.php +++ b/src/Repositories/RepositoryInterface.php @@ -6,6 +6,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\Repositories; /** diff --git a/src/Repositories/ScopeRepositoryInterface.php b/src/Repositories/ScopeRepositoryInterface.php index 568f0e57..52db05de 100644 --- a/src/Repositories/ScopeRepositoryInterface.php +++ b/src/Repositories/ScopeRepositoryInterface.php @@ -22,7 +22,7 @@ interface ScopeRepositoryInterface extends RepositoryInterface * * @param string $identifier The scope identifier * - * @return \League\OAuth2\Server\Entities\ScopeEntityInterface + * @return ScopeEntityInterface */ public function getScopeEntityByIdentifier($identifier); @@ -30,12 +30,12 @@ interface ScopeRepositoryInterface extends RepositoryInterface * Given a client, grant type and optional user identifier validate the set of scopes requested are valid and optionally * append additional scopes or remove requested scopes. * - * @param ScopeEntityInterface[] $scopes - * @param string $grantType - * @param \League\OAuth2\Server\Entities\ClientEntityInterface $clientEntity - * @param null|string $userIdentifier + * @param ScopeEntityInterface[] $scopes + * @param string $grantType + * @param ClientEntityInterface $clientEntity + * @param null|string $userIdentifier * - * @return \League\OAuth2\Server\Entities\ScopeEntityInterface[] + * @return ScopeEntityInterface[] */ public function finalizeScopes( array $scopes, diff --git a/src/Repositories/UserRepositoryInterface.php b/src/Repositories/UserRepositoryInterface.php index b2de24d6..0a9efef0 100644 --- a/src/Repositories/UserRepositoryInterface.php +++ b/src/Repositories/UserRepositoryInterface.php @@ -10,18 +10,19 @@ namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\ClientEntityInterface; +use League\OAuth2\Server\Entities\UserEntityInterface; interface UserRepositoryInterface extends RepositoryInterface { /** * Get a user entity. * - * @param string $username - * @param string $password - * @param string $grantType The grant type used - * @param \League\OAuth2\Server\Entities\ClientEntityInterface $clientEntity + * @param string $username + * @param string $password + * @param string $grantType The grant type used + * @param ClientEntityInterface $clientEntity * - * @return \League\OAuth2\Server\Entities\UserEntityInterface + * @return UserEntityInterface */ public function getUserEntityByUserCredentials( $username, diff --git a/src/RequestEvent.php b/src/RequestEvent.php index 42ce47b2..1558e11f 100644 --- a/src/RequestEvent.php +++ b/src/RequestEvent.php @@ -6,6 +6,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server; use League\Event\Event; @@ -18,15 +19,15 @@ class RequestEvent extends Event const REFRESH_TOKEN_CLIENT_FAILED = 'refresh_token.client.failed'; /** - * @var \Psr\Http\Message\ServerRequestInterface + * @var ServerRequestInterface */ private $request; /** * RequestEvent constructor. * - * @param string $name - * @param \Psr\Http\Message\ServerRequestInterface $request + * @param string $name + * @param ServerRequestInterface $request */ public function __construct($name, ServerRequestInterface $request) { diff --git a/src/RequestTypes/AuthorizationRequest.php b/src/RequestTypes/AuthorizationRequest.php index 2a5fcd5f..ad67dafd 100644 --- a/src/RequestTypes/AuthorizationRequest.php +++ b/src/RequestTypes/AuthorizationRequest.php @@ -125,7 +125,7 @@ class AuthorizationRequest } /** - * @return \League\OAuth2\Server\Entities\ScopeEntityInterface[] + * @return ScopeEntityInterface[] */ public function getScopes() { @@ -133,9 +133,9 @@ class AuthorizationRequest } /** - * @param \League\OAuth2\Server\Entities\ScopeEntityInterface[] $scopes + * @param ScopeEntityInterface[] $scopes */ - public function setScopes($scopes) + public function setScopes(array $scopes) { $this->scopes = $scopes; } diff --git a/src/ResourceServer.php b/src/ResourceServer.php index 6fe8b1fc..0fb8fbee 100644 --- a/src/ResourceServer.php +++ b/src/ResourceServer.php @@ -6,34 +6,38 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server; use League\OAuth2\Server\AuthorizationValidators\AuthorizationValidatorInterface; use League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator; +use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use Psr\Http\Message\ServerRequestInterface; class ResourceServer { /** - * @var \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface + * @var AccessTokenRepositoryInterface */ private $accessTokenRepository; + /** - * @var \League\OAuth2\Server\CryptKey|string + * @var CryptKey */ private $publicKey; + /** - * @var \League\OAuth2\Server\AuthorizationValidators\AuthorizationValidatorInterface|null + * @var null|AuthorizationValidatorInterface */ private $authorizationValidator; /** * New server instance. * - * @param \League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface $accessTokenRepository - * @param \League\OAuth2\Server\CryptKey|string $publicKey - * @param null|\League\OAuth2\Server\AuthorizationValidators\AuthorizationValidatorInterface $authorizationValidator + * @param AccessTokenRepositoryInterface $accessTokenRepository + * @param CryptKey|string $publicKey + * @param null|AuthorizationValidatorInterface $authorizationValidator */ public function __construct( AccessTokenRepositoryInterface $accessTokenRepository, @@ -51,7 +55,7 @@ class ResourceServer } /** - * @return \League\OAuth2\Server\AuthorizationValidators\AuthorizationValidatorInterface + * @return AuthorizationValidatorInterface */ protected function getAuthorizationValidator() { @@ -67,11 +71,11 @@ class ResourceServer /** * Determine the access token validity. * - * @param \Psr\Http\Message\ServerRequestInterface $request + * @param ServerRequestInterface $request * - * @throws \League\OAuth2\Server\Exception\OAuthServerException + * @throws OAuthServerException * - * @return \Psr\Http\Message\ServerRequestInterface + * @return ServerRequestInterface */ public function validateAuthenticatedRequest(ServerRequestInterface $request) { diff --git a/src/ResponseTypes/AbstractResponseType.php b/src/ResponseTypes/AbstractResponseType.php index 02ce842b..6e164392 100644 --- a/src/ResponseTypes/AbstractResponseType.php +++ b/src/ResponseTypes/AbstractResponseType.php @@ -8,6 +8,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\ResponseTypes; use League\OAuth2\Server\CryptTrait; @@ -19,12 +20,12 @@ abstract class AbstractResponseType implements ResponseTypeInterface use CryptTrait; /** - * @var \League\OAuth2\Server\Entities\AccessTokenEntityInterface + * @var AccessTokenEntityInterface */ protected $accessToken; /** - * @var \League\OAuth2\Server\Entities\RefreshTokenEntityInterface + * @var RefreshTokenEntityInterface */ protected $refreshToken; diff --git a/src/ResponseTypes/BearerTokenResponse.php b/src/ResponseTypes/BearerTokenResponse.php index a65ecaae..921f13b0 100644 --- a/src/ResponseTypes/BearerTokenResponse.php +++ b/src/ResponseTypes/BearerTokenResponse.php @@ -1,6 +1,6 @@ * @copyright Copyright (c) Alex Bilbie @@ -8,6 +8,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\ResponseTypes; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; diff --git a/src/ResponseTypes/RedirectResponse.php b/src/ResponseTypes/RedirectResponse.php index 575a49e7..e4639148 100644 --- a/src/ResponseTypes/RedirectResponse.php +++ b/src/ResponseTypes/RedirectResponse.php @@ -1,4 +1,13 @@ + * @copyright Copyright (c) Alex Bilbie + * @license http://mit-license.org/ + * + * @link https://github.com/thephpleague/oauth2-server + */ namespace League\OAuth2\Server\ResponseTypes; diff --git a/src/ResponseTypes/ResponseTypeInterface.php b/src/ResponseTypes/ResponseTypeInterface.php index a26466a7..9f358a53 100644 --- a/src/ResponseTypes/ResponseTypeInterface.php +++ b/src/ResponseTypes/ResponseTypeInterface.php @@ -8,6 +8,7 @@ * * @link https://github.com/thephpleague/oauth2-server */ + namespace League\OAuth2\Server\ResponseTypes; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; @@ -17,12 +18,12 @@ use Psr\Http\Message\ResponseInterface; interface ResponseTypeInterface { /** - * @param \League\OAuth2\Server\Entities\AccessTokenEntityInterface $accessToken + * @param AccessTokenEntityInterface $accessToken */ public function setAccessToken(AccessTokenEntityInterface $accessToken); /** - * @param \League\OAuth2\Server\Entities\RefreshTokenEntityInterface $refreshToken + * @param RefreshTokenEntityInterface $refreshToken */ public function setRefreshToken(RefreshTokenEntityInterface $refreshToken); From c874c59b9c1aef05fad35cc2fd4339f80aca0a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Unger?= Date: Sat, 9 Jul 2016 12:09:21 +0200 Subject: [PATCH 17/36] Explicitly compare to false when checking not instanceof --- src/AuthorizationServer.php | 8 ++++---- src/Grant/AbstractGrant.php | 4 ++-- src/Grant/AuthCodeGrant.php | 6 +++--- src/Grant/ImplicitGrant.php | 4 ++-- src/Grant/PasswordGrant.php | 2 +- src/Grant/RefreshTokenGrant.php | 2 +- src/ResourceServer.php | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index b46a574f..2cc48ab2 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -88,12 +88,12 @@ class AuthorizationServer implements EmitterAwareInterface $this->accessTokenRepository = $accessTokenRepository; $this->scopeRepository = $scopeRepository; - if (!$privateKey instanceof CryptKey) { + if ($privateKey instanceof CryptKey === false) { $privateKey = new CryptKey($privateKey); } $this->privateKey = $privateKey; - if (!$publicKey instanceof CryptKey) { + if ($publicKey instanceof CryptKey === false) { $publicKey = new CryptKey($publicKey); } $this->publicKey = $publicKey; @@ -109,7 +109,7 @@ class AuthorizationServer implements EmitterAwareInterface */ public function enableGrantType(GrantTypeInterface $grantType, \DateInterval $accessTokenTTL = null) { - if (!$accessTokenTTL instanceof \DateInterval) { + if ($accessTokenTTL instanceof \DateInterval === false) { $accessTokenTTL = new \DateInterval('PT1H'); } @@ -202,7 +202,7 @@ class AuthorizationServer implements EmitterAwareInterface */ protected function getResponseType() { - if (!$this->responseType instanceof ResponseTypeInterface) { + if ($this->responseType instanceof ResponseTypeInterface === false) { $this->responseType = new BearerTokenResponse(); } diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 2790e80f..e230c500 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -159,7 +159,7 @@ abstract class AbstractGrant implements GrantTypeInterface true ); - if (!$client instanceof ClientEntityInterface) { + if ($client instanceof ClientEntityInterface === false) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); throw OAuthServerException::invalidClient(); } @@ -210,7 +210,7 @@ abstract class AbstractGrant implements GrantTypeInterface foreach ($scopesList as $scopeItem) { $scope = $this->scopeRepository->getScopeEntityByIdentifier($scopeItem); - if (!$scope instanceof ScopeEntityInterface) { + if ($scope instanceof ScopeEntityInterface === false) { throw OAuthServerException::invalidScope($scopeItem, $redirectUri); } diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index babf3d56..df89400e 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -107,7 +107,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant foreach ($authCodePayload->scopes as $scopeId) { $scope = $this->scopeRepository->getScopeEntityByIdentifier($scopeId); - if (!$scope instanceof ScopeEntityInterface) { + if ($scope instanceof ScopeEntityInterface === false) { // @codeCoverageIgnoreStart throw OAuthServerException::invalidScope($scopeId); // @codeCoverageIgnoreEnd @@ -220,7 +220,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant false ); - if (!$client instanceof ClientEntityInterface) { + if ($client instanceof ClientEntityInterface === false) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); throw OAuthServerException::invalidClient(); } @@ -284,7 +284,7 @@ class AuthCodeGrant extends AbstractAuthorizeGrant */ public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest) { - if (!$authorizationRequest->getUser() instanceof UserEntityInterface) { + if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) { throw new \LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest'); } diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 08585f15..a85b70d4 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -122,7 +122,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant false ); - if (!$client instanceof ClientEntityInterface) { + if ($client instanceof ClientEntityInterface === false) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::CLIENT_AUTHENTICATION_FAILED, $request)); throw OAuthServerException::invalidClient(); } @@ -168,7 +168,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant */ public function completeAuthorizationRequest(AuthorizationRequest $authorizationRequest) { - if (!$authorizationRequest->getUser() instanceof UserEntityInterface) { + if ($authorizationRequest->getUser() instanceof UserEntityInterface === false) { throw new \LogicException('An instance of UserEntityInterface should be set on the AuthorizationRequest'); } diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 07eba5f1..31755613 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -92,7 +92,7 @@ class PasswordGrant extends AbstractGrant $this->getIdentifier(), $client ); - if (!$user instanceof UserEntityInterface) { + if ($user instanceof UserEntityInterface === false) { $this->getEmitter()->emit(new RequestEvent(RequestEvent::USER_AUTHENTICATION_FAILED, $request)); throw OAuthServerException::invalidCredentials(); diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 600eae8f..17448a92 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -51,7 +51,7 @@ class RefreshTokenGrant extends AbstractGrant $scopes = array_map(function ($scopeId) use ($client) { $scope = $this->scopeRepository->getScopeEntityByIdentifier($scopeId); - if (!$scope instanceof ScopeEntityInterface) { + if ($scope instanceof ScopeEntityInterface === false) { // @codeCoverageIgnoreStart throw OAuthServerException::invalidScope($scopeId); // @codeCoverageIgnoreEnd diff --git a/src/ResourceServer.php b/src/ResourceServer.php index 0fb8fbee..5e9c13f3 100644 --- a/src/ResourceServer.php +++ b/src/ResourceServer.php @@ -46,7 +46,7 @@ class ResourceServer ) { $this->accessTokenRepository = $accessTokenRepository; - if (!$publicKey instanceof CryptKey) { + if ($publicKey instanceof CryptKey === false) { $publicKey = new CryptKey($publicKey); } $this->publicKey = $publicKey; @@ -59,7 +59,7 @@ class ResourceServer */ protected function getAuthorizationValidator() { - if (!$this->authorizationValidator instanceof AuthorizationValidatorInterface) { + if ($this->authorizationValidator instanceof AuthorizationValidatorInterface === false) { $this->authorizationValidator = new BearerTokenValidator($this->accessTokenRepository); } From 57323f38f790f51c7527c37d42791341188b2367 Mon Sep 17 00:00:00 2001 From: Pierre Rineau Date: Wed, 13 Jul 2016 12:03:05 +0200 Subject: [PATCH 18/36] while(array_shift()) makes the AuthorizationServer class configuration mutable --- src/AuthorizationServer.php | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index 2cc48ab2..0517124a 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -135,14 +135,9 @@ class AuthorizationServer implements EmitterAwareInterface */ public function validateAuthorizationRequest(ServerRequestInterface $request) { - $authRequest = null; - $enabledGrantTypes = $this->enabledGrantTypes; - while ($authRequest === null && $grantType = array_shift($enabledGrantTypes)) { - /** @var \League\OAuth2\Server\Grant\GrantTypeInterface $grantType */ + foreach ($this->enabledGrantTypes as $grantType) { if ($grantType->canRespondToAuthorizationRequest($request)) { - $authRequest = $grantType->validateAuthorizationRequest($request); - - return $authRequest; + return $grantType->validateAuthorizationRequest($request); } } @@ -176,20 +171,18 @@ class AuthorizationServer implements EmitterAwareInterface */ public function respondToAccessTokenRequest(ServerRequestInterface $request, ResponseInterface $response) { - $tokenResponse = null; - while ($tokenResponse === null && $grantType = array_shift($this->enabledGrantTypes)) { - /** @var \League\OAuth2\Server\Grant\GrantTypeInterface $grantType */ + foreach ($this->enabledGrantTypes as $grantType) { if ($grantType->canRespondToAccessTokenRequest($request)) { $tokenResponse = $grantType->respondToAccessTokenRequest( $request, $this->getResponseType(), $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] ); - } - } - if ($tokenResponse instanceof ResponseTypeInterface) { - return $tokenResponse->generateHttpResponse($response); + if ($tokenResponse instanceof ResponseTypeInterface) { + return $tokenResponse->generateHttpResponse($response); + } + } } throw OAuthServerException::unsupportedGrantType(); From 090c01d3d18060e43a1dab3a5aa1375cb5085b67 Mon Sep 17 00:00:00 2001 From: Ian Littman Date: Sat, 16 Jul 2016 10:27:33 -0500 Subject: [PATCH 19/36] Allow easy addition of custom fields to Bearer token response --- src/ResponseTypes/BearerTokenResponse.php | 16 ++++++ .../ResponseTypes/BearerResponseTypeTest.php | 49 ++++++++++++++++++- .../BearerTokenResponseWithParams.php | 14 ++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/ResponseTypes/BearerTokenResponseWithParams.php diff --git a/src/ResponseTypes/BearerTokenResponse.php b/src/ResponseTypes/BearerTokenResponse.php index 921f13b0..ceeeed9d 100644 --- a/src/ResponseTypes/BearerTokenResponse.php +++ b/src/ResponseTypes/BearerTokenResponse.php @@ -11,6 +11,7 @@ namespace League\OAuth2\Server\ResponseTypes; +use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use Psr\Http\Message\ResponseInterface; @@ -48,6 +49,8 @@ class BearerTokenResponse extends AbstractResponseType $responseParams['refresh_token'] = $refreshToken; } + $responseParams = array_merge($this->getExtraParams($this->accessToken), $responseParams); + $response = $response ->withStatus(200) ->withHeader('pragma', 'no-cache') @@ -58,4 +61,17 @@ class BearerTokenResponse extends AbstractResponseType return $response; } + + /** + * Add custom fields to your Bearer Token response here, then override + * AuthorizationServer::getResponseType() to pull in your version of + * this class rather than the default. + * + * @param AccessTokenEntityInterface $accessToken + * @return array + */ + protected function getExtraParams(AccessTokenEntityInterface $accessToken) + { + return []; + } } diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index 59955397..ca660ab7 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -61,6 +61,53 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase $this->assertTrue(isset($json->refresh_token)); } + public function testGenerateHttpResponseWithExtraParams() + { + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + + $responseType = new BearerTokenResponseWithParams($accessTokenRepositoryMock); + $responseType->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $responseType->setPublicKey(new CryptKey('file://' . __DIR__ . '/../Stubs/public.key')); + + $client = new ClientEntity(); + $client->setIdentifier('clientName'); + + $scope = new ScopeEntity(); + $scope->setIdentifier('basic'); + + $accessToken = new AccessTokenEntity(); + $accessToken->setIdentifier('abcdef'); + $accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H'))); + $accessToken->setClient($client); + $accessToken->addScope($scope); + + $refreshToken = new RefreshTokenEntity(); + $refreshToken->setIdentifier('abcdef'); + $refreshToken->setAccessToken($accessToken); + $refreshToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H'))); + + $responseType->setAccessToken($accessToken); + $responseType->setRefreshToken($refreshToken); + + $response = $responseType->generateHttpResponse(new Response()); + + $this->assertTrue($response instanceof ResponseInterface); + $this->assertEquals(200, $response->getStatusCode()); + $this->assertEquals('no-cache', $response->getHeader('pragma')[0]); + $this->assertEquals('no-store', $response->getHeader('cache-control')[0]); + $this->assertEquals('application/json; charset=UTF-8', $response->getHeader('content-type')[0]); + + $response->getBody()->rewind(); + $json = json_decode($response->getBody()->getContents()); + $this->assertEquals('Bearer', $json->token_type); + $this->assertTrue(isset($json->expires_in)); + $this->assertTrue(isset($json->access_token)); + $this->assertTrue(isset($json->refresh_token)); + + $this->assertTrue(isset($json->foo)); + $this->assertEquals('bar', $json->foo); + } + public function testDetermineAccessTokenInHeaderValidToken() { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); @@ -226,7 +273,7 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase ); } } - + public function testDetermineMissingBearerInHeader() { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); diff --git a/tests/ResponseTypes/BearerTokenResponseWithParams.php b/tests/ResponseTypes/BearerTokenResponseWithParams.php new file mode 100644 index 00000000..4ba09f4b --- /dev/null +++ b/tests/ResponseTypes/BearerTokenResponseWithParams.php @@ -0,0 +1,14 @@ + 'bar', 'token_type' => 'Should not overwrite']; + } +} From d8930af5eecd4ae453d2f2951e5d8463c1116133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Guti=C3=A9rrez?= Date: Tue, 19 Jul 2016 15:01:31 +0200 Subject: [PATCH 20/36] key file auto-generation from string --- src/CryptKey.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/CryptKey.php b/src/CryptKey.php index e088abcf..617bb8e8 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -13,6 +13,9 @@ namespace League\OAuth2\Server; class CryptKey { + const RSA_KEY_PATTERN = + '/^(-----BEGIN (RSA )?(PUBLIC|PRIVATE) KEY-----\n)(.|\n)+(-----END (RSA )?(PUBLIC|PRIVATE) KEY-----)$/'; + /** * @var string */ @@ -29,6 +32,10 @@ class CryptKey */ public function __construct($keyPath, $passPhrase = null) { + if (preg_match(self::RSA_KEY_PATTERN, $keyPath)) { + $keyPath = $this->saveKeyToFile($keyPath); + } + if (strpos($keyPath, 'file://') !== 0) { $keyPath = 'file://' . $keyPath; } @@ -41,6 +48,24 @@ class CryptKey $this->passPhrase = $passPhrase; } + /** + * @param string $key + * + * @return string + */ + private function saveKeyToFile($key) + { + $keyPath = sys_get_temp_dir() . '/' . sha1($key) . '.key'; + + if (!file_exists($keyPath) && !mkdir($keyPath)) { + throw new \RuntimeException('"%s" key file could not be created', $keyPath); + } + + file_put_contents($keyPath, $key); + + return 'file://' . $keyPath; + } + /** * Retrieve key path. * From 039537ebe26f29b31fe5eba1fe96675291a0be1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Guti=C3=A9rrez?= Date: Tue, 19 Jul 2016 15:06:32 +0200 Subject: [PATCH 21/36] touch! --- src/CryptKey.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CryptKey.php b/src/CryptKey.php index 617bb8e8..adcacfd3 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -57,7 +57,7 @@ class CryptKey { $keyPath = sys_get_temp_dir() . '/' . sha1($key) . '.key'; - if (!file_exists($keyPath) && !mkdir($keyPath)) { + if (!file_exists($keyPath) && !touch($keyPath)) { throw new \RuntimeException('"%s" key file could not be created', $keyPath); } From 065ef5db996c5bebc4eee840b791289b7c53aecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Guti=C3=A9rrez?= Date: Tue, 19 Jul 2016 17:15:36 +0200 Subject: [PATCH 22/36] CryptKey tests --- src/CryptKey.php | 4 ++++ tests/CryptKeyTest.php | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 tests/CryptKeyTest.php diff --git a/src/CryptKey.php b/src/CryptKey.php index adcacfd3..aedeafb0 100644 --- a/src/CryptKey.php +++ b/src/CryptKey.php @@ -51,6 +51,8 @@ class CryptKey /** * @param string $key * + * @throws \RuntimeException + * * @return string */ private function saveKeyToFile($key) @@ -58,7 +60,9 @@ class CryptKey $keyPath = sys_get_temp_dir() . '/' . sha1($key) . '.key'; if (!file_exists($keyPath) && !touch($keyPath)) { + // @codeCoverageIgnoreStart throw new \RuntimeException('"%s" key file could not be created', $keyPath); + // @codeCoverageIgnoreEnd } file_put_contents($keyPath, $key); diff --git a/tests/CryptKeyTest.php b/tests/CryptKeyTest.php new file mode 100644 index 00000000..c7f7f4a0 --- /dev/null +++ b/tests/CryptKeyTest.php @@ -0,0 +1,36 @@ +assertEquals('file://' . $keyFile, $key->getKeyPath()); + $this->assertEquals('secret', $key->getPassPhrase()); + } + + public function testKeyFileCreation() + { + $keyContent = file_get_contents(__DIR__ . '/Stubs/public.key'); + $key = new CryptKey($keyContent); + + $this->assertEquals( + 'file://' . sys_get_temp_dir() . '/' . sha1($keyContent) . '.key', + $key->getKeyPath() + ); + } +} From b8b92e59255ffe586ddd50a3975d7219ca9a8c38 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Tue, 26 Jul 2016 15:42:03 -0400 Subject: [PATCH 23/36] Changelog update --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49fb51e9..44c09559 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 5.1.1 (released 2016-07-26) + +* Improved test suite (Issue #614) +* Updated docblocks (Issue #616) +* Replace `array_shift` with `foreach` loop (Issue #621) +* Allow easy addition of custom fields to Bearer token response (Issue #624) +* Key file auto-generation from string (Issue #625) + ## 5.1.0 (released 2016-06-28) * Implemented RFC7636 (Issue #574) From d7df2f7e24a63dc52dcfccac4133d7c88dedd042 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Tue, 13 Sep 2016 15:16:58 +0100 Subject: [PATCH 24/36] Fix for #650 --- src/Grant/ImplicitGrant.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index a85b70d4..3e97d81f 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -150,6 +150,14 @@ class ImplicitGrant extends AbstractAuthorizeGrant ? $client->getRedirectUri()[0] : $client->getRedirectUri() ); + + // Finalize the requested scopes + $scopes = $this->scopeRepository->finalizeScopes( + $scopes, + $this->getIdentifier(), + $client, + $authCodePayload->user_id + ); $stateParameter = $this->getQueryStringParameter('state', $request); From 11ccc305d00d11bd0c293a399b5fb1be1bf5f0c3 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Tue, 13 Sep 2016 14:17:09 +0000 Subject: [PATCH 25/36] Applied fixes from StyleCI --- examples/public/api.php | 3 +-- examples/public/client_credentials.php | 4 ++-- examples/public/password.php | 8 +++----- examples/src/Repositories/ScopeRepository.php | 2 +- src/AuthorizationValidators/BearerTokenValidator.php | 2 +- .../UniqueTokenIdentifierConstraintViolationException.php | 1 - src/Grant/AbstractGrant.php | 3 +++ src/Grant/ImplicitGrant.php | 2 +- src/RequestTypes/AuthorizationRequest.php | 2 ++ src/ResponseTypes/BearerTokenResponse.php | 1 + tests/Grant/AuthCodeGrantTest.php | 1 - 11 files changed, 15 insertions(+), 14 deletions(-) diff --git a/examples/public/api.php b/examples/public/api.php index c386363c..3032ffed 100644 --- a/examples/public/api.php +++ b/examples/public/api.php @@ -31,7 +31,6 @@ $app->add( $app->get( '/users', function (ServerRequestInterface $request, ResponseInterface $response) use ($app) { - $users = [ [ 'id' => 123, @@ -70,4 +69,4 @@ $app->get( } ); -$app->run(); \ No newline at end of file +$app->run(); diff --git a/examples/public/client_credentials.php b/examples/public/client_credentials.php index e4b8ddff..c982f275 100644 --- a/examples/public/client_credentials.php +++ b/examples/public/client_credentials.php @@ -30,9 +30,9 @@ $app = new App([ $accessTokenRepository = new AccessTokenRepository(); // instance of AccessTokenRepositoryInterface // Path to public and private keys - $privateKey = 'file://'.__DIR__.'/../private.key'; + $privateKey = 'file://' . __DIR__ . '/../private.key'; //$privateKey = new CryptKey('file://path/to/private.key', 'passphrase'); // if private key has a pass phrase - $publicKey = 'file://'.__DIR__.'/../public.key'; + $publicKey = 'file://' . __DIR__ . '/../public.key'; // Setup the authorization server $server = new AuthorizationServer( diff --git a/examples/public/password.php b/examples/public/password.php index 75766477..02a85a56 100644 --- a/examples/public/password.php +++ b/examples/public/password.php @@ -23,8 +23,8 @@ $app = new App([ new ClientRepository(), // instance of ClientRepositoryInterface new AccessTokenRepository(), // instance of AccessTokenRepositoryInterface new ScopeRepository(), // instance of ScopeRepositoryInterface - 'file://'.__DIR__.'/../private.key', // path to private key - 'file://'.__DIR__.'/../public.key' // path to public key + 'file://' . __DIR__ . '/../private.key', // path to private key + 'file://' . __DIR__ . '/../public.key' // path to public key ); $grant = new PasswordGrant( @@ -54,19 +54,17 @@ $app->post( // Try to respond to the access token request return $server->respondToAccessTokenRequest($request, $response); - } catch (OAuthServerException $exception) { // All instances of OAuthServerException can be converted to a PSR-7 response return $exception->generateHttpResponse($response); - } catch (\Exception $exception) { // Catch unexpected exceptions $body = $response->getBody(); $body->write($exception->getMessage()); - return $response->withStatus(500)->withBody($body); + return $response->withStatus(500)->withBody($body); } } ); diff --git a/examples/src/Repositories/ScopeRepository.php b/examples/src/Repositories/ScopeRepository.php index f9879850..d050d55f 100644 --- a/examples/src/Repositories/ScopeRepository.php +++ b/examples/src/Repositories/ScopeRepository.php @@ -54,7 +54,7 @@ class ScopeRepository implements ScopeRepositoryInterface $scope->setIdentifier('email'); $scopes[] = $scope; } - + return $scopes; } } diff --git a/src/AuthorizationValidators/BearerTokenValidator.php b/src/AuthorizationValidators/BearerTokenValidator.php index f24d9abb..2bab4cb5 100644 --- a/src/AuthorizationValidators/BearerTokenValidator.php +++ b/src/AuthorizationValidators/BearerTokenValidator.php @@ -75,7 +75,7 @@ class BearerTokenValidator implements AuthorizationValidatorInterface } catch (\InvalidArgumentException $exception) { // JWT couldn't be parsed so return the request as is throw OAuthServerException::accessDenied($exception->getMessage()); - } catch(\RuntimeException $exception){ + } catch (\RuntimeException $exception) { //JWR couldn't be parsed so return the request as is throw OAuthServerException::accessDenied('Error while decoding to JSON'); } diff --git a/src/Exception/UniqueTokenIdentifierConstraintViolationException.php b/src/Exception/UniqueTokenIdentifierConstraintViolationException.php index 816c249f..a67855b2 100644 --- a/src/Exception/UniqueTokenIdentifierConstraintViolationException.php +++ b/src/Exception/UniqueTokenIdentifierConstraintViolationException.php @@ -9,7 +9,6 @@ namespace League\OAuth2\Server\Exception; - class UniqueTokenIdentifierConstraintViolationException extends OAuthServerException { public static function create() diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index e230c500..d916e3f1 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -345,6 +345,7 @@ abstract class AbstractGrant implements GrantTypeInterface $accessToken->setIdentifier($this->generateUniqueIdentifier()); try { $this->accessTokenRepository->persistNewAccessToken($accessToken); + return $accessToken; } catch (UniqueTokenIdentifierConstraintViolationException $e) { if ($maxGenerationAttempts === 0) { @@ -391,6 +392,7 @@ abstract class AbstractGrant implements GrantTypeInterface $authCode->setIdentifier($this->generateUniqueIdentifier()); try { $this->authCodeRepository->persistNewAuthCode($authCode); + return $authCode; } catch (UniqueTokenIdentifierConstraintViolationException $e) { if ($maxGenerationAttempts === 0) { @@ -420,6 +422,7 @@ abstract class AbstractGrant implements GrantTypeInterface $refreshToken->setIdentifier($this->generateUniqueIdentifier()); try { $this->refreshTokenRepository->persistNewRefreshToken($refreshToken); + return $refreshToken; } catch (UniqueTokenIdentifierConstraintViolationException $e) { if ($maxGenerationAttempts === 0) { diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 3e97d81f..ef1feb0c 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -150,7 +150,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant ? $client->getRedirectUri()[0] : $client->getRedirectUri() ); - + // Finalize the requested scopes $scopes = $this->scopeRepository->finalizeScopes( $scopes, diff --git a/src/RequestTypes/AuthorizationRequest.php b/src/RequestTypes/AuthorizationRequest.php index ad67dafd..41bfb509 100644 --- a/src/RequestTypes/AuthorizationRequest.php +++ b/src/RequestTypes/AuthorizationRequest.php @@ -66,12 +66,14 @@ class AuthorizationRequest /** * The code challenge (if provided) + * * @var string */ protected $codeChallenge; /** * The code challenge method (if provided) + * * @var string */ protected $codeChallengeMethod; diff --git a/src/ResponseTypes/BearerTokenResponse.php b/src/ResponseTypes/BearerTokenResponse.php index ceeeed9d..a57573a0 100644 --- a/src/ResponseTypes/BearerTokenResponse.php +++ b/src/ResponseTypes/BearerTokenResponse.php @@ -68,6 +68,7 @@ class BearerTokenResponse extends AbstractResponseType * this class rather than the default. * * @param AccessTokenEntityInterface $accessToken + * * @return array */ protected function getExtraParams(AccessTokenEntityInterface $accessToken) diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index 18420c16..498fdb4e 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -137,7 +137,6 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $this->assertTrue($grant->validateAuthorizationRequest($request) instanceof AuthorizationRequest); } - public function testValidateAuthorizationRequestCodeChallenge() { $client = new ClientEntity(); From b1bfff732526775160a3e59028f09e9da846cbd9 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Mon, 19 Sep 2016 10:05:55 +0100 Subject: [PATCH 26/36] Don't pass in user because we don't know who user is --- src/Grant/ImplicitGrant.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index ef1feb0c..62a48147 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -155,8 +155,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant $scopes = $this->scopeRepository->finalizeScopes( $scopes, $this->getIdentifier(), - $client, - $authCodePayload->user_id + $client ); $stateParameter = $this->getQueryStringParameter('state', $request); From 56e8d374fbb51c4d83139ab34c7523017de83817 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Mon, 19 Sep 2016 10:06:00 +0100 Subject: [PATCH 27/36] Fix broken tests --- tests/Grant/ImplicitGrantTest.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/Grant/ImplicitGrantTest.php b/tests/Grant/ImplicitGrantTest.php index f5f1feb2..0fc06370 100644 --- a/tests/Grant/ImplicitGrantTest.php +++ b/tests/Grant/ImplicitGrantTest.php @@ -9,11 +9,13 @@ use League\OAuth2\Server\Grant\ImplicitGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; +use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\RequestTypes\AuthorizationRequest; use League\OAuth2\Server\ResponseTypes\RedirectResponse; use LeagueTests\Stubs\AccessTokenEntity; use LeagueTests\Stubs\ClientEntity; use LeagueTests\Stubs\CryptTraitStub; +use LeagueTests\Stubs\ScopeEntity; use LeagueTests\Stubs\StubResponseType; use LeagueTests\Stubs\UserEntity; use Zend\Diactoros\ServerRequest; @@ -86,8 +88,14 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); + $scopeEntity = new ScopeEntity(); + $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); + $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); + $grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant->setClientRepository($clientRepositoryMock); + $grant->setScopeRepository($scopeRepositoryMock); $request = new ServerRequest( [], @@ -114,8 +122,14 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); + $scopeEntity = new ScopeEntity(); + $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); + $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); + $grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant->setClientRepository($clientRepositoryMock); + $grant->setScopeRepository($scopeRepositoryMock); $request = new ServerRequest( [], From e091d4812789cdce69dee43d300fd3707548a4aa Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Mon, 19 Sep 2016 10:23:42 +0100 Subject: [PATCH 28/36] Changelog bump --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44c09559..e21d5a30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.1.2 (released 2016-09-19) + +* Fixed `finalizeScopes` call (Issue #650) + ## 5.1.1 (released 2016-07-26) * Improved test suite (Issue #614) From c4a75b288086dc092368820fde0ac0a74e5f480a Mon Sep 17 00:00:00 2001 From: er0k Date: Tue, 11 Oct 2016 09:24:27 -0400 Subject: [PATCH 29/36] Increase the recommended RSA key length from 1024 to 2048 bits --- examples/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/README.md b/examples/README.md index bc785ee6..d8898b46 100644 --- a/examples/README.md +++ b/examples/README.md @@ -3,7 +3,7 @@ ## Installation 0. Run `composer install` in this directory to install dependencies -0. Create a private key `openssl genrsa -out private.key 1024` +0. Create a private key `openssl genrsa -out private.key 2048` 0. Create a public key `openssl rsa -in private.key -pubout > public.key` 0. `cd` into the public directory 0. Start a PHP server `php -S localhost:4444` From 01677a564e1cad0d091788435785996250a9860c Mon Sep 17 00:00:00 2001 From: jeremykendall Date: Tue, 11 Oct 2016 22:27:24 -0500 Subject: [PATCH 30/36] Fix WWW-Authenticate entry in $headers array In this context the header name should be the array key and the header value the array value. --- src/Exception/OAuthServerException.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Exception/OAuthServerException.php b/src/Exception/OAuthServerException.php index 1d1336a5..6ffa0fb1 100644 --- a/src/Exception/OAuthServerException.php +++ b/src/Exception/OAuthServerException.php @@ -267,7 +267,7 @@ class OAuthServerException extends \Exception ) { $authScheme = 'Bearer'; } - $headers[] = 'WWW-Authenticate: ' . $authScheme . ' realm="OAuth"'; + $headers['WWW-Authenticate'] = $authScheme . ' realm="OAuth"'; } // @codeCoverageIgnoreEnd return $headers; From f78dc2eca0774ec3958bbcf9b2a23d5ae61fb5aa Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Wed, 12 Oct 2016 15:08:15 +0100 Subject: [PATCH 31/36] Updated README --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e21d5a30..2ae31e9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 5.1.3 (released 2016-10-12) + +* Fixed WWW-Authenticate header (Issue #669) +* Increase the recommended RSA key length from 1024 to 2048 bits (Issue #668) + ## 5.1.2 (released 2016-09-19) * Fixed `finalizeScopes` call (Issue #650) From 25580b98b782500f4afde00b22eba179ea12241d Mon Sep 17 00:00:00 2001 From: Craig Duncan Date: Sun, 16 Oct 2016 16:48:44 +0100 Subject: [PATCH 32/36] [Travis] Test on PHP 7.1 --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eda7549c..13962424 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ php: - 5.5 - 5.6 - 7.0 + - 7.1 - hhvm install: @@ -21,4 +22,4 @@ script: branches: only: - - master \ No newline at end of file + - master From 518c1fcec57a170e09649df38738e06e6e7cbd46 Mon Sep 17 00:00:00 2001 From: George Wilson Date: Tue, 8 Nov 2016 12:27:49 +0000 Subject: [PATCH 33/36] Fix middleware example fatal error --- examples/public/middleware_use.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/examples/public/middleware_use.php b/examples/public/middleware_use.php index 2dfe1834..68b4ebc1 100644 --- a/examples/public/middleware_use.php +++ b/examples/public/middleware_use.php @@ -8,6 +8,7 @@ */ use League\OAuth2\Server\AuthorizationServer; +use League\OAuth2\Server\ResourceServer; use League\OAuth2\Server\Grant\AuthCodeGrant; use League\OAuth2\Server\Grant\RefreshTokenGrant; use League\OAuth2\Server\Middleware\AuthorizationServerMiddleware; @@ -66,6 +67,15 @@ $app = new App([ return $server; }, + ResourceServer::class => function () { + $publicKeyPath = 'file://' . __DIR__ . '/../public.key'; + + $server = new ResourceServer( + new AccessTokenRepository(), + $publicKeyPath + ); + return $server; + }, ]); // Access token issuer @@ -94,6 +104,6 @@ $app->group('/api', function () { return $response->withBody($body); }); -})->add(new ResourceServerMiddleware($app->getContainer()->get(AuthorizationServer::class))); +})->add(new ResourceServerMiddleware($app->getContainer()->get(ResourceServer::class))); $app->run(); From 90cb1bf012b8d1643f68593f3c1ee154d64d7ebd Mon Sep 17 00:00:00 2001 From: Sam Stenvall Date: Fri, 23 Dec 2016 00:30:54 +0200 Subject: [PATCH 34/36] Fix typo in the first README sentence --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de5f3471..dfaa938c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Quality Score](https://img.shields.io/scrutinizer/g/thephpleague/oauth2-server.svg?style=flat-square)](https://scrutinizer-ci.com/g/thephpleague/oauth2-server) [![Total Downloads](https://img.shields.io/packagist/dt/league/oauth2-server.svg?style=flat-square)](https://packagist.org/packages/league/oauth2-server) -`league/oauth2-server` is a a standards compliant implementation of an [OAuth 2.0](https://tools.ietf.org/html/rfc6749) authorization server written in PHP which makes working with OAuth 2.0 trivial. You can easily configure an OAuth 2.0 server to protect your API with access tokens, or allow clients to request new access tokens and refresh them. +`league/oauth2-server` is a standards compliant implementation of an [OAuth 2.0](https://tools.ietf.org/html/rfc6749) authorization server written in PHP which makes working with OAuth 2.0 trivial. You can easily configure an OAuth 2.0 server to protect your API with access tokens, or allow clients to request new access tokens and refresh them. It supports out of the box the following grants: From ded7c1ed47dd5f7cdf7af6409c47e5bdfada9313 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Thu, 2 Feb 2017 17:29:06 +0000 Subject: [PATCH 35/36] Mentioned PHP 7.1 support --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dfaa938c..8da0cf44 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ The following versions of PHP are supported: * PHP 5.5 (>=5.5.9) * PHP 5.6 * PHP 7.0 +* PHP 7.1 * HHVM The `openssl` extension is also required. From 13c608b849a6d805f119bf046651363171d6fe51 Mon Sep 17 00:00:00 2001 From: Toby Griffiths Date: Wed, 1 Mar 2017 13:08:42 +0000 Subject: [PATCH 36/36] Corrected DateInterval from 1 min to 1 month --- examples/public/middleware_use.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/public/middleware_use.php b/examples/public/middleware_use.php index 68b4ebc1..21f6bc23 100644 --- a/examples/public/middleware_use.php +++ b/examples/public/middleware_use.php @@ -62,7 +62,7 @@ $app = new App([ // Enable the refresh token grant on the server with a token TTL of 1 month $server->enableGrantType( new RefreshTokenGrant($refreshTokenRepository), - new \DateInterval('PT1M') + new \DateInterval('P1M') ); return $server;