Browse Source

Fix encryption of `java.time` types.

This commit makes sure to convert java.time types into their BsonValue representation before encrypting.

See #4432
Original pull request: #4439
pull/4447/head
Christoph Strobl 2 years ago committed by Mark Paluch
parent
commit
a8f08bab86
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 25
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java
  2. 36
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/AbstractEncryptionTestBase.java

25
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/BsonUtils.java

@ -15,6 +15,12 @@
*/ */
package org.springframework.data.mongodb.util; package org.springframework.data.mongodb.util;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.temporal.Temporal;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -362,6 +368,25 @@ public class BsonUtils {
return new BsonBinary(binary.getType(), binary.getData()); return new BsonBinary(binary.getType(), binary.getData());
} }
if(source instanceof Temporal) {
if (source instanceof Instant value) {
return new BsonDateTime(value.toEpochMilli());
}
if (source instanceof LocalDateTime value) {
return new BsonDateTime(value.toInstant(ZoneOffset.UTC).toEpochMilli());
}
if(source instanceof LocalDate value) {
return new BsonDateTime(value.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());
}
if(source instanceof LocalTime value) {
return new BsonDateTime(value.atDate(LocalDate.ofEpochDay(0L)).toInstant(ZoneOffset.UTC).toEpochMilli());
}
}
if(source instanceof Date date) {
new BsonDateTime(date.getTime());
}
throw new IllegalArgumentException(String.format("Unable to convert %s (%s) to BsonValue.", source, throw new IllegalArgumentException(String.format("Unable to convert %s (%s) to BsonValue.", source,
source != null ? source.getClass().getName() : "null")); source != null ? source.getClass().getName() : "null"));
} }

36
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/encryption/AbstractEncryptionTestBase.java

@ -21,6 +21,8 @@ import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.query.Criteria.*; import static org.springframework.data.mongodb.core.query.Criteria.*;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.time.LocalDate;
import java.time.Month;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -89,6 +91,21 @@ public abstract class AbstractEncryptionTestBase {
.loadedIsEqualToSource(); .loadedIsEqualToSource();
} }
@Test // GH-4432
void encryptAndDecryptJavaTime() {
Person source = new Person();
source.id = "id-1";
source.today = LocalDate.of(1979, Month.SEPTEMBER, 18);
template.save(source);
verifyThat(source) //
.identifiedBy(Person::getId) //
.wasSavedMatching(it -> assertThat(it.get("today")).isInstanceOf(Binary.class)) //
.loadedIsEqualToSource();
}
@Test // GH-4284 @Test // GH-4284
void encryptAndDecryptComplexValue() { void encryptAndDecryptComplexValue() {
@ -548,6 +565,9 @@ public abstract class AbstractEncryptionTestBase {
@ExplicitEncrypted(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Random) // @ExplicitEncrypted(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Random) //
Map<String, Address> mapOfComplex; Map<String, Address> mapOfComplex;
@ExplicitEncrypted(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Random) //
LocalDate today;
public String getId() { public String getId() {
return this.id; return this.id;
} }
@ -592,6 +612,10 @@ public abstract class AbstractEncryptionTestBase {
return this.mapOfComplex; return this.mapOfComplex;
} }
public LocalDate getToday() {
return today;
}
public void setId(String id) { public void setId(String id) {
this.id = id; this.id = id;
} }
@ -636,6 +660,10 @@ public abstract class AbstractEncryptionTestBase {
this.mapOfComplex = mapOfComplex; this.mapOfComplex = mapOfComplex;
} }
public void setToday(LocalDate today) {
this.today = today;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == this) { if (o == this) {
@ -650,13 +678,14 @@ public abstract class AbstractEncryptionTestBase {
&& Objects.equals(encryptedZip, person.encryptedZip) && Objects.equals(listOfString, person.listOfString) && Objects.equals(encryptedZip, person.encryptedZip) && Objects.equals(listOfString, person.listOfString)
&& Objects.equals(listOfComplex, person.listOfComplex) && Objects.equals(listOfComplex, person.listOfComplex)
&& Objects.equals(viaAltKeyNameField, person.viaAltKeyNameField) && Objects.equals(viaAltKeyNameField, person.viaAltKeyNameField)
&& Objects.equals(mapOfString, person.mapOfString) && Objects.equals(mapOfComplex, person.mapOfComplex); && Objects.equals(mapOfString, person.mapOfString) && Objects.equals(mapOfComplex, person.mapOfComplex)
&& Objects.equals(today, person.today);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, name, ssn, wallet, address, encryptedZip, listOfString, listOfComplex, viaAltKeyNameField, return Objects.hash(id, name, ssn, wallet, address, encryptedZip, listOfString, listOfComplex, viaAltKeyNameField,
mapOfString, mapOfComplex); mapOfString, mapOfComplex, today);
} }
public String toString() { public String toString() {
@ -664,7 +693,8 @@ public abstract class AbstractEncryptionTestBase {
+ ", wallet=" + this.getWallet() + ", address=" + this.getAddress() + ", encryptedZip=" + ", wallet=" + this.getWallet() + ", address=" + this.getAddress() + ", encryptedZip="
+ this.getEncryptedZip() + ", listOfString=" + this.getListOfString() + ", listOfComplex=" + this.getEncryptedZip() + ", listOfString=" + this.getListOfString() + ", listOfComplex="
+ this.getListOfComplex() + ", viaAltKeyNameField=" + this.getViaAltKeyNameField() + ", mapOfString=" + this.getListOfComplex() + ", viaAltKeyNameField=" + this.getViaAltKeyNameField() + ", mapOfString="
+ this.getMapOfString() + ", mapOfComplex=" + this.getMapOfComplex() + ")"; + this.getMapOfString() + ", mapOfComplex=" + this.getMapOfComplex()
+ ", today=" + this.getToday() + ")";
} }
} }

Loading…
Cancel
Save