Module: ClassMethods

Defined in:
lib/encrypt_column/encrypt_column.rb

Instance Method Summary collapse

Instance Method Details

#encrypt(name, options = {}) ⇒ Object

Encrypt any column with a hash (searchable: true) or conditionally(if: Proc) also has a failsafe (failsafe: true) feature to write to a different db column in the database, i.e. <name>_ciphertext. This prevents users from accidentally commenting out the encrypt declaration and reading/writing plaintext to the database.



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
# File 'lib/encrypt_column/encrypt_column.rb', line 7

def encrypt(name, options = {})
  searchable = options[:searchable] || false
  encrypt_cond = options[:if] || proc { true }
  failsafe = options[:failsafe] || false
  @@encrypt_column_key = options[:key] || ENV['ENCRYPT_KEY']
  @@hash_salt = options[:hash_salt] || ENV['HASH_SALT']
  column = name
  column = "#{name}_ciphertext" if failsafe
  hash_column = "#{name}_hash"

  # getter
  define_method(name) do
    return read_attribute(column) unless instance_eval(&encrypt_cond)
    Decrypt.ciphertext(read_attribute(column), @@encrypt_column_key)
  end

  # setter
  define_method("#{name}=") do |value|
    return write_attribute(column, value) unless instance_eval(&encrypt_cond)
    write_attribute(column, Encrypt.plaintext(value, @@encrypt_column_key))
    write_attribute(hash_column, Hashed.val(value, @@hash_salt)) if searchable
  end

  # search method when searchable specified
  define_singleton_method("with_#{name}") do |value|
    where(hash_column.to_sym => Hashed.val(value, @@hash_salt))
  end if searchable
end