blinkist-airbrake-scrubber 2.0.1 → 2.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b85ab4bf932163ef87c58a0213d5a66eedcba189
4
- data.tar.gz: 672688d23f9af0da1b52ae0eba8db74612810677
3
+ metadata.gz: f8fc147a1a2aedc718e46ffcb626a3ac6a58fc61
4
+ data.tar.gz: 7118c10d9e7b7e5cd05f0a96bd860131ea982f00
5
5
  SHA512:
6
- metadata.gz: 88453a2053ff065c9e41a841ee984436c625dac0934dba868442faf547d00128657f3c45abeda6773b234e3a0cd903a4c897f750a73d40c9eb96ea4ea6350047
7
- data.tar.gz: c5db35d6b008865fb28bf78dab40eff29aa379a53852fb1cd26cef618b72581c774deb8590ed2176c38e334dac4df172d696a4a97d43817763bd619af95f6aac
6
+ metadata.gz: 7bb657ded1f044a61be2bac7b00c08a9045a9e66fbb1922749626d15b99616afbee9c78089a6cf0c2a47eaedb9600209c389853f9cce9c85f2df880274ff8517
7
+ data.tar.gz: 2ec6867a21e8aee97510781c0d7a8e4ddeefce2f9925ff50f80f1e0e0ab7fade0cf3cc713b5f1c8c2714ed337bbdb99b002bc164479aa45d4654559c7d78a641
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
14
14
  gem.license = "MIT"
15
15
 
16
16
  # Airbrake
17
- gem.add_dependency "airbrake"
17
+ gem.add_dependency "airbrake", "~> 7"
18
18
 
19
19
  gem.files = Dir["{lib,spec}/**/*", "README.md", "Rakefile", "Gemfile", "*.gemspec"]
20
20
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -4,6 +4,7 @@ Dir[File.expand_path('../../lib/**/*.rb', __FILE__)].each do |f|
4
4
  end
5
5
 
6
6
  # Prepend the original Airbrake module
7
+ # Note: Do not remove from this file, it needs to be before Blinkist::Airbrake::Scrubber
7
8
  module Airbrake
8
9
  class << self
9
10
  prepend Blinkist::Airbrake::Scrubber
@@ -28,6 +29,7 @@ module Blinkist
28
29
  def self.run!
29
30
  SCRUBBERS.each { |scrubber| scrubber::scrub! }
30
31
  end
32
+
31
33
  end
32
34
  end
33
35
  end
@@ -0,0 +1,43 @@
1
+ # DeepTraversal provides traverse possibility of Hashes
2
+ # Can handle Hash objects with deep nesting, or other nested objects that can be dug deeper (e.g. Array)
3
+ module Blinkist
4
+ module Airbrake
5
+ module Scrubber
6
+
7
+ class DeepTraversal
8
+ def initialize(source)
9
+ @source = source
10
+ end
11
+
12
+ def traverse(&block)
13
+ recursive_traverse(@source, &block)
14
+ end
15
+
16
+ private
17
+
18
+ def recursive_traverse(input, &block)
19
+ case input
20
+ when Array
21
+ input.map { |i| recursive_traverse(i, &block) }
22
+
23
+ when Hash
24
+ Hash[input.map { |key, value|
25
+
26
+ # Go deeper for things that are not simple objects
27
+ case value
28
+ when Array, Hash
29
+ [ key, recursive_traverse(value, &block) ]
30
+ else
31
+ [ key, block.call(key, value) ]
32
+ end
33
+
34
+ }]
35
+ else
36
+ input
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -5,8 +5,9 @@ module Blinkist
5
5
 
6
6
  def self.scrub!
7
7
  ::Airbrake.add_filter do |notice|
8
- if notice[:params] && notice[:params][:email]
9
- notice[:params][:email] = FILTERED
8
+ notice[:params] = DeepTraversal.new(notice[:params]).traverse do |key, value|
9
+ value = FILTERED if key.to_s == 'email'
10
+ value
10
11
  end
11
12
  notice
12
13
  end
@@ -5,8 +5,9 @@ module Blinkist
5
5
 
6
6
  def self.scrub!
7
7
  ::Airbrake.add_filter do |notice|
8
- if notice[:params] && notice[:params][:password]
9
- notice[:params][:password] = FILTERED
8
+ notice[:params] = DeepTraversal.new(notice[:params]).traverse do |key, value|
9
+ value = FILTERED if key.to_s == 'password'
10
+ value
10
11
  end
11
12
  notice
12
13
  end
@@ -1,7 +1,7 @@
1
1
  module Blinkist
2
2
  module Airbrake
3
3
  module Scrubber
4
- VERSION = "2.0.1"
4
+ VERSION = "2.1.1"
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'blinkist-airbrake-scrubber'
3
+
4
+ describe Blinkist::Airbrake::Scrubber::DeepTraversal do
5
+ subject { described_class.new(source) }
6
+
7
+ let(:source) { Hash.new }
8
+
9
+ describe ".traverse" do
10
+ it "calls .recursive_traverse" do
11
+ expect(subject).to receive(:recursive_traverse).with(source)
12
+ subject.traverse { |k, v| v }
13
+ end
14
+ end
15
+
16
+ context "For single-level hashes" do
17
+ let(:source) { { email: 'user@example.org', password: 'whatever', param: true } }
18
+
19
+ it "filters out any key" do
20
+ returned_object = subject.traverse { |k, v| k.to_s == 'email' ? '[Filtered]' : v }
21
+ expect(returned_object).to eq({ email: '[Filtered]', password: 'whatever', param: true })
22
+ end
23
+
24
+ it "filters out any keys" do
25
+ returned_object = subject.traverse { |k, v| %w{ email password }.include?(k.to_s) ? '[Filtered]' : v }
26
+ expect(returned_object).to eq({ email: '[Filtered]', password: '[Filtered]', param: true })
27
+ end
28
+ end
29
+
30
+ context "For deeply-nested hashes" do
31
+ let(:source) { { email: 'user@example.org', params: { email: 'user@example.org', contact: { email: 'user@example.org' } } } }
32
+
33
+ it "filters out all keys" do
34
+ returned_object = subject.traverse { |k, v| k.to_s == 'email' ? '[Filtered]' : v }
35
+ expect(returned_object).to eq({ email: '[Filtered]', params: { email: '[Filtered]', contact: { email: '[Filtered]' } } })
36
+ end
37
+ end
38
+
39
+ context "For hashes with arrays" do
40
+ let(:source) { { email: 'user@example.org', emails: [ { email: 'user@example.org' }, { email: 'user@example.org' } ], whatever: [ nil ] } }
41
+
42
+ it "filters out all keys" do
43
+ returned_object = subject.traverse { |k, v| k.to_s == 'email' ? '[Filtered]' : v }
44
+ expect(returned_object).to eq({ email: '[Filtered]', emails: [ { email: '[Filtered]' }, { email: '[Filtered]' } ], whatever: [ nil ] })
45
+ end
46
+ end
47
+
48
+ context "For arrays" do
49
+ let(:source) { [ { email: 'user@example.org' }, { email: 'user@example.org' } ] }
50
+
51
+ it "filters out all keys" do
52
+ returned_object = subject.traverse { |k, v| k.to_s == 'email' ? '[Filtered]' : v }
53
+ expect(returned_object).to eq([ { email: '[Filtered]' }, { email: '[Filtered]' } ])
54
+ end
55
+ end
56
+
57
+ context "For simple objects (non-hash, non-array)" do
58
+ it "doesn't break String" do
59
+ returned_object = described_class.new("Sample").traverse { |k, v| k.to_s == 'email' ? '[Filtered]' : v }
60
+ expect(returned_object).to eq("Sample")
61
+ end
62
+
63
+ it "doesn't break Fixnum" do
64
+ returned_object = described_class.new(1).traverse { |k, v| k.to_s == 'email' ? '[Filtered]' : v }
65
+ expect(returned_object).to eq(1)
66
+ end
67
+
68
+ it "doesn't break Float" do
69
+ returned_object = described_class.new(3.14).traverse { |k, v| k.to_s == 'email' ? '[Filtered]' : v }
70
+ expect(returned_object).to eq(3.14)
71
+ end
72
+ end
73
+ end
@@ -25,6 +25,17 @@ describe Blinkist::Airbrake::Scrubber::ParamsEmail do
25
25
  notifier.instance_variable_get(:@filter_chain).refine(notice)
26
26
  expect(notice[:params][:email]).to eq(Blinkist::Airbrake::Scrubber::FILTERED)
27
27
  end
28
+
29
+ it "scrubs the deep-nested email from the params hash" do
30
+ notice = Airbrake[:default].build_notice(
31
+ Exception.new('whatever'),
32
+ { email: 'user@example.org', deeply: { nested: { email: 'user@example.org' } } }
33
+ )
34
+
35
+ notifier.instance_variable_get(:@filter_chain).refine(notice)
36
+ expect(notice[:params][:email]).to eq(Blinkist::Airbrake::Scrubber::FILTERED)
37
+ expect(notice[:params][:deeply][:nested][:email]).to eq(Blinkist::Airbrake::Scrubber::FILTERED)
38
+ end
28
39
  end
29
40
 
30
41
  end
@@ -25,6 +25,17 @@ describe Blinkist::Airbrake::Scrubber::ParamsPassword do
25
25
  notifier.instance_variable_get(:@filter_chain).refine(notice)
26
26
  expect(notice[:params][:password]).to eq(Blinkist::Airbrake::Scrubber::FILTERED)
27
27
  end
28
+
29
+ it "scrubs the deep-nested password from the params hash" do
30
+ notice = Airbrake[:default].build_notice(
31
+ Exception.new('whatever'),
32
+ { password: 'whatever', deeply: { nested: { password: 'whatever' } } }
33
+ )
34
+
35
+ notifier.instance_variable_get(:@filter_chain).refine(notice)
36
+ expect(notice[:params][:password]).to eq(Blinkist::Airbrake::Scrubber::FILTERED)
37
+ expect(notice[:params][:deeply][:nested][:password]).to eq(Blinkist::Airbrake::Scrubber::FILTERED)
38
+ end
28
39
  end
29
40
 
30
41
  end
@@ -10,9 +10,9 @@ describe Blinkist::Airbrake::Scrubber::VERSION do
10
10
  expect(version.instance_of?(String)).to be true
11
11
  end
12
12
 
13
- it 'equals 2.0.1 for auto-check purposes' do
13
+ it 'equals 2.1.1 for auto-check purposes' do
14
14
  version = Blinkist::Airbrake::Scrubber::VERSION
15
- expect(version).to eq '2.0.1'
15
+ expect(version).to eq '2.1.1'
16
16
  end
17
17
 
18
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blinkist-airbrake-scrubber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paweł Komarnicki
@@ -15,16 +15,16 @@ dependencies:
15
15
  name: airbrake
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ">="
18
+ - - "~>"
19
19
  - !ruby/object:Gem::Version
20
- version: '0'
20
+ version: '7'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ">="
25
+ - - "~>"
26
26
  - !ruby/object:Gem::Version
27
- version: '0'
27
+ version: '7'
28
28
  description: Email scrubbing configuration for Airbrake at Blinkist
29
29
  email:
30
30
  - pawel@blinkist.com
@@ -38,12 +38,14 @@ files:
38
38
  - Rakefile
39
39
  - blinkist-airbrake-scrubber.gemspec
40
40
  - lib/blinkist-airbrake-scrubber.rb
41
+ - lib/blinkist-airbrake-scrubber/deep_traversal.rb
41
42
  - lib/blinkist-airbrake-scrubber/scrubbers/message_email.rb
42
43
  - lib/blinkist-airbrake-scrubber/scrubbers/params_email.rb
43
44
  - lib/blinkist-airbrake-scrubber/scrubbers/params_password.rb
44
45
  - lib/blinkist-airbrake-scrubber/version.rb
45
46
  - spec/spec_helper.rb
46
- - spec/specs/lib/airbrake_spec.rb
47
+ - spec/specs/lib/blinkist-airbrake-scrubber/airbrake_spec.rb
48
+ - spec/specs/lib/blinkist-airbrake-scrubber/deep_traversal_spec.rb
47
49
  - spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/message_email_spec.rb
48
50
  - spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/params_email_spec.rb
49
51
  - spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/params_password_spec.rb
@@ -75,7 +77,8 @@ specification_version: 4
75
77
  summary: With this, Airbrake will not leak emails via exception notifications
76
78
  test_files:
77
79
  - spec/spec_helper.rb
78
- - spec/specs/lib/airbrake_spec.rb
80
+ - spec/specs/lib/blinkist-airbrake-scrubber/airbrake_spec.rb
81
+ - spec/specs/lib/blinkist-airbrake-scrubber/deep_traversal_spec.rb
79
82
  - spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/message_email_spec.rb
80
83
  - spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/params_email_spec.rb
81
84
  - spec/specs/lib/blinkist-airbrake-scrubber/scrubbers/params_password_spec.rb