Class: ActiveSupport::ParameterFilter

Inherits:
Object
  • Object
show all
Defined in:
lib/active_support/parameter_filter.rb

Overview

Active Support Parameter Filter

ParameterFilter replaces values in a Hash-like object if their keys match one of the specified filters.

Matching based on nested keys is possible by using dot notation, e.g. "credit_card.number".

If a proc is given as a filter, each key and value of the Hash-like and of any nested Hashes will be passed to it. The value or key can then be mutated as desired using methods such as String#replace.

# Replaces values with "[FILTERED]" for keys that match /password/i.
ActiveSupport::ParameterFilter.new([:password])

# Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
ActiveSupport::ParameterFilter.new([:foo, "bar"])

# Replaces values for the exact key "pin" and for keys that begin with
# "pin_". Does not match keys that otherwise include "pin" as a
# substring, such as "shipping_id".
ActiveSupport::ParameterFilter.new([/\Apin\z/, /\Apin_/])

# Replaces the value for :code in `{ credit_card: { code: "xxxx" } }`.
# Does not change `{ file: { code: "xxxx" } }`.
ActiveSupport::ParameterFilter.new(["credit_card.code"])

# Reverses values for keys that match /secret/i.
ActiveSupport::ParameterFilter.new([-> (k, v) do
  v.reverse! if /secret/i.match?(k)
end])

Constant Summary collapse

FILTERED =

:nodoc:

"[FILTERED]"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filters = [], mask: FILTERED) ⇒ ParameterFilter

Create instance with given filters. Supported type of filters are String, Regexp, and Proc. Other types of filters are treated as String using to_s. For Proc filters, key, value, and optional original hash is passed to block arguments.

Options

  • :mask - A replaced object when filtered. Defaults to "[FILTERED]".



77
78
79
80
# File 'lib/active_support/parameter_filter.rb', line 77

def initialize(filters = [], mask: FILTERED)
  @mask = mask
  compile_filters!(filters)
end

Class Method Details

.precompile_filters(filters) ⇒ Object

Precompiles an array of filters that otherwise would be passed directly to #initialize. Depending on the quantity and types of filters, precompilation can improve filtering performance, especially in the case where the ParameterFilter instance itself cannot be retained (but the precompiled filters can be retained).

filters = [/foo/, :bar, "nested.baz", /nested\.qux/]

precompiled = ActiveSupport::ParameterFilter.precompile_filters(filters)
# => [/(?-mix:foo)|(?i:bar)/, /(?i:nested\.baz)|(?-mix:nested\.qux)/]

ActiveSupport::ParameterFilter.new(precompiled)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/active_support/parameter_filter.rb', line 55

def self.precompile_filters(filters)
  filters, patterns = filters.partition { |filter| filter.is_a?(Proc) }

  patterns.map! do |pattern|
    pattern.is_a?(Regexp) ? pattern : "(?i:#{Regexp.escape pattern.to_s})"
  end

  deep_patterns = patterns.extract! { |pattern| pattern.to_s.include?("\\.") }

  filters << Regexp.new(patterns.join("|")) if patterns.any?
  filters << Regexp.new(deep_patterns.join("|")) if deep_patterns.any?

  filters
end

Instance Method Details

#filter(params) ⇒ Object

Mask value of params if key matches one of filters.



83
84
85
# File 'lib/active_support/parameter_filter.rb', line 83

def filter(params)
  @no_filters ? params.dup : call(params)
end

#filter_param(key, value) ⇒ Object

Returns filtered value for given key. For Proc filters, third block argument is not populated.



88
89
90
# File 'lib/active_support/parameter_filter.rb', line 88

def filter_param(key, value)
  @no_filters ? value : value_for_key(key, value)
end