Closed RudskikhIvan closed 1 year ago
Hey hey! Are you using Rails encryption? I know https://github.com/ankane/lockbox works fine with the current implementation
We use lockbox. But looks like it doesn't work with store_model.
Example:
class AccessToken < Authorization
class Config
include StoreModel::Model
extend Lockbox::Model
attribute :access_token_ciphertext, :string
has_encrypted :access_token
end
attribute :config, Config.to_type
end
It fails with:
NameError:
undefined method `access_token_ciphertext_changed?' for class `AccessToken::Config'
alias_method "#{name}_changed?", "#{encrypted_attribute}_changed?"
^^^^^^^^^^^^
# /Users/ivanrudskikh/.rvm/gems/ruby-3.1.3/gems/lockbox-1.2.0/lib/lockbox/model.rb:402:in `alias_method'
# /Users/ivanrudskikh/.rvm/gems/ruby-3.1.3/gems/lockbox-1.2.0/lib/lockbox/model.rb:402:in `block (2 levels) in has_encrypted'
# /Users/ivanrudskikh/.rvm/gems/ruby-3.1.3/gems/lockbox-1.2.0/lib/lockbox/model.rb:60:in `class_eval'
# /Users/ivanrudskikh/.rvm/gems/ruby-3.1.3/gems/lockbox-1.2.0/lib/lockbox/model.rb:60:in `block in has_encrypted'
# /Users/ivanrudskikh/.rvm/gems/ruby-3.1.3/gems/lockbox-1.2.0/lib/lockbox/model.rb:39:in `each'
# /Users/ivanrudskikh/.rvm/gems/ruby-3.1.3/gems/lockbox-1.2.0/lib/lockbox/model.rb:39:in `has_encrypted'
Anyway, current implementation doesn't use ActiveModel::Types in full.
Looks like there's something broken in the lockbox: there's a similar issue with the similar gem https://github.com/ankane/lockbox/issues/174. Author suggests to do something like:
class AccessToken < Authorization
class Config
include StoreModel::Model
extend Lockbox::Model
attribute :access_token, :string
has_encrypted :access_token
end
attribute :config, Config.to_type
end
i.e. attribute and has_encrypted get the same attribute name (but the column is called access_token_ciphertext in the table). Could you please try it out?
The same exception:
NameError:
undefined method `access_token_ciphertext_changed?' for class `AccessToken::Config'
alias_method "#{name}_changed?", "#{encrypted_attribute}_changed?"
Got it 😞Let's give it a shot, I'll make a major release at the end of the week, thank you for handling that!
Hi, I think this change broke the handling of defaults, I submitted a reproducible example over at #147
We use lockbox. But looks like it doesn't work with store_model.
store_model has no active_model/dirty included. did you try to include it or define missing methods explicitly?
class Config
include StoreModel::Model
include ActiveModel::Dirty
# ...
end
I'm using Lockbox's documentation for strings encryption, paired with a ActiveModel::Type::Value
for serialize/deserialize. It works pretty well. Something like this:
class Lockboxify < ActiveModel::Type::Value
def serialize(value)
return unless value.present?
lockbox = Lockbox.new(key: Lockbox.master_key, encode: true)
lockbox.encrypt(value)
end
def deserialize(value)
return unless value.present?
lockbox = Lockbox.new(key: Lockbox.master_key, encode: true)
lockbox.decrypt(value)
end
end
and then use like
class Something < Anything
class Store
include StoreModel::Model
attribute :token, Lockboxify.new
end
attribute :store, Store.to_type, default: -> { {} }
end
Hello,
In our project we need to encrypt some data stored through store_model. But it doesn't work out from the box, because store_model doesn't call serialize method for attributes. This PR is possible solution. There is breaking change, because now datetime and time uses serialization from types and stores without timezone. What do you think?