-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat (csas-migration): Add TransClient
- Loading branch information
Showing
2 changed files
with
205 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
); | ||
} | ||
} |