Giter VIP home page Giter VIP logo

Comments (7)

ankane avatar ankane commented on May 30, 2024 1

Created a serialize branch if you want to try it out: https://github.com/ankane/lockbox/compare/serialize

from lockbox.

ankane avatar ankane commented on May 30, 2024 1

Just pushed to master.

from lockbox.

ankane avatar ankane commented on May 30, 2024

Hey @tappleby, makes sense to me. It'd be nice to get Lockbox to play nicely with Rails serialized fields (if possible) so no additional options/custom serialization code is needed. I'll look into this when I have a chance.

from lockbox.

tappleby avatar tappleby commented on May 30, 2024

Awesome, will try it out when I get a chance.

from lockbox.

tappleby avatar tappleby commented on May 30, 2024

Did a quick test locally, seemed to work. Did run into 1 issue, although I also have hit this with attr_encrypted.

If you modify the serialized hash directly, the encrypted payload will not be updated:

irb(main):031:0> record.secrets
=> {"foo"=>"bar", "bin"=>"baz"}
irb(main):032:0> record.secrets['new'] = 'secret'
irb(main):033:0> record.changes
=> {"secrets"=>[{"foo"=>"bar", "bin"=>"baz"}, {"foo"=>"bar", "bin"=>"baz", "new"=>"secret"}]}
irb(main):034:0> record.save!
   (1.0ms)  BEGIN
  Record Update (1.4ms)  UPDATE "records" SET "updated_at" = $1 WHERE "records"."id" = $2  [["updated_at", "2019-07-14 19:55:50.233443"], ["id", 1]]
   (2.6ms)  COMMIT
=> true
irb(main):035:0> record.secrets
=> {"foo"=>"bar", "bin"=>"baz", "new"=>"secret"}
irb(main):036:0> record.reload
irb(main):037:0> record.secrets
=> {"foo"=>"bar", "bin"=>"baz"}

The work around is to always assign the property:

irb(main):052:0> record.secrets = record.secrets.merge(new: 'secret')
irb(main):053:0> record.save!
irb(main):054:0> record.reload
irb(main):055:0> record.secrets
=> {"foo"=>"bar", "bin"=>"baz", "new"=>"secret"}

from lockbox.

tappleby avatar tappleby commented on May 30, 2024

Might be able to handle this automatically using a save callback:

before_save do
  self.class.lockbox_attributes.values.each do |lockbox_attribute|
    attribute = lockbox_attribute[:attribute]

    if changed.include?(attribute) && self.class.attribute_types[attribute].is_a?(ActiveRecord::Type::Serialized)
      send("#{attribute}=", send(attribute))
    end
  end
end

This could end up re-encrypting the same payload in some cases. I had tried to only re-assign the attribute when lockbox_attribute[:encrypted_attribute] was not changed but this was not reliable since the encrypted column could be changed for a different value.

from lockbox.

ankane avatar ankane commented on May 30, 2024

Nice catch. Added the after_save callback to the types2 branch (which will supersede the serialize branch). I think the slight performance hit of potentially encrypting twice is worth it for more intuitive behavior.

from lockbox.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.