diff --git a/composer.json b/composer.json index 0bbb006..7d600f9 100644 --- a/composer.json +++ b/composer.json @@ -27,8 +27,9 @@ "zfr/zfr-oauth2-server": "0.1.*" }, "require-dev": { - "phpunit/phpunit": "~3.7", + "phpunit/phpunit": "~4.0", "squizlabs/php_codesniffer": "1.4.*", + "zendframework/zend-view": "~2.2", "satooshi/php-coveralls": "~0.6" }, "autoload": { diff --git a/src/ZfrOAuth2Module/Server/Authentication/Storage/AccessTokenStorage.php b/src/ZfrOAuth2Module/Server/Authentication/Storage/AccessTokenStorage.php index 9c39cfc..f9ace11 100644 --- a/src/ZfrOAuth2Module/Server/Authentication/Storage/AccessTokenStorage.php +++ b/src/ZfrOAuth2Module/Server/Authentication/Storage/AccessTokenStorage.php @@ -19,7 +19,8 @@ namespace ZfrOAuth2Module\Server\Authentication\Storage; use Zend\Authentication\Storage\NonPersistent; -use Zend\Http\Request as HttpRequest; +use Zend\Http\Request; +use Zend\Mvc\Application; use ZfrOAuth2\Server\ResourceServer; /** @@ -34,42 +35,57 @@ class AccessTokenStorage extends NonPersistent protected $resourceServer; /** - * @var HttpRequest + * @var Application */ - protected $request; + private $application; /** * @param ResourceServer $resourceServer + * @param Application $application */ - public function __construct(ResourceServer $resourceServer) + public function __construct(ResourceServer $resourceServer, Application $application) { $this->resourceServer = $resourceServer; + $this->application = $application; } /** - * Set the HTTP request - * - * @param HttpRequest $request - * @return void + * {@inheritDoc} */ - public function setRequest(HttpRequest $request) + public function isEmpty() { - $this->request = $request; + $request = $this->getCurrentRequest(); + + return $request ? $this->resourceServer->getAccessToken($request) === null : true; } /** * {@inheritDoc} */ - public function isEmpty() + public function read() { - return $this->resourceServer->getAccessToken($this->request) === null; + $request = $this->getCurrentRequest(); + + if (! $request) { + return null; + } + + $accessToken = $this->resourceServer->getAccessToken($request); + + return $accessToken ? $accessToken->getOwner() : null; } /** - * {@inheritDoc} + * @return Request|null */ - public function read() + private function getCurrentRequest() { - return $this->resourceServer->getAccessToken($this->request)->getOwner(); + $request = $this->application->getMvcEvent()->getRequest(); + + if (! $request instanceof Request || ! $this->resourceServer->isRequestValid($request)) { + return null; + } + + return $request; } } diff --git a/src/ZfrOAuth2Module/Server/Factory/AccessTokenStorageFactory.php b/src/ZfrOAuth2Module/Server/Factory/AccessTokenStorageFactory.php index 781fd01..7fc14f8 100644 --- a/src/ZfrOAuth2Module/Server/Factory/AccessTokenStorageFactory.php +++ b/src/ZfrOAuth2Module/Server/Factory/AccessTokenStorageFactory.php @@ -34,15 +34,11 @@ class AccessTokenStorageFactory implements FactoryInterface */ public function createService(ServiceLocatorInterface $serviceLocator) { - $accessTokenStorage = new AccessTokenStorage($serviceLocator->get('ZfrOAuth2\Server\ResourceServer')); + /* @var $resourceServer \ZfrOAuth2\Server\ResourceServer */ + $resourceServer = $serviceLocator->get('ZfrOAuth2\Server\ResourceServer'); + /* @var $application \Zend\Mvc\Application */ + $application = $serviceLocator->get('Application'); - // It only makes sense to set the request if it is HTTP request - $request = $serviceLocator->get('Application')->getRequest(); - - if ($request instanceof HttpRequest) { - $accessTokenStorage->setRequest($request); - } - - return $accessTokenStorage; + return new AccessTokenStorage($resourceServer, $application); } } diff --git a/tests/ZfrOAuth2ModuleTest/Server/Authentication/AuthenticationFunctionalTest.php b/tests/ZfrOAuth2ModuleTest/Server/Authentication/AuthenticationFunctionalTest.php new file mode 100644 index 0000000..70070ca --- /dev/null +++ b/tests/ZfrOAuth2ModuleTest/Server/Authentication/AuthenticationFunctionalTest.php @@ -0,0 +1,172 @@ + + * @licence MIT + * + * @coversNothing + */ +class AuthenticationFunctionalTest extends PHPUnit_Framework_TestCase +{ + /** + * @var \ZfrOAuth2\Server\ResourceServer|\PHPUnit_Framework_MockObject_MockObject + */ + private $resourceServer; + + /** + * @var AccessTokenStorage + */ + private $authenticationStorage; + + /** + * @var AuthenticationService + */ + private $authenticationService; + + /** + * @var \Zend\Mvc\MvcEvent|\PHPUnit_Framework_MockObject_MockObject + */ + private $mvcEvent; + + /** + * {@inheritDoc} + */ + protected function setUp() + { + $this->mvcEvent = $this->getMock('Zend\Mvc\MvcEvent'); + $application = $this->getMock('Zend\Mvc\Application', [], [], '', false); + $this->resourceServer = $this->getMock('ZfrOAuth2\Server\ResourceServer', [], [], '', false); + $this->authenticationStorage = new AccessTokenStorage($this->resourceServer, $application); + $this->authenticationService = new AuthenticationService($this->authenticationStorage); + + $application->expects($this->any())->method('getMvcEvent')->will($this->returnValue($this->mvcEvent)); + } + + public function testSuccessAuthenticationOnValidToken() + { + $request = new HttpRequest(); + + $this->mvcEvent->expects($this->any())->method('getRequest')->will($this->returnValue($request)); + + $token = new AccessToken(); + $owner = $this->getMock('ZfrOAuth2\Server\Entity\TokenOwnerInterface'); + $token->setOwner($owner); + + $this + ->resourceServer + ->expects($this->atLeastOnce()) + ->method('isRequestValid') + ->with($request) + ->will($this->returnValue(true)); + + $this + ->resourceServer + ->expects($this->atLeastOnce()) + ->method('getAccessToken') + ->with($request) + ->will($this->returnValue($token)); + + + $this->assertTrue($this->authenticationService->hasIdentity()); + $this->assertSame($owner, $this->authenticationService->getIdentity()); + } + + public function testFailAuthenticationOnNoToken() + { + $request = new HttpRequest(); + + $this->mvcEvent->expects($this->any())->method('getRequest')->will($this->returnValue($request)); + + $token = new AccessToken(); + $owner = $this->getMock('ZfrOAuth2\Server\Entity\TokenOwnerInterface'); + $token->setOwner($owner); + + $this + ->resourceServer + ->expects($this->atLeastOnce()) + ->method('isRequestValid') + ->with($request) + ->will($this->returnValue(false)); + + $this->resourceServer->expects($this->never())->method('getAccessToken'); + + $this->assertFalse($this->authenticationService->hasIdentity()); + $this->assertNull($this->authenticationService->getIdentity()); + } + + public function testFailAuthenticationOnExpiredToken() + { + $request = new HttpRequest(); + + $this->mvcEvent->expects($this->any())->method('getRequest')->will($this->returnValue($request)); + + $token = new AccessToken(); + $owner = $this->getMock('ZfrOAuth2\Server\Entity\TokenOwnerInterface'); + $token->setOwner($owner); + + $this + ->resourceServer + ->expects($this->atLeastOnce()) + ->method('isRequestValid') + ->with($request) + ->will($this->returnValue(true)); + + $this + ->resourceServer + ->expects($this->atLeastOnce()) + ->method('getAccessToken') + ->with($request) + ->will($this->throwException(new OAuth2Exception('Expired token', 123))); + + $this->setExpectedException('ZfrOAuth2\Server\Exception\OAuth2Exception', 'Expired token', 123); + + $this->authenticationService->getIdentity(); + } + + public function testFailAuthenticationOnNoRequest() + { + $this->resourceServer->expects($this->never())->method('isRequestValid'); + $this->resourceServer->expects($this->never())->method('getAccessToken'); + + $this->assertFalse($this->authenticationService->hasIdentity()); + $this->assertNull($this->authenticationService->getIdentity()); + } + + public function testFailAuthenticationOnNonHttpRequest() + { + $request = $this->getMock('Zend\Stdlib\RequestInterface'); + + $this->mvcEvent->expects($this->any())->method('getRequest')->will($this->returnValue($request)); + + $this->resourceServer->expects($this->never())->method('isRequestValid'); + $this->resourceServer->expects($this->never())->method('getAccessToken'); + + $this->assertFalse($this->authenticationService->hasIdentity()); + $this->assertNull($this->authenticationService->getIdentity()); + } +} diff --git a/tests/ZfrOAuth2ModuleTest/Server/Authentication/Storage/AccessTokenStorageTest.php b/tests/ZfrOAuth2ModuleTest/Server/Authentication/Storage/AccessTokenStorageTest.php index 6737385..c63aa68 100644 --- a/tests/ZfrOAuth2ModuleTest/Server/Authentication/Storage/AccessTokenStorageTest.php +++ b/tests/ZfrOAuth2ModuleTest/Server/Authentication/Storage/AccessTokenStorageTest.php @@ -18,8 +18,8 @@ namespace ZfrOAuth2ModuleTest\Server\Authentication\Storage; -use Zend\Authentication\Result; use Zend\Http\Request as HttpRequest; +use Zend\Mvc\MvcEvent; use ZfrOAuth2\Server\Entity\AccessToken; use ZfrOAuth2Module\Server\Authentication\Storage\AccessTokenStorage; @@ -31,39 +31,70 @@ */ class AccessTokenStorageTest extends \PHPUnit_Framework_TestCase { - public function testIsConsideredAsEmptyIfNoAccessToken() - { - $resourceServer = $this->getMock('ZfrOAuth2\Server\ResourceServer', [], [], '', false); - $request = new HttpRequest(); + /** + * @var \ZfrOAuth2\Server\ResourceServer|\PHPUnit_Framework_MockObject_MockObject + */ + private $resourceServer; + + /** + * @var HttpRequest + */ + private $request; - $storage = new AccessTokenStorage($resourceServer); - $storage->setRequest($request); + /** + * @var AccessTokenStorage + */ + private $storage; - $resourceServer->expects($this->once()) - ->method('getAccessToken') - ->with($request) - ->will($this->returnValue(null)); + /** + * {@inheritDoc} + */ + protected function setUp() + { + $application = $this->getMock('Zend\Mvc\Application', [], [], '', false); + $mvcEvent = new MvcEvent(); + $this->resourceServer = $this->getMock('ZfrOAuth2\Server\ResourceServer', [], [], '', false); + $this->request = new HttpRequest(); + $this->storage = new AccessTokenStorage($this->resourceServer, $application); - $this->isTrue($storage->isEmpty()); + $application->expects($this->any())->method('getMvcEvent')->will($this->returnValue($mvcEvent)); + $mvcEvent->setRequest($this->request); } - public function testReadOwnerFromAccessToken() + public function testIsConsideredAsEmptyIfNoAccessToken() { - $resourceServer = $this->getMock('ZfrOAuth2\Server\ResourceServer', [], [], '', false); - $request = new HttpRequest(); + $this->resourceServer + ->expects($this->atLeastOnce()) + ->method('isRequestValid') + ->with($this->request) + ->will($this->returnValue(false)); - $storage = new AccessTokenStorage($resourceServer); - $storage->setRequest($request); + $this->resourceServer->expects($this->never())->method('getAccessToken'); + $this->assertTrue($this->storage->isEmpty()); + $this->assertNull($this->storage->read()); + } + + public function testReadOwnerFromAccessToken() + { $token = new AccessToken(); $owner = $this->getMock('ZfrOAuth2\Server\Entity\TokenOwnerInterface'); + $token->setOwner($owner); - $resourceServer->expects($this->once()) - ->method('getAccessToken') - ->with($request) - ->will($this->returnValue($token)); + $this->resourceServer + ->expects($this->atLeastOnce()) + ->method('isRequestValid') + ->with($this->request) + ->will($this->returnValue(true)); + + $this->resourceServer + ->expects($this->atLeastOnce()) + ->method('getAccessToken') + ->with($this->request) + ->will($this->returnValue($token)); - $this->assertSame($owner, $storage->read()); + $this->assertFalse($this->storage->isEmpty()); + $this->assertSame($owner, $this->storage->read()); } } diff --git a/tests/ZfrOAuth2ModuleTest/Server/Factory/AccessTokenStorageFactoryTest.php b/tests/ZfrOAuth2ModuleTest/Server/Factory/AccessTokenStorageFactoryTest.php index 58e2b15..4a86d76 100644 --- a/tests/ZfrOAuth2ModuleTest/Server/Factory/AccessTokenStorageFactoryTest.php +++ b/tests/ZfrOAuth2ModuleTest/Server/Factory/AccessTokenStorageFactoryTest.php @@ -18,8 +18,6 @@ namespace ZfrOAuth2ModuleTest\Server\Factory; -use Zend\Http\Request as HttpRequest; -use Zend\ServiceManager\ServiceManager; use ZfrOAuth2Module\Server\Factory\AccessTokenStorageFactory; /** @@ -32,20 +30,18 @@ class AccessTokenStorageFactoryTest extends \PHPUnit_Framework_TestCase { public function testCanCreateFromFactory() { - $serviceManager = new ServiceManager(); + $serviceLocator = $this->getMock('Zend\ServiceManager\ServiceLocatorInterface'); - $serviceManager->setService( - 'ZfrOAuth2\Server\ResourceServer', - $this->getMock('ZfrOAuth2\Server\ResourceServer', [], [], '', false) - ); - - $application = $this->getMock('Zend\Mvc\ApplicationInterface'); - $application->expects($this->once())->method('getRequest')->will($this->returnValue(new HttpRequest())); - $serviceManager->setService('Application', $application); + $serviceLocator->expects($this->any())->method('get')->will($this->returnValueMap([ + ['ZfrOAuth2\Server\ResourceServer', $this->getMock('ZfrOAuth2\Server\ResourceServer', [], [], '', false)], + ['Application', $this->getMock('Zend\Mvc\Application', [], [], '', false)] + ])); $factory = new AccessTokenStorageFactory(); - $service = $factory->createService($serviceManager); - $this->assertInstanceOf('ZfrOAuth2Module\Server\Authentication\Storage\AccessTokenStorage', $service); + $this->assertInstanceOf( + 'ZfrOAuth2Module\Server\Authentication\Storage\AccessTokenStorage', + $factory->createService($serviceLocator) + ); } }