mirror of https://github.com/rails/rails
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 ```
This commit is contained in:
parent
12343bdc53
commit
8c3d4f2b24
|
@ -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.
|
||||
|
|
|
@ -12,6 +12,14 @@ module ActiveRecord
|
|||
# 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:
|
||||
|
@ -111,13 +119,17 @@ module ActiveRecord
|
|||
|
||||
# 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)
|
||||
|
|
|
@ -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"))
|
||||
|
|
Loading…
Reference in New Issue