Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/strm 1259 #4

Merged
merged 4 commits into from
Jul 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"require": {
"php": ">=7.2",
"guzzlehttp/guzzle": "^6.3 || ^7.3",
"wikimedia/avro": "^1.9"
"wikimedia/avro": "^1.9",
"ext-curl": "*",
"curl/curl": "^2.3",
"ext-json": "*"
}
}
20 changes: 10 additions & 10 deletions src/AuthProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,31 @@ class AuthProvider
{
protected const EXPIRATION_SLACK_SECONDS = 60;

/** @var string $idToken */
protected $idToken;
/** @var string $accessToken */
protected $accessToken;

/** @var string $refreshToken */
protected $refreshToken;

/** @var int $expiresAt */
protected $expiresAt;
public $expiresAt;

public function __construct(string $json)
{
$authData = json_decode($json);

if (!isset($authData->idToken, $authData->refreshToken, $authData->expiresAt)) {
if (!isset($authData->access_token, $authData->refresh_token)) {
throw new AuthenticationException('Invalid response from authenticate/refresh request');
}

$this->idToken = (string)$authData->idToken;
$this->refreshToken = (string)$authData->refreshToken;
$this->expiresAt = (int)$authData->expiresAt;
$this->accessToken = (string)$authData->access_token;
$this->refreshToken = (string)$authData->refresh_token;

$this->expiresAt = (int)$authData->expires_in + time();
}

public function getIdToken(): string
public function getAccessToken(): string
{
return $this->idToken;
return $this->accessToken;
}

public function getRefreshToken(): string
Expand Down
42 changes: 19 additions & 23 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

use GuzzleHttp\Client as HttpClient;
use GuzzleHttp\Exception\RequestException;
use PhpParser\Node\Scalar\String_;
use StrmPrivacy\Driver\Exceptions\AuthenticationException;
use StrmPrivacy\Driver\Exceptions\RefreshException;
use Curl\Curl;

class Client
{
Expand All @@ -15,9 +17,6 @@ class Client
/** @var \GuzzleHttp\Client $httpClient */
protected $httpClient;

/** @var string $billingId */
protected $billingId;

/** @var string $clientId */
protected $clientId;

Expand All @@ -28,16 +27,14 @@ class Client
protected $config;

public function __construct(
string $billingId,
string $clientId,
string $clientSecret,
array $customConfig = [],
array $httpConfig = []
) {
$this->billingId = $billingId;
array $customConfig = [],
array $httpConfig = []
)
{
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;

$this->config = new Config($customConfig);
$this->httpClient = new HttpClient($httpConfig);
}
Expand All @@ -49,19 +46,15 @@ public function authenticate(): void
'POST',
$this->config->getAuthUri(),
[
'json' => [
'billingId' => $this->billingId,
'clientId' => $this->clientId,
'clientSecret' => $this->clientSecret,
],
'headers' => ['content-type' => 'application/x-www-form-urlencoded'],
'body' => sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", $this->clientId, $this->clientSecret)
]
);
} catch (RequestException $e) {
throw new AuthenticationException(
sprintf(
'Error authenticating to %s for billingId %s and clientId %s, status code: %d, message: %s',
'Error authenticating to %s for clientId %s, status code: %d, message: %s',
$this->config->getAuthUri(),
$this->billingId,
$this->clientId,
$e->getCode(),
$e->getMessage()
Expand All @@ -82,19 +75,18 @@ public function refresh(): void
try {
$response = $this->httpClient->request(
'POST',
$this->config->getRefreshUri(),
$this->config->getAuthUri(),
[
'json' => [
'refreshToken' => $this->authProvider->getRefreshToken(),
],
'headers' => ['content-type' => 'application/x-www-form-urlencoded'],
'body' => sprintf("grant_type=refresh_token&client_id=%s&client_secret=%s&refresh_token=%s",
$this->clientId, $this->clientSecret, $this->authProvider->getRefreshToken())
]
);
} catch (RequestException $e) {
throw new RefreshException(
sprintf(
'Error refreshing auth token to %s for billingId %s and clientId %s, status code: %d, message: %s',
'Error refreshing auth token to %s for clientId %s, status code: %d, message: %s',
$this->config->getRefreshUri(),
$this->billingId,
$this->clientId,
$e->getCode(),
$e->getMessage()
Expand Down Expand Up @@ -123,7 +115,11 @@ public function authIsExpired(): bool
if (!isset($this->authProvider)) {
return true;
}

return $this->authProvider->isExpired();
}

public function getAccessToken(): string
{
return $this->authProvider->getAccessToken();
}
}
20 changes: 10 additions & 10 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ class Config
/** @var string $gatewayEndpoint */
protected $gatewayEndpoint = '/event';

/** @var string $stsProtocol */
protected $stsProtocol = 'https';
/** @var string $authProtocol */
protected $authProtocol = 'https';

/** @var string $stsHost */
protected $stsHost = 'sts.strmprivacy.io';
/** @var string $authHost */
public $authHost = 'accounts.strmprivacy.io';

/** @var string $stsAuthEndpoint */
protected $stsAuthEndpoint = '/auth';
/** @var string $authAuthEndpoint */
protected $authAuthEndpoint = '/auth/realms/streams/protocol/openid-connect/token';

/** @var string $stsRefreshEndpoint */
protected $stsRefreshEndpoint = '/refresh';
/** @var string $authRefreshEndpoint */
protected $authRefreshEndpoint = '/auth/realms/streams/protocol/openid-connect/token';

/** @var int $stsRefreshInterval */
protected $stsRefreshInterval = 3300;
Expand All @@ -44,11 +44,11 @@ public function getGatewayUri(): string

public function getAuthUri(): string
{
return sprintf('%s://%s/%s', $this->stsProtocol, $this->stsHost, ltrim($this->stsAuthEndpoint, '/'));
return sprintf('%s://%s/%s', $this->authProtocol, $this->authHost, ltrim($this->authAuthEndpoint, '/'));
}

public function getRefreshUri(): string
{
return sprintf('%s://%s/%s', $this->stsProtocol, $this->stsHost, ltrim($this->stsRefreshEndpoint, '/'));
return sprintf('%s://%s/%s', $this->authProtocol, $this->authHost, ltrim($this->authRefreshEndpoint, '/'));
}
}
5 changes: 2 additions & 3 deletions src/Sender.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function send(Event $event, string $serializationType): void
$this->config->getGatewayUri(),
[
'headers' => [
'Authorization' => 'Bearer ' . $this->authProvider->getIdToken(),
'Authorization' => 'Bearer ' . $this->authProvider->getAccessToken(),
'Strm-Serialization-Type' => $serializer->getContentType(),
'Strm-Schema-Ref' => $event->getStrmSchemaRef(),
'Content-type' => $serializer->getContentType(),
Expand All @@ -35,9 +35,8 @@ public function send(Event $event, string $serializationType): void
} catch (RequestException $e) {
throw new SendingException(
sprintf(
'Error sending event to %s for billingId %s and clientId %s, status code: %d, message: %s',
'Error sending event to %s for clientId %s, status code: %d, message: %s',
$this->config->getGatewayUri(),
$this->billingId,
$this->clientId,
$e->getCode(),
$e->getMessage()
Expand Down
51 changes: 37 additions & 14 deletions tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,86 @@
use GuzzleHttp\Psr7\Response;
use PHPUnit\Framework\TestCase;
use StrmPrivacy\Driver\Client;
use StrmPrivacy\Driver\Config;

class ClientTest extends TestCase
{
public function testClientCanBeInstantiated(): void
{
$this->assertInstanceOf(
Client::class,
new Client('billingId', 'clientId', 'clientSecret')
new Client('clientId', 'clientSecret')
);
}

public function testClientCanAuthenticate(): void
{
$validResponse = $this->getMockResponse();
static::markTestSkipped('When enabling this test, enter client credentials');

$config = new Config(['authHost' => 'accounts.dev.strmprivacy.io']);
$client = new Client('clientId', 'clientSecret', (array)$config);
$client->authenticate();
$this->assertNotTrue($client->getAccessToken() == '', 'Access Token is empty');
}

public function testClientCanRefresh(): void
{
static::markTestSkipped('When enabling this test, enter client credentials');

$config = new Config(['authHost' => 'accounts.dev.strmprivacy.io']);
$client = new Client('clientId', 'clientSecret', (array)$config);
$client->authenticate();
$oldToken = $client->getAccessToken();
$client->refresh();
$this->assertTrue($client->getAccessToken() != '', 'Access Token is empty');
$this->assertTrue($client->getAccessToken() != $oldToken, 'Access Token has not changed');
}


public function testClientCanAuthenticateWithExpirationTime(): void
{
$validResponse = $this->getMockResponse(61);
$mockHandler = new MockHandler([$validResponse]);
$handlerStack = HandlerStack::create($mockHandler);
$client = new Client('billingId', 'clientId', 'clientSecret', [], ['handler' => $handlerStack]);
$client = new Client('clientId', 'clientSecret', [], ['handler' => $handlerStack]);

$client->authenticate();
$this->assertTrue(!$client->authIsExpired());
}

public function testClientShouldBeExpiredOnTime(): void
{
$almostExpiredResponse = $this->getMockResponse(time() + 59);
$almostExpiredResponse = $this->getMockResponse(59);
$mockHandler = new MockHandler([$almostExpiredResponse]);
$handlerStack = HandlerStack::create($mockHandler);
$client = new Client('billingId', 'clientId', 'clientSecret', [], ['handler' => $handlerStack]);
$client = new Client('clientId', 'clientSecret', [], ['handler' => $handlerStack]);

$client->authenticate();
$this->assertTrue($client->authIsExpired());
}

public function testExpiredAuthShouldRefresh(): void
{
$expiredResponse = $this->getMockResponse(time() - 100);
$validResponse = $this->getMockResponse();
$expiredResponse = $this->getMockResponse();
$validResponse = $this->getMockResponse(100);
$mockHandler = new MockHandler([$expiredResponse, $validResponse]);
$handlerStack = HandlerStack::create($mockHandler);
$client = new Client('billingId', 'clientId', 'clientSecret', [], ['handler' => $handlerStack]);
$client = new Client('clientId', 'clientSecret', [], ['handler' => $handlerStack]);

$client->authenticate();
$client->refresh();
$this->assertTrue(!$client->authIsExpired());
}

protected function getMockResponse(int $expiresAt = null): Response
protected function getMockResponse(int $expiresIn = null): Response
{
$expiresAt = is_null($expiresAt) ? time() + 3600 : $expiresAt;

return new Response(
200,
[],
json_encode([
'idToken' => 'dummy idToken',
'refreshToken' => 'dummy refreshToken',
'expiresAt' => $expiresAt,
'access_token' => 'dummy idToken',
'refresh_token' => 'dummy refreshToken',
'expires_in' => $expiresIn,
])
);
}
Expand Down
8 changes: 4 additions & 4 deletions tests/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ public function testCustomGatewayUriIsCorrect(): void
public function testCustomAuthUriIsCorrect(): void
{
$config = new Config([
'stsHost' => 'customhost',
'stsAuthEndpoint' => 'customendpoint',
'authHost' => 'customhost',
'authAuthEndpoint' => 'customendpoint',
]);

$this->assertEquals(
Expand All @@ -41,8 +41,8 @@ public function testCustomAuthUriIsCorrect(): void
public function testCustomRefreshUriIsCorrect(): void
{
$config = new Config([
'stsHost' => 'customhost',
'stsRefreshEndpoint' => 'customendpoint',
'authHost' => 'customhost',
'authRefreshEndpoint' => 'customendpoint',
]);

$this->assertEquals(
Expand Down