ankane / lockbox

Modern encryption for Ruby and Rails
MIT License
1.46k stars 68 forks source link

[Question] - Migrating from `attr_encrypted` with `marshal: true` #173

Closed jomey closed 1 year ago

jomey commented 1 year ago

I am running into an issue migrating from attr_encrypted to Lockbox, when the attributed used marshal: true

Example model:

class ToyModel < ApplicationRecord
  attr_encrypted :hash_attribute, marshal: true, key: :encryption_key

  has_encrypted :hash_attribute, type: :hash, key: :kms_key, migrating: true
end

I verified that the attribute values from attr_encrypted all come back as Hash.

When running the migration via

Lockbox.migrate(ToyModel)

Stacktrace:

can't convert Hash to String
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/encryptor.rb:72:in `check_string'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/encryptor.rb:16:in `encrypt'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/model.rb:555:in `block (3 levels) in has_encrypted'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/model.rb:457:in `block (3 levels) in has_encrypted'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/model.rb:435:in `block (3 levels) in has_encrypted'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:149:in `block (2 levels) in migrate_records'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:148:in `each'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:148:in `block in migrate_records'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:137:in `each'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:137:in `migrate_records'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:95:in `block in perform'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:102:in `block in each_batch'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/activerecord-5.2.8/lib/active_record/relation/batches.rb:136:in `block in find_in_batches'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/activerecord-5.2.8/lib/active_record/relation/batches.rb:238:in `block in in_batches'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/activerecord-5.2.8/lib/active_record/relation/batches.rb:222:in `loop'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/activerecord-5.2.8/lib/active_record/relation/batches.rb:222:in `in_batches'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/activerecord-5.2.8/lib/active_record/relation/batches.rb:135:in `find_in_batches'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:101:in `each_batch'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:94:in `perform'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox/migrator.rb:34:in `migrate'
/data/rbenv/versions/2.7.7/lib/ruby/gems/2.7.0/gems/lockbox-1.1.1/lib/lockbox.rb:40:in `migrate'

Versions (as seen in the trace):

This seems similar to #104 and I made sure to declare the type with the has_encrypted.

ankane commented 1 year ago

Hey @jomey, thanks for the report. Can you try the migrate-fix branch to see if that fixes it?

jomey commented 1 year ago

That does the trick.

Thank you very much for the fast turnaround @ankane!

ankane commented 1 year ago

Great, just pushed 1.1.2.