lhc 14.0.0 → 15.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7379ccaa5a569acd2eca8b6ea938996477391648efe913b45ff07e478f81e471
4
- data.tar.gz: a277d00a29c59e3da5c9fa4fa5b130a201d253ad65ac26a75e1bc348eacf479f
3
+ metadata.gz: 301499c3239741a748386c3e33d552611f2817f2880579b3df9e320b336db894
4
+ data.tar.gz: 27c61057ca12aa70076e0fbe71da8cf8f0eac225420dcdd11ba297336aea85e8
5
5
  SHA512:
6
- metadata.gz: 76713bd28a5e9ce252bfef62f77d5b04cf3820a290089d7331f2d1445a4e04ff4ebcfa6180b50d75f0ce4b0b62454f3a4bbece2f7a41f37fa2ea8158e755a196
7
- data.tar.gz: e33b20e2c2d8f12b68e5ef76842bc94c61cd761be66d4d61b22b0c2501fd6dfc4041c7a9e32bff1d964e34c154d40ed6acf865cfeadb01c7318729597c96b25c
6
+ metadata.gz: 890dd068ed2902de6990b1b90ef5082f4f6d0c26e65022db14157615dd858f7302a8419b8457f6da403f3423aabdfa13f0838a748846f7f93e13339c0415eca6
7
+ data.tar.gz: e66683421af741d105294a5eb5fb33f26dbab024653b51647f3597e3256cd2bb114202d1599e4f0019f6157b08123afea794c68ddddd6f286518a99476c9dc9d
data/README.md CHANGED
@@ -51,6 +51,7 @@ use it like:
51
51
  * [Configuration](#configuration)
52
52
  * [Configuring endpoints](#configuring-endpoints)
53
53
  * [Configuring placeholders](#configuring-placeholders)
54
+ * [Configuring scrubs](#configuring-scrubs)
54
55
  * [Interceptors](#interceptors)
55
56
  * [Quick start: Configure/Enable Interceptors](#quick-start-configureenable-interceptors)
56
57
  * [Interceptors on local request level](#interceptors-on-local-request-level)
@@ -491,6 +492,50 @@ You can configure global placeholders, that are used when generating urls from u
491
492
  LHC.get(:feedbacks) # http://datastore/v2/feedbacks
492
493
  ```
493
494
 
495
+ ### Configuring scrubs
496
+
497
+ You can filter out sensitive request data from your log files and rollbar by appending them to `LHS.config.scrubs`. These values will be marked `[FILTERED]` in the log and on rollbar. Also nested parameters are being filtered.
498
+ The scrubbing configuration affects all request done by LHC independent of the endpoint. You can scrub any attribute within `:params`, `:headers` or `:body`. For `:auth` you either can choose `:bearer` or `:basic` (default is both).
499
+
500
+ LHS scrubs per default:
501
+ - Bearer Token within the Request Header
502
+ - Basic Auth `username` and `password` within the Request Header
503
+ - `password` and `password_confirmation` within the Request Body
504
+
505
+ Enhance the default scrubbing by pushing the name of the parameter, which should be scrubbed, as string to the existing configuration.
506
+ You can also add multiple parameters at once by pushing multiple strings.
507
+
508
+ Example:
509
+ ```ruby
510
+ LHC.configure do |c|
511
+ c.scrubs[:params] << 'api_key'
512
+ c.scrubs[:body].push('user_token', 'secret_key')
513
+ end
514
+ ```
515
+
516
+ For disabling scrubbing, add following configuration:
517
+ ```ruby
518
+ LHC.configure do |c|
519
+ c.scrubs = {}
520
+ end
521
+ ```
522
+
523
+ If you want to turn off `:bearer` or `:basic` scrubbing, then just overwrite the `:auth` configuration.
524
+
525
+ Example:
526
+ ```ruby
527
+ LHC.configure do |c|
528
+ c.scrubs[:auth] = [:bearer]
529
+ end
530
+ ```
531
+
532
+ If your app has a different authentication strategy than Bearer Authentication or Basic Authentication then you can filter the data by scrubbing the whole header:
533
+ ```ruby
534
+ LHC.configure do |c|
535
+ c.scrubs[:headers] << 'Authorization'
536
+ end
537
+ ```
538
+
494
539
  ## Interceptors
495
540
 
496
541
  To monitor and manipulate the HTTP communication done with LHC, you can define interceptors that follow the (Inteceptor Pattern)[https://en.wikipedia.org/wiki/Interceptor_pattern].
@@ -573,12 +618,18 @@ Adds the following to body of all requests:
573
618
 
574
619
  ##### Reauthenticate
575
620
 
576
- The current implementation can only offer reauthenticate for _client access tokens_. For this to work the following has to be given:
577
-
578
- * You have configured and implemented `LHC::Auth.refresh_client_token = -> { TokenRefreshUtil.client_access_token(true) }` which when called will force a refresh of the token and return the new value. It is also expected that this implementation will handle invalidating caches if necessary.
579
- * Your interceptors contain `LHC::Auth` and `LHC::Retry`, whereas `LHC::Retry` comes _after_ `LHC::Auth` in the chain.
621
+ The current implementation offers only reauthentication for _client access tokens_.
622
+ Make sure that your interceptors contain `LHC::Auth` and `LHC::Retry`, whereas `LHC::Retry` comes _after_ `LHC::Auth` in the chain.
623
+ Provide the refresh token as following:
624
+ ```ruby
625
+ LHC.get('http://local.ch', auth: { bearer: -> { access_token }, refresh_client_token: -> { TokenRefreshUtil.client_access_token(true) })
626
+ ```
627
+ Where `TokenRefreshUtil.client_access_token(true)` forces a refresh of the token and returns the new token. It is also expected that this implementation will handle invalidating caches if necessary.
580
628
 
581
- ##### Bearer Authentication with client access token
629
+ You can also set a global `refresh_client_token`. This is not recommended for apps with multiple endpoint and different access tokens.
630
+ ```ruby
631
+ LHC::Auth.refresh_client_token = -> { TokenRefreshUtil.client_access_token(true) }
632
+ ```
582
633
 
583
634
  Reauthentication will be initiated if:
584
635
 
data/lhc.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.add_dependency 'activesupport', '>= 5.2'
26
26
  s.add_dependency 'addressable'
27
+ s.add_dependency 'local_uri'
27
28
  s.add_dependency 'typhoeus', '>= 0.11'
28
29
 
29
30
  s.add_development_dependency 'geminabox'
data/lib/lhc/config.rb CHANGED
@@ -5,9 +5,12 @@ require 'singleton'
5
5
  class LHC::Config
6
6
  include Singleton
7
7
 
8
+ attr_accessor :scrubs
9
+
8
10
  def initialize
9
11
  @endpoints = {}
10
12
  @placeholders = {}
13
+ @scrubs = default_scrubs
11
14
  end
12
15
 
13
16
  def endpoint(name, url, options = {})
@@ -42,9 +45,19 @@ class LHC::Config
42
45
  @interceptors = interceptors
43
46
  end
44
47
 
48
+ def default_scrubs
49
+ {
50
+ auth: [:bearer, :basic],
51
+ params: [],
52
+ headers: [],
53
+ body: ['password', 'password_confirmation']
54
+ }
55
+ end
56
+
45
57
  def reset
46
58
  @endpoints = {}
47
59
  @placeholders = {}
48
60
  @interceptors = nil
61
+ @scrubs = default_scrubs
49
62
  end
50
63
  end
data/lib/lhc/error.rb CHANGED
@@ -72,13 +72,12 @@ class LHC::Error < StandardError
72
72
 
73
73
  debug = []
74
74
  debug << [request.method, request.url].map { |str| self.class.fix_invalid_encoding(str) }.join(' ')
75
- debug << "Options: #{request.options}"
76
- debug << "Headers: #{request.headers}"
75
+ debug << "Options: #{request.scrubbed_options}"
76
+ debug << "Headers: #{request.scrubbed_headers}"
77
77
  debug << "Response Code: #{response.code} (#{response.options[:return_code]})"
78
- debug << "Response Options: #{response.options}"
78
+ debug << "Response Options: #{response.scrubbed_options}"
79
79
  debug << response.body
80
80
  debug << _message
81
-
82
81
  debug.map { |str| self.class.fix_invalid_encoding(str) }.join("\n")
83
82
  end
84
83
  end
@@ -30,7 +30,7 @@ class LHC::Auth < LHC::Interceptor
30
30
  def basic_authentication!
31
31
  auth = auth_options[:basic]
32
32
  credentials = "#{auth[:username]}:#{auth[:password]}"
33
- set_authorization_header("Basic #{Base64.strict_encode64(credentials).chomp}")
33
+ set_basic_authorization_header(Base64.strict_encode64(credentials).chomp)
34
34
  end
35
35
 
36
36
  def bearer_authentication!
@@ -44,7 +44,13 @@ class LHC::Auth < LHC::Interceptor
44
44
  request.headers['Authorization'] = value
45
45
  end
46
46
 
47
+ def set_basic_authorization_header(base_64_encoded_credentials)
48
+ request.options[:auth][:basic].merge!(base_64_encoded_credentials: base_64_encoded_credentials)
49
+ set_authorization_header("Basic #{base_64_encoded_credentials}")
50
+ end
51
+
47
52
  def set_bearer_authorization_header(token)
53
+ request.options[:auth].merge!(bearer_token: token)
48
54
  set_authorization_header("Bearer #{token}")
49
55
  end
50
56
  # rubocop:enable Style/AccessorMethodName
@@ -14,8 +14,8 @@ class LHC::Logging < LHC::Interceptor
14
14
  "<#{request.object_id}>",
15
15
  request.method.upcase,
16
16
  "#{request.url} at #{Time.now.iso8601}",
17
- "Params=#{request.params}",
18
- "Headers=#{request.headers}",
17
+ "Params=#{request.scrubbed_params}",
18
+ "Headers=#{request.scrubbed_headers}",
19
19
  request.source ? "\nCalled from #{request.source}" : nil
20
20
  ].compact.join(' ')
21
21
  )
@@ -23,8 +23,8 @@ class LHC::Rollbar < LHC::Interceptor
23
23
  request: {
24
24
  url: request.url,
25
25
  method: request.method,
26
- headers: request.headers,
27
- params: request.params
26
+ headers: request.scrubbed_headers,
27
+ params: request.scrubbed_params
28
28
  }
29
29
  }.merge additional_params
30
30
  begin
data/lib/lhc/request.rb CHANGED
@@ -12,7 +12,13 @@ class LHC::Request
12
12
 
13
13
  TYPHOEUS_OPTIONS ||= [:params, :method, :body, :headers, :follow_location, :params_encoding]
14
14
 
15
- attr_accessor :response, :options, :raw, :format, :error_handler, :errors_ignored, :source
15
+ attr_accessor :response,
16
+ :options,
17
+ :raw,
18
+ :format,
19
+ :error_handler,
20
+ :errors_ignored,
21
+ :source
16
22
 
17
23
  def initialize(options, self_executing = true)
18
24
  self.errors_ignored = (options.fetch(:ignore, []) || []).to_a.compact
@@ -56,6 +62,24 @@ class LHC::Request
56
62
  raw.run
57
63
  end
58
64
 
65
+ def scrubbed_params
66
+ LHC::ParamsScrubber.new(params.deep_dup).scrubbed
67
+ end
68
+
69
+ def scrubbed_headers
70
+ LHC::HeadersScrubber.new(headers.deep_dup, options[:auth]).scrubbed
71
+ end
72
+
73
+ def scrubbed_options
74
+ scrubbed_options = options.deep_dup
75
+ scrubbed_options[:cache] = LHC::CacheScrubber.new(scrubbed_options[:cache]).scrubbed
76
+ scrubbed_options[:params] = LHC::ParamsScrubber.new(scrubbed_options[:params]).scrubbed
77
+ scrubbed_options[:headers] = LHC::HeadersScrubber.new(scrubbed_options[:headers], scrubbed_options[:auth]).scrubbed
78
+ scrubbed_options[:auth] = LHC::AuthScrubber.new(scrubbed_options[:auth]).scrubbed
79
+ scrubbed_options[:body] = LHC::BodyScrubber.new(scrubbed_options[:body]).scrubbed
80
+ scrubbed_options
81
+ end
82
+
59
83
  private
60
84
 
61
85
  attr_accessor :interceptors
data/lib/lhc/response.rb CHANGED
@@ -54,6 +54,12 @@ class LHC::Response
54
54
  request.format
55
55
  end
56
56
 
57
+ def scrubbed_options
58
+ scrubbed_options = options.deep_dup
59
+ scrubbed_options[:effective_url] = LHC::EffectiveUrlScrubber.new(scrubbed_options[:effective_url]).scrubbed
60
+ scrubbed_options
61
+ end
62
+
57
63
  private
58
64
 
59
65
  attr_accessor :raw
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LHC::Scrubber
4
+ attr_accessor :scrubbed
5
+
6
+ SCRUB_DISPLAY = '[FILTERED]'
7
+
8
+ def initialize(data)
9
+ @scrubbed = data
10
+ end
11
+
12
+ private
13
+
14
+ def scrub_auth_elements
15
+ LHC.config.scrubs.dig(:auth)
16
+ end
17
+
18
+ def scrub!
19
+ return if scrub_elements.blank?
20
+ return if scrubbed.blank?
21
+
22
+ LHC::Scrubber.scrub_hash!(scrub_elements, scrubbed) if scrubbed.is_a?(Hash)
23
+ LHC::Scrubber.scrub_array!(scrub_elements, scrubbed) if scrubbed.is_a?(Array)
24
+ end
25
+
26
+ def self.scrub_array!(scrub_elements, scrubbed)
27
+ scrubbed.each do |scrubbed_hash|
28
+ LHC::Scrubber.scrub_hash!(scrub_elements, scrubbed_hash)
29
+ end
30
+ end
31
+
32
+ def self.scrub_hash!(scrub_elements, scrubbed)
33
+ scrub_elements.each do |scrub_element|
34
+ if scrubbed.key?(scrub_element.to_s)
35
+ key = scrub_element.to_s
36
+ elsif scrubbed.key?(scrub_element.to_sym)
37
+ key = scrub_element.to_sym
38
+ end
39
+ next if key.blank? || scrubbed[key].blank?
40
+
41
+ scrubbed[key] = SCRUB_DISPLAY
42
+ end
43
+ scrubbed.values.each { |v| LHC::Scrubber.scrub_hash!(scrub_elements, v) if v.instance_of?(Hash) }
44
+ end
45
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LHC::AuthScrubber < LHC::Scrubber
4
+ def initialize(data)
5
+ super(data)
6
+ scrub_auth_options!
7
+ end
8
+
9
+ private
10
+
11
+ def scrub_auth_options!
12
+ return if scrubbed.blank?
13
+ return if scrub_auth_elements.blank?
14
+
15
+ scrub_basic_auth_options! if scrub_auth_elements.include?(:basic)
16
+ scrub_bearer_auth_options! if scrub_auth_elements.include?(:bearer)
17
+ end
18
+
19
+ def scrub_basic_auth_options!
20
+ return if scrubbed[:basic].blank?
21
+
22
+ scrubbed[:basic][:username] = SCRUB_DISPLAY
23
+ scrubbed[:basic][:password] = SCRUB_DISPLAY
24
+ scrubbed[:basic][:base_64_encoded_credentials] = SCRUB_DISPLAY
25
+ end
26
+
27
+ def scrub_bearer_auth_options!
28
+ return if scrubbed[:bearer].blank?
29
+
30
+ scrubbed[:bearer] = SCRUB_DISPLAY if scrubbed[:bearer].is_a?(String)
31
+ scrubbed[:bearer_token] = SCRUB_DISPLAY
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LHC::BodyScrubber < LHC::Scrubber
4
+ def initialize(data)
5
+ super(data)
6
+ parse!
7
+ scrub!
8
+ end
9
+
10
+ private
11
+
12
+ def scrub_elements
13
+ LHC.config.scrubs[:body]
14
+ end
15
+
16
+ def parse!
17
+ return if scrubbed.nil? || scrubbed.is_a?(Hash) || scrubbed.is_a?(Array)
18
+
19
+ if scrubbed.is_a?(String)
20
+ json = scrubbed
21
+ else
22
+ json = scrubbed.to_json
23
+ end
24
+
25
+ parsed = JSON.parse(json)
26
+ self.scrubbed = parsed if parsed.is_a?(Hash) || parsed.is_a?(Array)
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LHC::CacheScrubber < LHC::Scrubber
4
+ def initialize(data)
5
+ super(data)
6
+ scrub_cache_options!
7
+ end
8
+
9
+ private
10
+
11
+ def scrub_cache_options!
12
+ return if scrubbed.blank?
13
+ return if scrub_elements.blank?
14
+
15
+ scrub_cache_key!
16
+ end
17
+
18
+ def scrub_cache_key!
19
+ return if scrubbed[:key].blank?
20
+
21
+ scrub_elements.each do |scrub_element|
22
+ matches = scrubbed[:key].match(/:#{scrub_element}=>"(.*?)"/)
23
+ next if matches.nil?
24
+
25
+ value = matches[-1]
26
+ scrubbed[:key].gsub!(value, SCRUB_DISPLAY)
27
+ end
28
+ end
29
+
30
+ def scrub_elements
31
+ # The cache key includes the whole request url inklusive params.
32
+ # We need to scrub those params from the cache key.
33
+ LHC.config.scrubs[:params]
34
+ end
35
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LHC::EffectiveUrlScrubber < LHC::Scrubber
4
+ def initialize(data)
5
+ super(data)
6
+ scrub_effective_url_options!
7
+ end
8
+
9
+ private
10
+
11
+ def scrub_effective_url_options!
12
+ return if scrubbed.blank?
13
+ return if scrub_elements.blank?
14
+
15
+ scrub_effective_url!
16
+ end
17
+
18
+ def scrub_effective_url!
19
+ return if scrubbed.blank?
20
+
21
+ scrub_elements.each do |scrub_element|
22
+ uri = LocalUri::URI.new(scrubbed)
23
+ self.scrubbed = CGI.unescape(uri.query.merge(scrub_element => SCRUB_DISPLAY).to_s)
24
+ end
25
+ end
26
+
27
+ def scrub_elements
28
+ # The effective url includes the params of the request
29
+ # so we need to scrub those params from the effective url.
30
+ LHC.config.scrubs[:params]
31
+ end
32
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LHC::HeadersScrubber < LHC::Scrubber
4
+ def initialize(data, auth_options)
5
+ super(data)
6
+ @auth_options = auth_options
7
+ scrub!
8
+ scrub_auth_headers!
9
+ end
10
+
11
+ private
12
+
13
+ attr_reader :auth_options
14
+
15
+ def scrub_elements
16
+ LHC.config.scrubs[:headers]
17
+ end
18
+
19
+ def scrub_auth_headers!
20
+ return if scrub_auth_elements.blank?
21
+ return if auth_options.blank?
22
+
23
+ scrub_basic_authentication_headers! if scrub_auth_elements.include?(:basic)
24
+ scrub_bearer_authentication_headers! if scrub_auth_elements.include?(:bearer)
25
+ end
26
+
27
+ def scrub_basic_authentication_headers!
28
+ return if !scrub_basic_authentication_headers?
29
+
30
+ scrubbed['Authorization'].gsub!(auth_options[:basic][:base_64_encoded_credentials], SCRUB_DISPLAY)
31
+ end
32
+
33
+ def scrub_bearer_authentication_headers!
34
+ return if !scrub_bearer_authentication_headers?
35
+
36
+ scrubbed['Authorization'].gsub!(auth_options[:bearer_token], SCRUB_DISPLAY)
37
+ end
38
+
39
+ def scrub_basic_authentication_headers?
40
+ auth_options[:basic].present? &&
41
+ scrubbed['Authorization'].present? &&
42
+ scrubbed['Authorization'].include?(auth_options[:basic][:base_64_encoded_credentials])
43
+ end
44
+
45
+ def scrub_bearer_authentication_headers?
46
+ auth_options[:bearer].present? &&
47
+ scrubbed['Authorization'].present? &&
48
+ scrubbed['Authorization'].include?(auth_options[:bearer_token])
49
+ end
50
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class LHC::ParamsScrubber < LHC::Scrubber
4
+ def initialize(data)
5
+ super(data)
6
+ scrub!
7
+ end
8
+
9
+ private
10
+
11
+ def scrub_elements
12
+ LHC.config.scrubs[:params]
13
+ end
14
+ end
data/lib/lhc/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module LHC
4
- VERSION ||= '14.0.0'
4
+ VERSION ||= '15.1.1'
5
5
  end
data/lib/lhc.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'local_uri'
3
4
  require 'typhoeus'
4
5
  require 'active_support/core_ext/object/blank'
5
6
  require 'active_support/core_ext/hash/keys'
@@ -113,6 +114,21 @@ module LHC
113
114
  autoload :UnknownError,
114
115
  'lhc/errors/unknown_error'
115
116
 
117
+ autoload :Scrubber,
118
+ 'lhc/scrubber'
119
+ autoload :AuthScrubber,
120
+ 'lhc/scrubbers/auth_scrubber'
121
+ autoload :BodyScrubber,
122
+ 'lhc/scrubbers/body_scrubber'
123
+ autoload :CacheScrubber,
124
+ 'lhc/scrubbers/cache_scrubber'
125
+ autoload :EffectiveUrlScrubber,
126
+ 'lhc/scrubbers/effective_url_scrubber'
127
+ autoload :HeadersScrubber,
128
+ 'lhc/scrubbers/headers_scrubber'
129
+ autoload :ParamsScrubber,
130
+ 'lhc/scrubbers/params_scrubber'
131
+
116
132
  autoload :Interceptor,
117
133
  'lhc/interceptor'
118
134
  autoload :Interceptors,
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHC do
6
+ it 'has a default value for scrubs' do
7
+ expect(LHC.config.scrubs[:auth]).to eq [:bearer, :basic]
8
+ expect(LHC.config.scrubs[:params]).to eq []
9
+ expect(LHC.config.scrubs[:headers]).to eq []
10
+ expect(LHC.config.scrubs[:body]).to eq ['password', 'password_confirmation']
11
+ end
12
+
13
+ describe 'auth' do
14
+ context 'when only bearer auth should get scrubbed' do
15
+ before(:each) do
16
+ LHC.configure do |c|
17
+ c.scrubs[:auth] = [:bearer]
18
+ end
19
+ end
20
+
21
+ it 'has only bearer auth in scrubs' do
22
+ expect(LHC.config.scrubs[:auth]).to eq([:bearer])
23
+ expect(LHC.config.scrubs[:params]).to eq []
24
+ expect(LHC.config.scrubs[:headers]).to eq []
25
+ expect(LHC.config.scrubs[:body]).to eq ['password', 'password_confirmation']
26
+ end
27
+ end
28
+ end
29
+
30
+ context 'params' do
31
+ context 'when additional param "api_key" should be scrubbed' do
32
+ before(:each) do
33
+ LHC.configure do |c|
34
+ c.scrubs[:params] << 'api_key'
35
+ end
36
+ end
37
+
38
+ it 'has "api_key" in scrubs' do
39
+ expect(LHC.config.scrubs[:auth]).to eq [:bearer, :basic]
40
+ expect(LHC.config.scrubs[:params]).to eq ['api_key']
41
+ expect(LHC.config.scrubs[:headers]).to eq []
42
+ expect(LHC.config.scrubs[:body]).to eq ['password', 'password_confirmation']
43
+ end
44
+ end
45
+ end
46
+
47
+ context 'headers' do
48
+ context 'when additional header "private_key" should be scrubbed' do
49
+ before(:each) do
50
+ LHC.configure do |c|
51
+ c.scrubs[:headers] << 'private_key'
52
+ end
53
+ end
54
+
55
+ it 'has "private_key" in scrubs' do
56
+ expect(LHC.config.scrubs[:auth]).to eq [:bearer, :basic]
57
+ expect(LHC.config.scrubs[:params]).to eq []
58
+ expect(LHC.config.scrubs[:headers]).to eq ['private_key']
59
+ expect(LHC.config.scrubs[:body]).to eq ['password', 'password_confirmation']
60
+ end
61
+ end
62
+ end
63
+
64
+ context 'body' do
65
+ context 'when only password should get scrubbed' do
66
+ before(:each) do
67
+ LHC.configure do |c|
68
+ c.scrubs[:body] = ['password']
69
+ end
70
+ end
71
+
72
+ it 'has password in scrubs' do
73
+ expect(LHC.config.scrubs[:auth]).to eq [:bearer, :basic]
74
+ expect(LHC.config.scrubs[:params]).to eq []
75
+ expect(LHC.config.scrubs[:headers]).to eq []
76
+ expect(LHC.config.scrubs[:body]).to eq(['password'])
77
+ end
78
+ end
79
+
80
+ context 'when "user_token" should be scrubbed' do
81
+ before(:each) do
82
+ LHC.configure do |c|
83
+ c.scrubs[:body] << 'user_token'
84
+ end
85
+ end
86
+
87
+ it 'has user_token in scrubs' do
88
+ expect(LHC.config.scrubs[:auth]).to eq [:bearer, :basic]
89
+ expect(LHC.config.scrubs[:params]).to eq []
90
+ expect(LHC.config.scrubs[:headers]).to eq []
91
+ expect(LHC.config.scrubs[:body]).to eq(['password', 'password_confirmation', 'user_token'])
92
+ end
93
+ end
94
+ end
95
+
96
+ context 'when nothing should be scrubbed' do
97
+ before(:each) do
98
+ LHC.configure do |c|
99
+ c.scrubs = {}
100
+ end
101
+ end
102
+
103
+ it 'does not have scrubs' do
104
+ expect(LHC.config.scrubs.blank?).to be true
105
+ expect(LHC.config.scrubs[:auth]).to be nil
106
+ end
107
+ end
108
+ end
@@ -48,17 +48,19 @@ describe LHC::Error do
48
48
  double('LHC::Request',
49
49
  method: 'GET',
50
50
  url: 'http://example.com/sessions',
51
- headers: { 'Bearer Token' => "aaaaaaaa-bbbb-cccc-dddd-eeee" },
52
- options: { followlocation: true,
53
- auth: { bearer: "aaaaaaaa-bbbb-cccc-dddd-eeee" },
54
- params: { limit: 20 }, url: "http://example.com/sessions" })
51
+ scrubbed_headers: { 'Bearer Token' => LHC::Scrubber::SCRUB_DISPLAY },
52
+ scrubbed_options: { followlocation: true,
53
+ auth: { bearer: LHC::Scrubber::SCRUB_DISPLAY },
54
+ params: { limit: 20 }, url: "http://example.com/sessions" })
55
55
  end
56
56
 
57
57
  let(:response) do
58
+ options = { return_code: :internal_error, response_headers: "" }
58
59
  double('LHC::Response',
59
60
  request: request,
60
61
  code: 500,
61
- options: { return_code: :internal_error, response_headers: "" },
62
+ options: options,
63
+ scrubbed_options: options,
62
64
  body: '{"status":500,"message":"undefined"}')
63
65
  end
64
66
 
@@ -72,8 +74,8 @@ describe LHC::Error do
72
74
  it 'produces correct debug output' do
73
75
  expect(subject.to_s.split("\n")).to eq(<<-MSG.strip_heredoc.split("\n"))
74
76
  GET http://example.com/sessions
75
- Options: {:followlocation=>true, :auth=>{:bearer=>"aaaaaaaa-bbbb-cccc-dddd-eeee"}, :params=>{:limit=>20}, :url=>"http://example.com/sessions"}
76
- Headers: {"Bearer Token"=>"aaaaaaaa-bbbb-cccc-dddd-eeee"}
77
+ Options: {:followlocation=>true, :auth=>{:bearer=>"#{LHC::Scrubber::SCRUB_DISPLAY}"}, :params=>{:limit=>20}, :url=>"http://example.com/sessions"}
78
+ Headers: {"Bearer Token"=>"#{LHC::Scrubber::SCRUB_DISPLAY}"}
77
79
  Response Code: 500 (internal_error)
78
80
  Response Options: {:return_code=>:internal_error, :response_headers=>""}
79
81
  {"status":500,"message":"undefined"}
@@ -8,7 +8,7 @@ describe LHC::Logging do
8
8
  before(:each) do
9
9
  LHC.config.interceptors = [LHC::Logging]
10
10
  LHC::Logging.logger = logger
11
- stub_request(:get, 'http://local.ch').to_return(status: 200)
11
+ stub_request(:get, /http:\/\/local.ch.*/).to_return(status: 200)
12
12
  end
13
13
 
14
14
  it 'does log information before and after every request made with LHC' do
@@ -34,4 +34,24 @@ describe LHC::Logging do
34
34
  )
35
35
  end
36
36
  end
37
+
38
+ context 'sensitive data' do
39
+ before :each do
40
+ LHC.config.scrubs[:params] << 'api_key'
41
+ LHC.config.scrubs[:headers] << 'private_key'
42
+ LHC.get('http://local.ch', params: { api_key: '123-abc' }, headers: { private_key: 'abc-123' })
43
+ end
44
+
45
+ it 'does not log sensitive params information' do
46
+ expect(logger).to have_received(:info).once.with(
47
+ a_string_including("Params={:api_key=>\"#{LHC::Scrubber::SCRUB_DISPLAY}\"}")
48
+ )
49
+ end
50
+
51
+ it 'does not log sensitive header information' do
52
+ expect(logger).to have_received(:info).once.with(
53
+ a_string_including(":private_key=>\"#{LHC::Scrubber::SCRUB_DISPLAY}\"")
54
+ )
55
+ end
56
+ end
37
57
  end
@@ -36,22 +36,34 @@ describe LHC::Rollbar do
36
36
  )
37
37
  end
38
38
 
39
- context 'additional params' do
40
- it 'does report errors to rollbar with additional data' do
41
- stub_request(:get, 'http://local.ch')
42
- .to_return(status: 400)
43
- expect(-> { LHC.get('http://local.ch', rollbar: { additional: 'data' }) })
44
- .to raise_error LHC::BadRequest
45
- expect(::Rollbar).to have_received(:warning)
46
- .with(
47
- 'Status: 400 URL: http://local.ch',
48
- hash_including(
49
- response: anything,
50
- request: anything,
51
- additional: 'data'
52
- )
39
+ it 'does report errors to rollbar with additional data' do
40
+ stub_request(:get, 'http://local.ch')
41
+ .to_return(status: 400)
42
+ expect(-> { LHC.get('http://local.ch', rollbar: { additional: 'data' }) })
43
+ .to raise_error LHC::BadRequest
44
+ expect(::Rollbar).to have_received(:warning)
45
+ .with(
46
+ 'Status: 400 URL: http://local.ch',
47
+ hash_including(
48
+ response: anything,
49
+ request: anything,
50
+ additional: 'data'
53
51
  )
54
- end
52
+ )
53
+ end
54
+
55
+ it 'scrubs sensitive data' do
56
+ LHC.config.scrubs[:params] << 'api_key'
57
+ LHC.config.scrubs[:headers] << 'private_key'
58
+ stub_request(:get, 'http://local.ch?api_key=123-abc').to_return(status: 400)
59
+ expect(-> { LHC.get('http://local.ch', params: { api_key: '123-abc' }, headers: { private_key: 'abc-123' }) })
60
+ .to raise_error LHC::BadRequest
61
+ expect(::Rollbar).to have_received(:warning)
62
+ .with(
63
+ 'Status: 400 URL: http://local.ch',
64
+ response: hash_including(body: anything, code: anything, headers: anything, time: anything, timeout?: anything),
65
+ request: hash_including(url: anything, method: anything, headers: hash_including(private_key: LHC::Scrubber::SCRUB_DISPLAY), params: { api_key: LHC::Scrubber::SCRUB_DISPLAY })
66
+ )
55
67
  end
56
68
  end
57
69
  end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHC::Request do
6
+ let(:headers) { { private_key: 'xyz-123' } }
7
+ let(:response) { LHC.get(:local, headers: headers) }
8
+ let(:auth) { {} }
9
+
10
+ before :each do
11
+ LHC.config.endpoint(:local, 'http://local.ch', auth: auth)
12
+ stub_request(:get, 'http://local.ch').with(headers: headers)
13
+ end
14
+
15
+ it 'scrubs "private_key"' do
16
+ LHC.config.scrubs[:headers] << 'private_key'
17
+ expect(response.request.scrubbed_headers).to include(private_key: LHC::Scrubber::SCRUB_DISPLAY)
18
+ end
19
+
20
+ it 'does not add a new attribute when a non existing header should be scrubbed' do
21
+ LHC.config.scrubs[:headers] << 'anything'
22
+ expect(response.request.scrubbed_headers).not_to include('anything' => LHC::Scrubber::SCRUB_DISPLAY)
23
+ end
24
+
25
+ context 'when strings instead of symbols are provided' do
26
+ let(:headers) { { 'private_key' => 'xyz-123' } }
27
+
28
+ it 'scrubs "private_key"' do
29
+ LHC.config.scrubs[:headers] << 'private_key'
30
+ expect(response.request.scrubbed_headers).to include('private_key' => LHC::Scrubber::SCRUB_DISPLAY)
31
+ end
32
+ end
33
+
34
+ context 'other authentication strategy' do
35
+ let(:api_key) { '123456' }
36
+ let(:authorization_header) { { 'Authorization' => "Apikey #{api_key}" } }
37
+ let(:headers) { authorization_header }
38
+
39
+ it 'provides srubbed Authorization header' do
40
+ LHC.config.scrubs[:headers] << 'Authorization'
41
+ expect(response.request.scrubbed_headers).to include('Authorization' => LHC::Scrubber::SCRUB_DISPLAY)
42
+ expect(response.request.headers).to include(authorization_header)
43
+ end
44
+ end
45
+
46
+ describe 'auth' do
47
+ before :each do
48
+ LHC.config.interceptors = [LHC::Auth]
49
+ stub_request(:get, 'http://local.ch').with(headers: authorization_header)
50
+ end
51
+
52
+ let(:request) do
53
+ response = LHC.get(:local)
54
+ response.request
55
+ end
56
+
57
+ context 'bearer authentication' do
58
+ let(:bearer_token) { '123456' }
59
+ let(:authorization_header) { { 'Authorization' => "Bearer #{bearer_token}" } }
60
+ let(:auth) { { bearer: -> { bearer_token } } }
61
+
62
+ it 'scrubs only the bearer token' do
63
+ expect(request.scrubbed_headers).to include('Authorization' => "Bearer #{LHC::Scrubber::SCRUB_DISPLAY}")
64
+ expect(request.headers).to include(authorization_header)
65
+ end
66
+
67
+ it 'scrubs whole "Authorization" header' do
68
+ LHC.config.scrubs[:headers] << 'Authorization'
69
+ expect(request.scrubbed_headers).to include('Authorization' => LHC::Scrubber::SCRUB_DISPLAY)
70
+ expect(request.headers).to include(authorization_header)
71
+ end
72
+
73
+ it 'scrubs nothing' do
74
+ LHC.config.scrubs = {}
75
+ expect(request.scrubbed_headers).to include(authorization_header)
76
+ end
77
+ end
78
+
79
+ context 'basic authentication' do
80
+ let(:username) { 'steve' }
81
+ let(:password) { 'abcdefg' }
82
+ let(:credentials_base_64_codiert) { Base64.strict_encode64("#{username}:#{password}").chomp }
83
+ let(:authorization_header) { { 'Authorization' => "Basic #{credentials_base_64_codiert}" } }
84
+ let(:auth) { { basic: { username: username, password: password } } }
85
+
86
+ it 'scrubs only credentials' do
87
+ expect(request.scrubbed_headers).to include('Authorization' => "Basic #{LHC::Scrubber::SCRUB_DISPLAY}")
88
+ expect(request.headers).to include(authorization_header)
89
+ end
90
+
91
+ it 'scrubs whole "Authorization" header' do
92
+ LHC.config.scrubs[:headers] << 'Authorization'
93
+ expect(request.scrubbed_headers).to include('Authorization' => LHC::Scrubber::SCRUB_DISPLAY)
94
+ expect(request.headers).to include(authorization_header)
95
+ end
96
+
97
+ it 'scrubs nothing' do
98
+ LHC.config.scrubs = {}
99
+ expect(request.scrubbed_headers).to include(authorization_header)
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,214 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHC::Request do
6
+ before :each do
7
+ LHC.config.interceptors = [LHC::Auth]
8
+ LHC.config.endpoint(:local, 'http://local.ch', auth: auth)
9
+ LHC.config.scrubs[:params] << 'api_key'
10
+ LHC.config.scrubs[:headers] << 'private_key'
11
+ LHC.config.scrubs[:body] << 'user_token'
12
+ stub_request(:post, "http://local.ch?#{params.to_query}").with(headers: authorization_header.merge(headers), body: body.to_json)
13
+ end
14
+
15
+ let(:bearer_token) { '123456' }
16
+ let(:authorization_header) { { 'Authorization' => "Bearer #{bearer_token}" } }
17
+ let(:auth) { { bearer: -> { bearer_token } } }
18
+ let(:params) { { api_key: 'api-key-params' } }
19
+ let(:headers) { { private_key: 'private-key-header' } }
20
+ let(:body) { { user_token: 'user-token-body' } }
21
+ let(:cache) do
22
+ { key: "LHS_REQUEST_CYCLE_CACHE(v1) POST http://local.ch?#{params}" }
23
+ end
24
+
25
+ let(:request) do
26
+ response = LHC.post(:local, params: params, headers: headers, body: body, cache: cache)
27
+ response.request
28
+ end
29
+
30
+ it 'provides srubbed request options' do
31
+ expect(request.scrubbed_options[:params]).to include(api_key: LHC::Scrubber::SCRUB_DISPLAY)
32
+ expect(request.scrubbed_options[:headers]).to include(private_key: LHC::Scrubber::SCRUB_DISPLAY)
33
+ expect(request.scrubbed_options[:body]).to include(user_token: LHC::Scrubber::SCRUB_DISPLAY)
34
+ expect(request.scrubbed_options[:auth][:bearer_token]).to eq(LHC::Scrubber::SCRUB_DISPLAY)
35
+ expect(request.scrubbed_options[:auth][:basic]).to be nil
36
+ expect(request.scrubbed_options[:cache])
37
+ .to include(key: "LHS_REQUEST_CYCLE_CACHE(v1) POST http://local.ch?{:api_key=>\"[FILTERED]\"}")
38
+ end
39
+
40
+ context 'when bearer auth is not a proc' do
41
+ let(:auth) { { bearer: bearer_token } }
42
+
43
+ it 'also scrubbes the bearer' do
44
+ expect(request.scrubbed_options[:auth][:bearer]).to eq(LHC::Scrubber::SCRUB_DISPLAY)
45
+ expect(request.scrubbed_options[:auth][:bearer_token]).to eq(LHC::Scrubber::SCRUB_DISPLAY)
46
+ end
47
+ end
48
+
49
+ context 'when options do not have auth' do
50
+ let(:authorization_header) { {} }
51
+ let(:auth) { nil }
52
+
53
+ it 'provides srubbed request options' do
54
+ expect(request.scrubbed_options[:params]).to include(api_key: LHC::Scrubber::SCRUB_DISPLAY)
55
+ expect(request.scrubbed_options[:headers]).to include(private_key: LHC::Scrubber::SCRUB_DISPLAY)
56
+ expect(request.scrubbed_options[:body]).to include(user_token: LHC::Scrubber::SCRUB_DISPLAY)
57
+ expect(request.scrubbed_options[:auth]).to be nil
58
+ end
59
+ end
60
+
61
+ context 'when parameter should not get scrubbed' do
62
+ let(:params) { { any_parameter: 'any-parameter' } }
63
+
64
+ let(:cache) do
65
+ { key: "LHS_REQUEST_CYCLE_CACHE(v1) POST http://local.ch?#{params}" }
66
+ end
67
+
68
+ it 'does not scrubb the parameter' do
69
+ expect(request.scrubbed_options[:cache])
70
+ .to include(key: "LHS_REQUEST_CYCLE_CACHE(v1) POST http://local.ch?#{params}")
71
+ end
72
+ end
73
+
74
+ context 'when body data is nested' do
75
+ let(:body) do
76
+ {
77
+ data: {
78
+ attributes: {
79
+ employee: {
80
+ name: 'Muster',
81
+ surname: 'Hans',
82
+ password: 'test-1234',
83
+ password_confirmation: 'test-1234'
84
+ }
85
+ }
86
+ }
87
+ }
88
+ end
89
+
90
+ it 'srubbes nested attributes' do
91
+ expect(request.scrubbed_options[:params]).to include(api_key: LHC::Scrubber::SCRUB_DISPLAY)
92
+ expect(request.scrubbed_options[:headers]).to include(private_key: LHC::Scrubber::SCRUB_DISPLAY)
93
+ expect(request.scrubbed_options[:body][:data][:attributes][:employee]).to include(password: LHC::Scrubber::SCRUB_DISPLAY)
94
+ expect(request.scrubbed_options[:body][:data][:attributes][:employee]).to include(password_confirmation: LHC::Scrubber::SCRUB_DISPLAY)
95
+ expect(request.scrubbed_options[:auth][:bearer_token]).to eq(LHC::Scrubber::SCRUB_DISPLAY)
96
+ expect(request.scrubbed_options[:auth][:basic]).to be nil
97
+ end
98
+ end
99
+
100
+ context 'basic authentication' do
101
+ let(:username) { 'steve' }
102
+ let(:password) { 'abcdefg' }
103
+ let(:credentials_base_64_codiert) { Base64.strict_encode64("#{username}:#{password}").chomp }
104
+ let(:authorization_header) { { 'Authorization' => "Basic #{credentials_base_64_codiert}" } }
105
+ let(:auth) { { basic: { username: username, password: password } } }
106
+
107
+ it 'provides srubbed request headers' do
108
+ expect(request.scrubbed_options[:auth][:basic][:username]).to eq(LHC::Scrubber::SCRUB_DISPLAY)
109
+ expect(request.scrubbed_options[:auth][:basic][:password]).to eq(LHC::Scrubber::SCRUB_DISPLAY)
110
+ expect(request.scrubbed_options[:auth][:basic][:base_64_encoded_credentials]).to eq(LHC::Scrubber::SCRUB_DISPLAY)
111
+ expect(request.scrubbed_options[:auth][:bearer]).to be nil
112
+ end
113
+ end
114
+
115
+ context 'when nothing should get scrubbed' do
116
+ before :each do
117
+ LHC.config.scrubs = {}
118
+ end
119
+
120
+ it 'does not filter anything' do
121
+ expect(request.scrubbed_options[:params]).not_to include(api_key: LHC::Scrubber::SCRUB_DISPLAY)
122
+ expect(request.scrubbed_options[:headers]).not_to include(private_key: LHC::Scrubber::SCRUB_DISPLAY)
123
+ expect(request.scrubbed_options[:body]).not_to include(user_token: LHC::Scrubber::SCRUB_DISPLAY)
124
+ expect(request.scrubbed_options[:auth][:bearer_token]).not_to eq(LHC::Scrubber::SCRUB_DISPLAY)
125
+ expect(request.scrubbed_options[:cache])
126
+ .not_to include(key: "LHS_REQUEST_CYCLE_CACHE(v1) POST http://local.ch?{:api_key=>\"[FILTERED]\"}")
127
+ end
128
+ end
129
+
130
+ context 'custom data structures that respond to as_json (like LHS data or record)' do
131
+ before do
132
+ class CustomStructure
133
+
134
+ def initialize(data)
135
+ @data = data
136
+ end
137
+
138
+ def as_json
139
+ @data.as_json
140
+ end
141
+
142
+ def to_json
143
+ as_json.to_json
144
+ end
145
+ end
146
+
147
+ stub_request(:post, 'http://local.ch').with(body: custom_structure.to_json)
148
+ end
149
+
150
+ let(:custom_structure) do
151
+ CustomStructure.new(user_token: '12345')
152
+ end
153
+
154
+ let(:request) do
155
+ response = LHC.post(:local, body: custom_structure)
156
+ response.request
157
+ end
158
+
159
+ it 'provides srubbed request options' do
160
+ expect(request.scrubbed_options[:body]).to include('user_token' => LHC::Scrubber::SCRUB_DISPLAY)
161
+ end
162
+ end
163
+
164
+ context 'encoded data hash' do
165
+ let(:body) { { user_token: 'user-token-body' } }
166
+
167
+ let(:request) do
168
+ response = LHC.post(:local, body: body.to_json)
169
+ response.request
170
+ end
171
+
172
+ before :each do
173
+ stub_request(:post, 'http://local.ch').with(body: body.to_json)
174
+ end
175
+
176
+ it 'provides srubbed request options' do
177
+ expect(request.scrubbed_options[:body]).to include('user_token' => LHC::Scrubber::SCRUB_DISPLAY)
178
+ end
179
+ end
180
+
181
+ context 'array' do
182
+ let(:body) { [{ user_token: 'user-token-body' }] }
183
+
184
+ let(:request) do
185
+ response = LHC.post(:local, body: body)
186
+ response.request
187
+ end
188
+
189
+ before :each do
190
+ stub_request(:post, 'http://local.ch').with(body: body.to_json)
191
+ end
192
+
193
+ it 'provides srubbed request options' do
194
+ expect(request.scrubbed_options[:body]).to eq([user_token: LHC::Scrubber::SCRUB_DISPLAY])
195
+ end
196
+ end
197
+
198
+ context 'encoded array' do
199
+ let(:body) { [{ user_token: 'user-token-body' }] }
200
+
201
+ let(:request) do
202
+ response = LHC.post(:local, body: body.to_json)
203
+ response.request
204
+ end
205
+
206
+ before :each do
207
+ stub_request(:post, 'http://local.ch').with(body: body.to_json)
208
+ end
209
+
210
+ it 'provides srubbed request options' do
211
+ expect(request.scrubbed_options[:body]).to eq(['user_token' => LHC::Scrubber::SCRUB_DISPLAY])
212
+ end
213
+ end
214
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHC::Request do
6
+ let(:params) { { api_key: 'xyz-123', secret_key: '123-xyz' } }
7
+ let(:response) { LHC.get(:local, params: params) }
8
+
9
+ before :each do
10
+ LHC.config.endpoint(:local, 'http://local.ch')
11
+ stub_request(:get, "http://local.ch?#{params.to_query}")
12
+ end
13
+
14
+ it 'scrubs "api_key"' do
15
+ LHC.config.scrubs[:params] << 'api_key'
16
+ expect(response.request.scrubbed_params).to include(api_key: LHC::Scrubber::SCRUB_DISPLAY)
17
+ expect(response.request.scrubbed_params).to include(secret_key: '123-xyz')
18
+ end
19
+
20
+ it 'scrubs "api_key" and "secret_key"' do
21
+ LHC.config.scrubs[:params].push('api_key', 'secret_key')
22
+ expect(response.request.scrubbed_params).to include(api_key: LHC::Scrubber::SCRUB_DISPLAY)
23
+ expect(response.request.scrubbed_params).to include(secret_key: LHC::Scrubber::SCRUB_DISPLAY)
24
+ end
25
+
26
+ context 'when value is empty' do
27
+ let(:params) { { api_key: nil, secret_key: '' } }
28
+
29
+ it 'does not filter the value' do
30
+ LHC.config.scrubs[:params].push('api_key', 'secret_key')
31
+ expect(response.request.scrubbed_params).to include(api_key: nil)
32
+ expect(response.request.scrubbed_params).to include(secret_key: '')
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails_helper'
4
+
5
+ describe LHC::Response do
6
+ let(:options) do
7
+ { effective_url: 'http://local.ch?api_key=api-key' }
8
+ end
9
+
10
+ let(:raw_response) { OpenStruct.new(options: options) }
11
+
12
+ before do
13
+ LHC.config.scrubs[:params] << 'api_key'
14
+ end
15
+
16
+ it 'scrubbes effective url' do
17
+ response = LHC::Response.new(raw_response, nil)
18
+ expect(response.scrubbed_options[:effective_url]).to eq "http://local.ch?api_key=#{LHC::Scrubber::SCRUB_DISPLAY}"
19
+ end
20
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhc
3
3
  version: !ruby/object:Gem::Version
4
- version: 14.0.0
4
+ version: 15.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/local-ch/lhc/contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-11 00:00:00.000000000 Z
11
+ date: 2021-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: local_uri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: typhoeus
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -270,6 +284,13 @@ files:
270
284
  - lib/lhc/response/data/collection.rb
271
285
  - lib/lhc/response/data/item.rb
272
286
  - lib/lhc/rspec.rb
287
+ - lib/lhc/scrubber.rb
288
+ - lib/lhc/scrubbers/auth_scrubber.rb
289
+ - lib/lhc/scrubbers/body_scrubber.rb
290
+ - lib/lhc/scrubbers/cache_scrubber.rb
291
+ - lib/lhc/scrubbers/effective_url_scrubber.rb
292
+ - lib/lhc/scrubbers/headers_scrubber.rb
293
+ - lib/lhc/scrubbers/params_scrubber.rb
273
294
  - lib/lhc/test/cache_helper.rb
274
295
  - lib/lhc/version.rb
275
296
  - script/ci/build.sh
@@ -281,6 +302,7 @@ files:
281
302
  - spec/basic_methods/request_without_rails_spec.rb
282
303
  - spec/config/endpoints_spec.rb
283
304
  - spec/config/placeholders_spec.rb
305
+ - spec/config/scrubs_spec.rb
284
306
  - spec/core_ext/hash/deep_transform_values_spec.rb
285
307
  - spec/dummy/README.rdoc
286
308
  - spec/dummy/Rakefile
@@ -382,6 +404,9 @@ files:
382
404
  - spec/request/parallel_requests_spec.rb
383
405
  - spec/request/params_encoding_spec.rb
384
406
  - spec/request/request_without_rails_spec.rb
407
+ - spec/request/scrubbed_headers_spec.rb
408
+ - spec/request/scrubbed_options_spec.rb
409
+ - spec/request/scrubbed_params_spec.rb
385
410
  - spec/request/url_patterns_spec.rb
386
411
  - spec/request/user_agent_spec.rb
387
412
  - spec/request/user_agent_without_rails_spec.rb
@@ -392,6 +417,7 @@ files:
392
417
  - spec/response/effective_url_spec.rb
393
418
  - spec/response/headers_spec.rb
394
419
  - spec/response/options_spec.rb
420
+ - spec/response/scrubbed_options_spec.rb
395
421
  - spec/response/success_spec.rb
396
422
  - spec/response/time_spec.rb
397
423
  - spec/spec_helper.rb
@@ -436,6 +462,7 @@ test_files:
436
462
  - spec/basic_methods/request_without_rails_spec.rb
437
463
  - spec/config/endpoints_spec.rb
438
464
  - spec/config/placeholders_spec.rb
465
+ - spec/config/scrubs_spec.rb
439
466
  - spec/core_ext/hash/deep_transform_values_spec.rb
440
467
  - spec/dummy/README.rdoc
441
468
  - spec/dummy/Rakefile
@@ -537,6 +564,9 @@ test_files:
537
564
  - spec/request/parallel_requests_spec.rb
538
565
  - spec/request/params_encoding_spec.rb
539
566
  - spec/request/request_without_rails_spec.rb
567
+ - spec/request/scrubbed_headers_spec.rb
568
+ - spec/request/scrubbed_options_spec.rb
569
+ - spec/request/scrubbed_params_spec.rb
540
570
  - spec/request/url_patterns_spec.rb
541
571
  - spec/request/user_agent_spec.rb
542
572
  - spec/request/user_agent_without_rails_spec.rb
@@ -547,6 +577,7 @@ test_files:
547
577
  - spec/response/effective_url_spec.rb
548
578
  - spec/response/headers_spec.rb
549
579
  - spec/response/options_spec.rb
580
+ - spec/response/scrubbed_options_spec.rb
550
581
  - spec/response/success_spec.rb
551
582
  - spec/response/time_spec.rb
552
583
  - spec/spec_helper.rb