|
|
|
@ -17,6 +17,7 @@ package org.springframework.data.mongodb.fle; |
|
|
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.*; |
|
|
|
import static org.assertj.core.api.Assertions.*; |
|
|
|
import static org.springframework.data.mongodb.core.EncryptionAlgorithms.*; |
|
|
|
import static org.springframework.data.mongodb.core.EncryptionAlgorithms.*; |
|
|
|
|
|
|
|
import static org.springframework.data.mongodb.core.query.Criteria.*; |
|
|
|
|
|
|
|
|
|
|
|
import lombok.Data; |
|
|
|
import lombok.Data; |
|
|
|
import org.springframework.data.mongodb.fle.FLETests.Person; |
|
|
|
import org.springframework.data.mongodb.fle.FLETests.Person; |
|
|
|
@ -34,6 +35,7 @@ import java.util.Collections; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map.Entry; |
|
|
|
import java.util.Map.Entry; |
|
|
|
|
|
|
|
import java.util.concurrent.ExecutionException; |
|
|
|
import java.util.function.Supplier; |
|
|
|
import java.util.function.Supplier; |
|
|
|
|
|
|
|
|
|
|
|
import org.bson.BsonArray; |
|
|
|
import org.bson.BsonArray; |
|
|
|
@ -152,8 +154,10 @@ public class ReactiveFLETests { |
|
|
|
return Mono.from(collection.find(new Document()).first()); |
|
|
|
return Mono.from(collection.find(new Document()).first()); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
System.out.println(": " + result.blockFirst().toJson()); |
|
|
|
System.out.println("encrypted: " + result.blockFirst().toJson()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Person id = template.query(Person.class).matching(where("id").is(person.id)).first().block(); |
|
|
|
|
|
|
|
System.out.println("decrypted: " + id); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Data |
|
|
|
@Data |
|
|
|
@ -260,7 +264,14 @@ public class ReactiveFLETests { |
|
|
|
public Object read(Object value, MongoConversionContext context) { |
|
|
|
public Object read(Object value, MongoConversionContext context) { |
|
|
|
|
|
|
|
|
|
|
|
ManualEncryptionContext encryptionContext = buildEncryptionContext(context); |
|
|
|
ManualEncryptionContext encryptionContext = buildEncryptionContext(context); |
|
|
|
Object decrypted = encryptionContext.decrypt(value, clientEncryption); |
|
|
|
Object decrypted = null; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
decrypted = encryptionContext.decrypt(value, clientEncryption); |
|
|
|
|
|
|
|
} catch (ExecutionException e) { |
|
|
|
|
|
|
|
throw new RuntimeException(e); |
|
|
|
|
|
|
|
} catch (InterruptedException e) { |
|
|
|
|
|
|
|
throw new RuntimeException(e); |
|
|
|
|
|
|
|
} |
|
|
|
return decrypted instanceof BsonValue ? BsonUtils.toJavaType((BsonValue) decrypted) : decrypted; |
|
|
|
return decrypted instanceof BsonValue ? BsonUtils.toJavaType((BsonValue) decrypted) : decrypted; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -374,50 +385,55 @@ public class ReactiveFLETests { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Object decrypt(Object value, ClientEncryption clientEncryption) { |
|
|
|
public Object decrypt(Object value, ClientEncryption clientEncryption) throws ExecutionException, InterruptedException { |
|
|
|
|
|
|
|
|
|
|
|
// this was a hack to avoid the 60 sec timeout of the key cache
|
|
|
|
// this was a hack to avoid the 60 sec timeout of the key cache
|
|
|
|
// ClientEncryptionSettings settings = (ClientEncryptionSettings) new DirectFieldAccessor(clientEncryption)
|
|
|
|
// ClientEncryptionSettings settings = (ClientEncryptionSettings) new DirectFieldAccessor(clientEncryption)
|
|
|
|
// .getPropertyValue("options");
|
|
|
|
// .getPropertyValue("options");
|
|
|
|
// clientEncryption = ClientEncryptions.create(settings);
|
|
|
|
// clientEncryption = ClientEncryptions.create(settings);
|
|
|
|
|
|
|
|
|
|
|
|
Object result = value; |
|
|
|
Object r = value; |
|
|
|
if (value instanceof Binary binary) { |
|
|
|
if (value instanceof Binary binary) { |
|
|
|
result = clientEncryption.decrypt(new BsonBinary(binary.getType(), binary.getData())); |
|
|
|
r = clientEncryption.decrypt(new BsonBinary(binary.getType(), binary.getData())); |
|
|
|
} |
|
|
|
} |
|
|
|
if (value instanceof BsonBinary binary) { |
|
|
|
if (value instanceof BsonBinary binary) { |
|
|
|
result = clientEncryption.decrypt(binary); |
|
|
|
r = clientEncryption.decrypt(binary); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// in case the driver has auto decryption (aka .bypassAutoEncryption(true)) active
|
|
|
|
// in case the driver has auto decryption (aka .bypassAutoEncryption(true)) active
|
|
|
|
// https://github.com/mongodb/mongo-java-driver/blob/master/driver-sync/src/examples/tour/ClientSideEncryptionExplicitEncryptionOnlyTour.java
|
|
|
|
// https://github.com/mongodb/mongo-java-driver/blob/master/driver-sync/src/examples/tour/ClientSideEncryptionExplicitEncryptionOnlyTour.java
|
|
|
|
if (value == result) { |
|
|
|
if (value == r) { |
|
|
|
return result; |
|
|
|
return r; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (persistentProperty.isCollectionLike() && result instanceof Iterable<?> iterable) { |
|
|
|
if(r instanceof Mono mono) { |
|
|
|
if (!persistentProperty.isEntity()) { |
|
|
|
return mono.map(result -> { |
|
|
|
Collection<Object> collection = CollectionFactory.createCollection(persistentProperty.getType(), 10); |
|
|
|
if (persistentProperty.isCollectionLike() && result instanceof Iterable<?> iterable) { |
|
|
|
iterable.forEach(it -> collection.add(BsonUtils.toJavaType((BsonValue) it))); |
|
|
|
if (!persistentProperty.isEntity()) { |
|
|
|
return collection; |
|
|
|
Collection<Object> collection = CollectionFactory.createCollection(persistentProperty.getType(), 10); |
|
|
|
} else { |
|
|
|
iterable.forEach(it -> collection.add(BsonUtils.toJavaType((BsonValue) it))); |
|
|
|
Collection<Object> collection = CollectionFactory.createCollection(persistentProperty.getType(), 10); |
|
|
|
return collection; |
|
|
|
iterable.forEach(it -> { |
|
|
|
} else { |
|
|
|
collection.add(context.read(BsonUtils.toJavaType((BsonValue) it), persistentProperty.getActualType())); |
|
|
|
Collection<Object> collection = CollectionFactory.createCollection(persistentProperty.getType(), 10); |
|
|
|
}); |
|
|
|
iterable.forEach(it -> { |
|
|
|
return collection; |
|
|
|
collection.add(context.read(BsonUtils.toJavaType((BsonValue) it), persistentProperty.getActualType())); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
return collection; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!persistentProperty.isEntity() && result instanceof BsonValue bsonValue) { |
|
|
|
if (!persistentProperty.isEntity() && result instanceof BsonValue bsonValue) { |
|
|
|
return BsonUtils.toJavaType(bsonValue); |
|
|
|
return BsonUtils.toJavaType(bsonValue); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (persistentProperty.isEntity() && result instanceof BsonDocument bsonDocument) { |
|
|
|
if (persistentProperty.isEntity() && result instanceof BsonDocument bsonDocument) { |
|
|
|
return context.read(BsonUtils.toJavaType(bsonDocument), persistentProperty.getTypeInformation()); |
|
|
|
return context.read(BsonUtils.toJavaType(bsonDocument), persistentProperty.getTypeInformation()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
}).toFuture().get(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return result; |
|
|
|
return r; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|