diff --git a/psalm-baseline.xml b/psalm-baseline.xml index a02fc0fc8..5816fc227 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -231,8 +231,12 @@ + + + + diff --git a/src/Client.php b/src/Client.php index 7e551de27..c9d36a6c8 100644 --- a/src/Client.php +++ b/src/Client.php @@ -119,12 +119,8 @@ public function __construct(?string $uri = null, array $uriOptions = [], array $ throw InvalidArgumentException::invalidType('"typeMap" driver option', $driverOptions['typeMap'], 'array'); } - if (isset($driverOptions['autoEncryption']['keyVaultClient'])) { - if ($driverOptions['autoEncryption']['keyVaultClient'] instanceof self) { - $driverOptions['autoEncryption']['keyVaultClient'] = $driverOptions['autoEncryption']['keyVaultClient']->manager; - } elseif (! $driverOptions['autoEncryption']['keyVaultClient'] instanceof Manager) { - throw InvalidArgumentException::invalidType('"keyVaultClient" autoEncryption option', $driverOptions['autoEncryption']['keyVaultClient'], [self::class, Manager::class]); - } + if (isset($driverOptions['autoEncryption']) && is_array($driverOptions['autoEncryption'])) { + $driverOptions['autoEncryption'] = $this->prepareEncryptionOptions($driverOptions['autoEncryption']); } if (isset($driverOptions['builderEncoder']) && ! $driverOptions['builderEncoder'] instanceof Encoder) { @@ -213,13 +209,7 @@ final public function addSubscriber(Subscriber $subscriber): void */ public function createClientEncryption(array $options) { - if (isset($options['keyVaultClient'])) { - if ($options['keyVaultClient'] instanceof self) { - $options['keyVaultClient'] = $options['keyVaultClient']->manager; - } elseif (! $options['keyVaultClient'] instanceof Manager) { - throw InvalidArgumentException::invalidType('"keyVaultClient" option', $options['keyVaultClient'], [self::class, Manager::class]); - } - } + $options = $this->prepareEncryptionOptions($options); return $this->manager->createClientEncryption($options); } @@ -499,4 +489,26 @@ private function mergeDriverInfo(array $driver): array return $mergedDriver; } + + private function prepareEncryptionOptions(array $options): array + { + if (isset($options['keyVaultClient'])) { + if ($options['keyVaultClient'] instanceof self) { + $options['keyVaultClient'] = $options['keyVaultClient']->manager; + } elseif (! $options['keyVaultClient'] instanceof Manager) { + throw InvalidArgumentException::invalidType('"keyVaultClient" option', $options['keyVaultClient'], [self::class, Manager::class]); + } + } + + // The server requires an empty document for automatic credentials. + if (isset($options['kmsProviders']) && is_array($options['kmsProviders'])) { + foreach ($options['kmsProviders'] as $name => $provider) { + if ($provider === []) { + $options['kmsProviders'][$name] = new stdClass(); + } + } + } + + return $options; + } } diff --git a/tests/ClientTest.php b/tests/ClientTest.php index a2fc917ae..45d852dc4 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -37,6 +37,18 @@ public function testConstructorAutoEncryptionOpts(): void new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]); } + #[DoesNotPerformAssertions] + public function testConstructorEmptyKmsProvider(): void + { + $autoEncryptionOpts = [ + 'keyVaultClient' => new Client(static::getUri()), + 'keyVaultNamespace' => 'default.keys', + 'kmsProviders' => ['gcp' => []], + ]; + + new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]); + } + #[DataProvider('provideInvalidConstructorDriverOptions')] public function testConstructorDriverOptionTypeChecks(array $driverOptions, string $exception = InvalidArgumentException::class): void { diff --git a/tests/Collection/CollectionFunctionalTest.php b/tests/Collection/CollectionFunctionalTest.php index 1c7af5be3..d937f7bee 100644 --- a/tests/Collection/CollectionFunctionalTest.php +++ b/tests/Collection/CollectionFunctionalTest.php @@ -404,7 +404,6 @@ public function testWithOptionsInheritsOptions(): void $rc = new ReflectionClass($clone); $rp = $rc->getProperty('autoEncryptionEnabled'); - $rp->setAccessible(true); $this->assertSame(true, $rp->getValue($clone)); } @@ -432,7 +431,6 @@ public function testWithOptionsPassesOptions(): void $rc = new ReflectionClass($clone); $rp = $rc->getProperty('autoEncryptionEnabled'); - $rp->setAccessible(true); $this->assertSame(true, $rp->getValue($clone)); } diff --git a/tests/Database/DatabaseFunctionalTest.php b/tests/Database/DatabaseFunctionalTest.php index 07f383ee1..fa9d9c926 100644 --- a/tests/Database/DatabaseFunctionalTest.php +++ b/tests/Database/DatabaseFunctionalTest.php @@ -397,7 +397,6 @@ public function testWithOptionsInheritsOptions(): void $rc = new ReflectionClass($clone); $rp = $rc->getProperty('autoEncryptionEnabled'); - $rp->setAccessible(true); $this->assertSame(true, $rp->getValue($clone)); } @@ -424,7 +423,6 @@ public function testWithOptionsPassesOptions(): void $rc = new ReflectionClass($clone); $rp = $rc->getProperty('autoEncryptionEnabled'); - $rp->setAccessible(true); $this->assertSame(true, $rp->getValue($clone)); }