Skip to content

Commit

Permalink
feat (csas-migration): Add TransClient
Browse files Browse the repository at this point in the history
  • Loading branch information
romantmb committed Feb 4, 2025
1 parent fb1b354 commit cd29f94
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/Temporary/TransClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Keboola\ObjectEncryptor\Temporary;

use Keboola\AzureKeyVaultClient\Client;
use Keboola\AzureKeyVaultClient\GuzzleClientFactory;

class TransClient extends Client
{
public function __construct(GuzzleClientFactory $clientFactory, ?string $encryptorId)
{
$vaultBaseUrl = (string) getenv(self::determinateVaultUrlEnvName($encryptorId));

if ($vaultBaseUrl === '') {
throw new TransClientNotAvailableException;
}

parent::__construct(
$clientFactory,
new TransAuthenticatorFactory(),
$vaultBaseUrl,
);
}

public static function determinateVaultUrlEnvName(?string $encryptorId): string
{
$transEnvName = 'TRANS_AZURE_KEY_VAULT_URL';

if (!empty($encryptorId)) { // not null or empty string
$suffix = (string) preg_replace('/[\s\-_]+/', '_', $encryptorId);
$suffix = trim($suffix, '_');
$transEnvName .= sprintf('_%s', strtoupper($suffix));
}

return $transEnvName;
}
}
166 changes: 166 additions & 0 deletions tests/Temporary/TransClientTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<?php

declare(strict_types=1);

namespace Keboola\ObjectEncryptor\Tests\Temporary;

use Keboola\AzureKeyVaultClient\GuzzleClientFactory;
use Keboola\ObjectEncryptor\Temporary\TransClient;
use Keboola\ObjectEncryptor\Temporary\TransClientNotAvailableException;
use PHPUnit\Framework\TestCase;
use Psr\Log\NullLogger;

class TransClientTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();

putenv('TRANS_AZURE_TENANT_ID=');
putenv('TRANS_AZURE_CLIENT_ID=');
putenv('TRANS_AZURE_CLIENT_SECRET=');

$definedEnvsInProviders = array_column([
...self::provideTransClientUrlTestData(),
...self::provideTransClientMismatchEnvsTestData(),
], 'envs');
foreach (array_keys(array_merge(...$definedEnvsInProviders)) as $envName) {
putenv(sprintf('%s=', $envName));
}
}

public static function provideDeterminateVaultUrlEnvNameTestData(): iterable
{
yield 'encryptorId is null' => [
'encryptorId' => null,
'expectedEnvName' => 'TRANS_AZURE_KEY_VAULT_URL',
];
yield 'encryptorId is empty' => [
'encryptorId' => '',
'expectedEnvName' => 'TRANS_AZURE_KEY_VAULT_URL',
];
yield 'encryptorId = "internal"' => [
'encryptorId' => 'internal',
'expectedEnvName' => 'TRANS_AZURE_KEY_VAULT_URL_INTERNAL',
];
yield 'encryptorId = "job_queue"' => [
'encryptorId' => 'job_queue',
'expectedEnvName' => 'TRANS_AZURE_KEY_VAULT_URL_JOB_QUEUE',
];
yield 'encryptorId = "job__queue_"' => [
'encryptorId' => 'job__queue_',
'expectedEnvName' => 'TRANS_AZURE_KEY_VAULT_URL_JOB_QUEUE',
];
yield 'encryptorId = "job-queue"' => [
'encryptorId' => 'job-queue',
'expectedEnvName' => 'TRANS_AZURE_KEY_VAULT_URL_JOB_QUEUE',
];
yield 'encryptorId = "job queue"' => [
'encryptorId' => 'job queue',
'expectedEnvName' => 'TRANS_AZURE_KEY_VAULT_URL_JOB_QUEUE',
];
}

/** @dataProvider provideDeterminateVaultUrlEnvNameTestData */
public function testDeterminateVaultUrlEnvName(
?string $encryptorId,
string $expectedEnvName,
): void {
self::assertSame(
$expectedEnvName,
TransClient::determinateVaultUrlEnvName($encryptorId),
);
}

public static function provideTransClientUrlTestData(): iterable
{
yield 'encryptorId is null' => [
'encryptorId' => null,
'envs' => [
'TRANS_AZURE_KEY_VAULT_URL' => 'https://vault-url',
],
'expectedClientUrl' => 'https://vault-url',
];

yield 'encryptorId = "internal"' => [
'encryptorId' => 'internal',
'envs' => [
'TRANS_AZURE_KEY_VAULT_URL_INTERNAL' => 'https://internal-vault-url',
],
'expectedClientUrl' => 'https://internal-vault-url',
];
}

/** @dataProvider provideTransClientUrlTestData */
public function testTransClientUrl(
?string $encryptorId,
array $envs,
string $expectedVaultUrl,
): void {
putenv('TRANS_AZURE_TENANT_ID=tenant-id');
putenv('TRANS_AZURE_CLIENT_ID=client-id');
putenv('TRANS_AZURE_CLIENT_SECRET=client-secret');
foreach ($envs as $envName => $envValue) {
putenv(sprintf('%s=%s', $envName, $envValue));
}

$guzzleClientFactoryCounter = self::exactly(2);
$guzzleClientFactoryMock = $this->createMock(GuzzleClientFactory::class);
$guzzleClientFactoryMock->expects($guzzleClientFactoryCounter)
->method('getClient')
->with(
self::callback(fn($url) => match ($guzzleClientFactoryCounter->getInvocationCount()) {
1 => $url === $expectedVaultUrl,
2 => $url === 'https://management.azure.com/metadata/endpoints?api-version=2020-01-01',
default => self::fail('Unexpected url: ' . $url),
}),
self::isType('array'),
);

try {
new TransClient(
$guzzleClientFactoryMock,
$encryptorId,
);
} catch (TransClientNotAvailableException) {
self::fail('Test should not have thrown an exception');
}
}

public static function provideTransClientMismatchEnvsTestData(): iterable
{
yield 'encryptorId is null, env has suffix' => [
'encryptorId' => null,
'envs' => [
'TRANS_AZURE_KEY_VAULT_URL_SOMETHING' => 'https://vault-url',
],
];

yield 'encryptorId = "internal", env suffix is missing' => [
'encryptorId' => 'internal',
'envs' => [
'TRANS_AZURE_KEY_VAULT_URL' => 'https://vault-url',
],
];
}

/** @dataProvider provideTransClientMismatchEnvsTestData */
public function testTransClientMismatchEnvs(
?string $encryptorId,
array $envs,
): void {
putenv('TRANS_AZURE_TENANT_ID=tenant-id');
putenv('TRANS_AZURE_CLIENT_ID=client-id');
putenv('TRANS_AZURE_CLIENT_SECRET=client-secret');
foreach ($envs as $envName => $envValue) {
putenv(sprintf('%s=%s', $envName, $envValue));
}

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

new TransClient(
new GuzzleClientFactory(new NullLogger()),
$encryptorId,
);
}
}

0 comments on commit cd29f94

Please sign in to comment.