Skip to content

Commit

Permalink
Merge pull request rails#50876 from djmb/ar-encryption-disable-compre…
Browse files Browse the repository at this point in the history
…ssion

Allow encryption without compression
  • Loading branch information
rafaelfranca authored Jan 29, 2024
2 parents 12343bd + 8c3d4f2 commit 00ca9f5
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
12 changes: 12 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
* Add an option to `ActiveRecord::Encryption::Encryptor` to disable compression

Allow compression to be disabled by setting `compress: false`

```ruby
class User
encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
end
```

*Donal McBreen*

* Deprecate passing strings to `ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename`.

A `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object should be passed instead.
Expand Down
14 changes: 13 additions & 1 deletion activerecord/lib/active_record/encryption/encryptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ module Encryption
# It interacts with a KeyProvider for getting the keys, and delegate to
# ActiveRecord::Encryption::Cipher the actual encryption algorithm.
class Encryptor
# === Options
#
# * <tt>:compress</tt> - Boolean indicating whether records should be compressed before encryption.
# Defaults to +true+.
def initialize(compress: true)
@compress = compress
end

# Encrypts +clean_text+ and returns the encrypted result
#
# Internally, it will:
Expand Down Expand Up @@ -111,13 +119,17 @@ def serializer

# Under certain threshold, ZIP compression is actually worse that not compressing
def compress_if_worth_it(string)
if string.bytesize > THRESHOLD_TO_JUSTIFY_COMPRESSION
if compress? && string.bytesize > THRESHOLD_TO_JUSTIFY_COMPRESSION
[compress(string), true]
else
[string, false]
end
end

def compress?
@compress
end

def compress(data)
Zlib::Deflate.deflate(data).tap do |compressed_data|
compressed_data.force_encoding(data.encoding)
Expand Down
9 changes: 9 additions & 0 deletions activerecord/test/cases/encryption/encryptor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ class ActiveRecord::Encryption::EncryptorTest < ActiveRecord::EncryptionTestCase
assert cipher_text.bytesize < content.bytesize
end

test "content is not compressed, when disabled" do
@encryptor = ActiveRecord::Encryption::Encryptor.new(compress: false)
content = SecureRandom.hex(5.kilobytes)
cipher_text = @encryptor.encrypt(content)

assert_encrypt_text content
assert cipher_text.bytesize > content.bytesize
end

test "trying to encrypt custom classes raises a ForbiddenClass exception" do
assert_raises ActiveRecord::Encryption::Errors::ForbiddenClass do
@encryptor.encrypt(Struct.new(:name).new("Jorge"))
Expand Down

0 comments on commit 00ca9f5

Please sign in to comment.