1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #13897 from gmalette/nested-parameter-filtering-2

Allow filtering params based on parent keys
This commit is contained in:
Arthur Nogueira Neves 2015-07-06 16:33:01 +02:00
commit e598967548
3 changed files with 28 additions and 7 deletions

View file

@ -1,3 +1,13 @@
* Add ability to filter parameters based on parent keys.
# matches {credit_card: {code: "xxxx"}}
# doesn't match {file: { code: "xxxx"}}
config.filter_parameters += [ "credit_card.code" ]
See #13897.
*Guillaume Malette*
* Deprecate passing first parameter as `Hash` and default status code for `head` method. * Deprecate passing first parameter as `Hash` and default status code for `head` method.
*Mehmet Emin İNAÇ* *Mehmet Emin İNAÇ*

View file

@ -30,36 +30,46 @@ module ActionDispatch
when Regexp when Regexp
regexps << item regexps << item
else else
strings << item.to_s strings << Regexp.escape(item.to_s)
end end
end end
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.") }
deep_strings, strings = strings.partition { |s| s.include?("\\.") }
regexps << Regexp.new(strings.join('|'), true) unless strings.empty? regexps << Regexp.new(strings.join('|'), true) unless strings.empty?
new regexps, blocks deep_regexps << Regexp.new(deep_strings.join('|'), true) unless deep_strings.empty?
new regexps, deep_regexps, blocks
end end
attr_reader :regexps, :blocks attr_reader :regexps, :deep_regexps, :blocks
def initialize(regexps, blocks) def initialize(regexps, deep_regexps, blocks)
@regexps = regexps @regexps = regexps
@deep_regexps = deep_regexps.any? ? deep_regexps : nil
@blocks = blocks @blocks = blocks
end end
def call(original_params) def call(original_params, parents = [])
filtered_params = {} filtered_params = {}
original_params.each do |key, value| original_params.each do |key, value|
parents.push(key) if deep_regexps
if regexps.any? { |r| key =~ r } if regexps.any? { |r| key =~ r }
value = FILTERED value = FILTERED
elsif deep_regexps && (joined = parents.join('.')) && deep_regexps.any? { |r| joined =~ r }
value = FILTERED
elsif value.is_a?(Hash) elsif value.is_a?(Hash)
value = call(value) value = call(value, parents)
elsif value.is_a?(Array) elsif value.is_a?(Array)
value = value.map { |v| v.is_a?(Hash) ? call(v) : v } value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v }
elsif blocks.any? elsif blocks.any?
key = key.dup if key.duplicable? key = key.dup if key.duplicable?
value = value.dup if value.duplicable? value = value.dup if value.duplicable?
blocks.each { |b| b.call(key, value) } blocks.each { |b| b.call(key, value) }
end end
parents.pop if deep_regexps
filtered_params[key] = value filtered_params[key] = value
end end

View file

@ -989,6 +989,7 @@ class RequestParameterFilter < BaseRequestTest
[{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'], [{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'],
[{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'], [{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'],
[{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana'], [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana'],
[{'deep'=>{'cc'=>{'code'=>'bar','bar'=>'foo'},'ss'=>{'code'=>'bar'}}},{'deep'=>{'cc'=>{'code'=>'[FILTERED]','bar'=>'foo'},'ss'=>{'code'=>'bar'}}},%w'deep.cc.code'],
[{'baz'=>[{'foo'=>'baz'}, "1"]}, {'baz'=>[{'foo'=>'[FILTERED]'}, "1"]}, [/foo/]]] [{'baz'=>[{'foo'=>'baz'}, "1"]}, {'baz'=>[{'foo'=>'[FILTERED]'}, "1"]}, [/foo/]]]
test_hashes.each do |before_filter, after_filter, filter_words| test_hashes.each do |before_filter, after_filter, filter_words|