Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brynary/481956 to your computer and use it in GitHub Desktop.
Save brynary/481956 to your computer and use it in GitHub Desktop.
From cdad3390406d7bf4b70c53122e622f877557861f Mon Sep 17 00:00:00 2001
From: Bryan Helmkamp <bryan@brynary.com>
Date: Mon, 19 Jul 2010 13:33:26 -0700
Subject: [PATCH] Extract ParameterFilter class from FilterParameters mixin
---
actionpack/lib/action_dispatch.rb | 1 +
.../lib/action_dispatch/http/filter_parameters.rb | 73 +++-----------------
.../lib/action_dispatch/http/parameter_filter.rb | 72 +++++++++++++++++++
actionpack/test/dispatch/request_test.rb | 8 +-
4 files changed, 86 insertions(+), 68 deletions(-)
create mode 100644 actionpack/lib/action_dispatch/http/parameter_filter.rb
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index cdf81c6..1da4a0d 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -63,6 +63,7 @@ module ActionDispatch
autoload :Headers
autoload :MimeNegotiation
autoload :Parameters
+ autoload :ParameterFilter
autoload :FilterParameters
autoload :Upload
autoload :UploadedFile, 'action_dispatch/http/upload'
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb
index 47643ce..1ab48ae 100644
--- a/actionpack/lib/action_dispatch/http/filter_parameters.rb
+++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb
@@ -26,85 +26,30 @@ module ActionDispatch
module FilterParameters
extend ActiveSupport::Concern
- @@compiled_parameter_filter_for = {}
+ @@parameter_filter_for = {}
# Return a hash of parameters with all sensitive data replaced.
def filtered_parameters
- @filtered_parameters ||= if filtering_parameters?
- process_parameter_filter(parameters)
- else
- parameters.dup
- end
+ @filtered_parameters ||= parameter_filter.filter(parameters)
end
# Return a hash of request.env with all sensitive data replaced.
def filtered_env
- filtered_env = @env.dup
- filtered_env.each do |key, value|
- if (key =~ /RAW_POST_DATA/i)
- filtered_env[key] = '[FILTERED]'
- elsif value.is_a?(Hash)
- filtered_env[key] = process_parameter_filter(value)
- end
- end
- filtered_env
+ @filtered_env ||= env_filter.filter(@env)
end
protected
- def filtering_parameters? #:nodoc:
- @env["action_dispatch.parameter_filter"].present?
+ def parameter_filter
+ parameter_filter_for(@env["action_dispatch.parameter_filter"])
end
- def process_parameter_filter(params) #:nodoc:
- compiled_parameter_filter_for(@env["action_dispatch.parameter_filter"]).call(params)
+ def env_filter
+ parameter_filter_for(Array.wrap(@env["action_dispatch.parameter_filter"]) << /RAW_POST_DATA/)
end
- def compile_parameter_filter(filters) #:nodoc:
- strings, regexps, blocks = [], [], []
-
- filters.each do |item|
- case item
- when NilClass
- when Proc
- blocks << item
- when Regexp
- regexps << item
- else
- strings << item.to_s
- end
- end
-
- regexps << Regexp.new(strings.join('|'), true) unless strings.empty?
- [regexps, blocks]
- end
-
- def compiled_parameter_filter_for(filters) #:nodoc:
- @@compiled_parameter_filter_for[filters] ||= begin
- regexps, blocks = compile_parameter_filter(filters)
-
- lambda do |original_params|
- filtered_params = {}
-
- original_params.each do |key, value|
- if regexps.find { |r| key =~ r }
- value = '[FILTERED]'
- elsif value.is_a?(Hash)
- value = process_parameter_filter(value)
- elsif value.is_a?(Array)
- value = value.map { |v| v.is_a?(Hash) ? process_parameter_filter(v) : v }
- elsif blocks.present?
- key = key.dup
- value = value.dup if value.duplicable?
- blocks.each { |b| b.call(key, value) }
- end
-
- filtered_params[key] = value
- end
-
- filtered_params
- end
- end
+ def parameter_filter_for(filters)
+ @@parameter_filter_for[filters] ||= ParameterFilter.new(filters)
end
end
diff --git a/actionpack/lib/action_dispatch/http/parameter_filter.rb b/actionpack/lib/action_dispatch/http/parameter_filter.rb
new file mode 100644
index 0000000..1480e8f
--- /dev/null
+++ b/actionpack/lib/action_dispatch/http/parameter_filter.rb
@@ -0,0 +1,72 @@
+module ActionDispatch
+ module Http
+ class ParameterFilter
+
+ def initialize(filters)
+ @filters = filters
+ end
+
+ def filter(params)
+ if enabled?
+ compiled_filter.call(params)
+ else
+ params.dup
+ end
+ end
+
+ private
+
+ def enabled?
+ @filters.present?
+ end
+
+ def compiled_filter
+ @compiled_filter ||= begin
+ regexps, blocks = compile_filter
+
+ lambda do |original_params|
+ filtered_params = {}
+
+ original_params.each do |key, value|
+ if regexps.find { |r| key =~ r }
+ value = '[FILTERED]'
+ elsif value.is_a?(Hash)
+ value = filter(value)
+ elsif value.is_a?(Array)
+ value = value.map { |v| v.is_a?(Hash) ? filter(v) : v }
+ elsif blocks.present?
+ key = key.dup
+ value = value.dup if value.duplicable?
+ blocks.each { |b| b.call(key, value) }
+ end
+
+ filtered_params[key] = value
+ end
+
+ filtered_params
+ end
+ end
+ end
+
+ def compile_filter
+ strings, regexps, blocks = [], [], []
+
+ @filters.each do |item|
+ case item
+ when NilClass
+ when Proc
+ blocks << item
+ when Regexp
+ regexps << item
+ else
+ strings << item.to_s
+ end
+ end
+
+ regexps << Regexp.new(strings.join('|'), true) unless strings.empty?
+ [regexps, blocks]
+ end
+
+ end
+ end
+end
diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb
index e5ee412..c8947aa 100644
--- a/actionpack/test/dispatch/request_test.rb
+++ b/actionpack/test/dispatch/request_test.rb
@@ -392,19 +392,19 @@ class RequestTest < ActiveSupport::TestCase
[{'baz'=>[{'foo'=>'baz'}, "1"]}, {'baz'=>[{'foo'=>'[FILTERED]'}, "1"]}, [/foo/]]]
test_hashes.each do |before_filter, after_filter, filter_words|
- request = stub_request('action_dispatch.parameter_filter' => filter_words)
- assert_equal after_filter, request.send(:process_parameter_filter, before_filter)
+ parameter_filter = ActionDispatch::Http::ParameterFilter.new(filter_words)
+ assert_equal after_filter, parameter_filter.filter(before_filter)
filter_words << 'blah'
filter_words << lambda { |key, value|
value.reverse! if key =~ /bargain/
}
- request = stub_request('action_dispatch.parameter_filter' => filter_words)
+ parameter_filter = ActionDispatch::Http::ParameterFilter.new(filter_words)
before_filter['barg'] = {'bargain'=>'gain', 'blah'=>'bar', 'bar'=>{'bargain'=>{'blah'=>'foo'}}}
after_filter['barg'] = {'bargain'=>'niag', 'blah'=>'[FILTERED]', 'bar'=>{'bargain'=>{'blah'=>'[FILTERED]'}}}
- assert_equal after_filter, request.send(:process_parameter_filter, before_filter)
+ assert_equal after_filter, parameter_filter.filter(before_filter)
end
end
--
1.7.1.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment