Skip to content

Commit c963c71

Browse files
authored
Validate RewrapManyDataKeyOptions (#1000)
Ensure that the provider exists if a master key has been provided. JAVA-4717
1 parent eb22d74 commit c963c71

File tree

5 files changed

+45
-16
lines changed

5 files changed

+45
-16
lines changed

driver-core/src/main/com/mongodb/client/model/vault/RewrapManyDataKeyOptions.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.mongodb.client.model.vault;
1818

19+
import com.mongodb.lang.Nullable;
1920
import org.bson.BsonDocument;
2021

2122
/**
@@ -48,6 +49,7 @@ public RewrapManyDataKeyOptions provider(final String provider) {
4849
/**
4950
* @return the provider name
5051
*/
52+
@Nullable
5153
public String getProvider() {
5254
return provider;
5355
}
@@ -110,6 +112,7 @@ public RewrapManyDataKeyOptions masterKey(final BsonDocument masterKey) {
110112
* </p>
111113
* @return the master key document
112114
*/
115+
@Nullable
113116
public BsonDocument getMasterKey() {
114117
return masterKey;
115118
}

driver-core/src/main/com/mongodb/internal/capi/MongoCryptHelper.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.mongodb.MongoClientException;
2424
import com.mongodb.MongoClientSettings;
2525
import com.mongodb.MongoConfigurationException;
26+
import com.mongodb.client.model.vault.RewrapManyDataKeyOptions;
2627
import com.mongodb.crypt.capi.MongoCryptOptions;
2728
import com.mongodb.internal.authentication.AwsCredentialHelper;
2829
import com.mongodb.lang.Nullable;
@@ -60,6 +61,12 @@ public static MongoCryptOptions createMongoCryptOptions(final AutoEncryptionSett
6061
settings.getEncryptedFieldsMap());
6162
}
6263

64+
public static void validateRewrapManyDataKeyOptions(final RewrapManyDataKeyOptions options) {
65+
if (options.getMasterKey() != null && options.getProvider() == null) {
66+
throw new MongoClientException("Missing the provider but supplied a master key in the RewrapManyDataKeyOptions");
67+
}
68+
}
69+
6370
private static MongoCryptOptions createMongoCryptOptions(
6471
final Map<String, Map<String, Object>> kmsProviders,
6572
final boolean bypassQueryAnalysis,

driver-core/src/test/functional/com/mongodb/internal/capi/MongoCryptHelperTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,22 @@
1818

1919
import com.mongodb.AutoEncryptionSettings;
2020
import com.mongodb.ClientEncryptionSettings;
21+
import com.mongodb.MongoClientException;
22+
import com.mongodb.client.model.vault.RewrapManyDataKeyOptions;
2123
import com.mongodb.crypt.capi.MongoCryptOptions;
2224
import org.bson.BsonDocument;
2325
import org.junit.jupiter.api.Test;
2426

2527
import java.util.HashMap;
2628
import java.util.Map;
2729

30+
import static com.mongodb.internal.capi.MongoCryptHelper.validateRewrapManyDataKeyOptions;
2831
import static java.util.Collections.emptyList;
2932
import static java.util.Collections.emptyMap;
3033
import static java.util.Collections.singletonList;
34+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
3135
import static org.junit.jupiter.api.Assertions.assertEquals;
36+
import static org.junit.jupiter.api.Assertions.assertThrows;
3237

3338
public class MongoCryptHelperTest {
3439

@@ -89,6 +94,16 @@ public void createsExpectedMongoCryptOptionsUsingAutoEncryptionSettings() {
8994
assertMongoCryptOptions(mongoCryptOptionsBuilder.searchPaths(emptyList()).build(), mongoCryptOptions);
9095
}
9196

97+
@Test
98+
public void validateRewrapManyDataKeyOptionsTest() {
99+
// Happy path
100+
assertDoesNotThrow(() -> validateRewrapManyDataKeyOptions(new RewrapManyDataKeyOptions()));
101+
assertDoesNotThrow(() -> validateRewrapManyDataKeyOptions(new RewrapManyDataKeyOptions().provider("AWS")));
102+
103+
// Failure
104+
assertThrows(MongoClientException.class, () -> validateRewrapManyDataKeyOptions(new RewrapManyDataKeyOptions().masterKey(new BsonDocument())));
105+
}
106+
92107
void assertMongoCryptOptions(final MongoCryptOptions expected, final MongoCryptOptions actual) {
93108
assertEquals(expected.getAwsKmsProviderOptions(), actual.getAwsKmsProviderOptions(), "AwsKmsProviderOptions not equal");
94109
assertEquals(expected.getEncryptedFieldsMap(), actual.getEncryptedFieldsMap(), "EncryptedFieldsMap not equal");

driver-reactive-streams/src/main/com/mongodb/reactivestreams/client/internal/vault/ClientEncryptionImpl.java

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import java.util.List;
4848
import java.util.stream.Collectors;
4949

50+
import static com.mongodb.internal.capi.MongoCryptHelper.validateRewrapManyDataKeyOptions;
5051
import static java.util.Arrays.asList;
5152
import static java.util.Collections.singletonList;
5253

@@ -155,22 +156,23 @@ public Publisher<RewrapManyDataKeyResult> rewrapManyDataKey(final Bson filter) {
155156

156157
@Override
157158
public Publisher<RewrapManyDataKeyResult> rewrapManyDataKey(final Bson filter, final RewrapManyDataKeyOptions options) {
158-
return crypt.rewrapManyDataKey(filter.toBsonDocument(BsonDocument.class, collection.getCodecRegistry()), options)
159-
.flatMap(results -> {
160-
if (results.isEmpty()) {
161-
return Mono.fromCallable(RewrapManyDataKeyResult::new);
162-
}
163-
List<UpdateOneModel<BsonDocument>> updateModels = results.getArray("v", new BsonArray()).stream().map(v -> {
164-
BsonDocument updateDocument = v.asDocument();
165-
return new UpdateOneModel<BsonDocument>(Filters.eq(updateDocument.get("_id")),
166-
Updates.combine(
167-
Updates.set("masterKey", updateDocument.get("masterKey")),
168-
Updates.set("keyMaterial", updateDocument.get("keyMaterial")),
169-
Updates.currentDate("updateDate"))
170-
);
171-
}).collect(Collectors.toList());
172-
return Mono.from(collection.bulkWrite(updateModels)).map(RewrapManyDataKeyResult::new);
173-
});
159+
return Mono.fromRunnable(() -> validateRewrapManyDataKeyOptions(options)).then(
160+
crypt.rewrapManyDataKey(filter.toBsonDocument(BsonDocument.class, collection.getCodecRegistry()), options)
161+
.flatMap(results -> {
162+
if (results.isEmpty()) {
163+
return Mono.fromCallable(RewrapManyDataKeyResult::new);
164+
}
165+
List<UpdateOneModel<BsonDocument>> updateModels = results.getArray("v", new BsonArray()).stream().map(v -> {
166+
BsonDocument updateDocument = v.asDocument();
167+
return new UpdateOneModel<BsonDocument>(Filters.eq(updateDocument.get("_id")),
168+
Updates.combine(
169+
Updates.set("masterKey", updateDocument.get("masterKey")),
170+
Updates.set("keyMaterial", updateDocument.get("keyMaterial")),
171+
Updates.currentDate("updateDate"))
172+
);
173+
}).collect(Collectors.toList());
174+
return Mono.from(collection.bulkWrite(updateModels)).map(RewrapManyDataKeyResult::new);
175+
}));
174176
}
175177

176178
@Override

driver-sync/src/main/com/mongodb/client/internal/ClientEncryptionImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import java.util.List;
4545
import java.util.stream.Collectors;
4646

47+
import static com.mongodb.internal.capi.MongoCryptHelper.validateRewrapManyDataKeyOptions;
4748
import static java.util.Arrays.asList;
4849
import static java.util.Collections.singletonList;
4950

@@ -146,6 +147,7 @@ public RewrapManyDataKeyResult rewrapManyDataKey(final Bson filter) {
146147

147148
@Override
148149
public RewrapManyDataKeyResult rewrapManyDataKey(final Bson filter, final RewrapManyDataKeyOptions options) {
150+
validateRewrapManyDataKeyOptions(options);
149151
BsonDocument results = crypt.rewrapManyDataKey(filter.toBsonDocument(BsonDocument.class, collection.getCodecRegistry()), options);
150152
if (results.isEmpty()) {
151153
return new RewrapManyDataKeyResult();

0 commit comments

Comments
 (0)