diff --git a/docs/includes/apiargs-MongoDBClient-method-createClientEncryption-param.yaml b/docs/includes/apiargs-MongoDBClient-method-createClientEncryption-param.yaml new file mode 100644 index 000000000..73ad04d0b --- /dev/null +++ b/docs/includes/apiargs-MongoDBClient-method-createClientEncryption-param.yaml @@ -0,0 +1,4 @@ +source: + file: apiargs-common-param.yaml + ref: $options +... diff --git a/docs/reference/class/MongoDBClient.txt b/docs/reference/class/MongoDBClient.txt index ae1906ff0..b638dc4b9 100644 --- a/docs/reference/class/MongoDBClient.txt +++ b/docs/reference/class/MongoDBClient.txt @@ -30,6 +30,7 @@ Methods /reference/method/MongoDBClient__construct /reference/method/MongoDBClient__get + /reference/method/MongoDBClient-createClientEncryption /reference/method/MongoDBClient-dropDatabase /reference/method/MongoDBClient-getManager /reference/method/MongoDBClient-getReadConcern diff --git a/docs/reference/method/MongoDBClient-createClientEncryption.txt b/docs/reference/method/MongoDBClient-createClientEncryption.txt new file mode 100644 index 000000000..9b6f817ea --- /dev/null +++ b/docs/reference/method/MongoDBClient-createClientEncryption.txt @@ -0,0 +1,51 @@ +========================================= +MongoDB\\Client::createClientEncryption() +========================================= + +.. default-domain:: mongodb + +.. contents:: On this page + :local: + :backlinks: none + :depth: 1 + :class: singlecol + +Definition +---------- + +.. phpmethod:: MongoDB\\Client::createClientEncryption() + + Returns a :php:`MongoDB\\Driver\\ClientEncryption ` + object for manual encryption and decryption of values. + + .. code-block:: php + + function createClientEncryption(array $options): MongoDB\Driver\ClientEncryption + + This method has the following parameters: + + .. include:: /includes/apiargs/MongoDBClient-method-createClientEncryption-param.rst + + The ``$options`` parameter supports all options documented in the + :php:`extension manual `. + For the ``keyVaultClient`` option, an instance of :phpclass:`MongoDB\\Client` + is automatically unwrapped and the :php:`MongoDB\\Driver\\Manager ` + instance is passed to the extension. + +Return Values +------------- + +A :php:`MongoDB\\Driver\\ClientEncryption ` +instance which can be used to encrypt and decrypt values. + +Errors/Exceptions +----------------- + +.. include:: /includes/extracts/error-invalidargumentexception.rst +.. include:: /includes/extracts/error-driver-invalidargumentexception.rst + +See Also +-------- + +- :php:`MongoDB\\Driver\\Manager::createClientEncryption() + ` diff --git a/src/Client.php b/src/Client.php index 363c2b686..ae028f887 100644 --- a/src/Client.php +++ b/src/Client.php @@ -17,6 +17,7 @@ namespace MongoDB; +use MongoDB\Driver\ClientEncryption; use MongoDB\Driver\Exception\InvalidArgumentException as DriverInvalidArgumentException; use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; use MongoDB\Driver\Manager; @@ -161,6 +162,26 @@ public function __toString() return $this->uri; } + /** + * Returns a ClientEncryption instance for explicit encryption and decryption + * + * @param array $options Encryption options + * + * @return ClientEncryption + */ + 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]); + } + } + + return $this->manager->createClientEncryption($options); + } + /** * Drop a database. * diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 46b8a47ec..b5c87823b 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -3,6 +3,7 @@ namespace MongoDB\Tests; use MongoDB\Client; +use MongoDB\Driver\ClientEncryption; use MongoDB\Driver\ReadConcern; use MongoDB\Driver\ReadPreference; use MongoDB\Driver\WriteConcern; @@ -173,4 +174,55 @@ public function testSelectDatabasePassesOptions() $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']); $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW()); } + + public function testCreateClientEncryption() + { + $client = new Client(static::getUri()); + + $options = [ + 'keyVaultNamespace' => 'default.keys', + 'kmsProviders' => ['aws' => ['accessKeyId' => 'abc', 'secretAccessKey' => 'def']], + ]; + + $clientEncryption = $client->createClientEncryption($options); + $this->assertInstanceOf(ClientEncryption::class, $clientEncryption); + } + + public function testCreateClientEncryptionWithKeyVaultClient() + { + $client = new Client(static::getUri()); + + $options = [ + 'keyVaultClient' => $client, + 'keyVaultNamespace' => 'default.keys', + 'kmsProviders' => ['aws' => ['accessKeyId' => 'abc', 'secretAccessKey' => 'def']], + ]; + + $clientEncryption = $client->createClientEncryption($options); + $this->assertInstanceOf(ClientEncryption::class, $clientEncryption); + } + + public function testCreateClientEncryptionWithManager() + { + $client = new Client(static::getUri()); + + $options = [ + 'keyVaultClient' => $client->getManager(), + 'keyVaultNamespace' => 'default.keys', + 'kmsProviders' => ['aws' => ['accessKeyId' => 'abc', 'secretAccessKey' => 'def']], + ]; + + $clientEncryption = $client->createClientEncryption($options); + $this->assertInstanceOf(ClientEncryption::class, $clientEncryption); + } + + public function testCreateClientEncryptionWithInvalidKeyVaultClient() + { + $client = new Client(static::getUri()); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Expected "keyVaultClient" option to have type "MongoDB\Client" or "MongoDB\Driver\Manager" but found "string"'); + + $client->createClientEncryption(['keyVaultClient' => 'foo']); + } }