Skip to content

Commit

Permalink
Introduce compressor option to ActiveRecord::Encryption::Encryptor
Browse files Browse the repository at this point in the history
  • Loading branch information
heka1024 committed May 4, 2024
1 parent d65fec4 commit 17ff722
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
20 changes: 20 additions & 0 deletions activerecord/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
* `ActiveRecord::Encryption::Encryptor` now supports a `:compressor` option to customize the compression algorithm used.

```ruby
module ZstdCompressor
def self.inflate(data)
Zstd.decompress(data)
end

def self.deflate(data)
Zstd.compress(data)
end
end

class User
encrypts :name, encryptor: ActiveRecord::Encryption::Encryptor.new(compressor: ZstdCompressor)
end
```

*heka1024*

* Added support for recursive common table expressions.

```ruby
Expand Down
9 changes: 6 additions & 3 deletions activerecord/lib/active_record/encryption/encryptor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ class Encryptor
#
# * <tt>:compress</tt> - Boolean indicating whether records should be compressed before encryption.
# Defaults to +true+.
def initialize(compress: true)
# * <tt>:compressor</tt> - The compressor to use. Defaults to +Zlib+.
# It must respond to +deflate+ and +inflate+.
def initialize(compress: true, compressor: Zlib)
@compress = compress
@compressor = compressor
end

# Encrypts +clean_text+ and returns the encrypted result
Expand Down Expand Up @@ -135,7 +138,7 @@ def compress?
end

def compress(data)
Zlib::Deflate.deflate(data).tap do |compressed_data|
@compressor.deflate(data).tap do |compressed_data|
compressed_data.force_encoding(data.encoding)
end
end
Expand All @@ -149,7 +152,7 @@ def uncompress_if_needed(data, compressed)
end

def uncompress(data)
Zlib::Inflate.inflate(data).tap do |uncompressed_data|
@compressor.inflate(data).tap do |uncompressed_data|
uncompressed_data.force_encoding(data.encoding)
end
end
Expand Down
16 changes: 16 additions & 0 deletions activerecord/test/cases/encryption/encryptor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,22 @@ class ActiveRecord::Encryption::EncryptorTest < ActiveRecord::EncryptionTestCase
assert_equal Encoding::ISO_8859_1, decrypted_text.encoding
end

test "accept a custom compressor" do
compressor = Module.new do
def self.deflate(data)
"compressed #{data}"
end

def self.inflate(data)
data.sub(/\Acompressed /, "")
end
end
@encryptor = ActiveRecord::Encryption::Encryptor.new(compressor: compressor)
content = SecureRandom.hex(5.kilobytes)

assert_encrypt_text content
end

private
def assert_encrypt_text(clean_text)
encrypted_text = @encryptor.encrypt(clean_text)
Expand Down

0 comments on commit 17ff722

Please sign in to comment.