Module: SymmetricEncryption::Generator

Defined in:
lib/symmetric_encryption/generator.rb

Class Method Summary collapse

Class Method Details

.generate_decrypted_accessors(model, decrypted_name, encrypted_name, options) ⇒ Object

Common internal method for generating accessors for decrypted accessors Primarily used by extensions



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/symmetric_encryption/generator.rb', line 5

def self.generate_decrypted_accessors(model, decrypted_name, encrypted_name, options)

  random_iv      = options.delete(:random_iv) || false
  compress       = options.delete(:compress) || false
  type           = options.delete(:type) || :string

  # For backward compatibility
  if options.delete(:marshal) == true
    warn("The :marshal option has been deprecated in favor of :type. For example: attr_encrypted name, type: :yaml")
    raise "Marshal is depreacted and cannot be used in conjunction with :type, just use :type. For #{params.inspect}" if type != :string
    type = :yaml
  end

  options.each {|option| warn "Ignoring unknown option #{option.inspect} supplied when encrypting #{decrypted_name} with #{params.inspect}"}

  raise "Invalid type: #{type.inspect}. Valid types: #{SymmetricEncryption::COERCION_TYPES.inspect}" unless SymmetricEncryption::COERCION_TYPES.include?(type)

  if model.const_defined?(:EncryptedAttributes, _search_ancestors = false)
    mod = model.const_get(:EncryptedAttributes)
  else
    mod = model.const_set(:EncryptedAttributes, Module.new)
    model.send(:include, mod)
  end

  # Generate getter and setter methods
  mod.module_eval("  # Set the un-encrypted field\n  # Also updates the encrypted field with the encrypted value\n  # Freeze the decrypted field value so that it is not modified directly\n  def \#{decrypted_name}=(value)\n    v = SymmetricEncryption::coerce(value, :\#{type})\n    self.\#{encrypted_name} = @stored_\#{encrypted_name} = ::SymmetricEncryption.encrypt(v,\#{random_iv},\#{compress},:\#{type})\n    @\#{decrypted_name} = v.freeze\n  end\n\n  # Returns the decrypted value for the encrypted field\n  # The decrypted value is cached and is only decrypted if the encrypted value has changed\n  # If this method is not called, then the encrypted value is never decrypted\n  def \#{decrypted_name}\n    if @stored_\#{encrypted_name} != self.\#{encrypted_name}\n      @\#{decrypted_name} = ::SymmetricEncryption.decrypt(self.\#{encrypted_name},version=nil,:\#{type}).freeze\n      @stored_\#{encrypted_name} = self.\#{encrypted_name}\n    end\n    @\#{decrypted_name}\n  end\n\n  EOS\nend\n", __FILE__, __LINE__ + 1)