Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encryption not working with store attributes #138

Open
joesiewert opened this issue Nov 8, 2023 · 1 comment
Open

Encryption not working with store attributes #138

joesiewert opened this issue Nov 8, 2023 · 1 comment

Comments

@joesiewert
Copy link

When trying to use store_accessor on models, the following is happening during encryption. This issue came up while attempting to upgrade to Rails 6.1. It is currently working on Rails 6.0.6.1 for us. 馃

Expected behavior

A store attribute can be encrypted. Stored values can be read and written with accessors.

Actual behavior

When attempting to use a store accessor, an error is raised:

Failures:

1) Vault::Rails with default options encrypts store attributes
Failure/Error: person = Person.create!(eye_color: "blue", hair_color: "brown")

NoMethodError:
  undefined method `accessor' for #<ActiveModel::Type::Value:0x0000563c30ebdd50>
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/store.rb:217:in `store_accessor_for'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/store.rb:212:in `write_store_attribute'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/store.rb:136:in `block (3 levels) in store_accessor'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activemodel-6.1.7.6/lib/active_model/attribute_assignment.rb:49:in `public_send'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activemodel-6.1.7.6/lib/active_model/attribute_assignment.rb:49:in `_assign_attribute'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/attribute_assignment.rb:21:in `block in _assign_attributes'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/attribute_assignment.rb:13:in `each'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/attribute_assignment.rb:13:in `_assign_attributes'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activemodel-6.1.7.6/lib/active_model/attribute_assignment.rb:34:in `assign_attributes'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/core.rb:525:in `initialize'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/inheritance.rb:72:in `new'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/inheritance.rb:72:in `new'
# /home/cs/cache/bundler/ruby/2.7.0/gems/activerecord-6.1.7.6/lib/active_record/persistence.rb:54:in `create!'
# ./spec/integration/rails_spec.rb:19:in `block (3 levels) in <top (required)>'

Reproduction

Failing test branch at https://github.com/codeship/vault-rails/tree/rails-6.1

Possibly also related to rails/rails#43012

In looking at the store_accessor_for method, with Vault enabled, it returns:

https://github.com/rails/rails/blob/v6.1.7.6/activerecord/lib/active_record/store.rb#L216-L218

pry(#<Person>)> type_for_attribute(store_attribute).accessor
NoMethodError: undefined method `accessor' for #<ActiveModel::Type::Value:0x0000561514633c40>
from (pry):1:in `store_accessor_for'

System configuration

Rails version: 6.1.7.6
Ruby version: 2.7.8
vault-rails gem version: 0.9.0

@joesiewert
Copy link
Author

Looking more at the store_accessor_for and type_for_attribute methods:

https://github.com/rails/rails/blob/v6.1.7.7/activerecord/lib/active_record/store.rb#L216-L218

def store_accessor_for(store_attribute)
  type_for_attribute(store_attribute).accessor
end

In our currently working code on Rails 6.0.6.1 I get these back:

pp type_for_attribute(store_attribute)

#<ActiveModel::Type::Value:0x000055792c0d5ac0
 @limit=nil,
 @precision=nil,
 @scale=nil>
=> #<ActiveModel::Type::Value:0x000055792c0d5ac0 @limit=nil, @precision=nil, @scale=nil>

pp type_for_attribute(store_attribute).accessor

ActiveRecord::Store::IndifferentHashAccessor
=> ActiveRecord::Store::IndifferentHashAccessor

Then in Rails 6.1 (6.1.7.7) the same call:

pp type_for_attribute(store_attribute).accessor

NoMethodError: undefined method `accessor' for #<ActiveModel::Type::Value:0x000055792c0d5ac0>
from (pry):3:in `store_accessor_for'

I can force the store_accessor_for method to return ActiveRecord::Store::IndifferentHashAccessor and my example spec here will pass. It's unclear to me what changed between Rails 6.0 and 6.1 that is triggering this change. I've poured over changelogs and issue reports on the Rails repo but have not been able to find anything (or more likely, I've looked at the right issue but lack the full understanding to tie it back to this problem 馃槅).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant