aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r--actionpack/lib/action_dispatch/http/filter_parameters.rb98
-rw-r--r--actionpack/lib/action_dispatch/http/parameters.rb23
-rwxr-xr-xactionpack/lib/action_dispatch/http/request.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/notifications.rb32
-rw-r--r--actionpack/lib/action_dispatch/railtie.rb3
-rw-r--r--actionpack/lib/action_dispatch/railties/subscriber.rb17
6 files changed, 99 insertions, 75 deletions
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb
new file mode 100644
index 0000000000..1958e1668d
--- /dev/null
+++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb
@@ -0,0 +1,98 @@
+require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/hash/keys'
+
+module ActionDispatch
+ module Http
+ # Allows you to specify sensitive parameters which will be replaced from
+ # the request log by looking in all subhashes of the param hash for keys
+ # to filter. If a block is given, each key and value of the parameter
+ # hash and all subhashes is passed to it, the value or key can be replaced
+ # using String#replace or similar method.
+ #
+ # Examples:
+ #
+ # env["action_dispatch.parameter_filter"] = [:password]
+ # => replaces the value to all keys matching /password/i with "[FILTERED]"
+ #
+ # env["action_dispatch.parameter_filter"] = [:foo, "bar"]
+ # => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
+ #
+ # env["action_dispatch.parameter_filter"] = lambda do |k,v|
+ # v.reverse! if k =~ /secret/i
+ # end
+ # => reverses the value to all keys matching /secret/i
+ #
+ module FilterParameters
+ extend ActiveSupport::Concern
+
+ # Return a hash of parameters with all sensitive data replaced.
+ def filtered_parameters
+ @filtered_parameters ||= process_parameter_filter(parameters)
+ end
+ alias :fitered_params :filtered_parameters
+
+ # 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
+ end
+
+ protected
+
+ def compile_parameter_filter #:nodoc:
+ strings, regexps, blocks = [], [], []
+
+ Array(@env["action_dispatch.parameter_filter"]).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 filtering_parameters? #:nodoc:
+ @env["action_dispatch.parameter_filter"].present?
+ end
+
+ def process_parameter_filter(original_params) #:nodoc:
+ return original_params.dup unless filtering_parameters?
+
+ filtered_params = {}
+ regexps, blocks = compile_parameter_filter
+
+ 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 { |i| process_parameter_filter(i) }
+ 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
+end \ No newline at end of file
diff --git a/actionpack/lib/action_dispatch/http/parameters.rb b/actionpack/lib/action_dispatch/http/parameters.rb
index 68ba3637bf..40b40ea94e 100644
--- a/actionpack/lib/action_dispatch/http/parameters.rb
+++ b/actionpack/lib/action_dispatch/http/parameters.rb
@@ -30,29 +30,6 @@ module ActionDispatch
@env["action_dispatch.request.path_parameters"] ||= {}
end
- def filter_parameters
- # TODO: Remove dependency on controller
- if controller = @env['action_controller.instance']
- controller.send(:filter_parameters, params)
- else
- params
- end
- end
-
- def filter_env
- if controller = @env['action_controller.instance']
- @env.map do |key, value|
- if (key =~ /RAW_POST_DATA/i)
- '[FILTERED]'
- else
- controller.send(:filter_parameters, {key => value}).values[0]
- end
- end
- else
- env
- end
- end
-
private
# Convert nested Hashs to HashWithIndifferentAccess
def normalize_parameters(value)
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 187ce7c15d..7a17023ed2 100755
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -11,6 +11,7 @@ module ActionDispatch
include ActionDispatch::Http::Cache::Request
include ActionDispatch::Http::MimeNegotiation
include ActionDispatch::Http::Parameters
+ include ActionDispatch::Http::FilterParameters
include ActionDispatch::Http::Upload
include ActionDispatch::Http::URL
diff --git a/actionpack/lib/action_dispatch/middleware/notifications.rb b/actionpack/lib/action_dispatch/middleware/notifications.rb
deleted file mode 100644
index ce3732b740..0000000000
--- a/actionpack/lib/action_dispatch/middleware/notifications.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-module ActionDispatch
- # Provide notifications in the middleware stack. Notice that for the before_dispatch
- # and after_dispatch notifications, we just send the original env, so we don't pile
- # up large env hashes in the queue. However, in exception cases, the whole env hash
- # is actually useful, so we send it all.
- class Notifications
- def initialize(app)
- @app = app
- end
-
- def call(env)
- request = Request.new(env)
- payload = retrieve_payload_from_env(request.filter_env)
-
- ActiveSupport::Notifications.instrument("action_dispatch.before_dispatch", payload)
-
- ActiveSupport::Notifications.instrument!("action_dispatch.after_dispatch", payload) do
- @app.call(env)
- end
- rescue Exception => exception
- ActiveSupport::Notifications.instrument('action_dispatch.exception',
- :env => env, :exception => exception)
- raise exception
- end
-
- protected
- # Remove any rack related constants from the env, like rack.input.
- def retrieve_payload_from_env(env)
- Hash[:env => env.except(*env.keys.select { |k| k.to_s.index("rack.") == 0 })]
- end
- end
-end
diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb
index 18978bfb39..e4bd143e78 100644
--- a/actionpack/lib/action_dispatch/railtie.rb
+++ b/actionpack/lib/action_dispatch/railtie.rb
@@ -5,9 +5,6 @@ module ActionDispatch
class Railtie < Rails::Railtie
plugin_name :action_dispatch
- require "action_dispatch/railties/subscriber"
- subscriber ActionDispatch::Railties::Subscriber.new
-
# Prepare dispatcher callbacks and run 'prepare' callbacks
initializer "action_dispatch.prepare_dispatcher" do |app|
# TODO: This used to say unless defined?(Dispatcher). Find out why and fix.
diff --git a/actionpack/lib/action_dispatch/railties/subscriber.rb b/actionpack/lib/action_dispatch/railties/subscriber.rb
deleted file mode 100644
index cdb1162eac..0000000000
--- a/actionpack/lib/action_dispatch/railties/subscriber.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-module ActionDispatch
- module Railties
- class Subscriber < Rails::Subscriber
- def before_dispatch(event)
- request = Request.new(event.payload[:env])
- path = request.request_uri.inspect rescue "unknown"
-
- info "\n\nStarted #{request.method.to_s.upcase} #{path} " <<
- "for #{request.remote_ip} at #{event.time.to_s(:db)}"
- end
-
- def logger
- ActionController::Base.logger
- end
- end
- end
-end \ No newline at end of file