Skip to content

Commit

Permalink
Revoke tokens (#21)
Browse files Browse the repository at this point in the history
* Added revoke access token
* Added revoke refresh token

Co-authored-by: @ciungulete
  • Loading branch information
sandervanhooft authored Mar 11, 2021
1 parent f626d42 commit fde192d
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 1 deletion.
86 changes: 85 additions & 1 deletion src/Provider/Mollie.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ class Mollie extends AbstractProvider
*/
const CLIENT_ID_PREFIX = 'app_';

/**
* @var string HTTP method used to revoke tokens.
*/
const METHOD_DELETE = 'DELETE';

/**
* @var string Token type hint for Mollie access tokens.
*/
const TOKEN_TYPE_ACCESS = 'access_token';

/**
* @var string Token type hint for Mollie refresh tokens.
*/
const TOKEN_TYPE_REFRESH = 'refresh_token';

/**
* Shortcuts to the available Mollie scopes.
*
Expand Down Expand Up @@ -121,7 +136,7 @@ public function getBaseAuthorizationUrl ()
}

/**
* Returns the base URL for requesting an access token.
* Returns the base URL for requesting or revoking an access token.
*
* Eg. https://oauth.service.com/token
*
Expand All @@ -144,6 +159,75 @@ public function getResourceOwnerDetailsUrl (AccessToken $token)
return static::MOLLIE_API_URL . '/v2/organizations/me';
}

/**
* Revoke a Mollie access token.
*
* @param string $accessToken
*
* @return \Psr\Http\Message\ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function revokeAccessToken($accessToken)
{
return $this->revokeToken(self::TOKEN_TYPE_ACCESS, $accessToken);
}

/**
* Revoke a Mollie refresh token.
*
* @param string $refreshToken
*
* @return \Psr\Http\Message\ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function revokeRefreshToken($refreshToken)
{
return $this->revokeToken(self::TOKEN_TYPE_REFRESH, $refreshToken);
}

/**
* Revoke a Mollie access token or refresh token.
*
* @param string $type
* @param string $token
*
* @return \Psr\Http\Message\ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function revokeToken($type, $token)
{
return $this->getRevokeTokenResponse([
'token_type_hint' => $type,
'token' => $token,
]);
}

/**
* Sends a token revocation request and returns an response instance.
*
* @param array $params
*
* @return \Psr\Http\Message\ResponseInterface
* @throws \GuzzleHttp\Exception\GuzzleException
*/
protected function getRevokeTokenResponse(array $params)
{
$params['client_id'] = $this->clientId;
$params['client_secret'] = $this->clientSecret;
$params['redirect_uri'] = $this->redirectUri;

$options = ['headers' => ['content-type' => 'application/x-www-form-urlencoded']];
$options['body'] = $this->buildQueryString($params);

$request = $this->getRequest(
self::METHOD_DELETE,
$this->getBaseAccessTokenUrl([]),
$options
);

return $this->getHttpClient()->send($request);
}

/**
* The Mollie OAuth provider requests access to the organizations.read scope
* by default to enable retrieving the app user's details.
Expand Down
51 changes: 51 additions & 0 deletions tests/src/Provider/MollieTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,57 @@ public function testGetAccessToken()
$this->assertNull($token->getResourceOwnerId());
}

public function testRevokeToken()
{
$response = m::mock(ResponseInterface::class);
$response->shouldReceive('getBody')->andReturn('{"client_id":'.self::MOCK_CLIENT_ID.', "client_secret":'.self::MOCK_SECRET.', "redirect_uri":'.self::REDIRECT_URI.', "token_type_hint":"access_token":"mock_access_token"}');
$response->shouldReceive('getHeader')->andReturn(['content-type' => 'application/x-www-form-urlencoded']);
$response->shouldReceive('getStatusCode')->andReturn(204);

$client = m::mock(ClientInterface::class);
$client->shouldReceive('send')->times(1)->andReturn($response);

$this->provider->setHttpClient($client);

$result = $this->provider->revokeAccessToken('mock_access_token');

$this->assertEquals($result->getStatusCode(), 204);
}

public function testRevokeAccessToken()
{
$response = m::mock(ResponseInterface::class);
$response->shouldReceive('getBody')->andReturn('{"client_id":'.self::MOCK_CLIENT_ID.', "client_secret":'.self::MOCK_SECRET.', "redirect_uri":'.self::REDIRECT_URI.', "token_type_hint":"access_token":"mock_access_token"}');
$response->shouldReceive('getHeader')->andReturn(['content-type' => 'application/x-www-form-urlencoded']);
$response->shouldReceive('getStatusCode')->andReturn(204);

$client = m::mock(ClientInterface::class);
$client->shouldReceive('send')->times(1)->andReturn($response);

$this->provider->setHttpClient($client);

$result = $this->provider->revokeAccessToken('mock_access_token');

$this->assertEquals($result->getStatusCode(), 204);
}

public function testRevokeRefreshToken()
{
$response = m::mock(ResponseInterface::class);
$response->shouldReceive('getBody')->andReturn('{"client_id":'.self::MOCK_CLIENT_ID.', "client_secret":'.self::MOCK_SECRET.', "redirect_uri":'.self::REDIRECT_URI.', "token_type_hint":"refresh_token":"mock_refresh_token"}');
$response->shouldReceive('getHeader')->andReturn(['content-type' => 'application/x-www-form-urlencoded']);
$response->shouldReceive('getStatusCode')->andReturn(204);

$client = m::mock(ClientInterface::class);
$client->shouldReceive('send')->times(1)->andReturn($response);

$this->provider->setHttpClient($client);

$result = $this->provider->revokeRefreshToken('mock_refresh_token');

$this->assertEquals($result->getStatusCode(), 204);
}

public function testExceptionThrownWhenErrorObjectReceived()
{
$message = uniqid();
Expand Down

0 comments on commit fde192d

Please sign in to comment.