attr-encrypted / attr_encrypted

Generates attr_accessors that encrypt and decrypt attributes
MIT License
2.01k stars 427 forks source link

In place editing does not update encrypted value #175

Open mmustala opened 8 years ago

mmustala commented 8 years ago

Hi,

This is mainly just a documentation issue. When a value is edited in place (with downcase! for example) it doesn't update the encrypted value.

user = User.new(login: 'CAPITALS')
user.encrypted_login # "Lhsnj2q34bj/IgIkZGvv9w==\n"
user.login.downcase!
user.encrypted_login # "Lhsnj2q34bj/IgIkZGvv9w==\n"

This can be easily avoided by using

user.login = user.login.downcase
mmustala commented 8 years ago

This issue seems to come up also with ActiveRecord's store functionality that allows to use a serialized Hash as a simple key value store.

class MyModel < ActiveRecord::Base
  store :settings, accessories: [:option1, :option2]
  attr_encrypted :settings, key: ENCRYPTION_KEY, marshal: true
  validates :option1, presence: true
end

When I update option1 or option2 the encrypted_settings is not updating. Additionally to get this store functionality to work I need to have also the "settings" column in the database, but that is just because Rails code is using it for getting an accessor for the "settings" column. It seems to be totally unnecessary because the values are set into the settings hash on the object, not directly into the database.

To get the store fully functional I need to add a before_save callback to do settings = settings so that also the encrypted_settings gets updated.

mmustala commented 8 years ago

Added a pull request to rails to remove the need for this dummy column in the database. https://github.com/rails/rails/pull/22458

mltsy commented 6 years ago

Why would you be using store if attr_encrypted ..., marshal: true marshals the data for you? Could you just remove that and use store_accessor to solve this problem?

mltsy commented 6 years ago

You are right though - there are multiple issues with the same root cause - in-place editing eschews the encryption accessors: