Skip to content

Commit a8f08ba

Browse files
christophstroblmp911de
authored andcommitted
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
1 parent 19211a0 commit a8f08ba

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
*/
1616
package org.springframework.data.mongodb.util;
1717

18+
import java.time.Instant;
19+
import java.time.LocalDate;
20+
import java.time.LocalDateTime;
21+
import java.time.LocalTime;
22+
import java.time.ZoneOffset;
23+
import java.time.temporal.Temporal;
1824
import java.util.Arrays;
1925
import java.util.Collection;
2026
import java.util.Collections;
@@ -362,6 +368,25 @@ public static BsonValue simpleToBsonValue(Object source) {
362368
return new BsonBinary(binary.getType(), binary.getData());
363369
}
364370

371+
if(source instanceof Temporal) {
372+
if (source instanceof Instant value) {
373+
return new BsonDateTime(value.toEpochMilli());
374+
}
375+
if (source instanceof LocalDateTime value) {
376+
return new BsonDateTime(value.toInstant(ZoneOffset.UTC).toEpochMilli());
377+
}
378+
if(source instanceof LocalDate value) {
379+
return new BsonDateTime(value.atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli());
380+
}
381+
if(source instanceof LocalTime value) {
382+
return new BsonDateTime(value.atDate(LocalDate.ofEpochDay(0L)).toInstant(ZoneOffset.UTC).toEpochMilli());
383+
}
384+
}
385+
386+
if(source instanceof Date date) {
387+
new BsonDateTime(date.getTime());
388+
}
389+
365390
throw new IllegalArgumentException(String.format("Unable to convert %s (%s) to BsonValue.", source,
366391
source != null ? source.getClass().getName() : "null"));
367392
}

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

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import static org.springframework.data.mongodb.core.query.Criteria.*;
2222

2323
import java.security.SecureRandom;
24+
import java.time.LocalDate;
25+
import java.time.Month;
2426
import java.util.Arrays;
2527
import java.util.Collections;
2628
import java.util.HashMap;
@@ -89,6 +91,21 @@ void encryptAndDecryptSimpleValue() {
8991
.loadedIsEqualToSource();
9092
}
9193

94+
@Test // GH-4432
95+
void encryptAndDecryptJavaTime() {
96+
97+
Person source = new Person();
98+
source.id = "id-1";
99+
source.today = LocalDate.of(1979, Month.SEPTEMBER, 18);
100+
101+
template.save(source);
102+
103+
verifyThat(source) //
104+
.identifiedBy(Person::getId) //
105+
.wasSavedMatching(it -> assertThat(it.get("today")).isInstanceOf(Binary.class)) //
106+
.loadedIsEqualToSource();
107+
}
108+
92109
@Test // GH-4284
93110
void encryptAndDecryptComplexValue() {
94111

@@ -548,6 +565,9 @@ static class Person {
548565
@ExplicitEncrypted(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Random) //
549566
Map<String, Address> mapOfComplex;
550567

568+
@ExplicitEncrypted(algorithm = AEAD_AES_256_CBC_HMAC_SHA_512_Random) //
569+
LocalDate today;
570+
551571
public String getId() {
552572
return this.id;
553573
}
@@ -592,6 +612,10 @@ public Map<String, Address> getMapOfComplex() {
592612
return this.mapOfComplex;
593613
}
594614

615+
public LocalDate getToday() {
616+
return today;
617+
}
618+
595619
public void setId(String id) {
596620
this.id = id;
597621
}
@@ -636,6 +660,10 @@ public void setMapOfComplex(Map<String, Address> mapOfComplex) {
636660
this.mapOfComplex = mapOfComplex;
637661
}
638662

663+
public void setToday(LocalDate today) {
664+
this.today = today;
665+
}
666+
639667
@Override
640668
public boolean equals(Object o) {
641669
if (o == this) {
@@ -650,21 +678,23 @@ public boolean equals(Object o) {
650678
&& Objects.equals(encryptedZip, person.encryptedZip) && Objects.equals(listOfString, person.listOfString)
651679
&& Objects.equals(listOfComplex, person.listOfComplex)
652680
&& Objects.equals(viaAltKeyNameField, person.viaAltKeyNameField)
653-
&& Objects.equals(mapOfString, person.mapOfString) && Objects.equals(mapOfComplex, person.mapOfComplex);
681+
&& Objects.equals(mapOfString, person.mapOfString) && Objects.equals(mapOfComplex, person.mapOfComplex)
682+
&& Objects.equals(today, person.today);
654683
}
655684

656685
@Override
657686
public int hashCode() {
658687
return Objects.hash(id, name, ssn, wallet, address, encryptedZip, listOfString, listOfComplex, viaAltKeyNameField,
659-
mapOfString, mapOfComplex);
688+
mapOfString, mapOfComplex, today);
660689
}
661690

662691
public String toString() {
663692
return "EncryptionTests.Person(id=" + this.getId() + ", name=" + this.getName() + ", ssn=" + this.getSsn()
664693
+ ", wallet=" + this.getWallet() + ", address=" + this.getAddress() + ", encryptedZip="
665694
+ this.getEncryptedZip() + ", listOfString=" + this.getListOfString() + ", listOfComplex="
666695
+ this.getListOfComplex() + ", viaAltKeyNameField=" + this.getViaAltKeyNameField() + ", mapOfString="
667-
+ this.getMapOfString() + ", mapOfComplex=" + this.getMapOfComplex() + ")";
696+
+ this.getMapOfString() + ", mapOfComplex=" + this.getMapOfComplex()
697+
+ ", today=" + this.getToday() + ")";
668698
}
669699
}
670700

0 commit comments

Comments
 (0)