Skip to content

Commit

Permalink
[Action Cable] Add parameter filtering to logging
Browse files Browse the repository at this point in the history
- Reuses most of the architecture that Action Pack uses :)
- Fixes #25088
  • Loading branch information
maclover7 committed Jun 23, 2016
1 parent fa95c8b commit cd7b733
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 2 deletions.
29 changes: 29 additions & 0 deletions actioncable/lib/action_cable/channel/base.rb
@@ -1,4 +1,6 @@
require 'set'
require 'action_dispatch'
require 'action_dispatch/http/filter_parameters'

module ActionCable
module Channel
Expand Down Expand Up @@ -261,9 +263,36 @@ def dispatch_action(action, data)
end
end

# A helper class, with allows for select parameters to be filtered when being outputted.
# Used primarily in ActionCable::Channel::Base#action_signature.
class DataWrapper # :nodoc:
include ActionDispatch::Http::FilterParameters

def initialize(data)
@env = data
end

# If a block is given, it yields to the block if the value hasn't been set.
def fetch_header(name, &block)
@env.fetch(name, &block)
end

def parameters
@env
end

def parameter_filter
@env['action_dispatch.parameter_filter'] || super
end
end

def action_signature(action, data)
"#{self.class.name}##{action}".tap do |signature|
if (arguments = data.except('action')).any?
arguments['action_dispatch.parameter_filter'] ||= []
arguments['action_dispatch.parameter_filter'].concat(connection.server.config.filter_parameters)

arguments = DataWrapper.new(arguments).filtered_env
signature << "(#{arguments.inspect})"
end
end
Expand Down
2 changes: 2 additions & 0 deletions actioncable/lib/action_cable/engine.rb
Expand Up @@ -34,6 +34,8 @@ class Engine < Rails::Engine # :nodoc:
previous_connection_class = self.connection_class
self.connection_class = -> { 'ApplicationCable::Connection'.safe_constantize || previous_connection_class.call }

self.filter_parameters << Rails.application.config.filter_parameters

options.each { |k,v| send("#{k}=", v) }
end
end
Expand Down
3 changes: 2 additions & 1 deletion actioncable/lib/action_cable/server/configuration.rb
Expand Up @@ -5,7 +5,7 @@ module Server
class Configuration
attr_accessor :logger, :log_tags
attr_accessor :use_faye, :connection_class, :worker_pool_size
attr_accessor :disable_request_forgery_protection, :allowed_request_origins
attr_accessor :disable_request_forgery_protection, :allowed_request_origins, :filter_parameters
attr_accessor :cable, :url, :mount_path

def initialize
Expand All @@ -15,6 +15,7 @@ def initialize
@worker_pool_size = 4

@disable_request_forgery_protection = false
@filter_parameters = []
end

# Returns constant of subscription adapter specified in config/cable.yml.
Expand Down
9 changes: 9 additions & 0 deletions actioncable/test/channel/base_test.rb
Expand Up @@ -241,6 +241,15 @@ def rm_rf
end
end

test 'does not log filtered parameters' do
data = { 'action' => :topic, 'content' => "This is Sparta!", 'foo' => 'foo' }
@connection.server.config.filter_parameters << :foo

assert_logged('foo"=>"[FILTERED]"') do
@channel.perform_action data
end
end

private
def assert_logged(message)
old_logger = @connection.logger
Expand Down
2 changes: 1 addition & 1 deletion actioncable/test/stubs/test_server.rb
Expand Up @@ -9,7 +9,7 @@ class TestServer
def initialize(subscription_adapter: SuccessAdapter)
@logger = ActiveSupport::TaggedLogging.new ActiveSupport::Logger.new(StringIO.new)

@config = OpenStruct.new(log_tags: [], subscription_adapter: subscription_adapter)
@config = OpenStruct.new(log_tags: [], subscription_adapter: subscription_adapter, filter_parameters: [])
@config.use_faye = ENV['FAYE'].present?
@config.client_socket_class = if @config.use_faye
ActionCable::Connection::FayeClientSocket
Expand Down

0 comments on commit cd7b733

Please sign in to comment.