Class: ActiveSupport::ParameterFilter
Relationships & Source Files | |
Inherits: | Object |
Defined in: | activesupport/lib/active_support/parameter_filter.rb |
Overview
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 ::Hash
es 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
-
FILTERED =
Internal use only
# File 'activesupport/lib/active_support/parameter_filter.rb', line 40"[FILTERED]"
Class Method Summary
-
.new(filters = [], mask: FILTERED) ⇒ ParameterFilter
constructor
Create instance with given filters.
-
.precompile_filters(filters)
Precompiles an array of filters that otherwise would be passed directly to
#initialize
.
Instance Method Summary
-
#filter(params)
Mask value of
params
if key matches one of filters. -
#filter_param(key, value)
Returns filtered value for given key.
- #call(params, full_parent_key = nil, original_params = params) private
- #compile_filters!(filters) private
- #value_for_key(key, value, full_parent_key = nil, original_params = nil) private
Constructor Details
.new(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]"
.
# File 'activesupport/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)
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/, :, "nested.baz", /nested\.qux/]
precompiled = ActiveSupport::ParameterFilter.precompile_filters(filters)
# => [/(?-mix:foo)|(?i:bar)/, /(?i:nested\.baz)|(?-mix:nested\.qux)/]
ActiveSupport::ParameterFilter.new(precompiled)
# File 'activesupport/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
#call(params, full_parent_key = nil, original_params = params) (private)
[ GitHub ]# File 'activesupport/lib/active_support/parameter_filter.rb', line 125
def call(params, full_parent_key = nil, original_params = params) filtered_params = params.class.new params.each do |key, value| filtered_params[key] = value_for_key(key, value, full_parent_key, original_params) end filtered_params end
#compile_filters!(filters) (private)
[ GitHub ]# File 'activesupport/lib/active_support/parameter_filter.rb', line 93
def compile_filters!(filters) @no_filters = filters.empty? return if @no_filters @regexps, strings = [], [] @deep_regexps, deep_strings = nil, nil @blocks = nil filters.each do |item| case item when Proc (@blocks ||= []) << item when Regexp if item.to_s.include?("\\.") (@deep_regexps ||= []) << item else @regexps << item end else s = Regexp.escape(item.to_s) if s.include?("\\.") (deep_strings ||= []) << s else strings << s end end end @regexps << Regexp.new(strings.join("|"), true) unless strings.empty? (@deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings end
#filter(params)
Mask value of params
if key matches one of filters.
# File 'activesupport/lib/active_support/parameter_filter.rb', line 83
def filter(params) @no_filters ? params.dup : call(params) end
#filter_param(key, value)
Returns filtered value for given key. For Proc
filters, third block argument is not populated.
# File 'activesupport/lib/active_support/parameter_filter.rb', line 88
def filter_param(key, value) @no_filters ? value : value_for_key(key, value) end
#value_for_key(key, value, full_parent_key = nil, original_params = nil) (private)
[ GitHub ]# File 'activesupport/lib/active_support/parameter_filter.rb', line 135
def value_for_key(key, value, full_parent_key = nil, original_params = nil) if @deep_regexps full_key = full_parent_key ? "#{full_parent_key}.#{key}" : key.to_s end if @regexps.any? { |r| r.match?(key.to_s) } value = @mask elsif @deep_regexps&.any? { |r| r.match?(full_key) } value = @mask elsif value.is_a?(Hash) value = call(value, full_key, original_params) elsif value.is_a?(Array) value = value.map { |v| value_for_key(key, v, full_parent_key, original_params) } elsif @blocks key = key.dup if key.duplicable? value = value.dup if value.duplicable? @blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) } end value end