Module: AttrMasker

Defined in:
lib/attr_masker.rb,
lib/attr_masker/error.rb,
lib/attr_masker/railtie.rb,
lib/attr_masker/version.rb,
lib/attr_masker/performer.rb,
lib/attr_masker/maskers/simple.rb,
lib/attr_masker/maskers/replacing.rb

Overview

© 2017 Ribose Inc.

Defined Under Namespace

Modules: InstanceMethods, Maskers, Performer, Version Classes: Error, Railtie

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *arguments, &block) ⇒ Object

Forwards calls to :mask_#attribute to the corresponding mask method if attribute was configured with attr_masker

Example

class User
  attr_masker :email
end

User.mask_email('SOME_masker_EMAIL_STRING')


167
168
169
170
171
172
173
# File 'lib/attr_masker.rb', line 167

def method_missing(method, *arguments, &block)
  if method.to_s =~ /^mask_(.+)$/ && attr_masker?($1)
    send(:mask, $1, *arguments)
  else
    super
  end
end

Class Method Details

.extended(base) ⇒ Object

:nodoc:



17
18
19
20
21
22
23
24
25
# File 'lib/attr_masker.rb', line 17

def self.extended(base) # :nodoc:
  base.class_eval do

    # Only include the dangerous instance methods during the Rake task!
    include InstanceMethods
    attr_writer :attr_masker_options
    @attr_masker_options, @masker_attributes = {}, {}
  end
end

Instance Method Details

#attr_masker(*attributes) ⇒ Object

Generates attr_accessors that mask attributes transparently

Options (any other options you specify are passed to the masker’s mask methods)

:marshal          => If set to true, attributes will be marshaled as well as masker. This is useful if you're planning
                     on masking something other than a string. Defaults to false unless you're using it with ActiveRecord
                     or DataMapper.

:marshaler        => The object to use for marshaling. Defaults to Marshal.

:dump_method      => The dump method name to call on the <tt>:marshaler</tt> object to. Defaults to 'dump'.

:load_method      => The load method name to call on the <tt>:marshaler</tt> object. Defaults to 'load'.

:masker           => The object to use for masking. It must respond to +#mask+. Defaults to AttrMasker::Maskers::Simple.

:if               => Attributes are only masker if this option evaluates to true. If you pass a symbol representing an instance
                     method then the result of the method will be evaluated. Any objects that respond to <tt>:call</tt> are evaluated as well.
                     Defaults to true.

:unless           => Attributes are only masker if this option evaluates to false. If you pass a symbol representing an instance
                     method then the result of the method will be evaluated. Any objects that respond to <tt>:call</tt> are evaluated as well.
                     Defaults to false.

You can specify your own default options

class User
  # now all attributes will be encoded and marshaled by default
  attr_masker_options.merge!(:marshal => true, :some_other_option => true)
  attr_masker :configuration
end

Example

class User
  attr_masker :email, :credit_card
  attr_masker :configuration, :marshal => true
end

@user = User.new
@user.masker_email # nil
@user.email? # false
@user.email = '[email protected]'
@user.email? # true
@user.masker_email # returns the masker version of '[email protected]'

@user.configuration = { :time_zone => 'UTC' }
@user.masker_configuration # returns the masker version of configuration

See README for more examples


79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/attr_masker.rb', line 79

def attr_masker(*attributes)
  options = {
    :if               => true,
    :unless           => false,
    :column_name      => nil,
    :marshal          => false,
    :marshaler        => Marshal,
    :dump_method      => "dump",
    :load_method      => "load",
    :masker           => AttrMasker::Maskers::SIMPLE,
  }.merge!(attr_masker_options).merge!(attributes.last.is_a?(Hash) ? attributes.pop : {})

  attributes.each do |attribute|
    masker_attributes[attribute.to_sym] = options.merge(attribute: attribute.to_sym)
  end
end

#attr_masker?(attribute) ⇒ Boolean

Checks if an attribute is configured with attr_masker XXX:Keep

Example

class User
  attr_accessor :name
  attr_masker :email
end

User.attr_masker?(:name)  # false
User.attr_masker?(:email) # true

Returns:

  • (Boolean)


116
117
118
# File 'lib/attr_masker.rb', line 116

def attr_masker?(attribute)
  masker_attributes.has_key?(attribute.to_sym)
end

#attr_masker_optionsObject

Default options to use with calls to attr_masker XXX:Keep

It will inherit existing options from its superclass



100
101
102
# File 'lib/attr_masker.rb', line 100

def attr_masker_options
  @attr_masker_options ||= superclass.attr_masker_options.dup
end

#mask(attribute, value, options = {}) ⇒ Object

masks a value for the attribute specified XXX:modify

Example

class User
  attr_masker :email
end

masker_email = User.mask(:email, '[email protected]')


130
131
132
133
134
135
136
137
138
139
140
# File 'lib/attr_masker.rb', line 130

def mask(attribute, value, options = {})
  options = masker_attributes[attribute.to_sym].merge(options)
  # if options[:if] && !options[:unless] && !value.nil? && !(value.is_a?(String) && value.empty?)
  if options[:if] && !options[:unless]
    value = options[:marshal] ? options[:marshaler].send(options[:dump_method], value) : value.to_s
    masker_value = options[:masker].call(options.merge!(value: value))
    masker_value
  else
    value
  end
end

#masker_attributesObject

Contains a hash of masker attributes with virtual attribute names as keys and their corresponding options as values XXX:Keep

Example

class User
  attr_masker :email
end

User.masker_attributes # { :email => { :attribute => 'masker_email' } }


153
154
155
# File 'lib/attr_masker.rb', line 153

def masker_attributes
  @masker_attributes ||= superclass.masker_attributes.dup
end