lhc 14.0.0 → 15.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
  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