Skip to content

Instantly share code, notes, and snippets.

@IVedmak
Created June 25, 2014 07:45
Show Gist options
  • Save IVedmak/c40883df7802a949c33f to your computer and use it in GitHub Desktop.
Save IVedmak/c40883df7802a949c33f to your computer and use it in GitHub Desktop.
Complex version of AttributeEncryptionListener (support nested objects with attributes + decrypting in memory objects back)
@Component
public class AttributeEncryptionListener extends AbstractMongoEventListener {
/**
* This method called first before object persistence. It encrypts all the attributes of password type
*/
@Override
public void onBeforeConvert(Object source) {
super.onBeforeConvert(source);
passwordsPersistenceCare(source, true);
}
/**
* Once the data encrypted and saved to the disk we would like to use the passwords in our code => so they mast be
* in plane text while we have them in memory
*/
@Override
public void onAfterSave(Object source, DBObject dbo) {
super.onAfterSave(source, dbo);
passwordsPersistenceCare(source, false);
}
private void passwordsPersistenceCare(Object source, boolean shouldEncrypt) {
Field[] declaredFields = source.getClass().getDeclaredFields();
if (declaredFields.length == 0) {
declaredFields = source.getClass().getSuperclass().getDeclaredFields();
}
for (Field field : declaredFields) {
if (Collection.class.isAssignableFrom(field.getType())) {
if (((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0].toString().endsWith(Attribute.class.getName())) {
try {
field.setAccessible(true);
Collection<Attribute> attrs = (Collection<Attribute>) field.get(source);
for (Attribute attr : attrs) {
if (!AttributeUtils.isEmpty(attr) && AttributeType.PASSWORD.equals(attr.getAttributeType())) {
if (shouldEncrypt) {
// in case the same object referenced more than once by different objects it will come here and try to encrypt it again
// encrypted string always ends with "==\r\n", Same logic works for decryption
if(attr.getValue().toString().endsWith("==\r\n")) {
continue;
}
attr.setValue(EncryptionUtils.AESEncrypt(attr.getValue().toString()));
} else {
if(!attr.getValue().toString().endsWith("==\r\n")) {
continue;
}
attr.setValue(EncryptionUtils.AESDecrypt(attr.getValue().toString()));
}
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
} else if (Context.class.isAssignableFrom(field.getType()) || BaseModel.class.isAssignableFrom(field.getType())) {
try {
field.setAccessible(true);
if (field.get(source) != null) {
passwordsPersistenceCare(field.get(source), shouldEncrypt);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else if (Map.class.isAssignableFrom(field.getType())) {
try {
field.setAccessible(true);
if (field.get(source) != null) {
Map tmpMap = (Map) field.get(source);
for (Object key : tmpMap.keySet()) {
if(tmpMap.get(key) != null && BaseModel.class.isAssignableFrom(tmpMap.get(key).getClass())){
passwordsPersistenceCare(tmpMap.get(key), shouldEncrypt);
}
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onAfterConvert(DBObject dbo, Object source) {
super.onAfterConvert(dbo, source);
passwordsPersistenceCare(source, false);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment