Я решил свою проблему с помощью коллеги.
Для шифрования имени и фамилии было достаточно добавить флаг к модели, указывающий, зашифрован ли он или нет.Таким образом, если происходит несколько сохранений, модель знает, что она уже зашифрована, и может пропустить этот шаг:
def before_update(user)
unless user.encrypted
user.first_name = encrypt(user.first_name)
user.last_name = encrypt(user.last_name)
user.encrypted = true
end
end
def after_find(user)
if user.encrypted
user.first_name = decrypt(user.first_name)
user.last_name = decrypt(user.last_name)
user.encrypted = false
end
end
Для адреса электронной почты этого было недостаточно.Devise делал некоторые действительно странные вещи со сбросом кэшированных значений, так что адрес электронной почты все еще получал двойное шифрование.Поэтому вместо того, чтобы подключаться к обратным вызовам для шифрования адреса электронной почты, мы отвергли некоторые методы в пользовательской модели:
def email_before_type_cast
super.present? ? AES.decrypt(super, KEY) : ""
end
def email
return "" unless self[:email]
@email ||= AES.decrypt(self[:email], KEY)
end
def email=(provided_email)
self[:email] = encrypted_email(provided_email)
@email = provided_email
end
def self.find_for_authentication(conditions={})
conditions[:email] = encrypted_email(conditions[:email])
super
end
def self.find_or_initialize_with_errors(required_attributes, attributes, error=:invalid)
attributes[:email] = encrypted_email(attributes[:email]) if attributes[:email]
super
end
def self.encrypted_email decrypted_email
AES.encrypt(decrypted_email, KEY, {:iv => IV})
end
Это дало нам большую часть пути.Тем не менее, мои модели Devise могут быть повторно подтверждены, поэтому, когда я изменил адрес электронной почты пользователя и попытался сохранить, модуль с повторным подтверждением обнаружил нечто странное, запись была сохранена примерно сто раз или около того, а затем я получил переполнение стека и откат.Мы обнаружили, что нам нужно переопределить еще один метод в пользовательской модели, чтобы добиться цели:
def email_was
super.present? ? AES.decrypt(super, KEY) : ""
end
Теперь вся наша личная информация зашифрована!Ура!