Skip to content

feat: Add support for multiple environments #6

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

Merged
merged 6 commits into from
Dec 3, 2024
Merged
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ $client = new Client(
<TSID>, // Trusted Shops ID - e.g. 'X1234567890123456789012345678901'
<CLIENT_ID>, // Client ID - e.g. 'cot-switch-X1234567890123456789012345678901'
<CLIENT_SECRET>, // Client Secret - e.g. '1234567890123456789012345678901234567890123456789012345678901234'
<AUTH_STORAGE_INSTANCE> // It can be any storage option implementing AuthStorageInterface - e.g. new DatabaseAuthStorage()
<AUTH_STORAGE_INSTANCE>, // It can be any storage option implementing AuthStorageInterface - e.g. new DatabaseAuthStorage()
<ENV> // Environment (optional) - dev, qa, or prod, defaults to prod
);

// Invoke handleCallback function to handle code coming from the authentication server
Expand Down
74 changes: 61 additions & 13 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,6 @@
use TRSTD\COT\Util\EncryptionUtils;
use TRSTD\COT\Util\PKCEUtils;

if (!defined('AUTH_SERVER_BASE_URI')) {
define('AUTH_SERVER_BASE_URI', 'https://auth-qa.trustedshops.com/auth/realms/myTS-QA/protocol/openid-connect/');
}

if (!defined('RESOURCE_SERVER_BASE_URI')) {
define('RESOURCE_SERVER_BASE_URI', 'https://scoped-cns-data.consumer-account-test.trustedshops.com/api/v1/');
}

CacheManager::setDefaultConfig(new ConfigurationOption([
"path" => __DIR__ . "/cache"
]));
Expand All @@ -53,6 +45,24 @@ final class Client
private const CONSUMER_ANONYMOUS_DATA_CACHE_KEY = 'CONSUMER_ANONYMOUS_DATA_';
private const CONSUMER_ANONYMOUS_DATA_CACHE_TTL = 3600; // 1 hour

private const AUTH_SERVER_BASE_URI_DEV = 'https://auth-integr.trustedshops.com/auth/realms/myTS-DEV/protocol/openid-connect/';
private const AUTH_SERVER_BASE_URI_QA = 'https://auth-qa.trustedshops.com/auth/realms/myTS-QA/protocol/openid-connect/';
private const AUTH_SERVER_BASE_URI_PROD = 'https://auth.trustedshops.com/auth/realms/myTS/protocol/openid-connect/';

private const RESOURCE_SERVER_BASE_URI_DEV = 'https://scoped-cns-data.consumer-account-dev.trustedshops.com/api/v1/';
private const RESOURCE_SERVER_BASE_URI_QA = 'https://scoped-cns-data.consumer-account-test.trustedshops.com/api/v1/';
private const RESOURCE_SERVER_BASE_URI_PROD = 'https://scoped-cns-data.consumer-account.trustedshops.com/api/v1/';

/**
* @var string
*/
private $authServerBaseUri;

/**
* @var string
*/
private $resourceServerBaseUri;

/**
* @var string
*/
Expand Down Expand Up @@ -93,9 +103,10 @@ final class Client
* @param string $clientId client ID
* @param string $clientSecret client secret
* @param AuthStorageInterface $authStorage auth storage to store tokens
* @param string $env environment dev, qa, or prod
* @throws RequiredParameterMissingException if any required parameter is missing
*/
public function __construct($tsId, $clientId, $clientSecret, AuthStorageInterface $authStorage = null)
public function __construct($tsId, $clientId, $clientSecret, AuthStorageInterface $authStorage = null, $env = 'prod')
{
if (!$tsId) {
throw new RequiredParameterMissingException('TS ID is required.');
Expand All @@ -113,6 +124,9 @@ public function __construct($tsId, $clientId, $clientSecret, AuthStorageInterfac
throw new RequiredParameterMissingException('AuthStorage is required.');
}

$this->authServerBaseUri = $this->getAuthServerBaseUri($env);
$this->resourceServerBaseUri = $this->getResourceServerBaseUri($env);

$this->tsId = $tsId;
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
Expand Down Expand Up @@ -160,7 +174,7 @@ public function getAnonymousConsumerData()
'Authorization: Bearer ' . $accessToken,
];

$response = $this->httpClient->request("GET", "anonymous-data" . ($this->tsId ? "?shopId=" . $this->tsId : ""), ['headers' => $headers, 'base_uri' => RESOURCE_SERVER_BASE_URI]);
$response = $this->httpClient->request("GET", "anonymous-data" . ($this->tsId ? "?shopId=" . $this->tsId : ""), ['headers' => $headers, 'base_uri' => $this->resourceServerBaseUri]);
$consumerAnonymousData = json_decode($response->getContent());

// cache the consumer anonymous data
Expand Down Expand Up @@ -202,6 +216,40 @@ public function setCacheItemPool(CacheItemPoolInterface $cacheItemPool)
$this->cacheItemPool = $cacheItemPool;
}

/**
* @param string $env environment dev, qa, or prod
* @return string
*/
private function getAuthServerBaseUri($env = 'prod')
{
if ($env === 'dev') {
return self::AUTH_SERVER_BASE_URI_DEV;
} elseif ($env === 'qa') {
return self::AUTH_SERVER_BASE_URI_QA;
} elseif ($env === 'prod') {
return self::AUTH_SERVER_BASE_URI_PROD;
}

throw new Exception("Invalid environment.");
}

/**
* @param string $env environment dev, qa, or prod
* @return string
*/
private function getResourceServerBaseUri($env = 'prod')
{
if ($env === 'dev') {
return self::RESOURCE_SERVER_BASE_URI_DEV;
} elseif ($env === 'qa') {
return self::RESOURCE_SERVER_BASE_URI_QA;
} elseif ($env === 'prod') {
return self::RESOURCE_SERVER_BASE_URI_PROD;
}

throw new Exception("Invalid environment.");
}

/**
* @param string $code code to exchange for token
* @return Token|null
Expand Down Expand Up @@ -251,7 +299,7 @@ private function getToken($code)
'code_verifier' => $this->getCodeVerifierCookie(),
];

$response = $this->httpClient->request("POST", "token", ['headers' => $headers, 'body' => $data, 'base_uri' => AUTH_SERVER_BASE_URI]);
$response = $this->httpClient->request("POST", "token", ['headers' => $headers, 'body' => $data, 'base_uri' => $this->authServerBaseUri]);
$responseJson = json_decode($response->getContent());
if (!$responseJson || isset($responseJson->error)) {
return null;
Expand All @@ -277,7 +325,7 @@ private function getRefreshedToken($refreshToken)
'refresh_token' => $refreshToken,
];

$response = $this->httpClient->request("POST", "token", ['headers' => $headers, 'body' => $data, 'base_uri' => AUTH_SERVER_BASE_URI]);
$response = $this->httpClient->request("POST", "token", ['headers' => $headers, 'body' => $data, 'base_uri' => $this->authServerBaseUri]);
$responseJson = json_decode($response->getContent());
if (!$responseJson || isset($responseJson->error)) {
return null;
Expand Down Expand Up @@ -402,7 +450,7 @@ private function getJWKS()
$cachedJWKSItem = $this->cacheItemPool->getItem(self::JWKS_CACHE_KEY);

if (!$cachedJWKSItem->isHit()) {
$response = $this->httpClient->request("GET", "certs", ['base_uri' => AUTH_SERVER_BASE_URI]);
$response = $this->httpClient->request("GET", "certs", ['base_uri' => $this->authServerBaseUri]);
$jwks = json_decode($response->getContent(), true);
$cachedJWKSItem->set($jwks)->expiresAfter(self::JWKS_CACHE_TTL);
$this->cacheItemPool->save($cachedJWKSItem);
Expand Down
2 changes: 1 addition & 1 deletion tests/ClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public function testHandleCallbackWithCode()
$expectedRequests = [
function ($method, $url, $options): MockResponse {
$this->assertSame('POST', $method);
$this->assertSame('https://auth-qa.trustedshops.com/auth/realms/myTS-QA/protocol/openid-connect/token', $url);
$this->assertSame('https://auth.trustedshops.com/auth/realms/myTS/protocol/openid-connect/token', $url);
$this->assertArrayHasKey('body', $options);
$this->assertArrayHasKey('headers', $options);

Expand Down