Review class comments

Co-authored-by: Rafael Mendonça França <rafaelmfranca@gmail.com>
This commit is contained in:
Jorge Manrubia 2021-03-12 17:44:50 +01:00 committed by Jorge Manrubia
parent 3c379393c3
commit d5625c97df
8 changed files with 18 additions and 20 deletions

View File

@ -7,21 +7,21 @@ module ActiveRecord
# It uses AES-256-GCM. It will generate a random IV for non deterministic encryption (default)
# or derive an initialization vector from the encrypted content for deterministic encryption.
#
# See +Cipher::Aes256Gcm+
# See +Cipher::Aes256Gcm+.
class Cipher
DEFAULT_ENCODING = Encoding::UTF_8
# Encrypts the provided text and return an encrypted +Message+
# Encrypts the provided text and return an encrypted +Message+.
def encrypt(clean_text, key:, deterministic: false)
cipher_for(key, deterministic: deterministic).encrypt(clean_text).tap do |message|
message.headers.encoding = clean_text.encoding.name unless clean_text.encoding == DEFAULT_ENCODING
end
end
# Decrypt the provided +Message+
# Decrypt the provided +Message+.
#
# When +key+ is an Array, it will try all the keys raising a
# +ActiveRecord::Encryption::Errors::Decryption+ if none works
# +ActiveRecord::Encryption::Errors::Decryption+ if none works.
def decrypt(encrypted_message, key:)
try_to_decrypt_with_each(encrypted_message, keys: Array(key)).tap do |decrypted_text|
decrypted_text.force_encoding(encrypted_message.headers.encoding || DEFAULT_ENCODING)

View File

@ -6,16 +6,11 @@ require "base64"
module ActiveRecord
module Encryption
class Cipher
# A 256-GCM cipher
#
# This code is extracted from +ActiveSupport::MessageEncryptor+. Not using it directly because we want to control
# the message format and only serialize things once at the +ActiveRecord::Encryption::Message+ level. Also, this
# cipher is prepared to deal with deterministic/non deterministic encryption modes.
# A 256-GCM cipher.
#
# By default it will use random initialization vectors. For deterministic encryption, it will use a SHA-256 hash of
# the text to encrypt and the secret.
#
# See https://3.basecamp.com/2914079/buckets/14968485/todos/2426424308
# See +Encryptor+
class Aes256Gcm
CIPHER_TYPE = "aes-256-gcm"
@ -38,6 +33,10 @@ module ActiveRecord
end
def encrypt(clear_text)
# This code is extracted from +ActiveSupport::MessageEncryptor+. Not using it directly because we want to control
# the message format and only serialize things once at the +ActiveRecord::Encryption::Message+ level. Also, this
# cipher is prepared to deal with deterministic/non deterministic encryption modes.
cipher = OpenSSL::Cipher.new(CIPHER_TYPE)
cipher.encrypt
cipher.key = @secret

View File

@ -19,7 +19,7 @@ module ActiveRecord
end
class_methods do
# Configures a custom encryption context to use when running the provided block of code
# Configures a custom encryption context to use when running the provided block of code.
#
# It supports overriding all the properties defined in +Context+.
#

View File

@ -2,7 +2,7 @@
module ActiveRecord
module Encryption
# A +KeyProvider+ that derives keys from passwords
# A +KeyProvider+ that derives keys from passwords.
class DerivedSecretKeyProvider < KeyProvider
def initialize(passwords)
super(Array(passwords).collect { |password| Key.derive_from(password) })

View File

@ -57,7 +57,7 @@ module ActiveRecord
end
end
# Given a attribute name, it returns the name of the source attribute when it's a preserved one
# Given a attribute name, it returns the name of the source attribute when it's a preserved one.
def source_attribute_from_preserved_attribute(attribute_name)
attribute_name.to_s.sub(ORIGINAL_ATTRIBUTE_PREFIX, "") if /^#{ORIGINAL_ATTRIBUTE_PREFIX}/.match?(attribute_name)
end
@ -133,17 +133,17 @@ module ActiveRecord
end
end
# Returns whether a given attribute is encrypted or not
# Returns whether a given attribute is encrypted or not.
def encrypted_attribute?(attribute_name)
ActiveRecord::Encryption.encryptor.encrypted? ciphertext_for(attribute_name)
end
# Returns the ciphertext for +attribute_name+
# Returns the ciphertext for +attribute_name+.
def ciphertext_for(attribute_name)
read_attribute_before_type_cast(attribute_name)
end
# Encrypts all the encryptable attributes and saves the model
# Encrypts all the encryptable attributes and saves the model.
#
# === Options
#
@ -159,7 +159,7 @@ module ActiveRecord
end
end
# Decrypts all the encryptable attributes and saves the model
# Decrypts all the encryptable attributes and saves the model.
def decrypt
transaction do
decrypt_attributes if has_encrypted_attributes?

View File

@ -2,7 +2,7 @@
module ActiveRecord
module Encryption
# An +ActiveModel::Type+ that encrypts/decrypts strings of text
# An +ActiveModel::Type+ that encrypts/decrypts strings of text.
#
# This is the central piece that connects the encryption system with +encrypts+ declarations in the
# model classes. Whenever you declare an attribute as encrypted, it configures an +EncryptedAttributeType+

View File

@ -2,7 +2,6 @@
module ActiveRecord
module Encryption
# Encrypts encryptable columns when loading fixtures automatically
module EncryptedFixtures
def initialize(fixture, model_class)
@clean_values = {}

View File

@ -2,7 +2,7 @@
module ActiveRecord
module Encryption
# An encryptor that can encrypt data but can't decrypt it
# An encryptor that can encrypt data but can't decrypt it.
class EncryptingOnlyEncryptor < Encryptor
def decrypt(encrypted_text, key_provider: nil, cipher_options: {})
encrypted_text