Module: MongoMapper::Plugins::EncryptedKey::ClassMethods

Defined in:
lib/symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key.rb

Instance Method Summary collapse

Instance Method Details

#encrypted_key(key_name, type, full_options = {}) ⇒ Object

MongoMapper::Document.encrypted_key

Support automatic encryption and decryption of fields in MongoMapper

Example:

class Person
  include MongoMapper::Document

  key           :name,                   String
  encrypted_key :social_security_number, String
  key           :date_of_birth,          Date
  encrypted_key :life_history,           String, encrypted: { compress: true, random_iv: true }

  # Encrypted fields are _always_ stored in Mongo as a String
  # By specifying a type other than String, Symmetric Encryption will
  # perform the necessary conversions
  #
  # The following types are supported:
  #   String
  #   Integer
  #   Float
  #   BigDecimal
  #   DateTime
  #   Time
  #   Date
  #   Hash - (Stored as encrypted JSON in MongoDB)
  encrypted_key :age,                    Integer, encrypted: { random_iv: true }
end

The above document results in the following document in the Mongo collection ‘persons’:

"name" : "Joe",
"encrypted_social_security_number" : "...",
"age"  : 21
"encrypted_life_history" : "...",

Symmetric Encryption creates the getters and setters to be able to work with the field in it’s decrypted form. For example

Example:

person = Person.where(encrypted_social_security_number: '...').first

puts "Decrypted Social Security Number is: #{person.social_security_number}"

# Or is the same as
puts "Decrypted Social Security Number is: #{SymmetricEncryption.decrypt(person.encrypted_social_security_number)}"

# Sets the encrypted_social_security_number to encrypted version
person.social_security_number = "123456789"

# Or, is equivalent to:
person.encrypted_social_security_number = SymmetricEncryption.encrypt("123456789")

Note: Only “String” types are currently supported for encryption

Note: Unlike attr_encrypted finders must use the encrypted field name

Invalid Example, does not work:
  person = Person.where(social_security_number: '123456789').first

Valid Example:
  person = Person.where(encrypted_social_security_number: SymmetricEncryption.encrypt('123456789')).first

Defines all the fields that are accessible on the Document For each field that is defined, a getter and setter will be added as an instance method to the Document.

Note:

Use MongoMapper's built-in support for :field_name to specify a different
field name in MongoDB for the encrypted field from what is used via the model

Examples:

Define an encrypted key

encrypted_key :social_security_number, String, encrypted: {compress: false, random_iv: false}
encrypted_key :sensitive_text,         String, encrypted: {compress: true, random_iv: true}

Parameters:

  • name (Symbol)

    The name of the key.

  • type (Object)

    The type of the key.

  • options (Hash)

    The options to pass to the field, including any MongoMapper specific options



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/symmetric_encryption/extensions/mongo_mapper/plugins/encrypted_key.rb', line 108

def encrypted_key(key_name, type, full_options={})
  full_options       = full_options.is_a?(Hash) ? full_options.dup : {}
  options            = full_options.delete(:encrypted) || {}
  # Support overriding the name of the decrypted attribute
  encrypted_key_name = options.delete(:encrypt_as) || "encrypted_#{key_name}"
  options[:type]     = COERCION_MAP[type] unless [:yaml, :json].include?(options[:type])

  raise "Invalid type: #{type.inspect}. Valid types: #{COERCION_MAP.keys.join(',')}" unless options[:type]

  SymmetricEncryption::Generator.generate_decrypted_accessors(self, key_name, encrypted_key_name, options)

  key(encrypted_key_name, String, full_options)
end