diff --git a/examples/relational/Storage/AccessTokenStorage.php b/examples/relational/Storage/AccessTokenStorage.php index faccb46c..55949314 100644 --- a/examples/relational/Storage/AccessTokenStorage.php +++ b/examples/relational/Storage/AccessTokenStorage.php @@ -20,7 +20,6 @@ class AccessTokenStorage extends Adapter implements AccessTokenInterface { $result = Capsule::table('oauth_access_tokens') ->where('access_token', $token) - ->where('expire_time', '>=', time()) ->get(); if (count($result) === 1) { diff --git a/examples/relational/Storage/RefreshTokenStorage.php b/examples/relational/Storage/RefreshTokenStorage.php index ab291802..92c52647 100644 --- a/examples/relational/Storage/RefreshTokenStorage.php +++ b/examples/relational/Storage/RefreshTokenStorage.php @@ -17,7 +17,6 @@ class RefreshTokenStorage extends Adapter implements RefreshTokenInterface { $result = Capsule::table('oauth_refresh_tokens') ->where('refresh_token', $token) - ->where('expire_time', '>=', time()) ->get(); if (count($result) === 1) { diff --git a/src/Entity/AbstractTokenEntity.php b/src/Entity/AbstractTokenEntity.php index 04ca81f6..5eeb775f 100644 --- a/src/Entity/AbstractTokenEntity.php +++ b/src/Entity/AbstractTokenEntity.php @@ -96,6 +96,15 @@ abstract class AbstractTokenEntity return $this->expireTime; } + /** + * Is the token expired? + * @return bool + */ + public function isExpired() + { + return ((time() - $this->expireTime) > 0); + } + /** * Set token ID * @param string $token Token ID diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index df6c58b0..8d73560d 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -209,6 +209,11 @@ class AuthCodeGrant extends AbstractGrant throw new Exception\InvalidRequestException('code'); } + // Ensure the auth code hasn't expired + if ($code->isExpired() === true) { + throw new Exception\InvalidRequestException('code'); + } + // Check redirect URI presented matches redirect URI originally used in authorize request if ($code->getRedirectUri() !== $redirectUri) { throw new Exception\InvalidRequestException('redirect_uri'); diff --git a/src/ResourceServer.php b/src/ResourceServer.php index f9d9f6ea..6596a559 100644 --- a/src/ResourceServer.php +++ b/src/ResourceServer.php @@ -99,10 +99,17 @@ class ResourceServer extends AbstractServer // Set the access token $this->accessToken = $this->getAccessTokenStorage()->get($accessTokenString); + // Ensure the access token exists if (!$this->accessToken instanceof AccessTokenEntity) { throw new Exception\AccessDeniedException; } + // Check the access token hasn't expired + // Ensure the auth code hasn't expired + if ($this->accessToken->isExpired() === true) { + throw new Exception\AccessDeniedException; + } + return true; } diff --git a/tests/unit/Grant/AuthCodeGrantTest.php b/tests/unit/Grant/AuthCodeGrantTest.php index 1f281240..ad36a011 100644 --- a/tests/unit/Grant/AuthCodeGrantTest.php +++ b/tests/unit/Grant/AuthCodeGrantTest.php @@ -551,7 +551,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $authCodeStorage->shouldReceive('setServer'); $authCodeStorage->shouldReceive('delete'); $authCodeStorage->shouldReceive('get')->andReturn( - (new AuthCodeEntity($server))->setId('foobar')->setRedirectUri('http://foo/bar') + (new AuthCodeEntity($server))->setId('foobar')->setRedirectUri('http://foo/bar')->setExpireTime(time() + 300) ); $authCodeStorage->shouldReceive('getScopes')->andReturn([ (new ScopeEntity($server))->hydrate(['id' => 'foo']) @@ -622,7 +622,7 @@ class AuthCodeGrantTest extends \PHPUnit_Framework_TestCase $authCodeStorage->shouldReceive('setServer'); $authCodeStorage->shouldReceive('delete'); $authCodeStorage->shouldReceive('get')->andReturn( - (new AuthCodeEntity($server))->setId('foobar')->setRedirectUri('http://foo/bar') + (new AuthCodeEntity($server))->setId('foobar')->setRedirectUri('http://foo/bar')->setExpireTime(time() + 300) ); $authCodeStorage->shouldReceive('getScopes')->andReturn([ (new ScopeEntity($server))->hydrate(['id' => 'foo']) diff --git a/tests/unit/ResourceServerTest.php b/tests/unit/ResourceServerTest.php index 16d35b3f..34d61547 100644 --- a/tests/unit/ResourceServerTest.php +++ b/tests/unit/ResourceServerTest.php @@ -142,7 +142,7 @@ class ResourceServerTest extends \PHPUnit_Framework_TestCase }); $accessTokenStorage->shouldReceive('get')->andReturn( - (new AccessTokenEntity($server))->setId('abcdef') + (new AccessTokenEntity($server))->setId('abcdef')->setExpireTime(time() + 300) ); $accessTokenStorage->shouldReceive('getScopes')->andReturn([ @@ -167,4 +167,60 @@ class ResourceServerTest extends \PHPUnit_Framework_TestCase $this->assertTrue($server->isValidRequest()); $this->assertEquals('abcdef', $server->getAccessToken()); } + + /** + * @expectedException League\OAuth2\Server\Exception\AccessDeniedException + */ + public function testIsValidExpiredToken() + { + $sessionStorage = M::mock('League\OAuth2\Server\Storage\SessionInterface'); + $sessionStorage->shouldReceive('setServer'); + + $accessTokenStorage = M::mock('League\OAuth2\Server\Storage\AccessTokenInterface'); + $accessTokenStorage->shouldReceive('setServer'); + + $clientStorage = M::mock('League\OAuth2\Server\Storage\ClientInterface'); + $clientStorage->shouldReceive('setServer'); + + $scopeStorage = M::mock('League\OAuth2\Server\Storage\ScopeInterface'); + $scopeStorage->shouldReceive('setServer'); + + $server = new ResourceServer( + $sessionStorage, + $accessTokenStorage, + $clientStorage, + $scopeStorage + ); + + $server->setIdKey('at'); + + $server->addEventListener('session.owner', function($event) { + $this->assertTrue($event->getSession() instanceof \League\OAuth2\Server\Entity\SessionEntity); + }); + + $accessTokenStorage->shouldReceive('get')->andReturn( + (new AccessTokenEntity($server))->setId('abcdef')->setExpireTime(time() - 300) + ); + + $accessTokenStorage->shouldReceive('getScopes')->andReturn([ + (new ScopeEntity($server))->hydrate(['id' => 'foo']), + (new ScopeEntity($server))->hydrate(['id' => 'bar']) + ]); + + $sessionStorage->shouldReceive('getByAccessToken')->andReturn( + (new SessionEntity($server))->setId('foobar')->setOwner('user', 123) + ); + + $clientStorage->shouldReceive('getBySession')->andReturn( + (new ClientEntity($server))->hydrate(['id' => 'testapp']) + ); + + $request = new \Symfony\Component\HttpFoundation\Request(); + $request->headers = new \Symfony\Component\HttpFoundation\ParameterBag([ + 'Authorization' => 'Bearer abcdef' + ]); + $server->setRequest($request); + + $server->isValidRequest(); + } }