lightthefuserun/cloaked

View on GitHub
lib/cloaked.rb

Summary

Maintainability
A
0 mins
Test Coverage
# frozen_string_literal: true

require 'active_support'

require 'cloaked/active_record/cloaked/active_record'

module Cloaked
  extend ActiveSupport::Concern

  autoload :VERSION, 'cloaked/version'

  class InvalidMethod < StandardError; end

  DEFAULT_SIZE = 8

  included do
    cattr_accessor :cloaked_fields, instance_reader: false

    before_validation :cloak_fields

    extend ClassMethods
    include InstanceMethods
  end

  module ClassMethods
    def with_cloaked_keys(*fields, size: DEFAULT_SIZE, prefix: '', method: :url_safe)
      self.cloaked_fields ||= []

      fields.each do |field|
        self.cloaked_fields << {
          field_name: field,
          size: size,
          prefix: prefix,
          method: method
        }
      end
    end
  end

  module InstanceMethods
    def cloak_fields(force: false)
      self.class.cloaked_fields ||= []

      self.class.cloaked_fields.each do |field|
        cloak_field(field.merge(force: force))
      end

      self
    end

    def cloak_field(field_name: nil, size: DEFAULT_SIZE, prefix: '', force: false, method: :url_safe)
      return send(field_name) if send(field_name).present? && !force

      cloaked_value = prefix.to_s + value(method, size)

      return send("#{field_name}=", cloaked_value) unless self.class.exists?(field_name)
    end

    private

    def value(method, size)
      case method
      when :uuid then SecureRandom.uuid
      when :hex then SecureRandom.hex(size)
      when :url_safe then SecureRandom.urlsafe_base64(size)
      else raise InvalidMethod
      end
    end
  end
end

# require 'cloaked/railtie' if defined?(Rails)