123456789_123456789_123456789_123456789_123456789_

Module: Mongoid::Config::Encryption Private

Do not use. This module is for internal use only.
Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Extended In:
Defined in: lib/mongoid/config/encryption.rb

Overview

This module contains the logic for configuring Client Side Field Level automatic encryption.

Constant Summary

Instance Method Summary

Instance Method Details

#algorithm_for(field) ⇒ String (private)

Get the encryption algorithm to use for the provided field.

Parameters:

  • field (Mongoid::Field)

    The field to get the algorithm for.

Returns:

[ GitHub ]

  
# File 'lib/mongoid/config/encryption.rb', line 179

def algorithm_for(field)
  case field.deterministic?
  when true
    DETERMINISTIC_ALGORITHM
  when false
    RANDOM_ALGORITHM
  else
    nil
  end
end

#bson_type_for(field) ⇒ String (private)

Get the ::BSON type identifier for the provided field according to the www.mongodb.com/docs/manual/reference/bson-types/#std-label-bson-types

Parameters:

  • field (Mongoid::Field)

    The field to get the ::BSON type identifier for.

Returns:

  • (String)

    The BSON type identifier.

[ GitHub ]

  
# File 'lib/mongoid/config/encryption.rb', line 170

def bson_type_for(field)
  TYPE_MAPPINGS[field.type]
end

#encryption_schema_map(default_database, models = ::Mongoid.models) ⇒ Hash

Generate the encryption schema map for the provided models.

Parameters:

  • default_database (String)

    The default database name.

  • models (Array<Mongoid::Document>) (defaults to: ::Mongoid.models)

    The models to generate the schema map for. Defaults to all models in the application.

Returns:

  • (Hash)

    The encryption schema map.

[ GitHub ]

  
# File 'lib/mongoid/config/encryption.rb', line 23

def encryption_schema_map(default_database, models = ::Mongoid.models)
  visited = Set.new
  models.each_with_object({}) do |model, map|
    next if visited.include?(model)
    visited << model
    next if model.embedded?
    next unless model.encrypted?

    database = model.storage_options.fetch(:database) { default_database }
    key = "#{database}.#{model.collection_name}"
    props = (model).merge(properties_for(model, visited))
    map[key] = props unless props.empty?
  end
end

#key_id_for(key_id_base64, key_name_field) ⇒ Array<BSON::Binary> | String | nil (private)

Get the keyId encryption schema field for the base64 encrypted key id.

Parameters:

  • key_id_base64 (String | nil)

    The base64 encoded key id.

  • key_name_field (String | nil)

    The name of the key name field.

Returns:

  • (Array<BSON::Binary> | String | nil)

    The keyId encryption schema field, JSON pointer to the field that contains keyAltName, or nil if both key_id_base64 and key_name_field are nil.

[ GitHub ]

  
# File 'lib/mongoid/config/encryption.rb', line 199

def key_id_for(key_id_base64, key_name_field)
  return nil if key_id_base64.nil? && key_name_field.nil?
  if !key_id_base64.nil? && !key_name_field.nil?
    raise ArgumentError, 'Specifying both key_id and key_name_field is not allowed'
  end

  if key_id_base64.nil?
    "/#{key_name_field}"
  else
    [ BSON::Binary.new(Base64.decode64(key_id_base64), :uuid) ]
  end
end

#metadata_for(model) ⇒ Hash (private)

Generate the encryptMetadata object for the provided model.

Parameters:

Returns:

  • (Hash)

    The encryptMetadata object.

[ GitHub ]

  
# File 'lib/mongoid/config/encryption.rb', line 74

def (model)
   = {}.tap do ||
    if (key_id = key_id_for(model.[:key_id], model.[:key_name_field]))
      ['keyId'] = key_id
    end
    if model..key?(:deterministic)
      ['algorithm'] = if model.[:deterministic]
                                DETERMINISTIC_ALGORITHM
                              else
                                RANDOM_ALGORITHM
                              end
    end
  end
  if .empty?
    {}
  else
    {
      'bsonType' => 'object',
      'encryptMetadata' => 
    }
  end
end

#properties_for(model, visited) ⇒ Hash (private)

Generate encryption properties for the provided model.

This method generates the properties for the fields and relations that are marked as encrypted.

Parameters:

Returns:

  • (Hash)

    The encryption properties.

[ GitHub ]

  
# File 'lib/mongoid/config/encryption.rb', line 106

def properties_for(model, visited)
  result = properties_for_fields(model).merge(properties_for_relations(model, visited))
  if result.empty?
    {}
  else
    { 'properties' => result }
  end
end

#properties_for_fields(model) ⇒ Hash (private)

Generate encryption properties for the fields of the provided model.

Parameters:

Returns:

  • (Hash)

    The encryption properties.

[ GitHub ]

  
# File 'lib/mongoid/config/encryption.rb', line 120

def properties_for_fields(model)
  model.fields.each_with_object({}) do |(name, field), props|
    next unless field.is_a?(Mongoid::Fields::Encrypted)

    props[name] = {
      'encrypt' => {
        'bsonType' => bson_type_for(field)
      }
    }
    if (algorithm = algorithm_for(field))
      props[name]['encrypt']['algorithm'] = algorithm
    end
    if (key_id = key_id_for(field.key_id, field.key_name_field))
      props[name]['encrypt']['keyId'] = key_id
    end
  end
end

#properties_for_relations(model, visited) ⇒ Hash (private)

Generate encryption properties for the relations of the provided model.

This method generates the properties for the embedded relations that are configured to be encrypted.

Parameters:

Returns:

  • (Hash)

    The encryption properties.

[ GitHub ]

  
# File 'lib/mongoid/config/encryption.rb', line 147

def properties_for_relations(model, visited)
  model.relations.each_with_object({}) do |(name, relation), props|
    next if visited.include?(relation.relation_class)
    next unless relation.is_a?(Association::Embedded::EmbedsOne)
    next unless relation.relation_class.encrypted?

    visited << relation.relation_class
    (
      relation.relation_class
    ).merge(
      properties_for(relation.relation_class, visited)
    ).tap do |properties|
      props[name] = { 'bsonType' => 'object' }.merge(properties) unless properties.empty?
    end
  end
end