Skip to content

Commit 8282c64

Browse files
committed
Register encryption commands only when automatic encryption is configured
The mongodb:encrypted:create and mongodb:encrypted:diagnose commands are now registered only when at least one MongoDB connection configures driver_options.autoEncryption, matching the keys-first setup contract. Registration moves to boot() so the connection configuration is fully loaded before the check. The command test configures autoEncryption on the mongodb connection beforehand; without it the commands are not exposed.
1 parent 443aa52 commit 8282c64

2 files changed

Lines changed: 53 additions & 16 deletions

File tree

src/MongoDBServiceProvider.php

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use function class_exists;
3636
use function config;
3737
use function get_debug_type;
38+
use function is_array;
3839
use function is_string;
3940
use function sprintf;
4041

@@ -48,6 +49,17 @@ public function boot()
4849
Model::setConnectionResolver($this->app['db']);
4950

5051
Model::setEventDispatcher($this->app['events']);
52+
53+
// Only expose the Queryable Encryption CLI when a MongoDB connection is
54+
// configured with automatic encryption; otherwise the setup contract
55+
// (keys-first, config map) is not usable. Registered in boot() so the
56+
// connection configuration is fully loaded.
57+
if ($this->supportsQueryableEncryption()) {
58+
$this->commands([
59+
Commands\Encrypted\CreateEncryptedCommand::class,
60+
Commands\Encrypted\DiagnoseEncryptedCommand::class,
61+
]);
62+
}
5163
}
5264

5365
/**
@@ -109,11 +121,23 @@ public function register()
109121
$this->registerFlysystemAdapter();
110122
$this->registerScoutEngine();
111123
$this->registerBoostTools();
124+
}
125+
126+
/**
127+
* Determine whether at least one MongoDB connection config uses automatic
128+
* encryption (driver_options.autoEncryption).
129+
*/
130+
private function supportsQueryableEncryption(): bool
131+
{
132+
foreach (config('database.connections', []) as $connection) {
133+
$autoEncryption = is_array($connection) ? ($connection['driver_options']['autoEncryption'] ?? null) : null;
134+
135+
if (($connection['driver'] ?? null) === 'mongodb' && is_array($autoEncryption)) {
136+
return true;
137+
}
138+
}
112139

113-
$this->commands([
114-
Commands\Encrypted\CreateEncryptedCommand::class,
115-
Commands\Encrypted\DiagnoseEncryptedCommand::class,
116-
]);
140+
return false;
117141
}
118142

119143
private function registerFlysystemAdapter(): void

tests/Commands/EncryptedCommandsTest.php

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313

1414
class EncryptedCommandsTest extends TestCase
1515
{
16-
public function testDiagnoseFailsWhenEncryptionNotConfigured(): void
16+
protected function getEnvironmentSetUp($app): void
1717
{
18-
$this->artisan('mongodb:encrypted:diagnose', ['--no-server' => true])
19-
->expectsOutputToContain('Queryable Encryption is not enabled')
20-
->assertExitCode(Command::FAILURE);
18+
parent::getEnvironmentSetUp($app);
19+
20+
// Configure automatic encryption so the encryption commands are
21+
// registered on the "mongodb" connection (registered in boot());
22+
// the config is fully loaded by then.
23+
$app['config']->set('database.connections.mongodb.driver_options.autoEncryption', $this->encryptionOptions([]));
2124
}
2225

2326
public function testDiagnoseNoServerListsMappedCollections(): void
@@ -49,20 +52,30 @@ public function testCreateNoServerFailsWithoutMappedCollection(): void
4952
}
5053

5154
/**
52-
* Configure automatic encryption on the default MongoDB connection.
55+
* @param array<string, mixed> $encryptedFieldsMap
56+
*
57+
* @return array<string, mixed>
58+
*/
59+
private function encryptionOptions(array $encryptedFieldsMap): array
60+
{
61+
return [
62+
'keyVaultNamespace' => 'encryption.__keyVault',
63+
'kmsProviders' => ['local' => ['key' => base64_encode(random_bytes(96))]],
64+
// Opt out of crypt_shared so the tests run on a community server.
65+
'extraOptions' => ['cryptSharedLibRequired' => false],
66+
'encryptedFieldsMap' => $encryptedFieldsMap,
67+
];
68+
}
69+
70+
/**
71+
* Override the encrypted fields map on the default MongoDB connection.
5372
*
5473
* @param array<string, mixed> $encryptedFieldsMap
5574
*/
5675
private function enableEncryption(array $encryptedFieldsMap): void
5776
{
5877
config([
59-
'database.connections.mongodb.driver_options.autoEncryption' => [
60-
'keyVaultNamespace' => 'encryption.__keyVault',
61-
'kmsProviders' => ['local' => ['key' => base64_encode(random_bytes(96))]],
62-
// Opt out of crypt_shared so the tests run on a community server.
63-
'extraOptions' => ['cryptSharedLibRequired' => false],
64-
'encryptedFieldsMap' => $encryptedFieldsMap,
65-
],
78+
'database.connections.mongodb.driver_options.autoEncryption' => $this->encryptionOptions($encryptedFieldsMap),
6679
]);
6780
}
6881
}

0 commit comments

Comments
 (0)