модуль ActiveRecord::Encryption::EncryptableRecord
Это модуль, смешанный с моделями Active Record, чтобы сделать их шифруемыми. Он добавляет объявление атрибута encrypts, а также API для шифрования и дешифрования записей.
Константы
- ORIGINAL_ATTRIBUTE_PREFIX
Открытые методы экземпляров
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 132
def add_length_validation_for_encrypted_columns
encrypted_attributes&.each do |attribute_name|
validate_column_size attribute_name
end
end # File activerecord/lib/active_record/encryption/encryptable_record.rb, line 151
def ciphertext_for(attribute_name)
if encrypted_attribute?(attribute_name)
read_attribute_before_type_cast(attribute_name)
else
read_attribute_for_database(attribute_name)
end
end Возвращает шифрованный текст для attribute_name.
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 165 def decrypt decrypt_attributes if has_encrypted_attributes? end
Дешифрует все шифруемые атрибуты и сохраняет изменения.
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 58
def deterministic_encrypted_attributes
@deterministic_encrypted_attributes ||= encrypted_attributes&.find_all do |attribute_name|
type_for_attribute(attribute_name).deterministic?
end
end Возвращает список детерминированных шифруемых атрибутов в классе модели.
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 160 def encrypt encrypt_attributes if has_encrypted_attributes? end
Шифрует все шифруемые атрибуты и сохраняет изменения.
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 84
def encrypt_attribute(name, key_provider: nil, key: nil, deterministic: false, support_unencrypted_data: nil, downcase: false, ignore_case: false, previous: [], **context_properties)
encrypted_attributes << name.to_sym
attribute name do |cast_type|
scheme = scheme_for key_provider: key_provider, key: key, deterministic: deterministic, support_unencrypted_data: support_unencrypted_data, \
downcase: downcase, ignore_case: ignore_case, previous: previous, **context_properties
ActiveRecord::Encryption::EncryptedAttributeType.new(scheme: scheme, cast_type: cast_type, default: columns_hash[name.to_s]&.default)
end
preserve_original_encrypted(name) if ignore_case
ActiveRecord::Encryption.encrypted_attribute_was_declared(self, name)
end # File activerecord/lib/active_record/encryption/encryptable_record.rb, line 146 def encrypted_attribute?(attribute_name) ActiveRecord::Encryption.encryptor.encrypted? read_attribute_before_type_cast(attribute_name) end
Возвращает, является ли данный атрибут зашифрованным или нет.
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 49
def encrypts(*names, key_provider: nil, key: nil, deterministic: false, support_unencrypted_data: nil, downcase: false, ignore_case: false, previous: [], **context_properties)
self.encrypted_attributes ||= Set.new # not using :default because the instance would be shared across classes
names.each do |name|
encrypt_attribute name, key_provider: key_provider, key: key, deterministic: deterministic, support_unencrypted_data: support_unencrypted_data, downcase: downcase, ignore_case: ignore_case, previous: previous, **context_properties
end
end Шифрует атрибут name.
Параметры
-
:key_provider- Поставщик ключей для предоставления ключей шифрования и дешифрования. По умолчаниюActiveRecord::Encryption.key_provider. -
:key- Пароль для получения ключа. Это сокращенная форма для:key_provider, которая служит для вывода производных ключей. Оба параметра не могут быть использованы одновременно. -
:deterministic- По умолчанию шифрование не детерминировано. Оно использует случайный начальный вектор для каждой операции шифрования. Это означает, что шифрование одного и того же содержимого с одним и тем же ключом дважды приведет к различным шифрованным текстам. При установке в значениеtrue, оно будет генерировать начальный вектор на основе зашифрованного содержимого. Это означает, что одно и то же содержимое будет генерировать одинаковые шифрованные тексты. Это позволяет выполнять запросы к зашифрованному тексту с помощью Active Record. По умолчанию детерминированное шифрование будет использовать самую старую схему шифрования для шифрования новых данных. Вы можете изменить это, установивdeterministic: { fixed: false }. Это заставит его использовать новейшую схему шифрования для шифрования новых данных. -
:support_unencrypted_data- Если ‘config.active_record.encryption.support_unencrypted_data` имеет значениеtrue, вы можете установить это значение вfalse, чтобы отключить поддержку данных без шифрования для этого атрибута. Это полезно в сценариях, где вы шифруете один столбец и хотите отключить поддержку данных без шифрования, не изменяя глобальные настройки. -
:downcase- Если значение истинно, оно автоматически преобразует зашифрованное содержимое в нижний регистр. Это позволяет эффективно игнорировать регистр при запросе данных. Обратите внимание, что регистр теряется. Используйте:ignore_case, если вы заинтересованы в сохранении регистра. -
:ignore_case- Если значение истинно, оно ведет себя как:downcase, но также сохраняет исходный регистр в специально выделенном столбце +original_<name>+. При чтении зашифрованного содержимого отображается версия с исходным регистром. Однако вы все равно можете выполнять запросы, которые будут игнорировать регистр. Этот параметр может быть использован только когда:deterministicимеет значение истинно. -
:context_properties- Дополнительные свойства, которые переопределят настройкиContextпри шифровании и дешифровании этого атрибута. Например:encryptor:,cipher:,message_serializer:, и т.д. -
:previous- Список предыдущих схем шифрования. При указании они будут использоваться в порядке, когда происходит попытка чтения атрибута. Каждый элемент списка может содержать свойства, поддерживаемыеencrypts. Также, когда используется детерминированное шифрование, они будут использоваться для генерации дополнительных шифрованных текстов для проверки в запросах.
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 78
def global_previous_schemes_for(scheme)
ActiveRecord::Encryption.config.previous_schemes.filter_map do |previous_scheme|
scheme.merge(previous_scheme) if scheme.compatible_with?(previous_scheme)
end
end # File activerecord/lib/active_record/encryption/encryptable_record.rb, line 126 def load_schema! super add_length_validation_for_encrypted_columns if ActiveRecord::Encryption.config.validate_column_size end
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 109
def override_accessors_to_preserve_original(name, original_attribute_name)
include(Module.new do
define_method name do
if ((value = super()) && encrypted_attribute?(name)) || !ActiveRecord::Encryption.config.support_unencrypted_data
send(original_attribute_name)
else
value
end
end
define_method "#{name}=" do |value|
self.send "#{original_attribute_name}=", value
super(value)
end
end)
end # File activerecord/lib/active_record/encryption/encryptable_record.rb, line 98
def preserve_original_encrypted(name)
original_attribute_name = "#{ORIGINAL_ATTRIBUTE_PREFIX}#{name}".to_sym
if !ActiveRecord::Encryption.config.support_unencrypted_data && !column_names.include?(original_attribute_name.to_s)
raise Errors::Configuration, "To use :ignore_case for '#{name}' you must create an additional column named '#{original_attribute_name}'"
end
encrypts original_attribute_name
override_accessors_to_preserve_original name, original_attribute_name
end # File activerecord/lib/active_record/encryption/encryptable_record.rb, line 70
def scheme_for(key_provider: nil, key: nil, deterministic: false, support_unencrypted_data: nil, downcase: false, ignore_case: false, previous: [], **context_properties)
ActiveRecord::Encryption::Scheme.new(key_provider: key_provider, key: key, deterministic: deterministic,
support_unencrypted_data: support_unencrypted_data, downcase: downcase, ignore_case: ignore_case, **context_properties).tap do |scheme|
scheme.previous_schemes = global_previous_schemes_for(scheme) +
Array.wrap(previous).collect { |scheme_config| ActiveRecord::Encryption::Scheme.new(**scheme_config) }
end
end # File activerecord/lib/active_record/encryption/encryptable_record.rb, line 65 def source_attribute_from_preserved_attribute(attribute_name) attribute_name.to_s.sub(ORIGINAL_ATTRIBUTE_PREFIX, "") if attribute_name.start_with?(ORIGINAL_ATTRIBUTE_PREFIX) end
При заданном имени атрибута возвращает имя исходного атрибута, если это сохраненный атрибут.
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 138
def validate_column_size(attribute_name)
if limit = columns_hash[attribute_name.to_s]&.limit
validates_length_of attribute_name, maximum: limit
end
end
© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.