module AttrVault::ClassMethods

Public Instance Methods

vault_attr(name, opts={}) click to toggle source
# File lib/attr_vault.rb, line 76
def vault_attr(name, opts={})
  attr = VaultAttr.new(name, **opts)
  self.vault_attrs << attr

  define_method(name) do
    @vault_dirty_attrs ||= {}
    if @vault_dirty_attrs.has_key? name
      return @vault_dirty_attrs[name]
    end
    # if there is a plaintext source field, use that and ignore
    # the encrypted field
    if !attr.migrate_from_field.nil? && !self[attr.migrate_from_field].nil?
      return self[attr.migrate_from_field]
    end

    keyring = self.class.vault_keys
    key_id = self[self.class.vault_key_field]
    if key_id.nil?
      # if there is no recorded key, this is not an encrypted
      # record so we return nil
      return nil
    end
    record_key = self.class.vault_keys.fetch(key_id)

    encrypted_value = self[attr.encrypted_field]
    # TODO: cache decrypted value
    Cryptor.decrypt(encrypted_value, record_key.value)
  end

  define_method("#{name}=") do |value|
    old_value = self.public_send(name)
    return if value == old_value

    @vault_dirty_attrs ||= {}
    @vault_dirty_attrs[name] = value
    # ensure that Sequel knows that this is in fact dirty and must
    # be updated--otherwise, the object is never saved,
    # #before_save is never called, and we never store the update
    self.modified! attr.encrypted_field
    unless attr.digest_field.nil?
      self.modified! attr.digest_field
    end
  end
end
vault_attrs() click to toggle source
# File lib/attr_vault.rb, line 121
def vault_attrs
  @vault_attrs ||= []
end
vault_digests(data) click to toggle source
# File lib/attr_vault.rb, line 72
def vault_digests(data)
  @keyring.digests(data).map { |d| Sequel.blob(d) }
end
vault_key_field() click to toggle source
# File lib/attr_vault.rb, line 125
def vault_key_field
  @key_field
end
vault_keyring(keyring_data, key_field: :key_id) click to toggle source
# File lib/attr_vault.rb, line 67
def vault_keyring(keyring_data, key_field: :key_id)
  @key_field = key_field.to_sym
  @keyring = Keyring.load(keyring_data)
end
vault_keys() click to toggle source
# File lib/attr_vault.rb, line 129
def vault_keys
  @keyring
end