rollbar 2.9.1 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +23 -7
- data/CHANGELOG.md +16 -0
- data/README.md +11 -4
- data/gemfiles/rails50.gemfile +47 -0
- data/lib/rollbar.rb +0 -4
- data/lib/rollbar/configuration.rb +6 -0
- data/lib/rollbar/delay/delayed_job.rb +17 -0
- data/lib/rollbar/js/frameworks/rails.rb +21 -1
- data/lib/rollbar/js/middleware.rb +19 -12
- data/lib/rollbar/logger_proxy.rb +2 -0
- data/lib/rollbar/rake.rb +3 -1
- data/lib/rollbar/request_data_extractor.rb +12 -64
- data/lib/rollbar/scrubbers.rb +13 -0
- data/lib/rollbar/scrubbers/params.rb +98 -0
- data/lib/rollbar/sidekiq.rb +8 -1
- data/lib/rollbar/version.rb +1 -1
- data/spec/controllers/home_controller_spec.rb +12 -11
- data/spec/dummyapp/config/secrets.yml +2 -0
- data/spec/requests/home_spec.rb +1 -1
- data/spec/rollbar/delay/delayed_job_spec.rb +22 -0
- data/spec/rollbar/delay/thread_spec.rb +1 -1
- data/spec/rollbar/js/middleware_spec.rb +49 -0
- data/spec/rollbar/logger_proxy_spec.rb +13 -1
- data/spec/rollbar/request_data_extractor_spec.rb +0 -26
- data/spec/rollbar/scrubbers/params_spec.rb +268 -0
- data/spec/rollbar/scrubbers_spec.rb +31 -0
- data/spec/rollbar/sidekiq_spec.rb +23 -2
- data/spec/rollbar_spec.rb +5 -3
- data/spec/spec_helper.rb +7 -0
- data/spec/support/matchers.rb +23 -0
- metadata +15 -2
data/lib/rollbar/scrubbers.rb
CHANGED
@@ -1,4 +1,17 @@
|
|
1
1
|
module Rollbar
|
2
2
|
module Scrubbers
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def scrub_value(value)
|
6
|
+
if Rollbar.configuration.randomize_scrub_length
|
7
|
+
random_filtered_value
|
8
|
+
else
|
9
|
+
'*' * (value.length rescue 8)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def random_filtered_value
|
14
|
+
'*' * (rand(5) + 3)
|
15
|
+
end
|
3
16
|
end
|
4
17
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'rollbar/scrubbers'
|
2
|
+
|
3
|
+
module Rollbar
|
4
|
+
module Scrubbers
|
5
|
+
# This class contains the logic to scrub the receive parameters. It will
|
6
|
+
# scrub the parameters matching Rollbar.configuration.scrub_fields Array.
|
7
|
+
# Also, if that configuration option is se to :scrub_all, it will scrub all
|
8
|
+
# received parameters
|
9
|
+
class Params
|
10
|
+
SKIPPED_CLASSES = [Tempfile]
|
11
|
+
ATTACHMENT_CLASSES = %w(ActionDispatch::Http::UploadedFile Rack::Multipart::UploadedFile).freeze
|
12
|
+
SCRUB_ALL = :scrub_all
|
13
|
+
|
14
|
+
def self.call(*args)
|
15
|
+
new.call(*args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(params, extra_fields = [])
|
19
|
+
return {} unless params
|
20
|
+
|
21
|
+
config = Rollbar.configuration.scrub_fields
|
22
|
+
|
23
|
+
scrub(params, build_scrub_options(config, extra_fields))
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def build_scrub_options(config, extra_fields)
|
29
|
+
ary_config = Array(config)
|
30
|
+
|
31
|
+
{
|
32
|
+
:fields_regex => build_fields_regex(ary_config, extra_fields),
|
33
|
+
:scrub_all => ary_config.include?(SCRUB_ALL)
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def build_fields_regex(config, extra_fields)
|
38
|
+
fields = config.find_all { |f| f.is_a?(String) || f.is_a?(Symbol) }
|
39
|
+
fields += Array(extra_fields)
|
40
|
+
|
41
|
+
return unless fields.any?
|
42
|
+
|
43
|
+
Regexp.new(fields.map { |val| Regexp.escape(val.to_s).to_s }.join('|'), true)
|
44
|
+
end
|
45
|
+
|
46
|
+
def scrub(params, options)
|
47
|
+
fields_regex = options[:fields_regex]
|
48
|
+
scrub_all = options[:scrub_all]
|
49
|
+
|
50
|
+
params.to_hash.inject({}) do |result, (key, value)|
|
51
|
+
if value.is_a?(Hash)
|
52
|
+
result[key] = scrub(value, options)
|
53
|
+
elsif value.is_a?(Array)
|
54
|
+
result[key] = scrub_array(value, options)
|
55
|
+
elsif skip_value?(value)
|
56
|
+
result[key] = "Skipped value of class '#{value.class.name}'"
|
57
|
+
elsif fields_regex && fields_regex =~ Rollbar::Encoding.encode(key).to_s || scrub_all
|
58
|
+
result[key] = Rollbar::Scrubbers.scrub_value(value)
|
59
|
+
else
|
60
|
+
result[key] = rollbar_filtered_param_value(value)
|
61
|
+
end
|
62
|
+
|
63
|
+
result
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def scrub_array(array, options)
|
68
|
+
array.map do |value|
|
69
|
+
value.is_a?(Hash) ? scrub(value, options) : rollbar_filtered_param_value(value)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def rollbar_filtered_param_value(value)
|
74
|
+
if ATTACHMENT_CLASSES.include?(value.class.name)
|
75
|
+
begin
|
76
|
+
attachment_value(value)
|
77
|
+
rescue
|
78
|
+
'Uploaded file'
|
79
|
+
end
|
80
|
+
else
|
81
|
+
value
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def attachment_value(value)
|
86
|
+
{
|
87
|
+
:content_type => value.content_type,
|
88
|
+
:original_filename => value.original_filename,
|
89
|
+
:size => value.tempfile.size
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
93
|
+
def skip_value?(value)
|
94
|
+
SKIPPED_CLASSES.any? { |klass| value.is_a?(klass) }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/rollbar/sidekiq.rb
CHANGED
@@ -16,7 +16,14 @@ module Rollbar
|
|
16
16
|
return if skip_report?(msg_or_context, e)
|
17
17
|
|
18
18
|
params = msg_or_context.reject{ |k| PARAM_BLACKLIST.include?(k) }
|
19
|
-
scope = {
|
19
|
+
scope = {
|
20
|
+
:request => { :params => params },
|
21
|
+
:framework => "Sidekiq: #{::Sidekiq::VERSION}"
|
22
|
+
}
|
23
|
+
if params.is_a?(Hash)
|
24
|
+
scope[:context] = params['class']
|
25
|
+
scope[:queue] = params['queue']
|
26
|
+
end
|
20
27
|
|
21
28
|
Rollbar.scope(scope).error(e, :use_exception_level_filters => true)
|
22
29
|
end
|
data/lib/rollbar/version.rb
CHANGED
@@ -258,7 +258,7 @@ describe HomeController do
|
|
258
258
|
it "should raise a NameError and have PUT params in the reported exception" do
|
259
259
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
260
260
|
|
261
|
-
put '/report_exception', :putparam => "putval"
|
261
|
+
put '/report_exception', { :putparam => "putval" }
|
262
262
|
|
263
263
|
Rollbar.last_report.should_not be_nil
|
264
264
|
Rollbar.last_report[:request][:params]["putparam"].should == "putval"
|
@@ -268,7 +268,7 @@ describe HomeController do
|
|
268
268
|
it 'reports the errors successfully' do
|
269
269
|
logger_mock.should_receive(:info).with('[Rollbar] Success')
|
270
270
|
|
271
|
-
put '/deprecated_report_exception', :putparam => "putval"
|
271
|
+
put '/deprecated_report_exception', { :putparam => "putval" }
|
272
272
|
|
273
273
|
Rollbar.last_report.should_not be_nil
|
274
274
|
Rollbar.last_report[:request][:params]["putparam"].should == "putval"
|
@@ -291,7 +291,7 @@ describe HomeController do
|
|
291
291
|
it "should raise an uncaught exception and report a message" do
|
292
292
|
logger_mock.should_receive(:info).with('[Rollbar] Success').once
|
293
293
|
|
294
|
-
expect { get '/cause_exception' }.to raise_exception
|
294
|
+
expect { get '/cause_exception' }.to raise_exception(NameError)
|
295
295
|
end
|
296
296
|
|
297
297
|
context 'show_exceptions' do
|
@@ -338,7 +338,7 @@ describe HomeController do
|
|
338
338
|
before { cookies[:session_id] = user.id }
|
339
339
|
|
340
340
|
it 'sends the current user data' do
|
341
|
-
put '/report_exception', 'foo' => 'bar'
|
341
|
+
put '/report_exception', { 'foo' => 'bar' }
|
342
342
|
|
343
343
|
person_data = Rollbar.last_report[:person]
|
344
344
|
|
@@ -352,7 +352,7 @@ describe HomeController do
|
|
352
352
|
|
353
353
|
context 'with routing errors', :type => :request do
|
354
354
|
it 'raises a RoutingError exception' do
|
355
|
-
expect { get '/foo/bar', :foo => :bar }.to raise_exception
|
355
|
+
expect { get '/foo/bar', { :foo => :bar } }.to raise_exception(ActionController::RoutingError)
|
356
356
|
|
357
357
|
report = Rollbar.last_report
|
358
358
|
expect(report[:request][:params]['foo']).to be_eql('bar')
|
@@ -365,7 +365,7 @@ describe HomeController do
|
|
365
365
|
|
366
366
|
expect do
|
367
367
|
expect(controller.send(:rollbar_request_data)[:user_ip]).to be_nil
|
368
|
-
end.not_to raise_exception
|
368
|
+
end.not_to raise_exception
|
369
369
|
end
|
370
370
|
end
|
371
371
|
|
@@ -375,7 +375,7 @@ describe HomeController do
|
|
375
375
|
|
376
376
|
context 'with a single upload' do
|
377
377
|
it "saves attachment data" do
|
378
|
-
expect { post '/file_upload', :upload => file1 }.to raise_exception
|
378
|
+
expect { post '/file_upload', { :upload => file1 } }.to raise_exception(NameError)
|
379
379
|
|
380
380
|
upload_param = Rollbar.last_report[:request][:params]['upload']
|
381
381
|
|
@@ -390,7 +390,7 @@ describe HomeController do
|
|
390
390
|
|
391
391
|
context 'with multiple uploads', :type => :request do
|
392
392
|
it "saves attachment data for all uploads" do
|
393
|
-
expect { post '/file_upload', :upload => [file1, file2] }.to raise_exception
|
393
|
+
expect { post '/file_upload', { :upload => [file1, file2] } }.to raise_exception(NameError)
|
394
394
|
sent_params = Rollbar.last_report[:request][:params]['upload']
|
395
395
|
|
396
396
|
expect(sent_params).to be_kind_of(Array)
|
@@ -401,8 +401,9 @@ describe HomeController do
|
|
401
401
|
|
402
402
|
context 'with session data', :type => :request do
|
403
403
|
before { get '/set_session_data' }
|
404
|
+
|
404
405
|
it 'reports the session data' do
|
405
|
-
expect { get '/use_session_data' }.to raise_exception
|
406
|
+
expect { get '/use_session_data' }.to raise_exception(NoMethodError)
|
406
407
|
|
407
408
|
session_data = Rollbar.last_report[:request][:session]
|
408
409
|
|
@@ -416,7 +417,7 @@ describe HomeController do
|
|
416
417
|
it 'parses the correct headers' do
|
417
418
|
expect do
|
418
419
|
post '/cause_exception', params, { 'ACCEPT' => 'application/vnd.github.v3+json' }
|
419
|
-
end.to raise_exception
|
420
|
+
end.to raise_exception(NameError)
|
420
421
|
|
421
422
|
expect(Rollbar.last_report[:request][:params]['foo']).to be_eql('bar')
|
422
423
|
end
|
@@ -438,7 +439,7 @@ describe HomeController do
|
|
438
439
|
end
|
439
440
|
|
440
441
|
it 'scrubs sensible data from URL' do
|
441
|
-
expect { get '/cause_exception', { :password => 'my-secret-password' }, headers }.to raise_exception
|
442
|
+
expect { get '/cause_exception', { :password => 'my-secret-password' }, headers }.to raise_exception(NameError)
|
442
443
|
|
443
444
|
request_data = Rollbar.last_report[:request]
|
444
445
|
|
data/spec/requests/home_spec.rb
CHANGED
@@ -37,7 +37,7 @@ describe HomeController do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
it "should report uncaught exceptions" do
|
40
|
-
expect { get '/current_user' }.to raise_exception
|
40
|
+
expect { get '/current_user' }.to raise_exception(NoMethodError)
|
41
41
|
|
42
42
|
body = Rollbar.last_report[:body]
|
43
43
|
trace = body[:trace] && body[:trace] || body[:trace_chain][0]
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'delayed_job'
|
4
|
+
require 'delayed/worker'
|
5
|
+
require 'rollbar/delay/delayed_job'
|
6
|
+
require 'delayed/backend/test'
|
7
|
+
|
8
|
+
describe Rollbar::Delay::DelayedJob do
|
9
|
+
before do
|
10
|
+
Delayed::Backend::Test.prepare_worker
|
11
|
+
Delayed::Worker.backend = :test
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '.call' do
|
15
|
+
let(:payload) { {} }
|
16
|
+
it 'calls Rollbar' do
|
17
|
+
expect(Rollbar).to receive(:process_from_async_handler).with(payload)
|
18
|
+
|
19
|
+
Rollbar::Delay::DelayedJob.call(payload)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -22,6 +22,11 @@ describe Rollbar::Js::Middleware do
|
|
22
22
|
<h1>Testing the middleware</h1>
|
23
23
|
</body>
|
24
24
|
</html>
|
25
|
+
END
|
26
|
+
end
|
27
|
+
let(:minified_html) do
|
28
|
+
<<-END
|
29
|
+
<html><head><link rel="stylesheet" href="url" type="text/css" media="screen" /><script type="text/javascript" src="foo"></script></head><body><h1>Testing the middleware</h1></body></html>
|
25
30
|
END
|
26
31
|
end
|
27
32
|
let(:snippet) { 'THIS IS THE SNIPPET' }
|
@@ -65,6 +70,26 @@ END
|
|
65
70
|
res_status, res_headers, response = subject.call(env)
|
66
71
|
new_body = response.body.join
|
67
72
|
|
73
|
+
expect(new_body).to_not include('>>')
|
74
|
+
expect(new_body).to include(snippet)
|
75
|
+
expect(new_body).to include(config[:options].to_json)
|
76
|
+
expect(res_status).to be_eql(status)
|
77
|
+
expect(res_headers['Content-Type']).to be_eql(content_type)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'having a html 200 response with minified body' do
|
82
|
+
let(:body) { [minified_html] }
|
83
|
+
let(:status) { 200 }
|
84
|
+
let(:headers) do
|
85
|
+
{ 'Content-Type' => content_type }
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'adds the config and the snippet to the response' do
|
89
|
+
res_status, res_headers, response = subject.call(env)
|
90
|
+
new_body = response.body.join
|
91
|
+
|
92
|
+
expect(new_body).to_not include('>>')
|
68
93
|
expect(new_body).to include(snippet)
|
69
94
|
expect(new_body).to include(config[:options].to_json)
|
70
95
|
expect(res_status).to be_eql(status)
|
@@ -72,6 +97,30 @@ END
|
|
72
97
|
end
|
73
98
|
end
|
74
99
|
|
100
|
+
context 'having a html 200 response and SecureHeaders defined' do
|
101
|
+
let(:body) { [html] }
|
102
|
+
let(:status) { 200 }
|
103
|
+
let(:headers) do
|
104
|
+
{ 'Content-Type' => content_type }
|
105
|
+
end
|
106
|
+
|
107
|
+
before do
|
108
|
+
Object.const_set('SecureHeaders', Module.new)
|
109
|
+
allow(SecureHeaders).to receive(:content_security_policy_script_nonce) { 'lorem-ipsum-nonce' }
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'renders the snippet and config in the response with nonce in script tag when SecureHeaders installed' do
|
113
|
+
res_status, res_headers, response = subject.call(env)
|
114
|
+
new_body = response.body.join
|
115
|
+
|
116
|
+
expect(new_body).to include('<script type="text/javascript" nonce="lorem-ipsum-nonce">')
|
117
|
+
expect(new_body).to include("var _rollbarConfig = #{config[:options].to_json};")
|
118
|
+
expect(new_body).to include(snippet)
|
119
|
+
|
120
|
+
Object.send(:remove_const, 'SecureHeaders')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
75
124
|
context 'having a html 200 response without head', :add_js => false do
|
76
125
|
let(:body) { ['foobar'] }
|
77
126
|
let(:status) { 200 }
|
@@ -22,7 +22,19 @@ describe Rollbar::LoggerProxy do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
describe '#
|
25
|
+
describe '#log' do
|
26
|
+
context 'if Rollbar is disabled' do
|
27
|
+
before do
|
28
|
+
expect(Rollbar.configuration).to receive(:enabled).and_return(false)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'doesnt call the logger' do
|
32
|
+
expect(logger).to_not receive(:error)
|
33
|
+
|
34
|
+
subject.log('error', 'foo')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
26
38
|
context 'if the logger fails' do
|
27
39
|
it 'doesnt raise' do
|
28
40
|
allow(logger).to receive(:info).and_raise(StandardError.new)
|
@@ -53,30 +53,4 @@ describe Rollbar::RequestDataExtractor do
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
|
-
|
57
|
-
describe '#rollbar_scrubbed_value' do
|
58
|
-
context 'with random scrub length' do
|
59
|
-
before do
|
60
|
-
allow(Rollbar.configuration).to receive(:randomize_scrub_length).and_return(true)
|
61
|
-
end
|
62
|
-
|
63
|
-
let(:value) { 'herecomesaverylongvalue' }
|
64
|
-
|
65
|
-
it 'randomizes the scrubbed string' do
|
66
|
-
expect(subject.rollbar_scrubbed(value)).to match(/\*{3,8}/)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context 'with no-random scrub length' do
|
71
|
-
before do
|
72
|
-
allow(Rollbar.configuration).to receive(:randomize_scrub_length).and_return(false)
|
73
|
-
end
|
74
|
-
|
75
|
-
let(:value) { 'herecomesaverylongvalue' }
|
76
|
-
|
77
|
-
it 'randomizes the scrubbed string' do
|
78
|
-
expect(subject.rollbar_scrubbed(value)).to match(/\*{#{value.length}}/)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
56
|
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'rollbar/scrubbers/params'
|
4
|
+
|
5
|
+
require 'rspec/expectations'
|
6
|
+
|
7
|
+
describe Rollbar::Scrubbers::Params do
|
8
|
+
describe '.call' do
|
9
|
+
it 'calls #call in a new instance' do
|
10
|
+
arguments = [:foo, :bar]
|
11
|
+
expect_any_instance_of(described_class).to receive(:call).with(*arguments)
|
12
|
+
|
13
|
+
described_class.call(*arguments)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#call' do
|
18
|
+
before do
|
19
|
+
allow(Rollbar.configuration).to receive(:scrub_fields).and_return(scrub_config)
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'with scrub fields configured' do
|
23
|
+
let(:scrub_config) do
|
24
|
+
[:secret, :password]
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with simple Hash' do
|
28
|
+
let(:params) do
|
29
|
+
{
|
30
|
+
:foo => 'bar',
|
31
|
+
:secret => 'the-secret',
|
32
|
+
:password => 'the-password',
|
33
|
+
:password_confirmation => 'the-password'
|
34
|
+
}
|
35
|
+
end
|
36
|
+
let(:result) do
|
37
|
+
{
|
38
|
+
:foo => 'bar',
|
39
|
+
:secret => /\*+/,
|
40
|
+
:password => /\*+/,
|
41
|
+
:password_confirmation => /\*+/
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'scrubs the required parameters' do
|
46
|
+
expect(subject.call(params)).to be_eql_hash_with_regexes(result)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'with nested Hash' do
|
51
|
+
let(:params) do
|
52
|
+
{
|
53
|
+
:foo => 'bar',
|
54
|
+
:extra => {
|
55
|
+
:secret => 'the-secret',
|
56
|
+
:password => 'the-password',
|
57
|
+
:password_confirmation => 'the-password'
|
58
|
+
}
|
59
|
+
}
|
60
|
+
end
|
61
|
+
let(:result) do
|
62
|
+
{
|
63
|
+
:foo => 'bar',
|
64
|
+
:extra => {
|
65
|
+
:secret => /\*+/,
|
66
|
+
:password => /\*+/,
|
67
|
+
:password_confirmation => /\*+/
|
68
|
+
}
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'scrubs the required parameters' do
|
73
|
+
expect(subject.call(params)).to be_eql_hash_with_regexes(result)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'with nested Array' do
|
78
|
+
let(:params) do
|
79
|
+
{
|
80
|
+
:foo => 'bar',
|
81
|
+
:extra => [{
|
82
|
+
:secret => 'the-secret',
|
83
|
+
:password => 'the-password',
|
84
|
+
:password_confirmation => 'the-password'
|
85
|
+
}]
|
86
|
+
}
|
87
|
+
end
|
88
|
+
let(:result) do
|
89
|
+
{
|
90
|
+
:foo => 'bar',
|
91
|
+
:extra => [{
|
92
|
+
:secret => /\*+/,
|
93
|
+
:password => /\*+/,
|
94
|
+
:password_confirmation => /\*+/
|
95
|
+
}]
|
96
|
+
}
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'scrubs the required parameters' do
|
100
|
+
expect(subject.call(params)).to be_eql_hash_with_regexes(result)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'with skipped instance' do
|
105
|
+
let(:tempfile) { Tempfile.new('foo') }
|
106
|
+
let(:params) do
|
107
|
+
{
|
108
|
+
:foo => 'bar',
|
109
|
+
:extra => [{
|
110
|
+
:secret => 'the-secret',
|
111
|
+
:password => 'the-password',
|
112
|
+
:password_confirmation => 'the-password',
|
113
|
+
:skipped => tempfile
|
114
|
+
}]
|
115
|
+
}
|
116
|
+
end
|
117
|
+
let(:result) do
|
118
|
+
{
|
119
|
+
:foo => 'bar',
|
120
|
+
:extra => [{
|
121
|
+
:secret => /\*+/,
|
122
|
+
:password => /\*+/,
|
123
|
+
:password_confirmation => /\*+/,
|
124
|
+
:skipped => "Skipped value of class 'Tempfile'"
|
125
|
+
}]
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
after { tempfile.close }
|
130
|
+
|
131
|
+
it 'scrubs the required parameters' do
|
132
|
+
expect(subject.call(params)).to be_eql_hash_with_regexes(result)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'with attachment instance' do
|
137
|
+
let(:tempfile) { double(:size => 100) }
|
138
|
+
let(:attachment) do
|
139
|
+
double(:class => double(:name => 'ActionDispatch::Http::UploadedFile'),
|
140
|
+
:tempfile => tempfile,
|
141
|
+
:content_type => 'content-type',
|
142
|
+
'original_filename' => 'filename')
|
143
|
+
end
|
144
|
+
let(:params) do
|
145
|
+
{
|
146
|
+
:foo => 'bar',
|
147
|
+
:extra => [{
|
148
|
+
:secret => 'the-secret',
|
149
|
+
:password => 'the-password',
|
150
|
+
:password_confirmation => 'the-password',
|
151
|
+
:attachment => attachment
|
152
|
+
}]
|
153
|
+
}
|
154
|
+
end
|
155
|
+
let(:result) do
|
156
|
+
{
|
157
|
+
:foo => 'bar',
|
158
|
+
:extra => [{
|
159
|
+
:secret => /\*+/,
|
160
|
+
:password => /\*+/,
|
161
|
+
:password_confirmation => /\*+/,
|
162
|
+
:attachment => {
|
163
|
+
:content_type => 'content-type',
|
164
|
+
:original_filename => 'filename',
|
165
|
+
:size => 100
|
166
|
+
}
|
167
|
+
}]
|
168
|
+
}
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'scrubs the required parameters' do
|
172
|
+
expect(subject.call(params)).to be_eql_hash_with_regexes(result)
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'if getting the attachment values fails' do
|
176
|
+
let(:tempfile) { Object.new }
|
177
|
+
let(:attachment) do
|
178
|
+
double(:class => double(:name => 'ActionDispatch::Http::UploadedFile'),
|
179
|
+
:tempfile => tempfile,
|
180
|
+
:content_type => 'content-type',
|
181
|
+
'original_filename' => 'filename')
|
182
|
+
end
|
183
|
+
let(:params) do
|
184
|
+
{
|
185
|
+
:foo => 'bar',
|
186
|
+
:extra => [{
|
187
|
+
:secret => 'the-secret',
|
188
|
+
:password => 'the-password',
|
189
|
+
:password_confirmation => 'the-password',
|
190
|
+
:attachment => attachment
|
191
|
+
}]
|
192
|
+
}
|
193
|
+
end
|
194
|
+
let(:result) do
|
195
|
+
{
|
196
|
+
:foo => 'bar',
|
197
|
+
:extra => [{
|
198
|
+
:secret => /\*+/,
|
199
|
+
:password => /\*+/,
|
200
|
+
:password_confirmation => /\*+/,
|
201
|
+
:attachment => 'Uploaded file'
|
202
|
+
}]
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'scrubs the required parameters' do
|
207
|
+
expect(subject.call(params)).to be_eql_hash_with_regexes(result)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context 'without params' do
|
213
|
+
let(:params) do
|
214
|
+
nil
|
215
|
+
end
|
216
|
+
let(:result) do
|
217
|
+
{}
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'scrubs the required parameters' do
|
221
|
+
expect(subject.call(params)).to be_eql_hash_with_regexes(result)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'with :scrub_all option' do
|
227
|
+
let(:scrub_config) { :scrub_all }
|
228
|
+
let(:params) do
|
229
|
+
{
|
230
|
+
:foo => 'bar',
|
231
|
+
:password => 'the-password',
|
232
|
+
:bar => 'foo',
|
233
|
+
:extra => {
|
234
|
+
:foo => 'more-foo',
|
235
|
+
:bar => 'more-bar'
|
236
|
+
}
|
237
|
+
}
|
238
|
+
end
|
239
|
+
let(:result) do
|
240
|
+
{
|
241
|
+
:foo => /\*+/,
|
242
|
+
:password => /\*+/,
|
243
|
+
:bar => /\*+/,
|
244
|
+
:extra => {
|
245
|
+
:foo => /\*+/,
|
246
|
+
:bar => /\*+/
|
247
|
+
}
|
248
|
+
}
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'scrubs the required parameters' do
|
252
|
+
expect(subject.call(params)).to be_eql_hash_with_regexes(result)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
describe Rollbar::Scrubbers::Params::ATTACHMENT_CLASSES do
|
259
|
+
it 'has the correct values' do
|
260
|
+
expect(described_class).to be_eql(%w(ActionDispatch::Http::UploadedFile Rack::Multipart::UploadedFile).freeze)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
describe Rollbar::Scrubbers::Params::SKIPPED_CLASSES do
|
265
|
+
it 'has the correct values' do
|
266
|
+
expect(described_class).to be_eql([Tempfile])
|
267
|
+
end
|
268
|
+
end
|