bugsnag 6.13.1 → 6.14.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,31 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## 6.14.0 (20 July 2020)
5
+
6
+ ### Enhancements
7
+
8
+ * Add configurable `discard_classes` option to allow filtering errors using either a `String` or `Regexp` matched against the error's class name
9
+ | [#597](https://github.com/bugsnag/bugsnag-ruby/pull/597)
10
+
11
+ * The Breadcrumb name limit of 30 characters has been removed
12
+ | [#600](https://github.com/bugsnag/bugsnag-ruby/pull/600)
13
+
14
+ * Improve performance of payload cleaning
15
+ | [#601](https://github.com/bugsnag/bugsnag-ruby/pull/601)
16
+
17
+ * Improve performance when processing stacktraces
18
+ | [#602](https://github.com/bugsnag/bugsnag-ruby/pull/602)
19
+ | [#603](https://github.com/bugsnag/bugsnag-ruby/pull/603)
20
+
21
+ * If a custom object responds to `id` method, show the id and class in error reports
22
+ | [#531](https://github.com/bugsnag/bugsnag-ruby/pull/531)
23
+ | [manojmj92](https://github.com/manojmj92)
24
+
25
+ ### Deprecated
26
+
27
+ * The `ignore_classes` configuration option has been deprecated in favour of `discard_classes`. `ignore_classes` will be removed in the next major release
28
+
4
29
  ## 6.13.1 (11 May 2020)
5
30
 
6
31
  ### Fixes
data/Gemfile CHANGED
@@ -32,13 +32,15 @@ group :coverage, optional: true do
32
32
  end
33
33
 
34
34
  group :rubocop, optional: true do
35
- gem 'rubocop', '~> 0.52.1'
35
+ gem 'rubocop', '~> 0.83'
36
36
  end
37
37
 
38
38
  group :sidekiq, optional: true do
39
39
  gem 'sidekiq', '~> 5.2.7'
40
40
  # redis 4.1.2 dropped support for Ruby 2.2
41
41
  gem 'redis', ruby_version < Gem::Version.new('2.3.0') ? '4.1.1' : '>= 4.1.2'
42
+ # rack 2.2.0 dropped support for Ruby 2.2
43
+ gem 'rack', ruby_version < Gem::Version.new('2.3.0') ? '< 2.2.0' : '~> 2.2'
42
44
  end
43
45
 
44
46
  group :doc, optional: true do
data/TESTING.md CHANGED
@@ -42,7 +42,7 @@ aws configure --profile=opensource
42
42
  Subsequently you'll need to run the following commmand to authenticate with the registry:
43
43
 
44
44
  ```
45
- $(aws ecr get-login --profile=opensource --no-include-email)
45
+ aws ecr get-login-password --profile=opensource | docker login --username AWS --password-stdin 855461928731.dkr.ecr.us-west-1.amazonaws.com
46
46
  ```
47
47
 
48
48
  __Your session will periodically expire__, so you'll need to run this command to re-authenticate when that happens.
@@ -64,7 +64,7 @@ Configure the tests to be run in the following way:
64
64
  When running the end-to-end tests, you'll want to restrict the feature files run to the specific test features for the platform. This is done using the Cucumber CLI syntax at the end of the `docker-compose run ruby-maze-runner` command, i.e:
65
65
 
66
66
  ```
67
- RUBY_TEST_VERSION=2.6 RAILS_VERSION=6 docker-compose run ruby-maze-runner features/rails_features --tags "@rails6"
67
+ RUBY_TEST_VERSION=2.6 RAILS_VERSION=6 docker-compose run --use-aliases ruby-maze-runner features/rails_features --tags "@rails6"
68
68
  ```
69
69
 
70
70
  - Plain ruby tests should target `features/plain_features`
@@ -75,7 +75,7 @@ RUBY_TEST_VERSION=2.6 RAILS_VERSION=6 docker-compose run ruby-maze-runner featur
75
75
  In order to target specific features the exact `.feature` file can be specified, i.e:
76
76
 
77
77
  ```
78
- RUBY_TEST_VERSION=2.6 RAILS_VERSION=6 docker-compose run ruby-maze-runner features/rails_features/app_version.feature --tags "@rails6"
78
+ RUBY_TEST_VERSION=2.6 RAILS_VERSION=6 docker-compose run --use-aliases ruby-maze-runner features/rails_features/app_version.feature --tags "@rails6"
79
79
  ```
80
80
 
81
81
  In order to avoid running flakey or unfinished tests, the tag `"not @wip"` can be added to the tags option. This is recommended for all CI runs. If a tag is already specified, this should be added using the `and` keyword, e.g. `--tags "@rails6 and not @wip"`
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.13.1
1
+ 6.14.0
@@ -20,7 +20,7 @@ COPY spec ./spec
20
20
  RUN gem build bugsnag.gemspec
21
21
 
22
22
  # The maze-runner node tests
23
- FROM 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner:v2-cli as ruby-maze-runner
23
+ FROM 855461928731.dkr.ecr.us-west-1.amazonaws.com/maze-runner:latest-cli as ruby-maze-runner
24
24
  WORKDIR /app/
25
25
  COPY features ./features
26
26
  COPY --from=ruby-package-builder /app/bugsnag-*.gem bugsnag.gem
@@ -11,10 +11,11 @@ Bugsnag.configure do |config|
11
11
  config.release_stage = ENV["BUGSNAG_RELEASE_STAGE"] if ENV.include? "BUGSNAG_RELEASE_STAGE"
12
12
  config.send_code = ENV["BUGSNAG_SEND_CODE"] != "false"
13
13
  config.send_environment = ENV["BUGSNAG_SEND_ENVIRONMENT"] == "true"
14
+ config.meta_data_filters << 'filtered_parameter'
14
15
 
15
16
  if ENV["SQL_ONLY_BREADCRUMBS"] == "true"
16
17
  config.before_breadcrumb_callbacks << Proc.new do |breadcrumb|
17
18
  breadcrumb.ignore! unless breadcrumb.meta_data[:event_name] == "sql.active_record" && breadcrumb.meta_data[:name] == "User Load"
18
19
  end
19
20
  end
20
- end
21
+ end
@@ -11,6 +11,7 @@ Bugsnag.configure do |config|
11
11
  config.release_stage = ENV["BUGSNAG_RELEASE_STAGE"] if ENV.include? "BUGSNAG_RELEASE_STAGE"
12
12
  config.send_code = ENV["BUGSNAG_SEND_CODE"] != "false"
13
13
  config.send_environment = ENV["BUGSNAG_SEND_ENVIRONMENT"] == "true"
14
+ config.meta_data_filters << 'filtered_parameter'
14
15
 
15
16
  if ENV["SQL_ONLY_BREADCRUMBS"] == "true"
16
17
  config.before_breadcrumb_callbacks << Proc.new do |breadcrumb|
@@ -11,6 +11,7 @@ Bugsnag.configure do |config|
11
11
  config.release_stage = ENV["BUGSNAG_RELEASE_STAGE"] if ENV.include? "BUGSNAG_RELEASE_STAGE"
12
12
  config.send_code = ENV["BUGSNAG_SEND_CODE"] != "false"
13
13
  config.send_environment = ENV["BUGSNAG_SEND_ENVIRONMENT"] == "true"
14
+ config.meta_data_filters << 'filtered_parameter'
14
15
 
15
16
  if ENV["SQL_ONLY_BREADCRUMBS"] == "true"
16
17
  config.before_breadcrumb_callbacks << Proc.new do |breadcrumb|
@@ -11,6 +11,7 @@ Bugsnag.configure do |config|
11
11
  config.release_stage = ENV["BUGSNAG_RELEASE_STAGE"] if ENV.include? "BUGSNAG_RELEASE_STAGE"
12
12
  config.send_code = ENV["BUGSNAG_SEND_CODE"] != "false"
13
13
  config.send_environment = ENV["BUGSNAG_SEND_ENVIRONMENT"] == "true"
14
+ config.meta_data_filters << 'filtered_parameter'
14
15
 
15
16
  if ENV["SQL_ONLY_BREADCRUMBS"] == "true"
16
17
  config.before_breadcrumb_callbacks << Proc.new do |breadcrumb|
@@ -3,12 +3,14 @@ Feature: Metadata filters
3
3
  @rails3 @rails4 @rails5 @rails6
4
4
  Scenario: Meta_data_filters should include Rails.configuration.filter_parameters
5
5
  Given I start the rails service
6
- When I navigate to the route "/metadata_filters/filter" on the rails app
6
+ When I navigate to the route "/metadata_filters/filter?filtered_parameter=foo&other_parameter=bar" on the rails app
7
7
  And I wait to receive a request
8
8
  Then the request is valid for the error reporting API version "4.0" for the "Ruby Bugsnag Notifier"
9
9
  And the event "unhandled" is false
10
10
  And the exception "errorClass" equals "RuntimeError"
11
11
  And the exception "message" starts with "handled string"
12
12
  And the event "app.type" equals "rails"
13
- And the event "metaData.request.url" ends with "/metadata_filters/filter"
13
+ And the event "metaData.request.url" ends with "/metadata_filters/filter?filtered_parameter=[FILTERED]&other_parameter=bar"
14
14
  And the event "metaData.my_specific_filter" equals "[FILTERED]"
15
+ And the event "metaData.request.params.filtered_parameter" equals "[FILTERED]"
16
+ And the event "metaData.request.params.other_parameter" equals "bar"
@@ -33,6 +33,7 @@ require "bugsnag/breadcrumbs/validator"
33
33
  require "bugsnag/breadcrumbs/breadcrumb"
34
34
  require "bugsnag/breadcrumbs/breadcrumbs"
35
35
 
36
+ # rubocop:todo Metrics/ModuleLength
36
37
  module Bugsnag
37
38
  LOCK = Mutex.new
38
39
  INTEGRATIONS = [:resque, :sidekiq, :mailman, :delayed_job, :shoryuken, :que, :mongo]
@@ -63,7 +64,7 @@ module Bugsnag
63
64
  auto_notify = false
64
65
  end
65
66
 
66
- return unless deliver_notification?(exception, auto_notify)
67
+ return unless should_deliver_notification?(exception, auto_notify)
67
68
 
68
69
  exception = NIL_EXCEPTION_DESCRIPTION if exception.nil?
69
70
 
@@ -71,6 +72,7 @@ module Bugsnag
71
72
 
72
73
  # If this is an auto_notify we yield the block before the any middleware is run
73
74
  yield(report) if block_given? && auto_notify
75
+
74
76
  if report.ignore?
75
77
  configuration.debug("Not notifying #{report.exceptions.last[:errorClass]} due to ignore being signified in auto_notify block")
76
78
  return
@@ -97,6 +99,7 @@ module Bugsnag
97
99
  # If this is not an auto_notify then the block was provided by the user. This should be the last
98
100
  # block that is run as it is the users "most specific" block.
99
101
  yield(report) if block_given? && !auto_notify
102
+
100
103
  if report.ignore?
101
104
  configuration.debug("Not notifying #{report.exceptions.last[:errorClass]} due to ignore being signified in user provided block")
102
105
  return
@@ -111,13 +114,7 @@ module Bugsnag
111
114
  report.severity_reason = initial_reason
112
115
  end
113
116
 
114
- # Deliver
115
- configuration.info("Notifying #{configuration.notify_endpoint} of #{report.exceptions.last[:errorClass]}")
116
- options = {:headers => report.headers}
117
- payload = ::JSON.dump(Bugsnag::Helpers.trim_if_needed(report.as_json))
118
- Bugsnag::Delivery[configuration.delivery_method].deliver(configuration.notify_endpoint, payload, configuration, options)
119
- report_summary = report.summary
120
- leave_breadcrumb(report_summary[:error_class], report_summary, Bugsnag::Breadcrumbs::ERROR_BREADCRUMB_TYPE, :auto)
117
+ deliver_notification(report)
121
118
  end
122
119
  end
123
120
 
@@ -147,6 +144,7 @@ module Bugsnag
147
144
  # Configuration getters
148
145
  ##
149
146
  # Returns the client's Configuration object, or creates one if not yet created.
147
+ # @return [Configuration]
150
148
  def configuration
151
149
  @configuration = nil unless defined?(@configuration)
152
150
  @configuration || LOCK.synchronize { @configuration ||= Bugsnag::Configuration.new }
@@ -211,27 +209,40 @@ module Bugsnag
211
209
  validator.validate(breadcrumb)
212
210
 
213
211
  # Skip if it's already invalid
214
- unless breadcrumb.ignore?
215
- # Run callbacks
216
- configuration.before_breadcrumb_callbacks.each do |c|
217
- c.arity > 0 ? c.call(breadcrumb) : c.call
218
- break if breadcrumb.ignore?
219
- end
212
+ return if breadcrumb.ignore?
220
213
 
221
- # Return early if ignored
222
- return if breadcrumb.ignore?
214
+ # Run callbacks
215
+ configuration.before_breadcrumb_callbacks.each do |c|
216
+ c.arity > 0 ? c.call(breadcrumb) : c.call
217
+ break if breadcrumb.ignore?
218
+ end
219
+
220
+ # Return early if ignored
221
+ return if breadcrumb.ignore?
223
222
 
224
- # Validate again in case of callback alteration
225
- validator.validate(breadcrumb)
223
+ # Validate again in case of callback alteration
224
+ validator.validate(breadcrumb)
226
225
 
227
- # Add to breadcrumbs buffer if still valid
228
- configuration.breadcrumbs << breadcrumb unless breadcrumb.ignore?
226
+ # Add to breadcrumbs buffer if still valid
227
+ configuration.breadcrumbs << breadcrumb unless breadcrumb.ignore?
228
+ end
229
+
230
+ ##
231
+ # Returns the client's Cleaner object, or creates one if not yet created.
232
+ #
233
+ # @api private
234
+ #
235
+ # @return [Cleaner]
236
+ def cleaner
237
+ @cleaner = nil unless defined?(@cleaner)
238
+ @cleaner || LOCK.synchronize do
239
+ @cleaner ||= Bugsnag::Cleaner.new(configuration)
229
240
  end
230
241
  end
231
242
 
232
243
  private
233
244
 
234
- def deliver_notification?(exception, auto_notify)
245
+ def should_deliver_notification?(exception, auto_notify)
235
246
  reason = abort_reason(exception, auto_notify)
236
247
  configuration.debug(reason) unless reason.nil?
237
248
  reason.nil?
@@ -249,6 +260,32 @@ module Bugsnag
249
260
  end
250
261
  end
251
262
 
263
+ ##
264
+ # Deliver the notification to Bugsnag
265
+ #
266
+ # @param report [Report]
267
+ # @return void
268
+ def deliver_notification(report)
269
+ configuration.info("Notifying #{configuration.notify_endpoint} of #{report.exceptions.last[:errorClass]}")
270
+
271
+ payload = report_to_json(report)
272
+ options = {:headers => report.headers}
273
+
274
+ Bugsnag::Delivery[configuration.delivery_method].deliver(
275
+ configuration.notify_endpoint,
276
+ payload,
277
+ configuration,
278
+ options
279
+ )
280
+
281
+ leave_breadcrumb(
282
+ report.summary[:error_class],
283
+ report.summary,
284
+ Bugsnag::Breadcrumbs::ERROR_BREADCRUMB_TYPE,
285
+ :auto
286
+ )
287
+ end
288
+
252
289
  # Check if the API key is valid and warn (once) if it is not
253
290
  def check_key_valid
254
291
  @key_warning = false unless defined?(@key_warning)
@@ -273,7 +310,23 @@ module Bugsnag
273
310
  raise ArgumentError, "The session endpoint cannot be modified without the notify endpoint"
274
311
  end
275
312
  end
313
+
314
+ ##
315
+ # Convert the Report object to JSON
316
+ #
317
+ # We ensure the report is safe to send by removing recursion, fixing
318
+ # encoding errors and redacting metadata according to "meta_data_filters"
319
+ #
320
+ # @param report [Report]
321
+ # @return string
322
+ def report_to_json(report)
323
+ cleaned = cleaner.clean_object(report.as_json)
324
+ trimmed = Bugsnag::Helpers.trim_if_needed(cleaned)
325
+
326
+ ::JSON.dump(trimmed)
327
+ end
276
328
  end
277
329
  end
330
+ # rubocop:enable Metrics/ModuleLength
278
331
 
279
332
  Bugsnag.load_integrations unless ENV["BUGSNAG_DISABLE_AUTOCONFIGURE"]
@@ -1,6 +1,4 @@
1
1
  module Bugsnag::Breadcrumbs
2
- MAX_NAME_LENGTH = 30
3
-
4
2
  VALID_BREADCRUMB_TYPES = [
5
3
  ERROR_BREADCRUMB_TYPE = "error",
6
4
  MANUAL_BREADCRUMB_TYPE = "manual",
@@ -15,12 +15,6 @@ module Bugsnag::Breadcrumbs
15
15
  #
16
16
  # @param breadcrumb [Bugsnag::Breadcrumbs::Breadcrumb] the breadcrumb to be validated
17
17
  def validate(breadcrumb)
18
- # Check name length
19
- if breadcrumb.name.size > Bugsnag::Breadcrumbs::MAX_NAME_LENGTH
20
- @configuration.debug("Breadcrumb name trimmed to length #{Bugsnag::Breadcrumbs::MAX_NAME_LENGTH}. Original name: #{breadcrumb.name}")
21
- breadcrumb.name = breadcrumb.name.slice(0...Bugsnag::Breadcrumbs::MAX_NAME_LENGTH)
22
- end
23
-
24
18
  # Check meta_data hash doesn't contain complex values
25
19
  breadcrumb.meta_data = breadcrumb.meta_data.select do |k, v|
26
20
  if valid_meta_data_type?(v)
@@ -1,19 +1,76 @@
1
1
  require 'uri'
2
2
 
3
3
  module Bugsnag
4
+ # @api private
4
5
  class Cleaner
5
6
  FILTERED = '[FILTERED]'.freeze
6
7
  RECURSION = '[RECURSION]'.freeze
7
8
  OBJECT = '[OBJECT]'.freeze
8
9
  RAISED = '[RAISED]'.freeze
10
+ OBJECT_WITH_ID_AND_CLASS = '[OBJECT]: [Class]: %<class_name>s [ID]: %<id>d'.freeze
9
11
 
10
- def initialize(filters)
11
- @filters = Array(filters)
12
- @deep_filters = @filters.any? {|f| f.kind_of?(Regexp) && f.to_s.include?("\\.".freeze) }
12
+ ##
13
+ # @param configuration [Configuration]
14
+ def initialize(configuration)
15
+ @configuration = configuration
13
16
  end
14
17
 
15
- def clean_object(obj)
16
- traverse_object(obj, {}, nil)
18
+ def clean_object(object)
19
+ @deep_filters = deep_filters?
20
+
21
+ traverse_object(object, {}, nil)
22
+ end
23
+
24
+ ##
25
+ # @param url [String]
26
+ # @return [String]
27
+ def clean_url(url)
28
+ return url if @configuration.meta_data_filters.empty?
29
+
30
+ uri = URI(url)
31
+ return url unless uri.query
32
+
33
+ query_params = uri.query.split('&').map { |pair| pair.split('=') }
34
+ query_params.map! do |key, val|
35
+ if filters_match?(key)
36
+ "#{key}=#{FILTERED}"
37
+ else
38
+ "#{key}=#{val}"
39
+ end
40
+ end
41
+
42
+ uri.query = query_params.join('&')
43
+ uri.to_s
44
+ end
45
+
46
+ private
47
+
48
+ ##
49
+ # This method calculates whether we need to filter deeply or not; i.e. whether
50
+ # we should match both with and without 'request.params'
51
+ #
52
+ # This is cached on the instance variable '@deep_filters' for performance
53
+ # reasons
54
+ #
55
+ # @return [Boolean]
56
+ def deep_filters?
57
+ @configuration.meta_data_filters.any? do |filter|
58
+ filter.is_a?(Regexp) && filter.to_s.include?("\\.".freeze)
59
+ end
60
+ end
61
+
62
+ def clean_string(str)
63
+ if defined?(str.encoding) && defined?(Encoding::UTF_8)
64
+ if str.encoding == Encoding::UTF_8
65
+ str.valid_encoding? ? str : str.encode('utf-16', invalid: :replace, undef: :replace).encode('utf-8')
66
+ else
67
+ str.encode('utf-8', invalid: :replace, undef: :replace)
68
+ end
69
+ elsif defined?(Iconv)
70
+ Iconv.conv('UTF-8//IGNORE', 'UTF-8', str) || str
71
+ else
72
+ str
73
+ end
17
74
  end
18
75
 
19
76
  def traverse_object(obj, seen, scope)
@@ -28,12 +85,14 @@ module Bugsnag
28
85
  value = case obj
29
86
  when Hash
30
87
  clean_hash = {}
31
- obj.each do |k,v|
88
+ obj.each do |k, v|
32
89
  begin
33
- if filters_match_deeply?(k, scope)
90
+ current_scope = [scope, k].compact.join('.')
91
+
92
+ if filters_match_deeply?(k, current_scope)
34
93
  clean_hash[k] = FILTERED
35
94
  else
36
- clean_hash[k] = traverse_object(v, seen, [scope, k].compact.join('.'))
95
+ clean_hash[k] = traverse_object(v, seen, current_scope)
37
96
  end
38
97
  # If we get an error here, we assume the key needs to be filtered
39
98
  # to avoid leaking things we shouldn't. We also remove the key itself
@@ -63,7 +122,12 @@ module Bugsnag
63
122
 
64
123
  # avoid leaking potentially sensitive data from objects' #inspect output
65
124
  if str =~ /#<.*>/
66
- OBJECT
125
+ # Use id of the object if available
126
+ if obj.respond_to?(:id)
127
+ format(OBJECT_WITH_ID_AND_CLASS, class_name: obj.class, id: obj.id)
128
+ else
129
+ OBJECT
130
+ end
67
131
  else
68
132
  clean_string(str)
69
133
  end
@@ -73,67 +137,56 @@ module Bugsnag
73
137
  value
74
138
  end
75
139
 
76
- def clean_string(str)
77
- if defined?(str.encoding) && defined?(Encoding::UTF_8)
78
- if str.encoding == Encoding::UTF_8
79
- str.valid_encoding? ? str : str.encode('utf-16', invalid: :replace, undef: :replace).encode('utf-8')
140
+ ##
141
+ # @param key [String, #to_s]
142
+ # @return [Boolean]
143
+ def filters_match?(key)
144
+ str = key.to_s
145
+
146
+ @configuration.meta_data_filters.any? do |filter|
147
+ case filter
148
+ when Regexp
149
+ str.match(filter)
80
150
  else
81
- str.encode('utf-8', invalid: :replace, undef: :replace)
151
+ str.include?(filter.to_s)
82
152
  end
83
- elsif defined?(Iconv)
84
- Iconv.conv('UTF-8//IGNORE', 'UTF-8', str) || str
85
- else
86
- str
87
153
  end
88
154
  end
89
155
 
90
- def self.clean_object_encoding(obj)
91
- new(nil).clean_object(obj)
92
- end
156
+ ##
157
+ # If someone has a Rails filter like /^stuff\.secret/, it won't match
158
+ # "request.params.stuff.secret", so we try it both with and without the
159
+ # "request.params." bit.
160
+ #
161
+ # @param key [String, #to_s]
162
+ # @param scope [String]
163
+ # @return [Boolean]
164
+ def filters_match_deeply?(key, scope)
165
+ return false unless scope_should_be_filtered?(scope)
93
166
 
94
- def clean_url(url)
95
- return url if @filters.empty?
167
+ return true if filters_match?(key)
168
+ return false unless @deep_filters
96
169
 
97
- uri = URI(url)
98
- return url unless uri.query
170
+ return true if filters_match?(scope)
99
171
 
100
- query_params = uri.query.split('&').map { |pair| pair.split('=') }
101
- query_params.map! do |key, val|
102
- if filters_match?(key)
103
- "#{key}=#{FILTERED}"
172
+ @configuration.scopes_to_filter.any? do |scope_to_filter|
173
+ if scope.start_with?("#{scope_to_filter}.request.params.")
174
+ filters_match?(scope.sub("#{scope_to_filter}.request.params.", ''))
104
175
  else
105
- "#{key}=#{val}"
176
+ filters_match?(scope.sub("#{scope_to_filter}.", ''))
106
177
  end
107
178
  end
108
-
109
- uri.query = query_params.join('&')
110
- uri.to_s
111
179
  end
112
180
 
113
- private
114
-
115
- def filters_match?(key)
116
- str = key.to_s
117
-
118
- @filters.any? do |f|
119
- case f
120
- when Regexp
121
- str.match(f)
122
- else
123
- str.include?(f.to_s)
124
- end
181
+ ##
182
+ # Should the given scope be filtered?
183
+ #
184
+ # @param scope [String]
185
+ # @return [Boolean]
186
+ def scope_should_be_filtered?(scope)
187
+ @configuration.scopes_to_filter.any? do |scope_to_filter|
188
+ scope.start_with?("#{scope_to_filter}.")
125
189
  end
126
190
  end
127
-
128
- # If someone has a Rails filter like /^stuff\.secret/, it won't match "request.params.stuff.secret",
129
- # so we try it both with and without the "request.params." bit.
130
- def filters_match_deeply?(key, scope)
131
- return true if filters_match?(key)
132
- return false unless @deep_filters
133
-
134
- long = [scope, key].compact.join('.')
135
- short = long.sub(/^request\.params\./, '')
136
- filters_match?(long) || filters_match?(short)
137
- end
138
191
  end
139
192
  end