Skip to content

Commit

Permalink
Merge pull request #45033 from basecamp/encrypt-default-attributes
Browse files Browse the repository at this point in the history
Support encrypted attributes on columns with default values
  • Loading branch information
eileencodes committed May 9, 2022
2 parents 068c783 + 238432d commit d94b65a
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 3 deletions.
8 changes: 8 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,3 +1,11 @@
* Support encrypted attributes on columns with default db values.

This adds support for encrypted attributes defined on columns with default values.
It will encrypt those values at creation time. Before, it would raise an
error unless `config.active_record.encryption.support_unencrypted_data` was true.

*Jorge Manrubia* and *Dima Fatko*

* Allow overriding `reading_request?` in `DatabaseSelector::Resolver`

The default implementation checks if a request is a `get?` or `head?`,
Expand Down
Expand Up @@ -82,7 +82,7 @@ def global_previous_schemes_for(scheme)
def encrypt_attribute(name, attribute_scheme)
encrypted_attributes << name.to_sym

attribute name do |cast_type|
attribute name, default: -> { columns_hash[name.to_s]&.default } do |cast_type|
ActiveRecord::Encryption::EncryptedAttributeType.new scheme: attribute_scheme, cast_type: cast_type
end

Expand Down
Expand Up @@ -40,7 +40,7 @@ def serialize(value)
end

def changed_in_place?(raw_old_value, new_value)
old_value = raw_old_value.nil? ? nil : deserialize(raw_old_value)
old_value = raw_old_value.nil? ? nil : deserialize_previous_value_to_determine_change(raw_old_value)
old_value != new_value
end

Expand Down Expand Up @@ -135,6 +135,14 @@ def decryption_options
def clean_text_scheme
@clean_text_scheme ||= ActiveRecord::Encryption::Scheme.new(downcase: downcase?, encryptor: ActiveRecord::Encryption::NullEncryptor.new)
end

def deserialize_previous_value_to_determine_change(raw_old_value)
deserialize(raw_old_value)
# We tolerate unencrypted data when determining if a column changed
# to support default DB values in encrypted attributes
rescue ActiveRecord::Encryption::Errors::Decryption
nil
end
end
end
end
5 changes: 5 additions & 0 deletions activerecord/test/cases/encryption/encryptable_record_test.rb
Expand Up @@ -292,6 +292,11 @@ def name
assert_equal Encoding::US_ASCII, book.reload.name.encoding
end

test "support encrypted attributes defined on columns with default values" do
book = EncryptedBook.create!
assert_encrypted_attribute(book, :name, "<untitled>")
end

private
class FailingKeyProvider
def decryption_key(message) end
Expand Down
2 changes: 1 addition & 1 deletion activerecord/test/schema/schema.rb
Expand Up @@ -141,7 +141,7 @@
create_table :encrypted_books, id: :integer, force: true do |t|
t.references :author
t.string :format
t.column :name, :string
t.column :name, :string, default: "<untitled>"
t.column :original_name, :string

t.datetime :created_at
Expand Down

0 comments on commit d94b65a

Please sign in to comment.