module ActiveRecord::PGCrypto::SymmetricCoder

PGCrypto symmetric encryption/decryption coder for attribute serialization

Public Class Methods

decrypted_arel(node) click to toggle source

Wraps a node for decryption calls

@return [Arel::Node]

# File lib/active_record/pgcrypto/symmetric_coder.rb, line 50
def self.decrypted_arel(node)
  Arel::Nodes::NamedFunction.new(
    'PGP_SYM_DECRYPT_BYTEA', [
      node, Arel::Nodes::Quoted.new(pgcrypto_key)
    ]
  )
end
decrypted_arel_text(node) click to toggle source

Wraps a node for decryption and text encoded calls

@return [Arel::Node]

# File lib/active_record/pgcrypto/symmetric_coder.rb, line 61
def self.decrypted_arel_text(node)
  Arel::Nodes::NamedFunction.new(
    'ENCODE', [
      decrypted_arel(node),
      Arel::Nodes::Quoted.new('escape')
    ]
  )
end
dump(value) click to toggle source

Encrypts the requested value

@return [String] binary data

# File lib/active_record/pgcrypto/symmetric_coder.rb, line 25
def self.dump(value)
  encrypt(value)
end
load(value) click to toggle source

Decrypts the requested value

@return [String]

# File lib/active_record/pgcrypto/symmetric_coder.rb, line 18
def self.load(value)
  decrypt(value)
end

Private Class Methods

arel_query(arel_nodes) click to toggle source

Executes the [Arel::Node] generated query

@return [String] the first returned value

# File lib/active_record/pgcrypto/symmetric_coder.rb, line 85
def self.arel_query(arel_nodes)
  sel_manager = Arel::SelectManager.new(nil)

  if ::ActiveRecord::VERSION::MAJOR == 4
    sel_manager = Arel::SelectManager.new(::ActiveRecord::Base)
  end

  query = sel_manager.project(arel_nodes).to_sql
  ::ActiveRecord::Base.connection.select_value(query)
end
decrypt(value) click to toggle source

Wraps the value into an [Arel::Node] with SQL calls for decryption

@return [Arel::Node]

# File lib/active_record/pgcrypto/symmetric_coder.rb, line 73
def self.decrypt(value)
  return value if value.nil?

  value = ActiveRecord::Base.connection.escape_bytea(value)
  dec_value = arel_query(decrypted_arel(Arel::Nodes::Quoted.new(value)))
  dec_value = ActiveRecord::Base.connection.unescape_bytea(dec_value)
  dec_value.force_encoding(pgcrypto_encoding)
end
encrypt(value) click to toggle source

Wraps the value into an [Arel::Node] with SQL calls for encryption

@return [Arel::Node]

# File lib/active_record/pgcrypto/symmetric_coder.rb, line 32
def self.encrypt(value)
  return value if value.nil?

  encrypted = Arel::Nodes::NamedFunction.new(
    'PGP_SYM_ENCRYPT_BYTEA', [
      Arel::Nodes::Quoted.new(value.to_s),
      Arel::Nodes::Quoted.new(pgcrypto_key),
      Arel::Nodes::Quoted.new(pgcrypto_options)
    ]
  )

  enc_val = arel_query(encrypted)
  ActiveRecord::Base.connection.unescape_bytea(enc_val)
end