2626use InvalidArgumentException ;
2727use Jean85 \PrettyVersions ;
2828use LogicException ;
29+ use MongoDB \Client ;
30+ use MongoDB \Driver \Manager ;
2931use MongoDB \Driver \WriteConcern ;
3032use ProxyManager \Configuration as ProxyManagerConfiguration ;
3133use ProxyManager \Factory \LazyLoadingGhostFactory ;
3537use ReflectionClass ;
3638use Throwable ;
3739
40+ use function array_diff_key ;
41+ use function array_intersect_key ;
3842use function array_key_exists ;
39- use function array_key_first ;
4043use function class_exists ;
41- use function count ;
4244use function interface_exists ;
43- use function is_array ;
4445use function is_string ;
4546use function trigger_deprecation ;
4647use function trim ;
5657 * $dm = DocumentManager::create(new Connection(), $config);
5758 *
5859 * @phpstan-import-type CommitOptions from UnitOfWork
59- * @phpstan-type AutoEncryptionOptions array{
60- * keyVaultNamespace: string,
61- * kmsProviders: array<string, array<string, string>>,
62- * tlsOptions?: array{kmip: array{tlsCAFile: string, tlsCertificateKeyFile: string}},
63- * }
60+ * @phpstan-type KmsProvider array{type: string, ...}
6461 */
6562class Configuration
6663{
@@ -133,7 +130,9 @@ class Configuration
133130 * proxyDir?: string,
134131 * proxyNamespace?: string,
135132 * repositoryFactory?: RepositoryFactory,
136- * autoEncryption?: AutoEncryptionOptions,
133+ * kmsProvider?: KmsProvider,
134+ * defaultMasterKey?: array<string, mixed>|null,
135+ * autoEncryption?: array<string, mixed>,
137136 * }
138137 */
139138 private array $ attributes = [];
@@ -163,13 +162,34 @@ public function getDriverOptions(): array
163162 ],
164163 ];
165164
166- if (isset ($ this ->attributes ['autoEncryption ' ])) {
167- $ driverOptions ['autoEncryption ' ] = $ this ->attributes [ ' autoEncryption ' ] ;
165+ if (isset ($ this ->attributes ['kmsProvider ' ])) {
166+ $ driverOptions ['autoEncryption ' ] = $ this ->getAutoEncryptionOptions () ;
168167 }
169168
170169 return $ driverOptions ;
171170 }
172171
172+ /**
173+ * Get options to create a ClientEncryption instance.
174+ *
175+ * @see https://www.php.net/manual/en/mongodb-driver-clientencryption.construct.php
176+ *
177+ * @return array{keyVaultClient?: Client|Manager, keyVaultNamespace: string, kmsProviders: array<string, mixed>, tlsOptions?: array<string, mixed>}
178+ */
179+ public function getClientEncryptionOptions (): array
180+ {
181+ if (! isset ($ this ->attributes ['kmsProvider ' ])) {
182+ throw ConfigurationException::clientEncryptionOptionsNotSet ();
183+ }
184+
185+ return array_intersect_key ($ this ->getAutoEncryptionOptions (), [
186+ 'keyVaultClient ' => 1 ,
187+ 'keyVaultNamespace ' => 1 ,
188+ 'kmsProviders ' => 1 ,
189+ 'tlsOptions ' => 1 ,
190+ ]);
191+ }
192+
173193 /**
174194 * Adds a namespace under a certain alias.
175195 */
@@ -688,47 +708,72 @@ public function isLazyGhostObjectEnabled(): bool
688708 }
689709
690710 /**
691- * Set the options for auto-encryption.
711+ * Set the KMS provider to use for auto-encryption. The name of the KMS provider
712+ * must be specified in the 'type' key of the array.
692713 *
693714 * @see https://www.php.net/manual/en/mongodb-driver-clientencryption.construct.php
694715 *
695- * @phpstan-param AutoEncryptionOptions $options
696- *
697- * @throws InvalidArgumentException If the options are invalid.
716+ * @param KmsProvider $kmsProvider
698717 */
699- public function setAutoEncryption (array $ options ): void
718+ public function setKmsProvider (array $ kmsProvider ): void
700719 {
701- if (! isset ($ options [ ' keyVaultNamespace ' ]) || ! is_string ( $ options [ ' keyVaultNamespace ' ])) {
702- throw new InvalidArgumentException ( ' The "keyVaultNamespace" option is required. ' );
720+ if (! isset ($ kmsProvider [ ' type ' ])) {
721+ throw ConfigurationException:: kmsProviderTypeRequired ( );
703722 }
704723
705- // @todo Throw en exception if multiple KMS providers are defined. This is not supported yet and would require a setting for the KMS provider to use when creating a new collection
706- if (! isset ($ options ['kmsProviders ' ]) || ! is_array ($ options ['kmsProviders ' ]) || count ($ options ['kmsProviders ' ]) < 1 ) {
707- throw new InvalidArgumentException ('The "kmsProviders" option is required. ' );
724+ if (! is_string ($ kmsProvider ['type ' ])) {
725+ throw ConfigurationException::kmsProviderTypeMustBeString ();
708726 }
709727
710- $ this ->attributes ['autoEncryption ' ] = $ options ;
728+ $ this ->attributes ['kmsProvider ' ] = $ kmsProvider ;
711729 }
712730
713731 /**
714- * Get the options for auto-encryption .
732+ * Set the default master key to use when creating encrypted collections .
715733 *
716- * @see https://www.php.net/manual/en/mongodb-driver-clientencryption.construct.php
734+ * @param array<string, mixed>|null $masterKey
735+ */
736+ public function setDefaultMasterKey (?array $ masterKey ): void
737+ {
738+ $ this ->attributes ['defaultMasterKey ' ] = $ masterKey ;
739+ }
740+
741+ /**
742+ * Set the options for auto-encryption.
743+ *
744+ * @see https://www.php.net/manual/en/mongodb-driver-manager.construct.php
717745 *
718- * @phpstan-return AutoEncryptionOptions
746+ * @param array{ keyVaultClient?: Client|Manager, keyVaultNamespace?: string, tlsOptions?: array<string, mixed>, schemaMap?: array<string, mixed>, encryptedFieldsMap?: array<string, mixed>, extraOptions?: array<string, mixed>} $options
719747 */
720- public function getAutoEncryption ( ): ? array
748+ public function setAutoEncryption ( array $ options ): void
721749 {
722- return $ this ->attributes ['autoEncryption ' ] ?? null ;
750+ if (isset ($ options ['kmsProviders ' ])) {
751+ throw ConfigurationException::kmsProvidersOptionMustUseSetter ();
752+ }
753+
754+ $ this ->attributes ['autoEncryption ' ] = $ options ;
723755 }
724756
725- public function getKmsProvider (): ?string
757+ /**
758+ * Get the default KMS provider name used when creating encrypted collections.
759+ */
760+ public function getDefaultKmsProvider (): ?string
726761 {
727- if (! isset ($ this ->attributes ['autoEncryption ' ])) {
762+ return $ this ->attributes ['kmsProvider ' ]['type ' ] ?? null ;
763+ }
764+
765+ /**
766+ * Get the default master key used when creating encrypted collections.
767+ *
768+ * @return array<string, mixed>|null
769+ */
770+ public function getDefaultMasterKey (): ?array
771+ {
772+ if (! isset ($ this ->attributes ['kmsProvider ' ]) || $ this ->attributes ['kmsProvider ' ]['type ' ] === 'local ' ) {
728773 return null ;
729774 }
730775
731- return array_key_first ($ this ->attributes ['autoEncryption ' ]['kmsProviders ' ]);
776+ return $ this -> attributes [ ' defaultMasterKey ' ] ?? throw ConfigurationException:: masterKeyRequired ($ this ->attributes ['kmsProvider ' ]['type ' ]);
732777 }
733778
734779 private static function getVersion (): string
@@ -743,6 +788,16 @@ private static function getVersion(): string
743788
744789 return self ::$ version ;
745790 }
791+
792+ /** @return array<string, mixed> */
793+ private function getAutoEncryptionOptions (): array
794+ {
795+ return [
796+ 'kmsProviders ' => [$ this ->attributes ['kmsProvider ' ]['type ' ] => array_diff_key ($ this ->attributes ['kmsProvider ' ], ['type ' => 0 ])],
797+ 'keyVaultNamespace ' => $ this ->getDefaultDB () . '.datakeys ' ,
798+ ...$ this ->attributes ['autoEncryption ' ] ?? [],
799+ ];
800+ }
746801}
747802
748803interface_exists (MappingDriver::class);
0 commit comments