Skip to content

Commit

Permalink
Fixed error when decryption_key option is a proc or symbol and return…
Browse files Browse the repository at this point in the history
…s nil - #196

Co-authored-by: Felix Tscheulin <felix.tscheulin@flowd.de>
  • Loading branch information
ankane and Flixt committed Jun 13, 2024
1 parent 1782f4a commit 746f83a
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Added support for Active Record 7.2
- Added support for Mongoid 9
- Fixed error when `decryption_key` option is a proc or symbol and returns `nil`

## 1.3.3 (2024-02-07)

Expand Down
23 changes: 13 additions & 10 deletions lib/lockbox/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,16 @@ def attributes
# essentially a no-op if already loaded
# an exception is thrown if decryption fails
self.class.lockbox_attributes.each do |_, lockbox_attribute|
# don't try to decrypt if no decryption key given
next if lockbox_attribute[:algorithm] == "hybrid" && lockbox_attribute[:decryption_key].nil?

# it is possible that the encrypted attribute is not loaded, eg.
# if the record was fetched partially (`User.select(:id).first`).
# accessing a not loaded attribute raises an `ActiveModel::MissingAttributeError`.
send(lockbox_attribute[:attribute]) if has_attribute?(lockbox_attribute[:encrypted_attribute])
if has_attribute?(lockbox_attribute[:encrypted_attribute])
begin
send(lockbox_attribute[:attribute])
rescue ArgumentError => e
raise e if e.message != "No decryption key set"
end
end
end
super
end
Expand Down Expand Up @@ -492,12 +495,12 @@ def reload
# decrypt first for dirty tracking
# don't raise error if can't decrypt previous
# don't try to decrypt if no decryption key given
unless options[:algorithm] == "hybrid" && options[:decryption_key].nil?
begin
send(name)
rescue Lockbox::DecryptionError
warn "[lockbox] Decrypting previous value failed"
end
begin
send(name)
rescue Lockbox::DecryptionError
warn "[lockbox] Decrypting previous value failed"
rescue ArgumentError => e
raise e if e.message != "No decryption key set"
end

send("lockbox_direct_#{name}=", message)
Expand Down
1 change: 1 addition & 0 deletions test/internal/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
create_table :agents do |t|
t.text :name
t.text :email_ciphertext
t.text :personal_email_ciphertext
end

create_table :people do |t|
Expand Down
30 changes: 30 additions & 0 deletions test/model_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,36 @@ def test_hybrid_no_decryption_key
assert_equal "No decryption key set", error.message
end

def test_hybrid_no_decryption_key_proc
Agent.delete_all

agent = Agent.create!(personal_email: "test@example.org")
original_email_ciphertext = agent.personal_email_ciphertext
assert_equal agent, Agent.last

agent = Agent.last
agent.name = "Test"
agent.save!

agent = Agent.last
assert_equal original_email_ciphertext, agent.personal_email_ciphertext

agent = Agent.last
agent.personal_email = "new@example.org"
agent.save!

agent = Agent.last
assert agent.inspect
assert_nil agent.attributes["personal_email"]
assert agent.attributes["personal_email_ciphertext"]

# TODO change to Lockbox::DecryptionError?
error = assert_raises(ArgumentError) do
agent.personal_email
end
assert_equal "No decryption key set", error.message
end

def test_validations_valid
post = Post.new(title: "Hello World")
assert post.valid?
Expand Down
1 change: 1 addition & 0 deletions test/support/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ def record_key
class Agent < ActiveRecord::Base
key_pair = Lockbox.generate_key_pair
has_encrypted :email, algorithm: "hybrid", encryption_key: key_pair[:encryption_key]
has_encrypted :personal_email, algorithm: "hybrid", encryption_key: key_pair[:encryption_key], decryption_key: -> { nil }
end

class Person < ActiveRecord::Base
Expand Down

0 comments on commit 746f83a

Please sign in to comment.