Browse Source

Use write operation indicator to decide how to encrypt value

issue/4185-light
Christoph Strobl 9 months ago
parent
commit
25354697f5
No known key found for this signature in database
GPG Key ID: E6054036D0C37A4B
  1. 24
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java
  2. 7
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/UpdateMapper.java
  3. 2
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java
  4. 6
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java
  5. 2
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java
  6. 4
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java

24
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MongoConversionContext.java

@ -21,6 +21,7 @@ import org.springframework.data.mapping.model.PropertyValueProvider;
import org.springframework.data.mapping.model.SpELContext; import org.springframework.data.mapping.model.SpELContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.util.TypeInformation; import org.springframework.data.util.TypeInformation;
import org.springframework.lang.CheckReturnValue;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
@ -77,6 +78,17 @@ public class MongoConversionContext implements ValueConversionContext<MongoPersi
return persistentProperty; return persistentProperty;
} }
/**
*
* @param operatorContext
* @return new instance of {@link MongoConversionContext}.
* @since 4.5
*/
@CheckReturnValue
public MongoConversionContext forOperator(@Nullable OperatorContext operatorContext) {
return new MongoConversionContext(accessor, persistentProperty, mongoConverter, spELContext, operatorContext);
}
@Nullable @Nullable
public Object getValue(String propertyPath) { public Object getValue(String propertyPath) {
return accessor.getPropertyValue(getProperty().getOwner().getRequiredPersistentProperty(propertyPath)); return accessor.getPropertyValue(getProperty().getOwner().getRequiredPersistentProperty(propertyPath));
@ -123,6 +135,8 @@ public class MongoConversionContext implements ValueConversionContext<MongoPersi
* @return never {@literal null}. * @return never {@literal null}.
*/ */
String getPath(); String getPath();
boolean isWriteOperation();
} }
public static class WriteOperatorContext implements OperatorContext { public static class WriteOperatorContext implements OperatorContext {
@ -142,6 +156,11 @@ public class MongoConversionContext implements ValueConversionContext<MongoPersi
public String getPath() { public String getPath() {
return path; return path;
} }
@Override
public boolean isWriteOperation() {
return true;
}
} }
public static class QueryOperatorContext implements OperatorContext { public static class QueryOperatorContext implements OperatorContext {
@ -161,5 +180,10 @@ public class MongoConversionContext implements ValueConversionContext<MongoPersi
public String getPath() { public String getPath() {
return path; return path;
} }
@Override
public boolean isWriteOperation() {
return false;
}
} }
} }

7
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/UpdateMapper.java

@ -30,6 +30,7 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order; import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mapping.Association; import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.mongodb.core.convert.MongoConversionContext.WriteOperatorContext;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Query;
@ -163,14 +164,10 @@ public class UpdateMapper extends QueryMapper {
} }
protected Object convertValueWithConversionContext(Field documentField, Object sourceValue, Object value, protected Object convertValueWithConversionContext(Field documentField, Object sourceValue, Object value,
PropertyValueConverter<Object, Object, ValueConversionContext<MongoPersistentProperty>> valueConverter, PropertyValueConverter<Object, Object, ValueConversionContext<MongoPersistentProperty>> valueConverter,
MongoConversionContext conversionContext) { MongoConversionContext conversionContext) {
MongoConversionContext ctx = new MongoConversionContext(NoPropertyPropertyValueProvider.INSTANCE, return super.convertValueWithConversionContext(documentField, sourceValue, value, valueConverter, conversionContext.forOperator(new WriteOperatorContext(documentField.name)));
conversionContext.getProperty(), converter, conversionContext.getSpELContext(), null);
return super.convertValueWithConversionContext(documentField, sourceValue, value, valueConverter, ctx);
} }
private Entry<String, Object> getMappedUpdateModifier(Field field, Object rawValue) { private Entry<String, Object> getMappedUpdateModifier(Field field, Object rawValue) {

2
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/ExplicitEncryptionContext.java

@ -71,7 +71,7 @@ class ExplicitEncryptionContext implements EncryptionContext {
@Override @Override
@Nullable @Nullable
public OperatorContext getConversionOperation() { public OperatorContext getOperatorContext() {
return conversionContext.getOperatorContext(); return conversionContext.getOperatorContext();
} }
} }

6
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/encryption/MongoEncryptionConverter.java

@ -175,12 +175,12 @@ public class MongoEncryptionConverter implements EncryptingConverter<Object, Obj
String algorithm = annotation.algorithm(); String algorithm = annotation.algorithm();
EncryptionKey key = keyResolver.getKey(context); EncryptionKey key = keyResolver.getKey(context);
OperatorContext operatorContext = context.getConversionOperation(); OperatorContext operatorContext = context.getOperatorContext();
EncryptionOptions encryptionOptions = new EncryptionOptions(algorithm, key, EncryptionOptions encryptionOptions = new EncryptionOptions(algorithm, key,
getEQOptions(persistentProperty, operatorContext)); getEQOptions(persistentProperty, operatorContext));
if (operatorContext != null && encryptionOptions.queryableEncryptionOptions() != null if (operatorContext != null && !operatorContext.isWriteOperation() && encryptionOptions.queryableEncryptionOptions() != null
&& !encryptionOptions.queryableEncryptionOptions().getQueryType().equals("equality")) { && !encryptionOptions.queryableEncryptionOptions().getQueryType().equals("equality")) {
return encryptExpression(operatorContext, value, encryptionOptions); return encryptExpression(operatorContext, value, encryptionOptions);
} else { } else {
@ -207,7 +207,7 @@ public class MongoEncryptionConverter implements EncryptingConverter<Object, Obj
queryableEncryptionOptions = queryableEncryptionOptions.contentionFactor(queryableAnnotation.contentionFactor()); queryableEncryptionOptions = queryableEncryptionOptions.contentionFactor(queryableAnnotation.contentionFactor());
} }
boolean isPartOfARangeQuery = operatorContext != null; boolean isPartOfARangeQuery = operatorContext != null && !operatorContext.isWriteOperation();
if (isPartOfARangeQuery) { if (isPartOfARangeQuery) {
queryableEncryptionOptions = queryableEncryptionOptions.queryType(queryableAnnotation.queryType()); queryableEncryptionOptions = queryableEncryptionOptions.queryType(queryableAnnotation.queryType());
} }

2
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/encryption/EncryptionContext.java

@ -136,7 +136,7 @@ public interface EncryptionContext {
* @return can be {@literal null}. * @return can be {@literal null}.
*/ */
@Nullable @Nullable
default OperatorContext getConversionOperation() { default OperatorContext getOperatorContext() {
return null; return null;
} }
} }

4
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/RangeEncryptionTests.java

@ -358,8 +358,8 @@ class RangeEncryptionTests {
if (ctx.getProperty().getMongoField().getName().isPath()) { if (ctx.getProperty().getMongoField().getName().isPath()) {
path = StringUtils.arrayToDelimitedString(ctx.getProperty().getMongoField().getName().parts(), "."); path = StringUtils.arrayToDelimitedString(ctx.getProperty().getMongoField().getName().parts(), ".");
} }
if (ctx.getConversionOperation() != null) { if (ctx.getOperatorContext() != null) {
path = ctx.getConversionOperation().getPath(); path = ctx.getOperatorContext().getPath();
} }
return EncryptionKey.keyId(keyHolder.getEncryptionKey(path)); return EncryptionKey.keyId(keyHolder.getEncryptionKey(path));
})); }));

Loading…
Cancel
Save