Skip to content

Commit f21df7a

Browse files
author
Alexander Geist
committed
mongodb persistence encryption
1 parent d97787b commit f21df7a

16 files changed

+168
-222
lines changed

multibanking-persistence/src/main/java/de/adorsys/multibanking/domain/AccountAnalyticsEntity.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import de.adorsys.multibanking.encrypt.Encrypted;
44
import lombok.Data;
55
import org.springframework.data.annotation.Id;
6+
import org.springframework.data.mongodb.core.index.CompoundIndex;
7+
import org.springframework.data.mongodb.core.index.CompoundIndexes;
68
import org.springframework.data.mongodb.core.index.Indexed;
79
import org.springframework.data.mongodb.core.mapping.Document;
810

@@ -14,13 +16,16 @@
1416
*/
1517
@Data
1618
@Document
17-
@Encrypted(fields = {"incomeTotal", "incomeFixed", "incomeNext", "expensesTotal", "expensesFixed", "expensesNext", "balanceCalculated"})
19+
@Encrypted(exclude = {"_id", "accountId", "userId", "analyticsDate"})
20+
@CompoundIndexes({
21+
@CompoundIndex(name = "account_index", def = "{'userId': 1, 'accountId': 1}")
22+
})
1823
public class AccountAnalyticsEntity {
1924

2025
@Id
2126
private String id;
22-
@Indexed
2327
private String accountId;
28+
private String userId;
2429

2530
private LocalDate analyticsDate = LocalDate.now();
2631

multibanking-persistence/src/main/java/de/adorsys/multibanking/domain/BankAccessEntity.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import lombok.Data;
77
import org.springframework.data.annotation.Id;
88
import org.springframework.data.annotation.Transient;
9+
import org.springframework.data.mongodb.core.index.CompoundIndex;
10+
import org.springframework.data.mongodb.core.index.CompoundIndexes;
911
import org.springframework.data.mongodb.core.index.Indexed;
1012
import org.springframework.data.mongodb.core.mapping.Document;
1113

@@ -14,29 +16,18 @@
1416
*/
1517
@Data
1618
@Document
17-
@JsonIgnoreProperties({"getPassportState"})
18-
@Encrypted(fields = {"bankName", "bankLogin", "bankCode", "passportState"})
19+
@JsonIgnoreProperties({"getPassportState", "getPin"})
20+
@Encrypted(exclude = {"_id", "userId"})
1921
public class BankAccessEntity extends BankAccess {
2022

2123
@Id
2224
private String id;
2325
@Indexed
2426
private String userId;
25-
@Transient
2627
private String pin;
2728

2829
public BankAccessEntity id(String id) {
2930
this.id = id;
3031
return this;
3132
}
32-
33-
public BankAccessEntity userId(String userId) {
34-
this.userId = userId;
35-
return this;
36-
}
37-
38-
public BankAccessEntity pin(String pin) {
39-
this.pin = pin;
40-
return this;
41-
}
4233
}

multibanking-persistence/src/main/java/de/adorsys/multibanking/domain/BankAccountEntity.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import domain.BankAccount;
55
import lombok.Data;
66
import org.springframework.data.annotation.Id;
7+
import org.springframework.data.mongodb.core.index.CompoundIndex;
8+
import org.springframework.data.mongodb.core.index.CompoundIndexes;
79
import org.springframework.data.mongodb.core.index.Indexed;
810
import org.springframework.data.mongodb.core.mapping.Document;
911

@@ -12,14 +14,16 @@
1214
*/
1315
@Data
1416
@Document
15-
@Encrypted(fields = {"blzHbciAccount", "numberHbciAccount", "typeHbciAccount", "typeHbciAccount",
16-
"nameHbciAccount", "bicHbciAccount", "ibanHbciAccount", "bankAccountBalance.readyHbciBalance"})
17+
@Encrypted(exclude = {"_id", "bankAccessId", "userId", "syncStatus"})
18+
@CompoundIndexes({
19+
@CompoundIndex(name = "account_index", def = "{'userId': 1, 'bankAccessId': 1}")
20+
})
1721
public class BankAccountEntity extends BankAccount {
1822

1923
@Id
2024
private String id;
21-
@Indexed
2225
private String bankAccessId;
26+
private String userId;
2327

2428
public String getId() {
2529
return id;

multibanking-persistence/src/main/java/de/adorsys/multibanking/domain/BookingCategoryEntity.java

Lines changed: 0 additions & 43 deletions
This file was deleted.

multibanking-persistence/src/main/java/de/adorsys/multibanking/domain/BookingContractEntity.java

Lines changed: 0 additions & 43 deletions
This file was deleted.

multibanking-persistence/src/main/java/de/adorsys/multibanking/domain/BookingEntity.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,19 @@
1515
@Data
1616
@Document
1717
@CompoundIndexes({
18+
@CompoundIndex(name = "booking_index", def = "{'userId': 1, 'accountId': 1}"),
1819
@CompoundIndex(name = "booking_unique_index", def = "{'externalId': 1, 'accountId': 1}", unique = true)
1920
})
20-
@Encrypted(fields = {"amount", "usage", "balance", "otherAccount.blzHbciAccount",
21-
"otherAccount.numberHbciAccount", "otherAccount.nameHbciAccount"})
21+
@Encrypted(exclude = {"_id", "accountId", "externalId", "userId", "valutaDate", "bookingDate"})
2222
public class BookingEntity extends Booking {
2323

2424
@Id
2525
private String id;
26-
@Indexed
2726
private String accountId;
28-
private BookingCategoryEntity category;
27+
private String userId;
2928

3029
public BookingEntity id(String id) {
3130
this.id = id;
3231
return this;
3332
}
34-
35-
public BookingEntity accountId(String accountId) {
36-
this.accountId = accountId;
37-
return this;
38-
}
3933
}

multibanking-persistence/src/main/java/de/adorsys/multibanking/domain/UserEntity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.adorsys.multibanking.domain;
22

3+
import de.adorsys.multibanking.encrypt.Encrypted;
34
import domain.BankApiUser;
45
import lombok.Data;
56
import org.springframework.data.annotation.Id;
@@ -12,6 +13,7 @@
1213
*/
1314
@Data
1415
@Document
16+
@Encrypted(exclude = "_id")
1517
public class UserEntity {
1618

1719
@Id

multibanking-persistence/src/main/java/de/adorsys/multibanking/encrypt/Encrypted.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@
1212
@Retention(RetentionPolicy.RUNTIME)
1313
public @interface Encrypted {
1414

15-
String[] fields();
15+
String[] exclude();
1616
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package de.adorsys.multibanking.encrypt;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.mongodb.BasicDBObject;
6+
import com.mongodb.DBObject;
7+
import com.mongodb.util.JSON;
8+
import org.apache.commons.lang3.StringUtils;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.data.annotation.Id;
11+
import org.springframework.data.mongodb.core.index.Indexed;
12+
import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
13+
import org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent;
14+
import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent;
15+
import org.springframework.stereotype.Component;
16+
17+
import javax.crypto.SecretKey;
18+
import javax.crypto.spec.SecretKeySpec;
19+
import java.lang.reflect.Field;
20+
import java.security.Principal;
21+
import java.util.Arrays;
22+
import java.util.List;
23+
import java.util.Set;
24+
25+
/**
26+
* Created by alexg on 09.05.17.
27+
*/
28+
@Component
29+
public class EncryptionEventListener extends AbstractMongoEventListener<Object> {
30+
31+
@Autowired
32+
Principal principal;
33+
34+
private ObjectMapper objectMapper = new ObjectMapper();
35+
36+
private SecretKey secretKey = new SecretKeySpec("1234567890123456".getBytes(), "AES");
37+
38+
@Override
39+
public void onBeforeSave(BeforeSaveEvent<Object> event) {
40+
Object source = event.getSource();
41+
42+
if (source.getClass().isAnnotationPresent(Encrypted.class)) {
43+
try {
44+
//encrypt dbobject
45+
String json = objectMapper.writeValueAsString(source);
46+
String encrypted = EncryptionUtil.encrypt(json, secretKey);
47+
48+
//cleanup dbobject exclude annotated fields
49+
List<String> excludeFields = Arrays.asList(source.getClass().getAnnotation(Encrypted.class).exclude());
50+
Object[] keySet = event.getDBObject().keySet().toArray();
51+
for (int i = keySet.length - 1; i >= 0; i--) {
52+
if (!excludeFields.contains(keySet[i].toString())) {
53+
event.getDBObject().removeField(keySet[i].toString());
54+
}
55+
}
56+
57+
event.getDBObject().put("encrypted", encrypted);
58+
} catch (JsonProcessingException e) {
59+
throw new RuntimeException(e);
60+
}
61+
}
62+
}
63+
64+
@Override
65+
public void onAfterLoad(AfterLoadEvent event) {
66+
Class source = event.getType();
67+
68+
if (source.isAnnotationPresent(Encrypted.class)) {
69+
if (event.getDBObject().get("encrypted") == null) {
70+
return;
71+
}
72+
73+
String decryptedJson = EncryptionUtil.decrypt(event.getDBObject().get("encrypted").toString(), secretKey);
74+
DBObject decryptedDbObject = (DBObject) JSON.parse(decryptedJson);
75+
List<String> exclude = Arrays.asList(((Encrypted) source.getAnnotation(Encrypted.class)).exclude());
76+
77+
//cleanup loaded dbobject exclude annotated fields
78+
Object[] keySet = event.getDBObject().keySet().toArray();
79+
for (int i = keySet.length - 1; i >= 0; i--) {
80+
if (!exclude.contains(keySet[i].toString())) {
81+
event.getDBObject().removeField(keySet[i].toString());
82+
}
83+
}
84+
85+
//restore encrypted data exclude annotated fields
86+
keySet = decryptedDbObject.keySet().toArray();
87+
for (int i = keySet.length - 1; i >= 0; i--) {
88+
String key = keySet[i].toString();
89+
if (!exclude.contains(key)) {
90+
event.getDBObject().put(key, decryptedDbObject.get(key));
91+
}
92+
}
93+
}
94+
}
95+
96+
97+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
/**
1414
* Created by alexg on 09.05.17.
1515
*/
16-
public class FieldEncryptionUtil {
16+
public class EncryptionUtil {
1717

18-
private static final Logger log = LoggerFactory.getLogger(FieldEncryptionUtil.class);
18+
private static final Logger log = LoggerFactory.getLogger(EncryptionUtil.class);
1919

2020
private static final String AES_CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";
2121

0 commit comments

Comments
 (0)