Spec-Zone.ru › Ruby on Rails 7.0

модуль ActiveRecord::Encryption::EncryptableRecord

Данный concern добавляется в модели Active Record для шифрования. Он добавляет объявление атрибута encrypts, а также API для шифрования и дешифрования записей.

Константы

ORIGINAL_ATTRIBUTE_PREFIX

Публичные методы экземпляров

add_length_validation_for_encrypted_columns() Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 129
def add_length_validation_for_encrypted_columns
  encrypted_attributes&.each do |attribute_name|
    validate_column_size attribute_name
  end
end
ciphertext_for(attribute_name) Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 148
def ciphertext_for(attribute_name)
  read_attribute_before_type_cast(attribute_name)
end

Возвращает шифрованный текст для attribute_name.

decrypt() Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 158
def decrypt
  decrypt_attributes if has_encrypted_attributes?
end

Дешифрует все шифруемые атрибуты и сохраняет изменения.

deterministic_encrypted_attributes() Показать исходный код
# 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

Возвращает список детерминированных шифруемых атрибутов в классе модели.

encrypt() Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 153
def encrypt
  encrypt_attributes if has_encrypted_attributes?
end

Шифрует все шифруемые атрибуты и сохраняет изменения.

encrypt_attribute(name, attribute_scheme) Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 84
def encrypt_attribute(name, attribute_scheme)
  encrypted_attributes << name.to_sym

  attribute name do |cast_type|
    ActiveRecord::Encryption::EncryptedAttributeType.new scheme: attribute_scheme, cast_type: cast_type
  end

  preserve_original_encrypted(name) if attribute_scheme.ignore_case?
  ActiveRecord::Encryption.encrypted_attribute_was_declared(self, name)
end
encrypted_attribute?(attribute_name) Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 143
def encrypted_attribute?(attribute_name)
  ActiveRecord::Encryption.encryptor.encrypted? ciphertext_for(attribute_name)
end

Возвращает, зашифрован ли данный атрибут.

encrypts(*names, key_provider: nil, key: nil, deterministic: false, downcase: false, ignore_case: false, previous: [], **context_properties) Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 47
def encrypts(*names, key_provider: nil, key: nil, deterministic: false, downcase: false, ignore_case: false, previous: [], **context_properties)
  self.encrypted_attributes ||= Set.new # not using :default because the instance would be shared across classes
  scheme = scheme_for key_provider: key_provider, key: key, deterministic: deterministic, downcase: downcase, \
      ignore_case: ignore_case, previous: previous, **context_properties

  names.each do |name|
    encrypt_attribute name, scheme
  end
end

Шифрует атрибут name.

Параметры

  • :key_provider - Настройка поставщика ключей для шифрования и дешифрования данного атрибута. Если не указано, используется значение по умолчанию ActiveRecord::Encryption.key_provider.

  • :key - Пароль для вывода ключа. Это сокращенная запись для поставщика ключей, который выводит производные ключи. Оба параметра не могут использоваться одновременно.

  • :key_provider - Указывает поставщика ключей для шифрования и дешифрования. Если не указано, используется поставщик ключей, заданный в `config.key_provider`.

  • :deterministic - По умолчанию шифрование не детерминировано. Оно использует случайный вектор инициализации для каждой операции шифрования. Это означает, что шифрование одинаковых данных с тем же ключом дважды приведет к разным шифрованным текстам. Если установлено значение true, вектор инициализации будет генерироваться на основе шифрованного контента. Это означает, что одинаковые данные будут давать одинаковые шифрованные тексты. Это позволяет выполнять запросы к зашифрованному тексту с помощью Active Record. По умолчанию детерминированное шифрование будет использовать самую старую схему шифрования для шифрования новых данных. Вы можете изменить это, установив +deterministic: { fixed: false }+. Это заставит его использовать самую новую схему шифрования для шифрования новых данных.

  • :downcase - Если true, шифрованный контент автоматически приводится к нижнему регистру. Это позволяет эффективно игнорировать регистр при запросах к данным. Обратите внимание, что регистр будет утерян. Используйте :ignore_case если вам нужно сохранить регистр.

  • :ignore_case - Если true, ведет себя как :downcase, но также сохраняет исходный регистр в специально выделенном столбце +original_<name>+. При чтении зашифрованного контента используется версия с исходным регистром. Однако вы по-прежнему можете выполнять запросы, которые игнорируют регистр. Этот параметр может использоваться только при :deterministic равном true.

  • :context_properties - Дополнительные свойства, которые переопределят Context настройки при шифровании и дешифровании этого атрибута. Например: encryptor:, cipher:, message_serializer:, и т. д.

  • :previous - Список предыдущих схем шифрования. Если указано, они будут использоваться в порядке очереди при попытке чтения атрибута. Каждый элемент списка может содержать свойства, поддерживаемые encrypts. Кроме того, при использовании детерминированного шифрования они будут использоваться для генерации дополнительных шифрованных текстов для проверки в запросах.

global_previous_schemes_for(scheme) Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 78
def global_previous_schemes_for(scheme)
  ActiveRecord::Encryption.config.previous_schemes.collect do |previous_scheme|
    scheme.merge(previous_scheme)
  end
end
load_schema!() Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 123
def load_schema!
  super

  add_length_validation_for_encrypted_columns if ActiveRecord::Encryption.config.validate_column_size
end
Вызывает метод суперкласса
override_accessors_to_preserve_original(name, original_attribute_name) Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 106
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
preserve_original_encrypted(name) Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 95
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
scheme_for(key_provider: nil, key: nil, deterministic: false, downcase: false, ignore_case: false, previous: [], **context_properties) Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 70
def scheme_for(key_provider: nil, key: nil, deterministic: false, downcase: false, ignore_case: false, previous: [], **context_properties)
  ActiveRecord::Encryption::Scheme.new(key_provider: key_provider, key: key, deterministic: deterministic,
                                       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
source_attribute_from_preserved_attribute(attribute_name) Показать исходный код
# 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 /^#{ORIGINAL_ATTRIBUTE_PREFIX}/.match?(attribute_name)
end

Принимая имя атрибута, возвращает имя исходного атрибута, если это сохраненный атрибут.

validate_column_size(attribute_name) Показать исходный код
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 135
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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API