mirror of
https://github.com/elyby/oauth2-server.git
synced 2025-05-31 14:12:07 +05:30
Added a check for unique access token constraint violation
This commit is contained in:
@@ -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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user