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:
Mark Paluch
2019-07-01 14:18:04 +02:00
parent da0cb6d766
commit d49b1c33b7
5 changed files with 44 additions and 14 deletions

View File

@@ -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());

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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));

View File

@@ -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