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 ;
3638use Throwable ;
3739
3840use function array_diff_key ;
41+ use function array_intersect_key ;
3942use function array_key_exists ;
40- use function array_key_first ;
4143use function class_exists ;
42- use function count ;
4344use function interface_exists ;
44- use function is_array ;
4545use function is_string ;
4646use function sprintf ;
4747use function trigger_deprecation ;
5858 * $dm = DocumentManager::create(new Connection(), $config);
5959 *
6060 * @phpstan-import-type CommitOptions from UnitOfWork
61- * @phpstan-type AutoEncryptionOptions array{
62- * keyVaultNamespace: string,
63- * kmsProviders: array<string, array<string, mixed>>,
64- * kmsProvider?: string,
65- * masterKey?: array<string, mixed>|null,
66- * tlsOptions?: array{kmip: array{tlsCAFile: string, tlsCertificateKeyFile: string}},
67- * ...
68- * }
61+ * @phpstan-type KmsProvider array{name: string, ...}
6962 */
7063class Configuration
7164{
@@ -138,7 +131,9 @@ class Configuration
138131 * proxyDir?: string,
139132 * proxyNamespace?: string,
140133 * repositoryFactory?: RepositoryFactory,
141- * autoEncryption?: AutoEncryptionOptions,
134+ * kmsProvider?: KmsProvider,
135+ * defaultMasterKey?: array<string, mixed>|null,
136+ * autoEncryption?: array<string, mixed>,
142137 * }
143138 */
144139 private array $ attributes = [];
@@ -168,16 +163,34 @@ public function getDriverOptions(): array
168163 ],
169164 ];
170165
171- if (isset ($ this ->attributes ['autoEncryption ' ])) {
172- $ driverOptions ['autoEncryption ' ] = array_diff_key (
173- $ this ->attributes ['autoEncryption ' ],
174- ['kmsProvider ' => 0 , 'masterKey ' => 0 ],
175- );
166+ if (isset ($ this ->attributes ['kmsProvider ' ])) {
167+ $ driverOptions ['autoEncryption ' ] = $ this ->getAutoEncryptionOptions ();
176168 }
177169
178170 return $ driverOptions ;
179171 }
180172
173+ /**
174+ * Get options to create a ClientEncryption instance.
175+ *
176+ * @see https://www.php.net/manual/en/mongodb-driver-clientencryption.construct.php
177+ *
178+ * @return array{keyVaultClient?: Client|Manager, keyVaultNamespace: string, kmsProviders: array<string, mixed>, tlsOptions?: array<string, mixed>}
179+ */
180+ public function getClientEncryptionOptions (): array
181+ {
182+ if (! isset ($ this ->attributes ['kmsProvider ' ])) {
183+ throw new ConfigurationException ('MongoDB client encryption options are not set in configuration ' );
184+ }
185+
186+ return array_intersect_key ($ this ->getAutoEncryptionOptions (), [
187+ 'keyVaultClient ' => 1 ,
188+ 'keyVaultNamespace ' => 1 ,
189+ 'kmsProviders ' => 1 ,
190+ 'tlsOptions ' => 1 ,
191+ ]);
192+ }
193+
181194 /**
182195 * Adds a namespace under a certain alias.
183196 */
@@ -696,69 +709,72 @@ public function isLazyGhostObjectEnabled(): bool
696709 }
697710
698711 /**
699- * Set the options for auto-encryption.
712+ * Set the KMS provider to use for auto-encryption. The name of the KMS provider
713+ * must be specified in the 'name' key of the array.
700714 *
701715 * @see https://www.php.net/manual/en/mongodb-driver-clientencryption.construct.php
702716 *
703- * @phpstan-param AutoEncryptionOptions $options
704- *
705- * @throws InvalidArgumentException If the options are invalid.
717+ * @param KmsProvider $kmsProvider
706718 */
707- public function setAutoEncryption (array $ options ): void
719+ public function setKmsProvider (array $ kmsProvider ): void
708720 {
709- if (! isset ($ options ['keyVaultNamespace ' ]) || ! is_string ($ options ['keyVaultNamespace ' ])) {
710- throw new InvalidArgumentException ('The "keyVaultNamespace" encryption option is required. ' );
711- }
712-
713- if (! is_array ($ options ['kmsProviders ' ] ?? null ) || count ($ options ['kmsProviders ' ]) === 0 ) {
714- throw new InvalidArgumentException ('The "kmsProviders" encryption option is required and must be a non-empty. ' );
721+ if (! isset ($ kmsProvider ['name ' ])) {
722+ throw new ConfigurationException ('The "name" KMS provider option is required. ' );
715723 }
716724
717- if (! isset ( $ options [ ' kmsProvider ' ]) && count ( $ options [ ' kmsProviders ' ]) > 1 ) {
718- throw new InvalidArgumentException ('The "kmsProvider" encryption option is required when multiple KMS providers are specified . ' );
725+ if (! is_string ( $ kmsProvider[ ' name ' ])) {
726+ throw new ConfigurationException ('The "name" KMS provider option must be a non-empty string . ' );
719727 }
720728
721- $ options ['kmsProvider ' ] ??= array_key_first ($ options ['kmsProviders ' ]);
722-
723- if (! array_key_exists ($ options ['kmsProvider ' ], $ options ['kmsProviders ' ])) {
724- throw new InvalidArgumentException (sprintf ('The "kmsProvider" encryption option "%s" is not defined in the "kmsProviders" option. ' , $ options ['kmsProvider ' ]));
725- }
726-
727- if ($ options ['kmsProvider ' ] !== 'local ' && ! isset ($ options ['masterKey ' ])) {
728- throw new InvalidArgumentException ('The "masterKey" option is required when the KMS provider is not "local". ' );
729- }
729+ $ this ->attributes ['kmsProvider ' ] = $ kmsProvider ;
730+ }
730731
731- $ this ->attributes ['autoEncryption ' ] = $ options ;
732+ /**
733+ * Set the default master key to use when creating encrypted collections.
734+ *
735+ * @param array<string, mixed>|null $masterKey
736+ */
737+ public function setDefaultMasterKey (?array $ masterKey ): void
738+ {
739+ $ this ->attributes ['defaultMasterKey ' ] = $ masterKey ;
732740 }
733741
734742 /**
735- * Get the options for auto-encryption.
743+ * Set the options for auto-encryption.
736744 *
737- * @see https://www.php.net/manual/en/mongodb-driver-clientencryption .construct.php
745+ * @see https://www.php.net/manual/en/mongodb-driver-manager .construct.php
738746 *
739- * @phpstan-return AutoEncryptionOptions
747+ * @param array{ keyVaultClient?: Client|Manager, keyVaultNamespace?: string, tlsOptions?: array<string, mixed>, schemaMap?: array<string, mixed>, encryptedFieldsMap?: array<string, mixed>, extraOptions?: array<string, mixed>} $options
740748 */
741- public function getAutoEncryption ( ): ? array
749+ public function setAutoEncryption ( array $ options ): void
742750 {
743- return $ this ->attributes ['autoEncryption ' ] ?? null ;
751+ if (isset ($ options ['kmsProviders ' ])) {
752+ throw new ConfigurationException ('The "kmsProviders" encryption option must be set using the "setKmsProvider()" method. ' );
753+ }
754+
755+ $ this ->attributes ['autoEncryption ' ] = $ options ;
744756 }
745757
746758 /**
747- * Get the KMS provider name used for auto-encryption .
759+ * Get the default KMS provider name used when creating encrypted collections .
748760 */
749- public function getKmsProvider (): ?string
761+ public function getDefaultKmsProvider (): ?string
750762 {
751- return $ this ->attributes ['autoEncryption ' ]['kmsProvider ' ] ?? null ;
763+ return $ this ->attributes ['kmsProvider ' ]['name ' ] ?? null ;
752764 }
753765
754766 /**
755- * Get the master key used for auto-encryption .
767+ * Get the default master key used when creating encrypted collections .
756768 *
757769 * @return array<string, mixed>|null
758770 */
759- public function getMasterKey (): ?array
771+ public function getDefaultMasterKey (): ?array
760772 {
761- return $ this ->attributes ['autoEncryption ' ]['masterKey ' ] ?? null ;
773+ if (! isset ($ this ->attributes ['kmsProvider ' ]) || $ this ->attributes ['kmsProvider ' ]['name ' ] === 'local ' ) {
774+ return null ;
775+ }
776+
777+ return $ this ->attributes ['defaultMasterKey ' ] ?? throw new ConfigurationException (sprintf ('The "masterKey" configuration is required for the KMS provider "%s". ' , $ this ->attributes ['kmsProvider ' ]['name ' ]));
762778 }
763779
764780 private static function getVersion (): string
@@ -773,6 +789,16 @@ private static function getVersion(): string
773789
774790 return self ::$ version ;
775791 }
792+
793+ /** @return array<string, mixed> */
794+ private function getAutoEncryptionOptions (): array
795+ {
796+ return [
797+ 'kmsProviders ' => [$ this ->attributes ['kmsProvider ' ]['name ' ] => array_diff_key ($ this ->attributes ['kmsProvider ' ], ['name ' => 0 ])],
798+ 'keyVaultNamespace ' => $ this ->getDefaultDB () . '.datakeys ' ,
799+ ...$ this ->attributes ['autoEncryption ' ] ?? [],
800+ ];
801+ }
776802}
777803
778804interface_exists (MappingDriver::class);
0 commit comments