Sha256: 74d20c8ac19f7930986f112695fd092cc609531c462a6d8d6e363304e7c99566

Contents?: true

Size: 1.33 KB

Versions: 1

Compression:

Stored size: 1.33 KB

Contents

require "fernet"

module Sequel
  module Plugins
    module Vault
      class InvalidCiphertext < Exception; end

      def self.configure(model, keys = nil, *attrs)
        model.vault_attributes(keys, *attrs) unless attrs.empty?
      end

      module ClassMethods
        attr_accessor :vault_attributes_module

        def vault_attributes(keys, *attrs)
          include(self.vault_attributes_module ||= Module.new) unless vault_attributes_module
          vault_attributes_module.class_eval do
            attrs.each do |attr|
              define_method(attr) do
                cypher = super()
                decrypt(keys, cypher) unless cypher.nil?
              end

              define_method("#{attr}=") do |plain|
                cypher = encrypt(keys, plain) unless plain.nil?
                super(cypher)
              end
            end
          end
        end
      end

      module InstanceMethods
        private

        def encrypt(keys, plain)
          ::Fernet.generate(keys.first, plain)
        end

        def decrypt(keys, cypher)
          keys.each do |key|
            verifier = ::Fernet.verifier(key, cypher, enforce_ttl: false)
            next unless verifier.valid?
            return verifier.message
          end
          raise InvalidCiphertext, "Could not decrypt field"
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
sequel_vault-0.1 lib/sequel_vault.rb