Переопределение геттеров и сеттеров в аннотированной модели фреймов
Я работаю над новым программным обеспечением и хотел бы, чтобы значения в базе данных были зашифрованы. Мы используем OrientDB и пытаемся реализовать проект с использованием библиотек tinkerpop. Здесь я немного застрял.
Для одной функции мне нужно вытащить список всех вершин типа и вернуть их. У меня есть аннотированный интерфейс для объекта person, и я добавил методы для шифрования и дешифрования необходимых полей прямо сейчас. Но когда я расшифровываю их, он сохраняет расшифрованные значения обратно в базу данных.
Есть ли способ переопределить методы получения и установки для обработки шифрования / дешифрования в этой точке, или мне нужно отсоединить модели от БД перед выполнением моего дешифрования?
Вот мой код для моего интерфейса:
public interface iPerson {
@Property("firstName")
public void setFirstName(String firstName);
@Property("firstName")
public String getFirstName();
@Property("lastName")
public String getLastName();
@Property("lastName")
public void setLastName(String lastName);
@Property("id")
public String getId();
@Property("id")
public void setId(String id);
@Property("dateOfBirth")
public String getDateOfBirth();
@Property("dateOfBirth")
public void setDateOfBirth(String dateOfBirth);
@JavaHandler
public void encryptFields() throws Exception;
@JavaHandler
public void decryptFields() throws Exception;
public abstract class Impl implements JavaHandlerContext<Vertex>, iPerson {
@Initializer
public void init() {
//This will be called when a new framed element is added to the graph.
setFirstName("");
setLastName("");
setDateOfBirth("01-01-1900");
setPK_Person("-1");
}
/**
* shortcut method to make the class encrypt all of the fields that should be encrypted for data storage
* @throws Exception
*/
public void encryptFields() throws Exception {
setLastName(Crypto.encryptHex(getLastName()));
setFirstName(Crypto.encryptHex(getFirstName()));
if(getDateOfBirth() != null) {
setDateOfBirth(Crypto.encryptHex(getDateOfBirth()));
}
}
/**
* shortcut method to make the class decrypt all of the fields that should be decrypted for data display and return
* @throws Exception
*/
public void decryptFields() throws Exception {
setLastName(Crypto.decryptHex(getLastName()));
setFirstName(Crypto.decryptHex(getFirstName()));
if(getDateOfBirth() != null) {
setDateOfBirth(Crypto.decryptHex(getDateOfBirth()));
}
}
}
}
2 ответа
Спасибо за комментарий, и я должен был вернуться, чтобы ответить на это раньше, но недавно я нашел лучший ответ на мою проблему. Я искал способ сделать так, чтобы шифрование / дешифрование происходило без накладных расходов и без заметного развития разработчиками.
Наилучшим способом решения этой проблемы было на самом деле написать хуки для перед вставкой / обновлением и после чтения, чтобы обрабатывать их только на уровне базы данных. Я смог написать его в java, упаковать jar-файл для него и установить его на нашем экземпляре orientDB, подобрал довольно безупречно и помог нам зашифровать необходимые поля, не замечая снижения скорости.
(Я предполагаю) Данные сохраняются в базе данных, когда свойство Vertex установлено. Если вы хотите хранить зашифрованные значения в базе данных, то вам нужно убедиться, что значение зашифровано при установке свойства.
Если вы хотите переопределить поведение по умолчанию @Property
методы получения / установки (так что вы можете добавить en/decryption), я бы рекомендовал использовать пользовательский обработчик (например, @JavaHandler
).
Например:
IPerson
@JavaHandlerClass(Person.class)
public interface IPerson extends VertexFrame {
@JavaHandler
public void setFirstName(String firstName);
@JavaHandler
public String getFirstName();
}
Человек
abstract class Person implements JavaHandlerContext<Vertex>, IPerson {
@Override
void setFirstName(String firstName) {
asVertex().setProperty('firstName', encrypt(firstName))
}
@Override
String getFirstName() {
return decrypt(asVertex().getProperty('firstName'))
}
static String encrypt(String plain){
return plain.toUpperCase(); // <- your own implementation here
}
static String decrypt(Object encrypted){
return encrypted.toString().toLowerCase(); // <- your own implementation here
}
}
Пример использования (Groovy)
// setup
IPerson nickg = framedGraph.addVertex('PID1', IPerson)
IPerson jspriggs = framedGraph.addVertex('PID2', IPerson)
nickg.setFirstName('nickg')
jspriggs.setFirstName('jspriggs')
// re-retrieve from Frame vertices sometime later...
IPerson nickg2 = framedGraph.getVertex(nickg.asVertex().id, IPerson)
IPerson jspriggs2 = framedGraph.getVertex(jspriggs.asVertex().id, IPerson)
// check encrypted values (these are stored in the DB)...
assert nickg2.asVertex().getProperty('firstName') == 'NICKG'
assert jspriggs2.asVertex().getProperty('firstName') == 'JSPRIGGS'
// check decrypted getters...
assert nickg2.getFirstName() == 'nickg'
assert jspriggs2.getFirstName() == 'jspriggs'
При использовании Groovy
Вы можете перехватывать вызовы этих методов программно (что было бы неплохо, потому что вы могли бы продолжать использовать @Property
Аннотации).
Я не уверен, что есть Tinkerpop
решение для перехвата этих вызовов, кроме написания вашего собственного обработчика (возможно, попробуйте расширить JavaHandlerModule
?).