Skip to content

Commit

Permalink
Merge branch 'data-type-agnostic-encryptor'
Browse files Browse the repository at this point in the history
  • Loading branch information
eileencodes committed Jan 5, 2024
2 parents 1866ea9 + d0f3b00 commit 4470ad7
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 5 deletions.
10 changes: 10 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
* Make `ActiveRecord::Encryption::Encryptor` agnostic of the serialization format used for encrypted data.

Previously, the encryptor instance only allowed an encrypted value serialized as a `String` to be passed to the message serializer.

Now, the encryptor lets the configured `message_serializer` decide which types of serialized encrypted values are supported. A custom serialiser is therefore allowed to serialize `ActiveRecord::Encryption::Message` objects using a type other than `String`.

The default `ActiveRecord::Encryption::MessageSerializer` already ensures that only `String` objects are passed for deserialization.

*Maxime Réty*

* Fix `encrypted_attribute?` to take into account context properties passed to `encrypts`.

*Maxime Réty*
Expand Down
1 change: 0 additions & 1 deletion activerecord/lib/active_record/encryption/encryptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ def serialize_message(message)
end

def deserialize_message(message)
raise Errors::Encoding unless message.is_a?(String)
serializer.load message
rescue ArgumentError, TypeError, Errors::ForbiddenClass
raise Errors::Encoding
Expand Down
8 changes: 7 additions & 1 deletion activerecord/test/cases/encryption/encryptor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ class ActiveRecord::Encryption::EncryptorTest < ActiveRecord::EncryptionTestCase
assert_encrypt_text("my secret text")
end

test "decrypt and invalid string will raise a Decryption error" do
test "trying to decrypt something else than a string will raise a Decryption error" do
assert_raises(ActiveRecord::Encryption::Errors::Decryption) do
@encryptor.decrypt(:it_can_only_decrypt_strings)
end
end

test "decrypt an invalid string will raise a Decryption error" do
assert_raises(ActiveRecord::Encryption::Errors::Decryption) do
@encryptor.decrypt("some test that does not make sense")
end
Expand Down
10 changes: 8 additions & 2 deletions activerecord/test/cases/encryption/message_serializer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ class ActiveRecord::Encryption::MessageSerializerTest < ActiveRecord::Encryption
assert_nothing_raised { @serializer.load(class_loading_payload) }
end

test "detects random JSON data and raises an invalid dencryption error" do
test "detects random JSON data and raises a decryption error" do
assert_raises ActiveRecord::Encryption::Errors::Decryption do
@serializer.load JSON.dump("hey there")
end
end

test "detects random JSON hashes and raises an invalid decryption error" do
test "detects random JSON hashes and raises a decryption error" do
assert_raises ActiveRecord::Encryption::Errors::Decryption do
@serializer.load JSON.dump({ some: "other data" })
end
Expand All @@ -47,6 +47,12 @@ class ActiveRecord::Encryption::MessageSerializerTest < ActiveRecord::Encryption
end
end

test "raises a TypeError when trying to deserialize other data types" do
assert_raises TypeError do
@serializer.load(:it_can_only_deserialize_strings)
end
end

test "raises ForbiddenClass when trying to serialize other data types" do
assert_raises ActiveRecord::Encryption::Errors::ForbiddenClass do
@serializer.dump("it can only serialize messages!")
Expand Down
2 changes: 1 addition & 1 deletion guides/source/active_record_encryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ To encrypt Action Text fixtures, you should place them in `fixtures/action_text/

### Supported Types

`active_record.encryption` will serialize values using the underlying type before encrypting them, but *they must be serializable as strings*. Structured types like `serialized` are supported out of the box.
`active_record.encryption` will serialize values using the underlying type before encrypting them, but, unless using a custom `message_serializer`, *they must be serializable as strings*. Structured types like `serialized` are supported out of the box.

If you need to support a custom type, the recommended way is using a [serialized attribute](https://api.rubyonrails.org/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html). The declaration of the serialized attribute should go **before** the encryption declaration:

Expand Down

0 comments on commit 4470ad7

Please sign in to comment.