DATAMONGO-2306 - Polishing.
Add Nullable annotation to nullable method args. Remove IV from JSON Schema as it is not listed in Mongo specs. Tweak wording in docs. Parse encryption-settings-ref for MongoClientOptions. Add support for KeyId's in encrypted JSON schema properties. Original pull request: #766.
This commit is contained in:
@@ -35,6 +35,7 @@ import org.w3c.dom.Element;
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
abstract class MongoParsingUtils {
|
||||
@@ -92,6 +93,7 @@ abstract class MongoParsingUtils {
|
||||
setPropertyValue(clientOptionsDefBuilder, optionsElement, "heartbeat-socket-timeout", "heartbeatSocketTimeout");
|
||||
setPropertyValue(clientOptionsDefBuilder, optionsElement, "ssl", "ssl");
|
||||
setPropertyReference(clientOptionsDefBuilder, optionsElement, "ssl-socket-factory-ref", "sslSocketFactory");
|
||||
setPropertyReference(clientOptionsDefBuilder, optionsElement, "encryption-settings-ref", "autoEncryptionSettings");
|
||||
setPropertyValue(clientOptionsDefBuilder, optionsElement, "server-selection-timeout", "serverSelectionTimeout");
|
||||
|
||||
mongoClientBuilder.addPropertyValue("mongoClientOptions", clientOptionsDefBuilder.getBeanDefinition());
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.Map;
|
||||
|
||||
import org.bson.BsonDocument;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.mongodb.AutoEncryptionSettings;
|
||||
import com.mongodb.MongoClientSettings;
|
||||
@@ -104,7 +105,7 @@ public class MongoEncryptionSettingsFactoryBean implements FactoryBean<AutoEncry
|
||||
.build();
|
||||
}
|
||||
|
||||
private <K, V> Map<K, V> orEmpty(Map<K, V> source) {
|
||||
private <K, V> Map<K, V> orEmpty(@Nullable Map<K, V> source) {
|
||||
return source != null ? source : Collections.emptyMap();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,12 @@ package org.springframework.data.mongodb.core.schema;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ArrayJsonSchemaObject;
|
||||
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.BooleanJsonSchemaObject;
|
||||
@@ -1057,8 +1060,8 @@ public class IdentifiableJsonSchemaProperty<T extends JsonSchemaObject> implemen
|
||||
|
||||
private final JsonSchemaProperty targetProperty;
|
||||
private final @Nullable String algorithm;
|
||||
private final @Nullable char[] keyId;
|
||||
private final @Nullable char[] iv;
|
||||
private final @Nullable String keyId;
|
||||
private final @Nullable List<UUID> keyIds;
|
||||
|
||||
/**
|
||||
* Create new instance of {@link EncryptedJsonSchemaProperty} wrapping the given {@link JsonSchemaProperty target}.
|
||||
@@ -1069,14 +1072,14 @@ public class IdentifiableJsonSchemaProperty<T extends JsonSchemaObject> implemen
|
||||
this(target, null, null, null);
|
||||
}
|
||||
|
||||
private EncryptedJsonSchemaProperty(JsonSchemaProperty target, @Nullable String algorithm, @Nullable char[] keyId,
|
||||
@Nullable char[] iv) {
|
||||
private EncryptedJsonSchemaProperty(JsonSchemaProperty target, @Nullable String algorithm, @Nullable String keyId,
|
||||
@Nullable List<UUID> keyIds) {
|
||||
|
||||
Assert.notNull(target, "Target must not be null!");
|
||||
this.targetProperty = target;
|
||||
this.algorithm = algorithm;
|
||||
this.keyId = keyId;
|
||||
this.iv = iv;
|
||||
this.keyIds = keyIds;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1113,19 +1116,23 @@ public class IdentifiableJsonSchemaProperty<T extends JsonSchemaObject> implemen
|
||||
* @return new instance of {@link EncryptedJsonSchemaProperty}.
|
||||
*/
|
||||
public EncryptedJsonSchemaProperty algorithm(String algorithm) {
|
||||
return new EncryptedJsonSchemaProperty(targetProperty, algorithm, keyId, iv);
|
||||
return new EncryptedJsonSchemaProperty(targetProperty, algorithm, keyId, keyIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public EncryptedJsonSchemaProperty keyId(char[] key) {
|
||||
return new EncryptedJsonSchemaProperty(targetProperty, algorithm, key, iv);
|
||||
public EncryptedJsonSchemaProperty keyId(String keyId) {
|
||||
return new EncryptedJsonSchemaProperty(targetProperty, algorithm, keyId, null);
|
||||
}
|
||||
|
||||
public EncryptedJsonSchemaProperty keyId(String key) {
|
||||
return keyId(key.toCharArray());
|
||||
/**
|
||||
* @param keyId
|
||||
* @return
|
||||
*/
|
||||
public EncryptedJsonSchemaProperty keys(UUID... keyId) {
|
||||
return new EncryptedJsonSchemaProperty(targetProperty, algorithm, null, Arrays.asList(keyId));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1141,7 +1148,9 @@ public class IdentifiableJsonSchemaProperty<T extends JsonSchemaObject> implemen
|
||||
Document enc = new Document();
|
||||
|
||||
if (!ObjectUtils.isEmpty(keyId)) {
|
||||
enc.append("keyId", new String(keyId));
|
||||
enc.append("keyId", keyId);
|
||||
} else if (!ObjectUtils.isEmpty(keyIds)) {
|
||||
enc.append("keyId", keyIds);
|
||||
}
|
||||
|
||||
Type type = extractPropertyType(propertySpecification);
|
||||
|
||||
@@ -19,6 +19,8 @@ import static org.springframework.data.mongodb.core.schema.JsonSchemaProperty.*;
|
||||
import static org.springframework.data.mongodb.test.util.Assertions.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.Test;
|
||||
@@ -87,6 +89,22 @@ public class MongoJsonSchemaUnitTests {
|
||||
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").append("bsonType", "string"))))));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2306
|
||||
public void rendersEncryptedPropertyWithKeyIdCorrectly() {
|
||||
|
||||
UUID uuid = UUID.randomUUID();
|
||||
MongoJsonSchema schema = MongoJsonSchema.builder().properties( //
|
||||
encrypted(string("ssn")) //
|
||||
.aead_aes_256_cbc_hmac_sha_512_deterministic() //
|
||||
.keys(uuid) //
|
||||
).build();
|
||||
|
||||
assertThat(schema.toDocument()).isEqualTo(new Document("$jsonSchema",
|
||||
new Document("type", "object").append("properties",
|
||||
new Document("ssn", new Document("encrypt", new Document("keyId", Collections.singletonList(uuid))
|
||||
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").append("bsonType", "string"))))));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1835
|
||||
public void throwsExceptionOnNullRoot() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> MongoJsonSchema.of((JsonSchemaObject) null));
|
||||
|
||||
@@ -208,7 +208,7 @@ template.find(query(matchingDocumentStructure(schema)), Person.class);
|
||||
[[mongo.jsonSchema.encrypted-fields]]
|
||||
==== Encrypted Fields
|
||||
|
||||
MongoDB 4.2 https://docs.mongodb.com/master/core/security-client-side-encryption/[Field Level Encryption] allows to directly secure certain properties.
|
||||
MongoDB 4.2 https://docs.mongodb.com/master/core/security-client-side-encryption/[Field Level Encryption] allows to directly encrypt individual properties.
|
||||
|
||||
Properties can be wrapped within an encrypted property when setting up the JSON Schema as shown in the example below.
|
||||
|
||||
@@ -225,7 +225,7 @@ MongoJsonSchema schema = MongoJsonSchema.builder()
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Make sure to set the drivers `com.mongodb.AutoEncryptionSettings` to use client side encryption.
|
||||
NOTE: Make sure to set the drivers `com.mongodb.AutoEncryptionSettings` to use client-side encryption. MongoDB does not support encryption for all field types. Specific data types require deterministic encryption to preserve equality comparison functionality.
|
||||
|
||||
[[mongo.jsonSchema.types]]
|
||||
==== JSON Schema Types
|
||||
|
||||
Reference in New Issue
Block a user