Skip to content

Commit 8c3d4f2

Browse files
djmbrafaelfranca
authored andcommitted
Allow encryption without compression
Add a `compress` option to ActiveRecord::Encryption::Encryptor, which defaults to `true`. When set to `false`, the encryptor will never compress the data. This is useful for cases where the data is already compressed. This can be used with the `encryptor` option in the model: ```ruby class Record < ApplicationRecord encrypts :field, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false) end ```
1 parent 12343bd commit 8c3d4f2

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

activerecord/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
* Add an option to `ActiveRecord::Encryption::Encryptor` to disable compression
2+
3+
Allow compression to be disabled by setting `compress: false`
4+
5+
```ruby
6+
class User
7+
encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compress: false)
8+
end
9+
```
10+
11+
*Donal McBreen*
12+
113
* Deprecate passing strings to `ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename`.
214

315
A `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object should be passed instead.

activerecord/lib/active_record/encryption/encryptor.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ module Encryption
1212
# It interacts with a KeyProvider for getting the keys, and delegate to
1313
# ActiveRecord::Encryption::Cipher the actual encryption algorithm.
1414
class Encryptor
15+
# === Options
16+
#
17+
# * <tt>:compress</tt> - Boolean indicating whether records should be compressed before encryption.
18+
# Defaults to +true+.
19+
def initialize(compress: true)
20+
@compress = compress
21+
end
22+
1523
# Encrypts +clean_text+ and returns the encrypted result
1624
#
1725
# Internally, it will:
@@ -111,13 +119,17 @@ def serializer
111119

112120
# Under certain threshold, ZIP compression is actually worse that not compressing
113121
def compress_if_worth_it(string)
114-
if string.bytesize > THRESHOLD_TO_JUSTIFY_COMPRESSION
122+
if compress? && string.bytesize > THRESHOLD_TO_JUSTIFY_COMPRESSION
115123
[compress(string), true]
116124
else
117125
[string, false]
118126
end
119127
end
120128

129+
def compress?
130+
@compress
131+
end
132+
121133
def compress(data)
122134
Zlib::Deflate.deflate(data).tap do |compressed_data|
123135
compressed_data.force_encoding(data.encoding)

activerecord/test/cases/encryption/encryptor_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ class ActiveRecord::Encryption::EncryptorTest < ActiveRecord::EncryptionTestCase
4848
assert cipher_text.bytesize < content.bytesize
4949
end
5050

51+
test "content is not compressed, when disabled" do
52+
@encryptor = ActiveRecord::Encryption::Encryptor.new(compress: false)
53+
content = SecureRandom.hex(5.kilobytes)
54+
cipher_text = @encryptor.encrypt(content)
55+
56+
assert_encrypt_text content
57+
assert cipher_text.bytesize > content.bytesize
58+
end
59+
5160
test "trying to encrypt custom classes raises a ForbiddenClass exception" do
5261
assert_raises ActiveRecord::Encryption::Errors::ForbiddenClass do
5362
@encryptor.encrypt(Struct.new(:name).new("Jorge"))

0 commit comments

Comments
 (0)