Переопределение геттеров и сеттеров в аннотированной модели фреймов

Я работаю над новым программным обеспечением и хотел бы, чтобы значения в базе данных были зашифрованы. Мы используем 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?).

Другие вопросы по тегам