airbrake-ruby 1.5.0 → 1.6.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/lib/airbrake-ruby.rb +5 -36
- data/lib/airbrake-ruby/backtrace.rb +1 -1
- data/lib/airbrake-ruby/filters/keys_blacklist.rb +1 -1
- data/lib/airbrake-ruby/filters/keys_filter.rb +35 -1
- data/lib/airbrake-ruby/filters/keys_whitelist.rb +2 -2
- data/lib/airbrake-ruby/notice.rb +13 -20
- data/lib/airbrake-ruby/notifier.rb +11 -29
- data/lib/airbrake-ruby/sync_sender.rb +4 -6
- data/lib/airbrake-ruby/version.rb +1 -1
- data/spec/airbrake_spec.rb +0 -8
- data/spec/notifier_spec.rb +0 -262
- data/spec/notifier_spec/blacklist_keys_spec.rb +192 -0
- data/spec/notifier_spec/options_spec.rb +0 -195
- data/spec/notifier_spec/whitelist_keys_spec.rb +246 -0
- metadata +8 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab4ce2485ab1b938a76f15f2b71d92db0fe6e0e2
|
4
|
+
data.tar.gz: a48ae79d2523577c1400d2ed6b914e5340e9f5ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05d26b46d931156979aa32411b8d722c46023056eee2d0545be53df86a26e5ee565640a59999ddd37d1b947db44f113ac6dc636df5e9b6cb800682d66ef87c55
|
7
|
+
data.tar.gz: ec26b798eb2c9139ffbd44a0bd42385886663fade0ddcab147ea0b6d68b94c4635813398fe9c2b0b4e87398d26099751d016900e3b026cfac79acd0dc29d9998
|
data/lib/airbrake-ruby.rb
CHANGED
@@ -69,6 +69,11 @@ module Airbrake
|
|
69
69
|
# for special cases where we need to work around older implementations
|
70
70
|
RUBY_19 = RUBY_VERSION.start_with?('1.9')
|
71
71
|
|
72
|
+
##
|
73
|
+
# @return [Boolean] true if current Ruby is Ruby 2.0.*. The result is used
|
74
|
+
# for special cases where we need to work around older implementations
|
75
|
+
RUBY_20 = RUBY_VERSION.start_with?('2.0')
|
76
|
+
|
72
77
|
##
|
73
78
|
# A Hash that holds all notifiers. The keys of the Hash are notifier
|
74
79
|
# names, the values are Airbrake::Notifier instances.
|
@@ -188,42 +193,6 @@ module Airbrake
|
|
188
193
|
call_notifier(notifier, __method__, filter, &block)
|
189
194
|
end
|
190
195
|
|
191
|
-
##
|
192
|
-
# Specifies which keys should *not* be filtered. All other keys will be
|
193
|
-
# substituted with the +[Filtered]+ label.
|
194
|
-
#
|
195
|
-
# @macro proxy_method
|
196
|
-
# @example
|
197
|
-
# Airbrake.whitelist([:email, /user/i, 'account_id'])
|
198
|
-
#
|
199
|
-
# @param [Array<String, Symbol, Regexp>] keys The keys, which shouldn't be
|
200
|
-
# filtered
|
201
|
-
# @return [void]
|
202
|
-
# @since v5.0.0
|
203
|
-
# @see .blacklist_keys
|
204
|
-
# @deprecated Please use {Airbrake::Config#whitelist_keys} instead
|
205
|
-
def whitelist_keys(keys, notifier = :default)
|
206
|
-
call_notifier(notifier, __method__, keys)
|
207
|
-
end
|
208
|
-
|
209
|
-
##
|
210
|
-
# Specifies which keys *should* be filtered. Such keys will be replaced with
|
211
|
-
# the +[Filtered]+ label.
|
212
|
-
#
|
213
|
-
# @macro proxy_method
|
214
|
-
# @example
|
215
|
-
# Airbrake.blacklist_keys([:email, /credit/i, 'password'])
|
216
|
-
#
|
217
|
-
# @param [Array<String, Symbol, Regexp>] keys The keys, which should be
|
218
|
-
# filtered
|
219
|
-
# @return [void]
|
220
|
-
# @since v5.0.0
|
221
|
-
# @see .whitelist_keys
|
222
|
-
# @deprecated Please use {Airbrake::Config#blacklist_keys} instead
|
223
|
-
def blacklist_keys(keys, notifier = :default)
|
224
|
-
call_notifier(notifier, __method__, keys)
|
225
|
-
end
|
226
|
-
|
227
196
|
##
|
228
197
|
# Builds an Airbrake notice. This is useful, if you want to add or modify a
|
229
198
|
# value only for a specific notice. When you're done modifying the notice,
|
@@ -151,7 +151,7 @@ module Airbrake
|
|
151
151
|
return false unless defined?(ExecJS::RuntimeError)
|
152
152
|
return true if exception.is_a?(ExecJS::RuntimeError)
|
153
153
|
|
154
|
-
if Airbrake::RUBY_19
|
154
|
+
if Airbrake::RUBY_19 || Airbrake::RUBY_20
|
155
155
|
# Ruby 1.9 doesn't support Exception#cause. We work around this by
|
156
156
|
# parsing backtraces. It's slow, so we check only a few first frames.
|
157
157
|
exception.backtrace[0..2].each do |frame|
|
@@ -2,7 +2,7 @@ module Airbrake
|
|
2
2
|
module Filters
|
3
3
|
##
|
4
4
|
# A default Airbrake notice filter. Filters only specific keys listed in the
|
5
|
-
# list of parameters in the
|
5
|
+
# list of parameters in the payload of a notice.
|
6
6
|
#
|
7
7
|
# @example
|
8
8
|
# filter = Airbrake::Filters::KeysBlacklist.new(:email, /credit/i, 'password')
|
@@ -13,13 +13,20 @@ module Airbrake
|
|
13
13
|
# @return [String] The label to replace real values of filtered payload
|
14
14
|
FILTERED = '[Filtered]'.freeze
|
15
15
|
|
16
|
+
##
|
17
|
+
# @return [Array<String,Symbol,Regexp>] the array of classes instances of
|
18
|
+
# which can compared with payload keys
|
19
|
+
VALID_PATTERN_CLASSES = [String, Symbol, Regexp].freeze
|
20
|
+
|
16
21
|
##
|
17
22
|
# Creates a new KeysBlacklist or KeysWhitelist filter that uses the given
|
18
23
|
# +patterns+ for filtering a notice's payload.
|
19
24
|
#
|
20
25
|
# @param [Array<String,Regexp,Symbol>] patterns
|
21
|
-
def initialize(*patterns)
|
26
|
+
def initialize(logger, *patterns)
|
27
|
+
@logger = logger
|
22
28
|
@patterns = patterns
|
29
|
+
@valid_patterns = false
|
23
30
|
end
|
24
31
|
|
25
32
|
##
|
@@ -30,6 +37,11 @@ module Airbrake
|
|
30
37
|
# @return [void]
|
31
38
|
# @see FilterChain
|
32
39
|
def call(notice)
|
40
|
+
unless @valid_patterns
|
41
|
+
eval_proc_patterns!
|
42
|
+
validate_patterns
|
43
|
+
end
|
44
|
+
|
33
45
|
FILTERABLE_KEYS.each { |key| filter_hash(notice[key]) }
|
34
46
|
|
35
47
|
if notice[:context][:user]
|
@@ -86,6 +98,28 @@ module Airbrake
|
|
86
98
|
return unless url.query
|
87
99
|
notice[:context][:url] = filter_url_params(url)
|
88
100
|
end
|
101
|
+
|
102
|
+
def eval_proc_patterns!
|
103
|
+
return unless @patterns.any? { |pattern| pattern.is_a?(Proc) }
|
104
|
+
|
105
|
+
@patterns = @patterns.flat_map do |pattern|
|
106
|
+
next(pattern) unless pattern.respond_to?(:call)
|
107
|
+
pattern.call
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def validate_patterns
|
112
|
+
@valid_patterns = @patterns.all? do |pattern|
|
113
|
+
VALID_PATTERN_CLASSES.any? { |c| pattern.is_a?(c) }
|
114
|
+
end
|
115
|
+
|
116
|
+
return if @valid_patterns
|
117
|
+
|
118
|
+
@logger.error(
|
119
|
+
"#{LOG_LABEL} one of the patterns in #{self.class} is invalid. " \
|
120
|
+
"Known patterns: #{@patterns}"
|
121
|
+
)
|
122
|
+
end
|
89
123
|
end
|
90
124
|
end
|
91
125
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Airbrake
|
2
2
|
module Filters
|
3
3
|
##
|
4
|
-
# A default Airbrake notice filter. Filters everything in the
|
5
|
-
#
|
4
|
+
# A default Airbrake notice filter. Filters everything in the payload of a
|
5
|
+
# notice, but specified keys.
|
6
6
|
#
|
7
7
|
# @example
|
8
8
|
# filter = Airbrake::Filters::KeysWhitelist.new(:email, /user/i, 'account_id')
|
data/lib/airbrake-ruby/notice.rb
CHANGED
@@ -57,17 +57,14 @@ module Airbrake
|
|
57
57
|
def initialize(config, exception, params = {})
|
58
58
|
@config = config
|
59
59
|
|
60
|
-
@
|
61
|
-
notifier: NOTIFIER
|
62
|
-
}.freeze
|
63
|
-
|
64
|
-
@modifiable_payload = {
|
60
|
+
@payload = {
|
65
61
|
errors: NestedException.new(exception, @config.logger).as_json,
|
66
62
|
context: context(params),
|
67
63
|
environment: {},
|
68
64
|
session: {},
|
69
65
|
params: params
|
70
66
|
}
|
67
|
+
|
71
68
|
extract_custom_attributes(exception)
|
72
69
|
|
73
70
|
@truncator = PayloadTruncator.new(PAYLOAD_MAX_SIZE, @config.logger)
|
@@ -82,7 +79,7 @@ module Airbrake
|
|
82
79
|
def to_json
|
83
80
|
loop do
|
84
81
|
begin
|
85
|
-
json = payload.to_json
|
82
|
+
json = @payload.to_json
|
86
83
|
rescue *JSON_EXCEPTIONS => ex
|
87
84
|
@config.logger.debug("#{LOG_LABEL} `notice.to_json` failed: #{ex.class}: #{ex}")
|
88
85
|
else
|
@@ -100,7 +97,7 @@ module Airbrake
|
|
100
97
|
# @see #ignored?
|
101
98
|
# @note Ignored noticed can't be unignored
|
102
99
|
def ignore!
|
103
|
-
@
|
100
|
+
@payload = nil
|
104
101
|
end
|
105
102
|
|
106
103
|
##
|
@@ -109,21 +106,21 @@ module Airbrake
|
|
109
106
|
# @return [Boolean]
|
110
107
|
# @see #ignore!
|
111
108
|
def ignored?
|
112
|
-
@
|
109
|
+
@payload.nil?
|
113
110
|
end
|
114
111
|
|
115
112
|
##
|
116
|
-
# Reads a value from notice's
|
113
|
+
# Reads a value from notice's payload.
|
117
114
|
# @return [Object]
|
118
115
|
#
|
119
116
|
# @raise [Airbrake::Error] if the notice is ignored
|
120
117
|
def [](key)
|
121
118
|
raise_if_ignored
|
122
|
-
@
|
119
|
+
@payload[key]
|
123
120
|
end
|
124
121
|
|
125
122
|
##
|
126
|
-
# Writes a value to the
|
123
|
+
# Writes a value to the payload hash. Restricts unrecognized
|
127
124
|
# writes.
|
128
125
|
# @example
|
129
126
|
# notice[:params][:my_param] = 'foobar'
|
@@ -137,7 +134,7 @@ module Airbrake
|
|
137
134
|
raise_if_unrecognized_key(key)
|
138
135
|
raise_if_non_hash_value(value)
|
139
136
|
|
140
|
-
@
|
137
|
+
@payload[key] = value.to_hash
|
141
138
|
end
|
142
139
|
|
143
140
|
private
|
@@ -178,17 +175,13 @@ module Airbrake
|
|
178
175
|
raise Airbrake::Error, "Got #{value.class} value, wanted a Hash"
|
179
176
|
end
|
180
177
|
|
181
|
-
def payload
|
182
|
-
@modifiable_payload.merge(@private_payload)
|
183
|
-
end
|
184
|
-
|
185
178
|
def truncate_payload
|
186
|
-
@
|
179
|
+
@payload[:errors].each do |error|
|
187
180
|
@truncator.truncate_error(error)
|
188
181
|
end
|
189
182
|
|
190
183
|
Filters::FILTERABLE_KEYS.each do |key|
|
191
|
-
@truncator.truncate_object(@
|
184
|
+
@truncator.truncate_object(@payload[key])
|
192
185
|
end
|
193
186
|
|
194
187
|
new_max_size = @truncator.reduce_max_size
|
@@ -196,7 +189,7 @@ module Airbrake
|
|
196
189
|
@config.logger.error(
|
197
190
|
"#{LOG_LABEL} truncation failed. File an issue at " \
|
198
191
|
"https://github.com/airbrake/airbrake-ruby " \
|
199
|
-
"and attach the following payload: #{payload}"
|
192
|
+
"and attach the following payload: #{@payload}"
|
200
193
|
)
|
201
194
|
end
|
202
195
|
|
@@ -218,7 +211,7 @@ module Airbrake
|
|
218
211
|
return unless attributes
|
219
212
|
|
220
213
|
begin
|
221
|
-
@
|
214
|
+
@payload.merge!(attributes)
|
222
215
|
rescue TypeError
|
223
216
|
@config.logger.error(
|
224
217
|
"#{LOG_LABEL} #{exception.class}#to_airbrake failed:" \
|
@@ -36,13 +36,7 @@ module Airbrake
|
|
36
36
|
|
37
37
|
@filter_chain = FilterChain.new(@config)
|
38
38
|
|
39
|
-
|
40
|
-
add_filter(Filters::KeysBlacklist.new(*@config.blacklist_keys))
|
41
|
-
end
|
42
|
-
|
43
|
-
if @config.whitelist_keys.any?
|
44
|
-
add_filter(Filters::KeysWhitelist.new(*@config.whitelist_keys))
|
45
|
-
end
|
39
|
+
add_filters_for_config_keys
|
46
40
|
|
47
41
|
@async_sender = AsyncSender.new(@config)
|
48
42
|
@sync_sender = SyncSender.new(@config)
|
@@ -71,28 +65,6 @@ module Airbrake
|
|
71
65
|
@filter_chain.add_filter(block_given? ? block : filter)
|
72
66
|
end
|
73
67
|
|
74
|
-
##
|
75
|
-
# @macro see_public_api_method
|
76
|
-
# @deprecated Please use {Airbrake::Config#whitelist_keys} instead
|
77
|
-
def whitelist_keys(keys)
|
78
|
-
@config.logger.warn(
|
79
|
-
"#{LOG_LABEL} Airbrake.whitelist_keys is deprecated. Please use the " \
|
80
|
-
"whitelist_keys option instead (https://goo.gl/sQwpYN)"
|
81
|
-
)
|
82
|
-
add_filter(Filters::KeysWhitelist.new(*keys))
|
83
|
-
end
|
84
|
-
|
85
|
-
##
|
86
|
-
# @macro see_public_api_method
|
87
|
-
# @deprecated Please use {Airbrake::Config#blacklist_keys} instead
|
88
|
-
def blacklist_keys(keys)
|
89
|
-
@config.logger.warn(
|
90
|
-
"#{LOG_LABEL} Airbrake.blacklist_keys is deprecated. Please use the " \
|
91
|
-
"blacklist_keys option instead (https://goo.gl/jucrFt)"
|
92
|
-
)
|
93
|
-
add_filter(Filters::KeysBlacklist.new(*keys))
|
94
|
-
end
|
95
|
-
|
96
68
|
##
|
97
69
|
# @macro see_public_api_method
|
98
70
|
def build_notice(exception, params = {})
|
@@ -171,5 +143,15 @@ module Airbrake
|
|
171
143
|
return caller_copy if clean_bt.empty?
|
172
144
|
clean_bt
|
173
145
|
end
|
146
|
+
|
147
|
+
def add_filters_for_config_keys
|
148
|
+
if @config.blacklist_keys.any?
|
149
|
+
add_filter(Filters::KeysBlacklist.new(@config.logger, *@config.blacklist_keys))
|
150
|
+
end
|
151
|
+
|
152
|
+
return if @config.whitelist_keys.none?
|
153
|
+
|
154
|
+
add_filter(Filters::KeysWhitelist.new(@config.logger, *@config.whitelist_keys))
|
155
|
+
end
|
174
156
|
end
|
175
157
|
end
|
@@ -67,12 +67,10 @@ module Airbrake
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def proxy_params
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
@config.proxy[:password]]
|
75
|
-
end
|
70
|
+
return unless @config.proxy.key?(:host)
|
71
|
+
|
72
|
+
[@config.proxy[:host], @config.proxy[:port], @config.proxy[:user],
|
73
|
+
@config.proxy[:password]]
|
76
74
|
end
|
77
75
|
end
|
78
76
|
end
|
data/spec/airbrake_spec.rb
CHANGED
@@ -176,14 +176,6 @@ RSpec.describe Airbrake do
|
|
176
176
|
end
|
177
177
|
end
|
178
178
|
|
179
|
-
describe ".whitelist_keys" do
|
180
|
-
include_examples 'non-configured notifier handling', :whitelist_keys
|
181
|
-
end
|
182
|
-
|
183
|
-
describe ".blacklist_keys" do
|
184
|
-
include_examples 'non-configured notifier handling', :blacklist_keys
|
185
|
-
end
|
186
|
-
|
187
179
|
describe ".build_notice" do
|
188
180
|
include_examples 'non-configured notifier handling', :build_notice
|
189
181
|
end
|
data/spec/notifier_spec.rb
CHANGED
@@ -472,268 +472,6 @@ RSpec.describe Airbrake::Notifier do
|
|
472
472
|
end
|
473
473
|
end
|
474
474
|
|
475
|
-
describe "#blacklist_keys" do
|
476
|
-
describe "the list of arguments" do
|
477
|
-
it "accepts regexps" do
|
478
|
-
@airbrake.blacklist_keys(/\Abin/)
|
479
|
-
|
480
|
-
@airbrake.notify_sync(ex, bingo: 'bango')
|
481
|
-
|
482
|
-
expect(
|
483
|
-
a_request(:post, endpoint).
|
484
|
-
with(body: /"params":{"bingo":"\[Filtered\]"}/)
|
485
|
-
).to have_been_made.once
|
486
|
-
end
|
487
|
-
|
488
|
-
it "accepts symbols" do
|
489
|
-
@airbrake.blacklist_keys(:bingo)
|
490
|
-
|
491
|
-
@airbrake.notify_sync(ex, bingo: 'bango')
|
492
|
-
|
493
|
-
expect(
|
494
|
-
a_request(:post, endpoint).
|
495
|
-
with(body: /"params":{"bingo":"\[Filtered\]"}/)
|
496
|
-
).to have_been_made.once
|
497
|
-
end
|
498
|
-
|
499
|
-
it "accepts strings" do
|
500
|
-
@airbrake.blacklist_keys('bingo')
|
501
|
-
|
502
|
-
@airbrake.notify_sync(ex, bingo: 'bango', bbingoo: 'bbangoo')
|
503
|
-
|
504
|
-
expect(
|
505
|
-
a_request(:post, endpoint).
|
506
|
-
with(body: /"params":{"bingo":"\[Filtered\]","bbingoo":"bbangoo"}/)
|
507
|
-
).to have_been_made.once
|
508
|
-
end
|
509
|
-
end
|
510
|
-
|
511
|
-
describe "hash values" do
|
512
|
-
context "non-recursive" do
|
513
|
-
it "filters nested hashes" do
|
514
|
-
@airbrake.blacklist_keys('bish')
|
515
|
-
|
516
|
-
@airbrake.notify_sync(ex, bongo: { bish: 'bash' })
|
517
|
-
|
518
|
-
expect(
|
519
|
-
a_request(:post, endpoint).
|
520
|
-
with(body: /"params":{"bongo":{"bish":"\[Filtered\]"}}/)
|
521
|
-
).to have_been_made.once
|
522
|
-
end
|
523
|
-
end
|
524
|
-
|
525
|
-
context "recursive" do
|
526
|
-
it "filters recursive hashes" do
|
527
|
-
@airbrake.blacklist_keys('bango')
|
528
|
-
|
529
|
-
bongo = { bingo: {} }
|
530
|
-
bongo[:bingo][:bango] = bongo
|
531
|
-
|
532
|
-
@airbrake.notify_sync(ex, bongo)
|
533
|
-
|
534
|
-
expect(
|
535
|
-
a_request(:post, endpoint).
|
536
|
-
with(body: /"params":{"bingo":{"bango":"\[Filtered\]"}}/)
|
537
|
-
).to have_been_made.once
|
538
|
-
end
|
539
|
-
end
|
540
|
-
end
|
541
|
-
|
542
|
-
it "filters query parameters correctly" do
|
543
|
-
@airbrake.blacklist_keys(%w(bish))
|
544
|
-
|
545
|
-
notice = @airbrake.build_notice(ex)
|
546
|
-
notice[:context][:url] = 'http://localhost:3000/crash?foo=bar&baz=bongo&bish=bash&color=%23FFAAFF'
|
547
|
-
|
548
|
-
@airbrake.notify_sync(notice)
|
549
|
-
|
550
|
-
# rubocop:disable Metrics/LineLength
|
551
|
-
expected_body =
|
552
|
-
%r("context":{.*"url":"http://localhost:3000/crash\?foo=bar&baz=bongo&bish=\[Filtered\]&color=%23FFAAFF".*})
|
553
|
-
# rubocop:enable Metrics/LineLength
|
554
|
-
|
555
|
-
expect(
|
556
|
-
a_request(:post, endpoint).
|
557
|
-
with(body: expected_body)
|
558
|
-
).to have_been_made.once
|
559
|
-
end
|
560
|
-
|
561
|
-
it "filters out user" do
|
562
|
-
@airbrake.blacklist_keys('user')
|
563
|
-
|
564
|
-
notice = @airbrake.build_notice(ex)
|
565
|
-
notice[:context][:user] = { id: 1337, name: 'Bingo Bango' }
|
566
|
-
|
567
|
-
@airbrake.notify_sync(notice)
|
568
|
-
|
569
|
-
expect_a_request_with_body(/"user":"\[Filtered\]"/)
|
570
|
-
end
|
571
|
-
|
572
|
-
it "filters out individual user fields" do
|
573
|
-
@airbrake.blacklist_keys('name')
|
574
|
-
|
575
|
-
notice = @airbrake.build_notice(ex)
|
576
|
-
notice[:context][:user] = { id: 1337, name: 'Bingo Bango' }
|
577
|
-
|
578
|
-
@airbrake.notify_sync(notice)
|
579
|
-
|
580
|
-
expect_a_request_with_body(/"user":{"id":1337,"name":"\[Filtered\]"}/)
|
581
|
-
end
|
582
|
-
end
|
583
|
-
|
584
|
-
describe "#whitelist_keys" do
|
585
|
-
describe "the list of arguments" do
|
586
|
-
it "accepts regexes" do
|
587
|
-
@airbrake.whitelist_keys(/\Abin/)
|
588
|
-
|
589
|
-
@airbrake.notify_sync(ex, bingo: 'bango', bongo: 'bish', bash: 'bosh')
|
590
|
-
|
591
|
-
body = /"params":{"bingo":"bango","bongo":"\[Filtered\]","bash":"\[Filtered\]"}/
|
592
|
-
|
593
|
-
expect(
|
594
|
-
a_request(:post, endpoint).
|
595
|
-
with(body: body)
|
596
|
-
).to have_been_made.once
|
597
|
-
end
|
598
|
-
|
599
|
-
it "accepts symbols" do
|
600
|
-
@airbrake.whitelist_keys(:bongo)
|
601
|
-
|
602
|
-
@airbrake.notify_sync(ex, bingo: 'bango', bongo: 'bish', bash: 'bosh')
|
603
|
-
|
604
|
-
body = /"params":{"bingo":"\[Filtered\]","bongo":"bish","bash":"\[Filtered\]"}/
|
605
|
-
|
606
|
-
expect(
|
607
|
-
a_request(:post, endpoint).
|
608
|
-
with(body: body)
|
609
|
-
).to have_been_made.once
|
610
|
-
end
|
611
|
-
|
612
|
-
it "accepts strings" do
|
613
|
-
@airbrake.whitelist_keys('bash')
|
614
|
-
|
615
|
-
@airbrake.notify_sync(
|
616
|
-
ex,
|
617
|
-
bingo: 'bango',
|
618
|
-
bongo: 'bish',
|
619
|
-
bash: 'bosh',
|
620
|
-
bbashh: 'bboshh'
|
621
|
-
)
|
622
|
-
|
623
|
-
expect(
|
624
|
-
a_request(:post, endpoint).
|
625
|
-
with(
|
626
|
-
body: /"params":{"bingo":"\[Filtered\]","bongo":"\[Filtered\]",
|
627
|
-
"bash":"bosh","bbashh":"\[Filtered\]"}/x
|
628
|
-
)
|
629
|
-
).to have_been_made.once
|
630
|
-
end
|
631
|
-
end
|
632
|
-
|
633
|
-
describe "hash values" do
|
634
|
-
context "non-recursive" do
|
635
|
-
it "filters out everything but the provided keys" do
|
636
|
-
@airbrake.whitelist_keys(%w(bongo bish))
|
637
|
-
|
638
|
-
@airbrake.notify_sync(ex, bingo: 'bango', bongo: { bish: 'bash' })
|
639
|
-
|
640
|
-
expect(
|
641
|
-
a_request(:post, endpoint).
|
642
|
-
with(body: /"params":{"bingo":"\[Filtered\]","bongo":{"bish":"bash"}}/)
|
643
|
-
).to have_been_made.once
|
644
|
-
end
|
645
|
-
end
|
646
|
-
|
647
|
-
context "recursive" do
|
648
|
-
it "errors when nested hashes are not filtered" do
|
649
|
-
@airbrake.whitelist_keys(%w(bingo bango))
|
650
|
-
|
651
|
-
bongo = { bingo: {} }
|
652
|
-
bongo[:bingo][:bango] = bongo
|
653
|
-
|
654
|
-
if RUBY_ENGINE == 'jruby'
|
655
|
-
# JRuby might raise two different exceptions, which represent the
|
656
|
-
# same thing. One is a Java exception, the other is a Ruby
|
657
|
-
# exception. It's probably a JRuby bug:
|
658
|
-
# https://github.com/jruby/jruby/issues/1903
|
659
|
-
begin
|
660
|
-
expect do
|
661
|
-
@airbrake.notify_sync(ex, bongo)
|
662
|
-
end.to raise_error(SystemStackError)
|
663
|
-
rescue RSpec::Expectations::ExpectationNotMetError
|
664
|
-
expect do
|
665
|
-
@airbrake.notify_sync(ex, bongo)
|
666
|
-
end.to raise_error(java.lang.StackOverflowError)
|
667
|
-
end
|
668
|
-
else
|
669
|
-
expect do
|
670
|
-
@airbrake.notify_sync(ex, bongo)
|
671
|
-
end.to raise_error(SystemStackError)
|
672
|
-
end
|
673
|
-
end
|
674
|
-
end
|
675
|
-
end
|
676
|
-
|
677
|
-
describe "context/url" do
|
678
|
-
it "filters query parameters correctly" do
|
679
|
-
@airbrake.whitelist_keys(%w(bish))
|
680
|
-
|
681
|
-
notice = @airbrake.build_notice(ex)
|
682
|
-
notice[:context][:url] = 'http://localhost:3000/crash?foo=bar&baz=bongo&bish=bash'
|
683
|
-
|
684
|
-
@airbrake.notify_sync(notice)
|
685
|
-
|
686
|
-
# rubocop:disable Metrics/LineLength
|
687
|
-
expected_body =
|
688
|
-
%r("context":{.*"url":"http://localhost:3000/crash\?foo=\[Filtered\]&baz=\[Filtered\]&bish=bash".*})
|
689
|
-
# rubocop:enable Metrics/LineLength
|
690
|
-
|
691
|
-
expect(
|
692
|
-
a_request(:post, endpoint).
|
693
|
-
with(body: expected_body)
|
694
|
-
).to have_been_made.once
|
695
|
-
end
|
696
|
-
|
697
|
-
context "given a non-standard URL" do
|
698
|
-
it "leaves the URL unfiltered" do
|
699
|
-
@airbrake.whitelist_keys(%w(bish))
|
700
|
-
|
701
|
-
notice = @airbrake.build_notice(ex)
|
702
|
-
notice[:context][:url] =
|
703
|
-
'http://localhost:3000/cra]]]sh?foo=bar&baz=bongo&bish=bash'
|
704
|
-
|
705
|
-
@airbrake.notify_sync(notice)
|
706
|
-
|
707
|
-
# rubocop:disable Metrics/LineLength
|
708
|
-
expected_body =
|
709
|
-
%r("context":{.*"url":"http://localhost:3000/cra\]\]\]sh\?foo=bar&baz=bongo&bish=bash".*})
|
710
|
-
# rubocop:enable Metrics/LineLength
|
711
|
-
|
712
|
-
expect(
|
713
|
-
a_request(:post, endpoint).
|
714
|
-
with(body: expected_body)
|
715
|
-
).to have_been_made.once
|
716
|
-
end
|
717
|
-
end
|
718
|
-
|
719
|
-
context "given a URL without a query" do
|
720
|
-
it "skips params filtering and leaves the URL untouched" do
|
721
|
-
@airbrake.whitelist_keys(%w(bish))
|
722
|
-
|
723
|
-
notice = @airbrake.build_notice(ex)
|
724
|
-
notice[:context][:url] = 'http://localhost:3000/crash'
|
725
|
-
|
726
|
-
@airbrake.notify_sync(notice)
|
727
|
-
|
728
|
-
expect(
|
729
|
-
a_request(:post, endpoint).
|
730
|
-
with(body: %r("context":{.*"url":"http://localhost:3000/crash".*}))
|
731
|
-
).to have_been_made.once
|
732
|
-
end
|
733
|
-
end
|
734
|
-
end
|
735
|
-
end
|
736
|
-
|
737
475
|
describe "#build_notice" do
|
738
476
|
it "builds a notice from exception" do
|
739
477
|
expect(@airbrake.build_notice(ex)).to be_an Airbrake::Notice
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe "Airbrake::Notifier blacklist_keys" do
|
4
|
+
def expect_a_request_with_body(body)
|
5
|
+
expect(a_request(:post, endpoint).with(body: body)).to have_been_made.once
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:project_id) { 105138 }
|
9
|
+
let(:project_key) { 'fd04e13d806a90f96614ad8e529b2822' }
|
10
|
+
let(:localhost) { 'http://localhost:8080' }
|
11
|
+
|
12
|
+
let(:endpoint) do
|
13
|
+
"https://airbrake.io/api/v3/projects/#{project_id}/notices?key=#{project_key}"
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:airbrake_params) do
|
17
|
+
{ project_id: project_id,
|
18
|
+
project_key: project_key,
|
19
|
+
logger: Logger.new(StringIO.new) }
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:ex) { AirbrakeTestError.new }
|
23
|
+
|
24
|
+
shared_examples 'blacklisting' do |keys, params|
|
25
|
+
it "filters out the value" do
|
26
|
+
blacklist = { blacklist_keys: keys }
|
27
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(blacklist))
|
28
|
+
|
29
|
+
notifier.notify_sync(ex, params)
|
30
|
+
|
31
|
+
expect_a_request_with_body(expected_body)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
shared_examples 'logging' do |keys, params|
|
36
|
+
it "logs the error" do
|
37
|
+
out = StringIO.new
|
38
|
+
blacklist = { blacklist_keys: keys, logger: Logger.new(out) }
|
39
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(blacklist))
|
40
|
+
|
41
|
+
notifier.notify_sync(ex, params)
|
42
|
+
|
43
|
+
expect(out.string).to match(expected_output)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
before do
|
48
|
+
stub_request(:post, endpoint).to_return(status: 201, body: '{}')
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when blacklisting with a Regexp" do
|
52
|
+
let(:expected_body) { /"params":{"bingo":"\[Filtered\]"}/ }
|
53
|
+
include_examples('blacklisting', [/\Abin/], bingo: 'bango')
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when blacklisting with a Symbol" do
|
57
|
+
let(:expected_body) { /"params":{"bingo":"\[Filtered\]"}/ }
|
58
|
+
include_examples('blacklisting', [:bingo], bingo: 'bango')
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when blacklisting with a String" do
|
62
|
+
let(:expected_body) { /"params":{"bingo":"\[Filtered\]"}/ }
|
63
|
+
include_examples('blacklisting', ['bingo'], bingo: 'bango')
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when payload has a hash" do
|
67
|
+
context "and it is a non-recursive hash" do
|
68
|
+
let(:expected_body) { /"params":{"bongo":{"bish":"\[Filtered\]"}}/ }
|
69
|
+
include_examples('blacklisting', ['bish'], bongo: { bish: 'bash' })
|
70
|
+
end
|
71
|
+
|
72
|
+
context "and it is a recursive hash" do
|
73
|
+
let(:expected_body) { /"params":{"bingo":{"bango":"\[Filtered\]"}}/ }
|
74
|
+
|
75
|
+
bongo = { bingo: {} }
|
76
|
+
bongo[:bingo][:bango] = bongo
|
77
|
+
|
78
|
+
include_examples('blacklisting', ['bango'], bongo)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when there was invalid pattern provided" do
|
83
|
+
let(:expected_output) do
|
84
|
+
/ERROR.+KeysBlacklist is invalid.+patterns: \[#<Object:.+>\]/
|
85
|
+
end
|
86
|
+
|
87
|
+
include_examples('logging', [Object.new], bingo: 'bango')
|
88
|
+
end
|
89
|
+
|
90
|
+
context "when there was a proc provided, which returns an array of keys" do
|
91
|
+
let(:expected_body) { /"params":{"bingo":"\[Filtered\]","bongo":"bish"}/ }
|
92
|
+
include_examples('blacklisting', [proc { 'bingo' }], bingo: 'bango', bongo: 'bish')
|
93
|
+
end
|
94
|
+
|
95
|
+
context "when there was a proc provided along with normal keys" do
|
96
|
+
let(:expected_body) do
|
97
|
+
/"params":{"bingo":"bango","bongo":"\[Filtered\]","bash":"\[Filtered\]"}/
|
98
|
+
end
|
99
|
+
|
100
|
+
include_examples(
|
101
|
+
'blacklisting',
|
102
|
+
[proc { 'bongo' }, :bash],
|
103
|
+
bingo: 'bango', bongo: 'bish', bash: 'bosh'
|
104
|
+
)
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when there was a proc provided, which doesn't return an array of keys" do
|
108
|
+
let(:expected_output) do
|
109
|
+
/ERROR.+KeysBlacklist is invalid.+patterns: \[#<Object:.+>\]/
|
110
|
+
end
|
111
|
+
|
112
|
+
include_examples('logging', [proc { Object.new }], bingo: 'bango')
|
113
|
+
|
114
|
+
it "doesn't blacklist keys" do
|
115
|
+
blacklist = { blacklist_keys: [proc { Object.new }] }
|
116
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(blacklist))
|
117
|
+
|
118
|
+
notifier.notify_sync(ex, bingo: 'bango', bongo: 'bish')
|
119
|
+
|
120
|
+
expect_a_request_with_body(/"params":{"bingo":"bango","bongo":"bish"}/)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when there was a proc provided, which returns another proc" do
|
125
|
+
context "when called once" do
|
126
|
+
let(:expected_output) do
|
127
|
+
/ERROR.+KeysBlacklist is invalid.+patterns: \[#<Proc:.+>\]/
|
128
|
+
end
|
129
|
+
|
130
|
+
include_examples('logging', [proc { proc { ['bingo'] } }], bingo: 'bango')
|
131
|
+
end
|
132
|
+
|
133
|
+
context "when called twice" do
|
134
|
+
it "unwinds procs and filters keys" do
|
135
|
+
blacklist = { blacklist_keys: [proc { proc { ['bingo'] } }] }
|
136
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(blacklist))
|
137
|
+
|
138
|
+
notifier.notify_sync(ex, bingo: 'bango', bongo: 'bish')
|
139
|
+
notifier.notify_sync(ex, bingo: 'bango', bongo: 'bish')
|
140
|
+
|
141
|
+
expect_a_request_with_body(
|
142
|
+
/"params":{"bingo":"\[Filtered\]","bongo":"bish"}/
|
143
|
+
)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
it "filters query parameters correctly" do
|
149
|
+
blacklist = { blacklist_keys: ['bish'] }
|
150
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(blacklist))
|
151
|
+
|
152
|
+
notice = notifier.build_notice(ex)
|
153
|
+
notice[:context][:url] = 'http://localhost:3000/crash?foo=bar&baz=bongo&bish=bash&color=%23FFAAFF'
|
154
|
+
|
155
|
+
notifier.notify_sync(notice)
|
156
|
+
|
157
|
+
# rubocop:disable Metrics/LineLength
|
158
|
+
expected_body =
|
159
|
+
%r("context":{.*"url":"http://localhost:3000/crash\?foo=bar&baz=bongo&bish=\[Filtered\]&color=%23FFAAFF".*})
|
160
|
+
# rubocop:enable Metrics/LineLength
|
161
|
+
|
162
|
+
expect_a_request_with_body(expected_body)
|
163
|
+
end
|
164
|
+
|
165
|
+
context "when the user payload is present" do
|
166
|
+
context "and when the user key is ignored" do
|
167
|
+
it "filters out user entirely" do
|
168
|
+
blacklist = { blacklist_keys: ['user'] }
|
169
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(blacklist))
|
170
|
+
|
171
|
+
notice = notifier.build_notice(ex)
|
172
|
+
notice[:context][:user] = { id: 1337, name: 'Bingo Bango' }
|
173
|
+
|
174
|
+
notifier.notify_sync(notice)
|
175
|
+
|
176
|
+
expect_a_request_with_body(/"user":"\[Filtered\]"/)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it "filters out individual user fields" do
|
181
|
+
blacklist = { blacklist_keys: ['name'] }
|
182
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(blacklist))
|
183
|
+
|
184
|
+
notice = notifier.build_notice(ex)
|
185
|
+
notice[:context][:user] = { id: 1337, name: 'Bingo Bango' }
|
186
|
+
|
187
|
+
notifier.notify_sync(notice)
|
188
|
+
|
189
|
+
expect_a_request_with_body(/"user":{"id":1337,"name":"\[Filtered\]"}/)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -225,200 +225,5 @@ RSpec.describe Airbrake::Notifier do
|
|
225
225
|
include_examples 'sent notice', environment: :development
|
226
226
|
end
|
227
227
|
end
|
228
|
-
|
229
|
-
describe ":blacklist_keys" do
|
230
|
-
describe "the list of values" do
|
231
|
-
it "accepts regexps" do
|
232
|
-
params = { blacklist_keys: [/\Abin/] }
|
233
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
234
|
-
|
235
|
-
airbrake.notify_sync(ex, bingo: 'bango')
|
236
|
-
|
237
|
-
expect_a_request_with_body(/"params":{"bingo":"\[Filtered\]"}/)
|
238
|
-
end
|
239
|
-
|
240
|
-
it "accepts symbols" do
|
241
|
-
params = { blacklist_keys: [:bingo] }
|
242
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
243
|
-
|
244
|
-
airbrake.notify_sync(ex, bingo: 'bango')
|
245
|
-
|
246
|
-
expect_a_request_with_body(/"params":{"bingo":"\[Filtered\]"}/)
|
247
|
-
end
|
248
|
-
|
249
|
-
it "accepts strings" do
|
250
|
-
params = { blacklist_keys: ['bingo'] }
|
251
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
252
|
-
|
253
|
-
airbrake.notify_sync(ex, bingo: 'bango')
|
254
|
-
|
255
|
-
expect_a_request_with_body(/"params":{"bingo":"\[Filtered\]"}/)
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
describe "hash values" do
|
260
|
-
context "non-recursive" do
|
261
|
-
it "filters nested hashes" do
|
262
|
-
params = { blacklist_keys: ['bish'] }
|
263
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
264
|
-
|
265
|
-
airbrake.notify_sync(ex, bongo: { bish: 'bash' })
|
266
|
-
|
267
|
-
expect_a_request_with_body(/"params":{"bongo":{"bish":"\[Filtered\]"}}/)
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
context "recursive" do
|
272
|
-
it "filters recursive hashes" do
|
273
|
-
params = { blacklist_keys: ['bango'] }
|
274
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
275
|
-
|
276
|
-
bongo = { bingo: {} }
|
277
|
-
bongo[:bingo][:bango] = bongo
|
278
|
-
|
279
|
-
airbrake.notify_sync(ex, bongo)
|
280
|
-
|
281
|
-
expect_a_request_with_body(/"params":{"bingo":{"bango":"\[Filtered\]"}}/)
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
it "filters query parameters correctly" do
|
287
|
-
params = { blacklist_keys: ['bish'] }
|
288
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
289
|
-
|
290
|
-
notice = airbrake.build_notice(ex)
|
291
|
-
notice[:context][:url] = 'http://localhost:3000/crash?foo=bar&baz=bongo&bish=bash&color=%23FFAAFF'
|
292
|
-
|
293
|
-
airbrake.notify_sync(notice)
|
294
|
-
|
295
|
-
# rubocop:disable Metrics/LineLength
|
296
|
-
expected_body =
|
297
|
-
%r("context":{.*"url":"http://localhost:3000/crash\?foo=bar&baz=bongo&bish=\[Filtered\]&color=%23FFAAFF".*})
|
298
|
-
# rubocop:enable Metrics/LineLength
|
299
|
-
|
300
|
-
expect_a_request_with_body(expected_body)
|
301
|
-
end
|
302
|
-
|
303
|
-
it "filters out user" do
|
304
|
-
params = { blacklist_keys: ['user'] }
|
305
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
306
|
-
|
307
|
-
notice = airbrake.build_notice(ex)
|
308
|
-
notice[:context][:user] = { id: 1337, name: 'Bingo Bango' }
|
309
|
-
|
310
|
-
airbrake.notify_sync(notice)
|
311
|
-
|
312
|
-
expect_a_request_with_body(/"user":"\[Filtered\]"/)
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
316
|
-
describe ":whitelist_keys" do
|
317
|
-
describe "the list of values" do
|
318
|
-
it "accepts regexes" do
|
319
|
-
params = { whitelist_keys: [/\Abin/] }
|
320
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
321
|
-
|
322
|
-
airbrake.notify_sync(ex, bingo: 'bango', bongo: 'bish', bash: 'bosh')
|
323
|
-
|
324
|
-
expect_a_request_with_body(
|
325
|
-
/"params":{"bingo":"bango","bongo":"\[Filtered\]","bash":"\[Filtered\]"}/
|
326
|
-
)
|
327
|
-
end
|
328
|
-
|
329
|
-
it "accepts symbols" do
|
330
|
-
params = { whitelist_keys: [:bongo] }
|
331
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
332
|
-
|
333
|
-
airbrake.notify_sync(ex, bingo: 'bango', bongo: 'bish', bash: 'bosh')
|
334
|
-
|
335
|
-
expect_a_request_with_body(
|
336
|
-
/"params":{"bingo":"\[Filtered\]","bongo":"bish","bash":"\[Filtered\]"}/
|
337
|
-
)
|
338
|
-
end
|
339
|
-
|
340
|
-
it "accepts strings" do
|
341
|
-
params = { whitelist_keys: ['bash'] }
|
342
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
343
|
-
|
344
|
-
airbrake.notify_sync(
|
345
|
-
ex,
|
346
|
-
bingo: 'bango',
|
347
|
-
bongo: 'bish',
|
348
|
-
bash: 'bosh',
|
349
|
-
bbashh: 'bboshh'
|
350
|
-
)
|
351
|
-
|
352
|
-
expect_a_request_with_body(
|
353
|
-
/"params":{"bingo":"\[Filtered\]","bongo":"\[Filtered\]",
|
354
|
-
"bash":"bosh","bbashh":"\[Filtered\]"}/x
|
355
|
-
)
|
356
|
-
end
|
357
|
-
end
|
358
|
-
|
359
|
-
describe "hash values" do
|
360
|
-
context "non-recursive" do
|
361
|
-
it "filters out everything but the provided keys" do
|
362
|
-
params = { whitelist_keys: %w(bongo bish) }
|
363
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
364
|
-
|
365
|
-
airbrake.notify_sync(ex, bingo: 'bango', bongo: { bish: 'bash' })
|
366
|
-
|
367
|
-
expect_a_request_with_body(
|
368
|
-
/"params":{"bingo":"\[Filtered\]","bongo":{"bish":"bash"}}/
|
369
|
-
)
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
context "recursive" do
|
374
|
-
it "errors when nested hashes are not filtered" do
|
375
|
-
params = { whitelist_keys: %w(bingo bango) }
|
376
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
377
|
-
|
378
|
-
bongo = { bingo: {} }
|
379
|
-
bongo[:bingo][:bango] = bongo
|
380
|
-
|
381
|
-
if RUBY_ENGINE == 'jruby'
|
382
|
-
# JRuby might raise two different exceptions, which represent the
|
383
|
-
# same thing. One is a Java exception, the other is a Ruby
|
384
|
-
# exception. It's probably a JRuby bug:
|
385
|
-
# https://github.com/jruby/jruby/issues/1903
|
386
|
-
begin
|
387
|
-
expect do
|
388
|
-
airbrake.notify_sync(ex, bongo)
|
389
|
-
end.to raise_error(SystemStackError)
|
390
|
-
rescue RSpec::Expectations::ExpectationNotMetError
|
391
|
-
expect do
|
392
|
-
airbrake.notify_sync(ex, bongo)
|
393
|
-
end.to raise_error(java.lang.StackOverflowError)
|
394
|
-
end
|
395
|
-
else
|
396
|
-
expect do
|
397
|
-
airbrake.notify_sync(ex, bongo)
|
398
|
-
end.to raise_error(SystemStackError)
|
399
|
-
end
|
400
|
-
end
|
401
|
-
end
|
402
|
-
end
|
403
|
-
|
404
|
-
describe "context/url" do
|
405
|
-
it "filters query parameters correctly" do
|
406
|
-
params = { whitelist_keys: %w(bish) }
|
407
|
-
airbrake = described_class.new(airbrake_params.merge(params))
|
408
|
-
|
409
|
-
notice = airbrake.build_notice(ex)
|
410
|
-
notice[:context][:url] = 'http://localhost:3000/crash?foo=bar&baz=bongo&bish=bash'
|
411
|
-
|
412
|
-
airbrake.notify_sync(notice)
|
413
|
-
|
414
|
-
# rubocop:disable Metrics/LineLength
|
415
|
-
expected_body =
|
416
|
-
%r("context":{.*"url":"http://localhost:3000/crash\?foo=\[Filtered\]&baz=\[Filtered\]&bish=bash".*})
|
417
|
-
# rubocop:enable Metrics/LineLength
|
418
|
-
|
419
|
-
expect_a_request_with_body(expected_body)
|
420
|
-
end
|
421
|
-
end
|
422
|
-
end
|
423
228
|
end
|
424
229
|
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe "Airbrake::Notifier whitelist_keys" do
|
4
|
+
def expect_a_request_with_body(body)
|
5
|
+
expect(a_request(:post, endpoint).with(body: body)).to have_been_made.once
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:project_id) { 105138 }
|
9
|
+
let(:project_key) { 'fd04e13d806a90f96614ad8e529b2822' }
|
10
|
+
let(:localhost) { 'http://localhost:8080' }
|
11
|
+
|
12
|
+
let(:endpoint) do
|
13
|
+
"https://airbrake.io/api/v3/projects/#{project_id}/notices?key=#{project_key}"
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:airbrake_params) do
|
17
|
+
{ project_id: project_id,
|
18
|
+
project_key: project_key,
|
19
|
+
logger: Logger.new(StringIO.new) }
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:ex) { AirbrakeTestError.new }
|
23
|
+
|
24
|
+
shared_examples 'whitelisting' do |keys, params|
|
25
|
+
it "filters everything but the value of the specified key" do
|
26
|
+
whitelist = { whitelist_keys: keys }
|
27
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(whitelist))
|
28
|
+
|
29
|
+
notifier.notify_sync(ex, params)
|
30
|
+
|
31
|
+
expect_a_request_with_body(expected_body)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
shared_examples 'logging' do |keys, params|
|
36
|
+
it "logs the error" do
|
37
|
+
out = StringIO.new
|
38
|
+
whitelist = { whitelist_keys: keys, logger: Logger.new(out) }
|
39
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(whitelist))
|
40
|
+
|
41
|
+
notifier.notify_sync(ex, params)
|
42
|
+
|
43
|
+
expect(out.string).to match(expected_output)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
before do
|
48
|
+
stub_request(:post, endpoint).to_return(status: 201, body: '{}')
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when whitelisting with a Regexp" do
|
52
|
+
let(:expected_body) do
|
53
|
+
/"params":{"bingo":"bango","bongo":"\[Filtered\]","bash":"\[Filtered\]"}/
|
54
|
+
end
|
55
|
+
|
56
|
+
include_examples(
|
57
|
+
'whitelisting',
|
58
|
+
[/\Abin/],
|
59
|
+
bingo: 'bango', bongo: 'bish', bash: 'bosh'
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when whitelisting with a Symbol" do
|
64
|
+
let(:expected_body) do
|
65
|
+
/"params":{"bingo":"\[Filtered\]","bongo":"bish","bash":"\[Filtered\]"}/
|
66
|
+
end
|
67
|
+
|
68
|
+
include_examples(
|
69
|
+
'whitelisting',
|
70
|
+
[:bongo],
|
71
|
+
bingo: 'bango', bongo: 'bish', bash: 'bosh'
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when whitelisting with a String" do
|
76
|
+
let(:expected_body) do
|
77
|
+
/"params":{"bingo":"\[Filtered\]","bongo":"\[Filtered\]",
|
78
|
+
"bash":"bosh","bbashh":"\[Filtered\]"}/x
|
79
|
+
end
|
80
|
+
|
81
|
+
include_examples(
|
82
|
+
'whitelisting',
|
83
|
+
['bash'],
|
84
|
+
bingo: 'bango', bongo: 'bish', bash: 'bosh', bbashh: 'bboshh'
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when payload has a hash" do
|
89
|
+
context "and it is a non-recursive hash" do
|
90
|
+
let(:expected_body) { /"params":{"bingo":"\[Filtered\]","bongo":{"bish":"bash"}}/ }
|
91
|
+
|
92
|
+
include_examples(
|
93
|
+
'whitelisting',
|
94
|
+
%w(bongo bish),
|
95
|
+
bingo: 'bango', bongo: { bish: 'bash' }
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
context "and it is a recursive hash" do
|
100
|
+
it "errors when nested hashes are not filtered" do
|
101
|
+
whitelist = airbrake_params.merge(whitelist_keys: %w(bingo bango))
|
102
|
+
notifier = Airbrake::Notifier.new(whitelist)
|
103
|
+
|
104
|
+
bongo = { bingo: {} }
|
105
|
+
bongo[:bingo][:bango] = bongo
|
106
|
+
|
107
|
+
if RUBY_ENGINE == 'jruby'
|
108
|
+
# JRuby might raise two different exceptions, which represent the
|
109
|
+
# same thing. One is a Java exception, the other is a Ruby
|
110
|
+
# exception. It's probably a JRuby bug:
|
111
|
+
# https://github.com/jruby/jruby/issues/1903
|
112
|
+
begin
|
113
|
+
expect do
|
114
|
+
notifier.notify_sync(ex, bongo)
|
115
|
+
end.to raise_error(SystemStackError)
|
116
|
+
rescue RSpec::Expectations::ExpectationNotMetError
|
117
|
+
expect do
|
118
|
+
notifier.notify_sync(ex, bongo)
|
119
|
+
end.to raise_error(java.lang.StackOverflowError)
|
120
|
+
end
|
121
|
+
else
|
122
|
+
expect do
|
123
|
+
notifier.notify_sync(ex, bongo)
|
124
|
+
end.to raise_error(SystemStackError)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "when there was a proc provided, which returns an array of keys" do
|
131
|
+
let(:expected_body) do
|
132
|
+
/"params":{"bingo":"\[Filtered\]","bongo":"bish","bash":"\[Filtered\]"}/
|
133
|
+
end
|
134
|
+
|
135
|
+
include_examples(
|
136
|
+
'whitelisting',
|
137
|
+
[proc { 'bongo' }],
|
138
|
+
bingo: 'bango', bongo: 'bish', bash: 'bosh'
|
139
|
+
)
|
140
|
+
end
|
141
|
+
|
142
|
+
context "when there was a proc provided along with normal keys" do
|
143
|
+
let(:expected_body) do
|
144
|
+
/"params":{"bingo":"\[Filtered\]","bongo":"bish","bash":"bosh"}/
|
145
|
+
end
|
146
|
+
|
147
|
+
include_examples(
|
148
|
+
'whitelisting',
|
149
|
+
[proc { 'bongo' }, :bash],
|
150
|
+
bingo: 'bango', bongo: 'bish', bash: 'bosh'
|
151
|
+
)
|
152
|
+
end
|
153
|
+
|
154
|
+
context "when there was a proc provided, which returns another proc" do
|
155
|
+
context "when called once" do
|
156
|
+
let(:expected_output) do
|
157
|
+
/ERROR.+KeysWhitelist is invalid.+patterns: \[#<Proc:.+>\]/
|
158
|
+
end
|
159
|
+
|
160
|
+
include_examples('logging', [proc { proc { ['bingo'] } }], bingo: 'bango')
|
161
|
+
end
|
162
|
+
|
163
|
+
context "when called twice" do
|
164
|
+
it "unwinds procs and filters keys" do
|
165
|
+
whitelist = { whitelist_keys: [proc { proc { ['bingo'] } }] }
|
166
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(whitelist))
|
167
|
+
|
168
|
+
notifier.notify_sync(ex, bingo: 'bango', bongo: 'bish')
|
169
|
+
notifier.notify_sync(ex, bingo: 'bango', bongo: 'bish')
|
170
|
+
|
171
|
+
expect_a_request_with_body(
|
172
|
+
/"params":{"bingo":"bango","bongo":"\[Filtered\]"}/
|
173
|
+
)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "when there was a proc provided, which doesn't return an array of keys" do
|
179
|
+
let(:expected_output) do
|
180
|
+
/ERROR.+KeysWhitelist is invalid.+patterns: \[#<Object:.+>\]/
|
181
|
+
end
|
182
|
+
|
183
|
+
include_examples('logging', [proc { Object.new }], bingo: 'bango')
|
184
|
+
|
185
|
+
it "doesn't whitelist keys" do
|
186
|
+
whitelist = { whitelist_keys: [proc { Object.new }] }
|
187
|
+
notifier = Airbrake::Notifier.new(airbrake_params.merge(whitelist))
|
188
|
+
|
189
|
+
notifier.notify_sync(ex, bingo: 'bango', bongo: 'bish')
|
190
|
+
|
191
|
+
expect_a_request_with_body(
|
192
|
+
/"params":{"bingo":"\[Filtered\]","bongo":"\[Filtered\]"}/
|
193
|
+
)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
describe "context/url" do
|
198
|
+
let(:notifier) do
|
199
|
+
Airbrake::Notifier.new(airbrake_params.merge(whitelist_keys: %w(bish)))
|
200
|
+
end
|
201
|
+
|
202
|
+
context "given a standard URL" do
|
203
|
+
it "filters query parameters correctly" do
|
204
|
+
notice = notifier.build_notice(ex)
|
205
|
+
notice[:context][:url] = 'http://localhost:3000/crash?foo=bar&baz=bongo&bish=bash'
|
206
|
+
|
207
|
+
notifier.notify_sync(notice)
|
208
|
+
|
209
|
+
expect_a_request_with_body(
|
210
|
+
# rubocop:disable Metrics/LineLength
|
211
|
+
%r("context":{.*"url":"http://localhost:3000/crash\?foo=\[Filtered\]&baz=\[Filtered\]&bish=bash".*})
|
212
|
+
# rubocop:enable Metrics/LineLength
|
213
|
+
)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context "given a non-standard URL" do
|
218
|
+
it "leaves the URL unfiltered" do
|
219
|
+
notice = notifier.build_notice(ex)
|
220
|
+
notice[:context][:url] =
|
221
|
+
'http://localhost:3000/cra]]]sh?foo=bar&baz=bongo&bish=bash'
|
222
|
+
|
223
|
+
notifier.notify_sync(notice)
|
224
|
+
|
225
|
+
expect_a_request_with_body(
|
226
|
+
# rubocop:disable Metrics/LineLength
|
227
|
+
%r("context":{.*"url":"http://localhost:3000/cra\]\]\]sh\?foo=bar&baz=bongo&bish=bash".*})
|
228
|
+
# rubocop:enable Metrics/LineLength
|
229
|
+
)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
context "given a URL without a query" do
|
234
|
+
it "skips params filtering and leaves the URL untouched" do
|
235
|
+
notice = notifier.build_notice(ex)
|
236
|
+
notice[:context][:url] = 'http://localhost:3000/crash'
|
237
|
+
|
238
|
+
notifier.notify_sync(notice)
|
239
|
+
|
240
|
+
expect_a_request_with_body(
|
241
|
+
%r("context":{.*"url":"http://localhost:3000/crash".*})
|
242
|
+
)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: airbrake-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Airbrake Technologies, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '2'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '2'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: benchmark-ips
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,7 +121,9 @@ files:
|
|
121
121
|
- spec/nested_exception_spec.rb
|
122
122
|
- spec/notice_spec.rb
|
123
123
|
- spec/notifier_spec.rb
|
124
|
+
- spec/notifier_spec/blacklist_keys_spec.rb
|
124
125
|
- spec/notifier_spec/options_spec.rb
|
126
|
+
- spec/notifier_spec/whitelist_keys_spec.rb
|
125
127
|
- spec/payload_truncator_spec.rb
|
126
128
|
- spec/spec_helper.rb
|
127
129
|
- spec/sync_sender_spec.rb
|
@@ -158,7 +160,9 @@ test_files:
|
|
158
160
|
- spec/filter_chain_spec.rb
|
159
161
|
- spec/nested_exception_spec.rb
|
160
162
|
- spec/notice_spec.rb
|
163
|
+
- spec/notifier_spec/blacklist_keys_spec.rb
|
161
164
|
- spec/notifier_spec/options_spec.rb
|
165
|
+
- spec/notifier_spec/whitelist_keys_spec.rb
|
162
166
|
- spec/notifier_spec.rb
|
163
167
|
- spec/payload_truncator_spec.rb
|
164
168
|
- spec/spec_helper.rb
|