From 4b775fe24139f212e8f7a7fd3155383ff370cb97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Guti=C3=A9rrez?= Date: Fri, 18 Mar 2016 00:25:32 +0100 Subject: [PATCH] include CryptTrait tests, allow Server::respondToRequest trhow exceptions and fix ResposeType tests --- src/CryptTrait.php | 2 +- src/Grant/AuthCodeGrant.php | 2 + src/Grant/ImplicitGrant.php | 6 +- src/Grant/RefreshTokenGrant.php | 2 + src/Server.php | 34 +++--- tests/Grant/AuthCodeGrantTest.php | 108 +++++++++--------- tests/Grant/ImplicitGrantTest.php | 82 ++++++------- tests/Grant/RefreshTokenGrantTest.php | 21 ++-- .../ResourceServerMiddlewareTest.php | 23 +++- .../ResponseTypes/BearerResponseTypeTest.php | 79 +++++++------ tests/ServerTest.php | 27 +++-- 11 files changed, 200 insertions(+), 186 deletions(-) diff --git a/src/CryptTrait.php b/src/CryptTrait.php index 844f810f..3c648b79 100644 --- a/src/CryptTrait.php +++ b/src/CryptTrait.php @@ -108,7 +108,7 @@ trait CryptTrait while ($encryptedData) { $chunk = substr($encryptedData, 0, $chunkSize); $encryptedData = substr($encryptedData, $chunkSize); - if (openssl_public_decrypt($chunk, $decrypted, $publicKey, OPENSSL_PKCS1_OAEP_PADDING) === false) { + if (openssl_public_decrypt($chunk, $decrypted, $publicKey/*, OPENSSL_PKCS1_OAEP_PADDING*/) === false) { // @codeCoverageIgnoreStart throw new \LogicException('Failed to decrypt data'); // @codeCoverageIgnoreEnd diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index b031e6e6..17ccf76c 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -282,7 +282,9 @@ class AuthCodeGrant extends AbstractAuthorizeGrant ); if (!$scope) { + // @codeCoverageIgnoreStart throw OAuthServerException::invalidScope($scopeId); + // @codeCoverageIgnoreEnd } $scopes[] = $scope; diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 573d869f..9b46d019 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -176,7 +176,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant } // The user has either approved or denied the client, so redirect them back - $redirectUri = new Uri($client->getRedirectUri()); + $redirectUri = $client->getRedirectUri(); $redirectPayload = []; $stateParameter = $this->getQueryStringParameter('state', $request); @@ -208,8 +208,6 @@ class ImplicitGrant extends AbstractAuthorizeGrant } // The user denied the client, redirect them back with an error - $exception = OAuthServerException::accessDenied('The user denied the request', (string) $redirectUri); - - return $exception->generateHttpResponse(null, true); + throw OAuthServerException::accessDenied('The user denied the request', (string) $redirectUri); } } diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index be0d803e..3dee1073 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -54,7 +54,9 @@ class RefreshTokenGrant extends AbstractGrant ); if (!$scope) { + // @codeCoverageIgnoreStart throw OAuthServerException::invalidScope($scopeId); + // @codeCoverageIgnoreEnd } return $scope; diff --git a/src/Server.php b/src/Server.php index 5e0f2190..e77a344b 100644 --- a/src/Server.php +++ b/src/Server.php @@ -127,27 +127,23 @@ class Server implements EmitterAwareInterface */ public function respondToRequest(ServerRequestInterface $request, ResponseInterface $response) { - try { - $tokenResponse = null; - while ($tokenResponse === null && $grantType = array_shift($this->enabledGrantTypes)) { - /** @var \League\OAuth2\Server\Grant\GrantTypeInterface $grantType */ - if ($grantType->canRespondToRequest($request)) { - $tokenResponse = $grantType->respondToRequest( - $request, - $this->getResponseType(), - $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] - ); - } + $tokenResponse = null; + while ($tokenResponse === null && $grantType = array_shift($this->enabledGrantTypes)) { + /** @var \League\OAuth2\Server\Grant\GrantTypeInterface $grantType */ + if ($grantType->canRespondToRequest($request)) { + $tokenResponse = $grantType->respondToRequest( + $request, + $this->getResponseType(), + $this->grantTypeAccessTokenTTL[$grantType->getIdentifier()] + ); } - - if ($tokenResponse instanceof ResponseTypeInterface) { - return $tokenResponse->generateHttpResponse($response); - } - - throw OAuthServerException::unsupportedGrantType(); - } catch (OAuthServerException $e) { - return $e->generateHttpResponse($response); } + + if ($tokenResponse instanceof ResponseTypeInterface) { + return $tokenResponse->generateHttpResponse($response); + } + + throw OAuthServerException::unsupportedGrantType(); } /** diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index 31cd2f53..44bba0fc 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -12,12 +12,15 @@ use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\Repositories\UserRepositoryInterface; +use League\OAuth2\Server\ResponseTypes\HtmlResponse; +use League\OAuth2\Server\ResponseTypes\RedirectResponse; use LeagueTests\Stubs\ClientEntity; use LeagueTests\Stubs\CryptTraitStub; use LeagueTests\Stubs\ScopeEntity; use LeagueTests\Stubs\StubResponseType; use LeagueTests\Stubs\UserEntity; use Psr\Http\Message\ResponseInterface; +use Zend\Diactoros\Response; use Zend\Diactoros\ServerRequest; class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase @@ -81,6 +84,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $userEntity = new UserEntity(); $userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity); + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + $grant = new AuthCodeGrant( $this->getMock(AuthCodeRepositoryInterface::class), $this->getMock(RefreshTokenRepositoryInterface::class), @@ -88,6 +94,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); @@ -102,10 +109,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'code', @@ -121,10 +125,16 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - $this->assertTrue($response instanceof ResponseInterface); + $this->assertTrue($response instanceof RedirectResponse); + + $response = $response->generateHttpResponse(new Response); $this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false); } + /** + * @expectedException \League\OAuth2\Server\Exception\OAuthServerException + * @expectedExceptionCode 9 + */ public function testRespondToAuthorizationRequestUserDenied() { $client = new ClientEntity(); @@ -136,6 +146,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $userEntity = new UserEntity(); $userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity); + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + $grant = new AuthCodeGrant( $this->getMock(AuthCodeRepositoryInterface::class), $this->getMock(RefreshTokenRepositoryInterface::class), @@ -143,6 +156,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); @@ -157,10 +171,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'code', @@ -174,11 +185,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase ] ); - $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - - $this->assertTrue($response instanceof ResponseInterface); - $this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false); - $this->assertTrue(strstr($response->getHeader('location')[0], 'access_denied') !== false); + $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); } /** @@ -217,10 +224,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'code', @@ -232,9 +236,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase ] ); - $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - - $this->assertTrue($response instanceof ResponseInterface); + $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); } public function testRespondToAuthorizationRequestBadClient() @@ -268,10 +270,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'code', @@ -323,10 +322,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'code', @@ -397,9 +393,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase ] ); - $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - - $this->assertTrue($response instanceof ResponseInterface); + $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); } public function testRespondToAuthorizationRequestTryLogin() @@ -413,6 +407,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $userEntity = new UserEntity(); $userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity); + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + $grant = new AuthCodeGrant( $this->getMock(AuthCodeRepositoryInterface::class), $this->getMock(RefreshTokenRepositoryInterface::class), @@ -420,6 +417,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); @@ -434,10 +432,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => null]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => null])), ], [ 'response_type' => 'code', @@ -452,7 +447,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - $this->assertTrue($response instanceof ResponseInterface); + $this->assertTrue($response instanceof RedirectResponse); + + $response = $response->generateHttpResponse(new Response); $this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false); } @@ -467,6 +464,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $userEntity = null; $userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity); + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + $grant = new AuthCodeGrant( $this->getMock(AuthCodeRepositoryInterface::class), $this->getMock(RefreshTokenRepositoryInterface::class), @@ -474,6 +474,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); @@ -488,10 +489,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => null]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => null])), ], [ 'response_type' => 'code', @@ -506,9 +504,11 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - $this->assertTrue($response instanceof ResponseInterface); + $this->assertTrue($response instanceof HtmlResponse); + + $response = $response->generateHttpResponse(new Response); $this->assertTrue(strstr($response->getHeader('content-type')[0], 'text/html') !== false); - $this->assertTrue(strstr($response->getBody()->getContents(), 'Incorrect username or password') !== false); + $this->assertTrue(strstr((string) $response->getBody(), 'Incorrect username or password') !== false); } public function testRespondToAuthorizationRequestShowAuthorizeForm() @@ -523,6 +523,9 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $userEntity = new UserEntity(); $userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity); + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + $grant = new AuthCodeGrant( $this->getMock(AuthCodeRepositoryInterface::class), $this->getMock(RefreshTokenRepositoryInterface::class), @@ -530,6 +533,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase new \DateInterval('PT10M') ); $grant->setClientRepository($clientRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); @@ -544,10 +548,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'code', @@ -561,6 +562,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); + $response = $response->generateHttpResponse(new Response); $this->assertTrue($response instanceof ResponseInterface); $this->assertTrue(strstr($response->getHeader('set-cookie')[0], 'oauth_authorize_request') !== false); } @@ -623,8 +625,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'scopes' => ['foo'], 'redirect_uri' => 'http://foo/bar', ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ), ] ); @@ -779,8 +780,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'scopes' => ['foo'], 'redirect_uri' => 'http://foo/bar', ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ), ] ); @@ -849,8 +849,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'scopes' => ['foo'], 'redirect_uri' => 'http://foo/bar', ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ), ] ); @@ -916,8 +915,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase 'scopes' => ['foo'], 'redirect_uri' => 'http://foo/bar', ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ), ] ); diff --git a/tests/Grant/ImplicitGrantTest.php b/tests/Grant/ImplicitGrantTest.php index 3c597978..e4e10db0 100644 --- a/tests/Grant/ImplicitGrantTest.php +++ b/tests/Grant/ImplicitGrantTest.php @@ -7,10 +7,12 @@ use League\OAuth2\Server\Grant\ImplicitGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\UserRepositoryInterface; +use League\OAuth2\Server\ResponseTypes\HtmlResponse; use LeagueTests\Stubs\ClientEntity; +use LeagueTests\Stubs\CryptTraitStub; use LeagueTests\Stubs\StubResponseType; use LeagueTests\Stubs\UserEntity; -use Psr\Http\Message\ResponseInterface; +use Zend\Diactoros\Response; use Zend\Diactoros\ServerRequest; class ImplicitGrantTest extends \PHPUnit_Framework_TestCase @@ -22,7 +24,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->cryptStub = new CryptTraitStub; + $this->cryptStub = new CryptTraitStub(); } public function testGetIdentifier() @@ -52,6 +54,10 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase $this->assertTrue($grant->canRespondToRequest($request)); } + /** + * @expectedException \League\OAuth2\Server\Exception\OAuthServerException + * @expectedExceptionCode 9 + */ public function testRespondToAuthorizationRequest() { $client = new ClientEntity(); @@ -95,10 +101,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase ] ); - $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - - $this->assertTrue($response instanceof ResponseInterface); - $this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false); + $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); } /** @@ -122,10 +125,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'token', @@ -137,9 +137,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase ] ); - $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - - $this->assertTrue($response instanceof ResponseInterface); + $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); } public function testRespondToAuthorizationRequestBadClient() @@ -164,10 +162,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'token', @@ -214,10 +209,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'token', @@ -283,9 +275,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase ] ); - $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - - $this->assertTrue($response instanceof ResponseInterface); + $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); } public function testRespondToAuthorizationRequestTryLogin() @@ -299,8 +289,12 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase $userEntity = new UserEntity(); $userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity); + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + $grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class)); $grant->setClientRepository($clientRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); @@ -315,10 +309,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => null]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => null])), ], [ 'response_type' => 'token', @@ -332,9 +323,10 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase ); $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - $this->assertTrue($response instanceof ResponseInterface); - $this->assertTrue(strstr($response->getHeader('content-type')[0], 'text/html') !== false); - $this->assertTrue(strstr($response->getBody()->getContents(), 'Incorrect username or password') !== false); + $this->assertTrue($response instanceof HtmlResponse); + + $response = $response->generateHttpResponse(new Response); + $this->assertTrue(strstr((string) $response->getBody(), 'Incorrect username or password') !== false); } public function testRespondToAuthorizationRequestShowAuthorizeForm() @@ -348,8 +340,12 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase $userEntity = new UserEntity(); $userRepositoryMock->method('getUserEntityByUserCredentials')->willReturn($userEntity); + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('persistNewAccessToken')->willReturnSelf(); + $grant = new ImplicitGrant($this->getMock(UserRepositoryInterface::class)); $grant->setClientRepository($clientRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $grant->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); @@ -364,10 +360,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'code', @@ -381,10 +374,16 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - $this->assertTrue($response instanceof ResponseInterface); + $this->assertTrue($response instanceof HtmlResponse); + + $response = $response->generateHttpResponse(new Response); $this->assertTrue(strstr($response->getHeader('set-cookie')[0], 'oauth_authorize_request') !== false); } + /** + * @expectedException \League\OAuth2\Server\Exception\OAuthServerException + * @expectedExceptionCode 9 + */ public function testRespondToAuthorizationRequestUserDenied() { $client = new ClientEntity(); @@ -412,10 +411,7 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase 'php://input', [], [ - 'oauth_authorize_request' => $this->cryptStub->doEncrypt( - json_encode(['user_id' => 123]), - 'file://' . __DIR__ . '/../Stubs/private.key' - ), + 'oauth_authorize_request' => $this->cryptStub->doEncrypt(json_encode(['user_id' => 123])), ], [ 'response_type' => 'code', @@ -429,10 +425,6 @@ class ImplicitGrantTest extends \PHPUnit_Framework_TestCase ] ); - $response = $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); - - $this->assertTrue($response instanceof ResponseInterface); - $this->assertTrue(strstr($response->getHeader('location')[0], 'http://foo/bar') !== false); - $this->assertTrue(strstr($response->getHeader('location')[0], 'access_denied') !== false); + $grant->respondToRequest($request, new StubResponseType(), new \DateInterval('PT10M')); } } diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index dc2056cb..0250855b 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -10,6 +10,7 @@ use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use LeagueTests\Stubs\ClientEntity; +use LeagueTests\Stubs\CryptTraitStub; use LeagueTests\Stubs\ScopeEntity; use LeagueTests\Stubs\StubResponseType; use Zend\Diactoros\ServerRequest; @@ -23,7 +24,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->cryptStub = new CryptTraitStub; + $this->cryptStub = new CryptTraitStub(); } public function testGetIdentifier() @@ -69,8 +70,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase 'user_id' => 123, 'expire_time' => time() + 3600, ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ); $serverRequest = new ServerRequest(); @@ -125,8 +125,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase 'user_id' => 123, 'expire_time' => time() + 3600, ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ); $serverRequest = new ServerRequest(); @@ -186,8 +185,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase 'user_id' => 123, 'expire_time' => time() + 3600, ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ); $serverRequest = new ServerRequest(); @@ -308,8 +306,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase 'user_id' => 123, 'expire_time' => time() + 3600, ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ); $serverRequest = new ServerRequest(); @@ -356,8 +353,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase 'user_id' => 123, 'expire_time' => time() - 3600, ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ); $serverRequest = new ServerRequest(); @@ -405,8 +401,7 @@ class RefreshTokenGrantTest extends \PHPUnit_Framework_TestCase 'user_id' => 123, 'expire_time' => time() + 3600, ] - ), - 'file://' . __DIR__ . '/../Stubs/private.key' + ) ); $serverRequest = new ServerRequest(); diff --git a/tests/Middleware/ResourceServerMiddlewareTest.php b/tests/Middleware/ResourceServerMiddlewareTest.php index 590ae438..aff01cce 100644 --- a/tests/Middleware/ResourceServerMiddlewareTest.php +++ b/tests/Middleware/ResourceServerMiddlewareTest.php @@ -2,11 +2,17 @@ namespace LeagueTests\Middleware; +use Lcobucci\JWT\Builder; +use Lcobucci\JWT\Signer\Key; +use Lcobucci\JWT\Signer\Rsa\Sha256; +use Lcobucci\JWT\Token; +use League\OAuth2\Server\Entities\AccessTokenEntity; use League\OAuth2\Server\Middleware\ResourceServerMiddleware; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\Server; +use LeagueTests\Stubs\ClientEntity; use LeagueTests\Stubs\StubResponseType; use Zend\Diactoros\Response; use Zend\Diactoros\ServerRequest; @@ -21,13 +27,24 @@ class ResourceServerMiddlewareTest extends \PHPUnit_Framework_TestCase $clientRepository, $this->getMock(AccessTokenRepositoryInterface::class), $this->getMock(ScopeRepositoryInterface::class), - '', - '', + 'file://' . __DIR__ . '/../Stubs/private.key', + 'file://' . __DIR__ . '/../Stubs/public.key', new StubResponseType() ); + $client = new ClientEntity(); + $client->setIdentifier('clientName'); + + $accessToken = new AccessTokenEntity(); + $accessToken->setIdentifier('test'); + $accessToken->setUserIdentifier(123); + $accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H'))); + $accessToken->setClient($client); + + $token = $accessToken->convertToJWT('file://' . __DIR__ . '/../Stubs/private.key'); + $request = new ServerRequest(); - $request = $request->withHeader('authorization', 'Basic test'); + $request = $request->withHeader('authorization', sprintf('Bearer %s', $token)); $middleware = new ResourceServerMiddleware($server); $response = $middleware->__invoke( diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index fb9b91ca..a8b62f0e 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -2,6 +2,7 @@ namespace LeagueTests\ResponseTypes; +use League\OAuth2\Server\AuthorizationValidators\BearerTokenValidator; use League\OAuth2\Server\Entities\AccessTokenEntity; use League\OAuth2\Server\Entities\RefreshTokenEntity; use League\OAuth2\Server\Exception\OAuthServerException; @@ -19,11 +20,9 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); - $responseType = new BearerTokenResponse( - 'file://' . __DIR__ . '/../Stubs/private.key', - 'file://' . __DIR__ . '/../Stubs/public.key', - $accessTokenRepositoryMock - ); + $responseType = new BearerTokenResponse($accessTokenRepositoryMock); + $responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); + $responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $client = new ClientEntity(); $client->setIdentifier('clientName'); @@ -64,12 +63,11 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase public function testDetermineAccessTokenInHeaderValidToken() { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(false); - $responseType = new BearerTokenResponse( - 'file://' . __DIR__ . '/../Stubs/private.key', - 'file://' . __DIR__ . '/../Stubs/public.key', - $accessTokenRepositoryMock - ); + $responseType = new BearerTokenResponse($accessTokenRepositoryMock); + $responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); + $responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $client = new ClientEntity(); $client->setIdentifier('clientName'); @@ -89,13 +87,16 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase $responseType->setRefreshToken($refreshToken); $response = $responseType->generateHttpResponse(new Response()); - $response->getBody()->rewind(); - $json = json_decode($response->getBody()->getContents()); + $json = json_decode((string) $response->getBody()); + + $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); + $authorizationValidator->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); + $authorizationValidator->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $request = new ServerRequest(); $request = $request->withHeader('authorization', sprintf('Bearer %s', $json->access_token)); - $request = $responseType->validateAccessToken($request); + $request = $authorizationValidator->validateAuthorization($request); $this->assertEquals('abcdef', $request->getAttribute('oauth_access_token_id')); $this->assertEquals('clientName', $request->getAttribute('oauth_client_id')); @@ -106,12 +107,11 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase public function testDetermineAccessTokenInHeaderInvalidJWT() { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(false); - $responseType = new BearerTokenResponse( - 'file://' . __DIR__ . '/../Stubs/private.key', - 'file://' . __DIR__ . '/../Stubs/public.key', - $accessTokenRepositoryMock - ); + $responseType = new BearerTokenResponse($accessTokenRepositoryMock); + $responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); + $responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $client = new ClientEntity(); $client->setIdentifier('clientName'); @@ -131,14 +131,17 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase $responseType->setRefreshToken($refreshToken); $response = $responseType->generateHttpResponse(new Response()); - $response->getBody()->rewind(); - $json = json_decode($response->getBody()->getContents()); + $json = json_decode((string) $response->getBody()); + + $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); + $authorizationValidator->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); + $authorizationValidator->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $request = new ServerRequest(); $request = $request->withHeader('authorization', sprintf('Bearer %s', $json->access_token . 'foo')); try { - $responseType->validateAccessToken($request); + $authorizationValidator->validateAuthorization($request); } catch (OAuthServerException $e) { $this->assertEquals( 'Access token could not be verified', @@ -150,14 +153,11 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase public function testDetermineAccessTokenInHeaderRevokedToken() { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); - $accessTokenRepositoryMock->expects($this->once())->method('isAccessTokenRevoked')->willReturn(true); + $accessTokenRepositoryMock->method('isAccessTokenRevoked')->willReturn(true); - - $responseType = new BearerTokenResponse( - 'file://' . __DIR__ . '/../Stubs/private.key', - 'file://' . __DIR__ . '/../Stubs/public.key', - $accessTokenRepositoryMock - ); + $responseType = new BearerTokenResponse($accessTokenRepositoryMock); + $responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); + $responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $client = new ClientEntity(); $client->setIdentifier('clientName'); @@ -177,14 +177,17 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase $responseType->setRefreshToken($refreshToken); $response = $responseType->generateHttpResponse(new Response()); - $response->getBody()->rewind(); - $json = json_decode($response->getBody()->getContents()); + $json = json_decode((string) $response->getBody()); + + $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); + $authorizationValidator->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); + $authorizationValidator->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $request = new ServerRequest(); $request = $request->withHeader('authorization', sprintf('Bearer %s', $json->access_token)); try { - $responseType->validateAccessToken($request); + $authorizationValidator->validateAuthorization($request); } catch (OAuthServerException $e) { $this->assertEquals( 'Access token has been revoked', @@ -197,17 +200,19 @@ class BearerResponseTypeTest extends \PHPUnit_Framework_TestCase { $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); - $responseType = new BearerTokenResponse( - 'file://' . __DIR__ . '/../Stubs/private.key', - 'file://' . __DIR__ . '/../Stubs/public.key', - $accessTokenRepositoryMock - ); + $responseType = new BearerTokenResponse($accessTokenRepositoryMock); + $responseType->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); + $responseType->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); + + $authorizationValidator = new BearerTokenValidator($accessTokenRepositoryMock); + $authorizationValidator->setPrivateKeyPath('file://' . __DIR__ . '/../Stubs/private.key'); + $authorizationValidator->setPublicKeyPath('file://' . __DIR__ . '/../Stubs/public.key'); $request = new ServerRequest(); $request = $request->withHeader('authorization', 'Bearer blah'); try { - $responseType->validateAccessToken($request); + $authorizationValidator->validateAuthorization($request); } catch (OAuthServerException $e) { $this->assertEquals( 'The JWT string must have two dots', diff --git a/tests/ServerTest.php b/tests/ServerTest.php index 1563e34a..cf52cf8f 100644 --- a/tests/ServerTest.php +++ b/tests/ServerTest.php @@ -15,8 +15,10 @@ use League\OAuth2\Server\ResponseTypes\BearerTokenResponse; use League\OAuth2\Server\Server; use LeagueTests\Stubs\ClientEntity; use LeagueTests\Stubs\StubResponseType; +use LeagueTests\Stubs\UserEntity; use Psr\Http\Message\ResponseInterface; -use Zend\Diactoros\ServerRequest; +use Zend\Diactoros\Response; +use Zend\Diactoros\ServerRequestFactory; class ServerTest extends \PHPUnit_Framework_TestCase { @@ -34,7 +36,7 @@ class ServerTest extends \PHPUnit_Framework_TestCase $server->enableGrantType(new ClientCredentialsGrant(), new \DateInterval('PT1M')); try { - $server->respondToRequest(); + $server->respondToRequest(ServerRequestFactory::fromGlobals(), new Response); } catch (OAuthServerException $e) { $this->assertEquals('unsupported_grant_type', $e->getErrorType()); $this->assertEquals(400, $e->getHttpStatusCode()); @@ -60,7 +62,7 @@ class ServerTest extends \PHPUnit_Framework_TestCase $_POST['grant_type'] = 'client_credentials'; $_POST['client_id'] = 'foo'; $_POST['client_secret'] = 'bar'; - $response = $server->respondToRequest(); + $response = $server->respondToRequest(ServerRequestFactory::fromGlobals(), new Response); $this->assertEquals(200, $response->getStatusCode()); } @@ -77,16 +79,19 @@ class ServerTest extends \PHPUnit_Framework_TestCase $clientRepository, $this->getMock(AccessTokenRepositoryInterface::class), $this->getMock(ScopeRepositoryInterface::class), - '', - '', + 'file://' . __DIR__ . '/Stubs/private.key', + 'file://' . __DIR__ . '/Stubs/public.key', new StubResponseType() ); + $userRepository = $this->getMock(UserRepositoryInterface::class); + $userRepository->method('getUserEntityByUserCredentials')->willReturn(new UserEntity()); + $server->enableGrantType( new AuthCodeGrant( $this->getMock(AuthCodeRepositoryInterface::class), $this->getMock(RefreshTokenRepositoryInterface::class), - $this->getMock(UserRepositoryInterface::class), + $userRepository, new \DateInterval('PT1H') ), new \DateInterval('PT1M') @@ -97,9 +102,13 @@ class ServerTest extends \PHPUnit_Framework_TestCase $_GET['response_type'] = 'code'; $_GET['client_id'] = $client->getIdentifier(); $_GET['redirect_uri'] = $client->getRedirectUri(); - $response = $server->respondToRequest(); - $this->assertEquals(200, $response->getStatusCode()); + $_POST['action'] = 'approve'; + $_POST['username'] = 'user'; + $_POST['password'] = 'pass'; + $response = $server->respondToRequest(ServerRequestFactory::fromGlobals(), new Response); $this->assertTrue($response instanceof ResponseInterface); + $this->assertEquals(302, $response->getStatusCode()); + $this->assertTrue(strstr($response->getHeaderLine('location'), 'code=') !== false); } public function testGetResponseType() @@ -134,7 +143,7 @@ class ServerTest extends \PHPUnit_Framework_TestCase ); try { - $server->validateAuthenticatedRequest(new ServerRequest()); + $server->validateAuthenticatedRequest(ServerRequestFactory::fromGlobals()); } catch (OAuthServerException $e) { $this->assertEquals('Missing "Authorization" header', $e->getHint()); }