Module: Mongoid::Config::Encryption Private
| 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
-
DETERMINISTIC_ALGORITHM =
# File 'lib/mongoid/config/encryption.rb', line 48
The algorithm to use for the deterministic encryption.
'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' -
RANDOM_ALGORITHM =
# File 'lib/mongoid/config/encryption.rb', line 51
The algorithm to use for the non-deterministic encryption.
'AEAD_AES_256_CBC_HMAC_SHA_512-Random' -
TYPE_MAPPINGS =
# File 'lib/mongoid/config/encryption.rb', line 54
{ Hash => 'object', Integer => 'int', BSON::Int32 => 'int', BSON::Int64 => 'long', BSON::ObjectId => 'objectId', Time => 'date', Date => 'date', DateTime => 'date', Float => 'double', String => 'string', BSON::Binary => 'binData', Array => 'array', Mongoid::Boolean => 'bool', BigDecimal => 'decimal', Range => 'object', Regexp => 'regex', Set => 'array', Mongoid::StringifiedSymbol => 'string', ActiveSupport::TimeWithZone => 'date' }.freeze
Instance Method Summary
-
#encryption_schema_map(default_database, models = ::Mongoid.models) ⇒ Hash
Internal use only
Generate the encryption schema map for the provided models.
-
#algorithm_for(field) ⇒ String
private
Internal use only
Get the encryption algorithm to use for the provided field.
-
#bson_type_for(field) ⇒ String
private
Internal use only
Get the
::BSONtype identifier for the provided field according to the https://www.mongodb.com/docs/manual/reference/bson-types/#std-bson-types. -
#key_id_for(key_id_base64, key_name_field) ⇒ Array<BSON::Binary> | String | nil
private
Internal use only
Get the keyId encryption schema field for the base64 encrypted key id.
-
#metadata_for(model) ⇒ Hash
private
Internal use only
Generate the encryptMetadata object for the provided model.
-
#properties_for(model, path) ⇒ Hash
private
Internal use only
Generate encryption properties for the provided model.
-
#properties_for_fields(model) ⇒ Hash
private
Internal use only
Generate encryption properties for the fields of the provided model.
-
#properties_for_relations(model, path) ⇒ Hash
private
Internal use only
Generate encryption properties for the relations of the provided model.
Instance Method Details
#algorithm_for(field) ⇒ String (private)
Get the encryption algorithm to use for the provided field.
# File 'lib/mongoid/config/encryption.rb', line 196
def algorithm_for(field) case field.deterministic? when true DETERMINISTIC_ALGORITHM when false RANDOM_ALGORITHM end end
#bson_type_for(field) ⇒ String (private)
Get the ::BSON type identifier for the provided field according to the
https://www.mongodb.com/docs/manual/reference/bson-types/#std-bson-types
# File 'lib/mongoid/config/encryption.rb', line 187
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.
# File 'lib/mongoid/config/encryption.rb', line 22
def encryption_schema_map(default_database, models = ::Mongoid.models) models.each_with_object({}) do |model, map| next if model. next unless model.requires_encryption_schema? database = model..fetch(:database) { default_database } # A callable database name cannot be resolved here: the documented # multi-tenant idiom has no correct value while the client is being # built. Interpolating the callable would produce a key that never # matches any namespace, so leave the model out of the map. Writes # are refused later, by PersistenceContext, rather than silently # going out unencrypted. next if database.respond_to?(:call) key = "#{database}.#{model.collection_name}" props = (model).merge(properties_for(model, [ model ])) # The root of a collection schema describes the document, so it is # always an object. Saying so matters when a nested schema carries # encryptMetadata: mongocryptd rejects the schema otherwise. map[key] = { 'bsonType' => 'object' }.merge(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.
# File 'lib/mongoid/config/encryption.rb', line 214
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.
# File 'lib/mongoid/config/encryption.rb', line 81
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, path) ⇒ Hash (private)
Generate encryption properties for the provided model.
This method generates the properties for the fields and relations that are marked as encrypted.
# File 'lib/mongoid/config/encryption.rb', line 114
def properties_for(model, path) result = properties_for_fields(model).merge(properties_for_relations(model, path)) if result.empty? {} else { 'properties' => result } end end
#properties_for_fields(model) ⇒ Hash (private)
Generate encryption properties for the fields of the provided model.
# File 'lib/mongoid/config/encryption.rb', line 128
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, path) ⇒ 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.
# File 'lib/mongoid/config/encryption.rb', line 156
def properties_for_relations(model, path) model.relations.each_with_object({}) do |(name, relation), props| # relation_class constantizes, and a polymorphic embedded_in has no # class to resolve, so the relation type has to be checked first. next unless relation.is_a?(Association::Embedded::EmbedsOne) klass = relation.try_relation_class # An association target does not have to be a Mongoid document, and # the class it names does not have to exist. next unless klass.respond_to?(:requires_encryption_schema?) # Stop at a model the walk is already inside of, or a self-embedding # model never terminates. The path covers the current branch only: # a model embedded by two parents, or twice by one parent, has to be # emitted at every place it appears. next if path.include?(klass) next unless klass.requires_encryption_schema? (klass).merge( properties_for(klass, path + [ klass ]) ).tap do |properties| props[name] = { 'bsonType' => 'object' }.merge(properties) unless properties.empty? end end end