Skip to content

Commit

Permalink
bypass bc breaking change and add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hafezdivandari committed Dec 4, 2024
1 parent 4998c4a commit cc3a244
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 6 deletions.
6 changes: 4 additions & 2 deletions src/Entities/ClientEntityInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ public function getRedirectUri(): string|array;
public function isConfidential(): bool;

/**
* Returns true if the client handles the given grant type.
* Returns true if the client supports the given grant type.
*
* To be added in a future major release.
*/
public function hasGrantType(string $grantType): bool;
// public function supportsGrantType(string $grantType): bool;
}
4 changes: 2 additions & 2 deletions src/Entities/Traits/ClientTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public function isConfidential(): bool
}

/**
* Returns true if the client handles the given grant type.
* Returns true if the client supports the given grant type.
*/
public function hasGrantType(string $grantType): bool
public function supportsGrantType(string $grantType): bool
{
return true;
}
Expand Down
13 changes: 11 additions & 2 deletions src/Grant/AbstractGrant.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,22 @@ protected function getClientEntityOrFail(string $clientId, ServerRequestInterfac
throw OAuthServerException::invalidClient($request);
}

if (!$client->hasGrantType($this->getIdentifier())) {
if ($this->supportsGrantType($client, $this->getIdentifier()) === false) {
throw OAuthServerException::unauthorizedClient();
}

return $client;
}

/**
* Returns true if the given client is authorized to use the given grant type.
*/
protected function supportsGrantType(ClientEntityInterface $client, string $grantType): bool
{
return method_exists($client, 'supportsGrantType') === false
|| $client->supportsGrantType($grantType) === true;
}

/**
* Gets the client credentials from the request from the request body or
* the Http Basic Authorization header
Expand Down Expand Up @@ -488,7 +497,7 @@ protected function issueAuthCode(
*/
protected function issueRefreshToken(AccessTokenEntityInterface $accessToken): ?RefreshTokenEntityInterface
{
if (!$accessToken->getClient()->hasGrantType('refresh_token')) {
if ($this->supportsGrantType($accessToken->getClient(), 'refresh_token') === false) {
return null;
}

Expand Down
53 changes: 53 additions & 0 deletions tests/Grant/AbstractGrantTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,32 @@ public function testValidateClientBadClient(): void
$validateClientMethod->invoke($grantMock, $serverRequest, true);
}

public function testUnauthorizedClient(): void
{
$client = $this->getMockBuilder(ClientEntity::class)->getMock();
$client->method('supportsGrantType')->willReturn(false);

$clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock();
$clientRepositoryMock
->expects(self::once())
->method('getClientEntity')
->with('foo')
->willReturn($client);

/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setClientRepository($clientRepositoryMock);

$abstractGrantReflection = new ReflectionClass($grantMock);

$getClientEntityOrFailMethod = $abstractGrantReflection->getMethod('getClientEntityOrFail');
$getClientEntityOrFailMethod->setAccessible(true);

$this->expectException(OAuthServerException::class);

$getClientEntityOrFailMethod->invoke($grantMock, 'foo', new ServerRequest());
}

public function testCanRespondToRequest(): void
{
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
Expand Down Expand Up @@ -350,6 +376,33 @@ public function testIssueNullRefreshToken(): void
self::assertNull($issueRefreshTokenMethod->invoke($grantMock, $accessToken));
}

public function testIssueNullRefreshTokenUnauthorizedClient(): void
{
$client = $this->getMockBuilder(ClientEntity::class)->getMock();
$client
->expects(self::once())
->method('supportsGrantType')
->with('refresh_token')
->willReturn(false);

$refreshTokenRepoMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock();
$refreshTokenRepoMock->expects(self::never())->method('getNewRefreshToken');

/** @var AbstractGrant $grantMock */
$grantMock = $this->getMockForAbstractClass(AbstractGrant::class);
$grantMock->setRefreshTokenTTL(new DateInterval('PT1M'));
$grantMock->setRefreshTokenRepository($refreshTokenRepoMock);

$abstractGrantReflection = new ReflectionClass($grantMock);
$issueRefreshTokenMethod = $abstractGrantReflection->getMethod('issueRefreshToken');
$issueRefreshTokenMethod->setAccessible(true);

$accessToken = new AccessTokenEntity();
$accessToken->setClient($client);

self::assertNull($issueRefreshTokenMethod->invoke($grantMock, $accessToken));
}

public function testIssueAccessToken(): void
{
$accessTokenRepoMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock();
Expand Down

0 comments on commit cc3a244

Please sign in to comment.