api-auth 1.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/main.yml +71 -0
  3. data/.gitignore +13 -44
  4. data/.rubocop.yml +39 -0
  5. data/.rubocop_todo.yml +83 -0
  6. data/Appraisals +12 -36
  7. data/CHANGELOG.md +75 -1
  8. data/README.md +155 -52
  9. data/Rakefile +1 -1
  10. data/VERSION +1 -1
  11. data/api_auth.gemspec +35 -23
  12. data/gemfiles/rails_60.gemfile +9 -0
  13. data/gemfiles/rails_61.gemfile +9 -0
  14. data/gemfiles/rails_70.gemfile +9 -0
  15. data/lib/api-auth.rb +1 -1
  16. data/lib/api_auth/base.rb +41 -35
  17. data/lib/api_auth/errors.rb +4 -3
  18. data/lib/api_auth/headers.rb +38 -42
  19. data/lib/api_auth/helpers.rb +7 -16
  20. data/lib/api_auth/railtie.rb +34 -74
  21. data/lib/api_auth/request_drivers/action_controller.rb +27 -27
  22. data/lib/api_auth/request_drivers/action_dispatch.rb +0 -6
  23. data/lib/api_auth/request_drivers/curb.rb +16 -21
  24. data/lib/api_auth/request_drivers/faraday.rb +25 -34
  25. data/lib/api_auth/request_drivers/faraday_env.rb +102 -0
  26. data/lib/api_auth/request_drivers/grape_request.rb +87 -0
  27. data/lib/api_auth/request_drivers/http.rb +96 -0
  28. data/lib/api_auth/request_drivers/httpi.rb +22 -27
  29. data/lib/api_auth/request_drivers/net_http.rb +21 -26
  30. data/lib/api_auth/request_drivers/rack.rb +23 -28
  31. data/lib/api_auth/request_drivers/rest_client.rb +24 -29
  32. data/lib/api_auth.rb +4 -0
  33. data/lib/faraday/api_auth/middleware.rb +35 -0
  34. data/lib/faraday/api_auth.rb +8 -0
  35. data/spec/api_auth_spec.rb +135 -96
  36. data/spec/faraday_middleware_spec.rb +17 -0
  37. data/spec/headers_spec.rb +148 -108
  38. data/spec/helpers_spec.rb +8 -10
  39. data/spec/railtie_spec.rb +80 -99
  40. data/spec/request_drivers/action_controller_spec.rb +122 -79
  41. data/spec/request_drivers/action_dispatch_spec.rb +212 -85
  42. data/spec/request_drivers/curb_spec.rb +36 -33
  43. data/spec/request_drivers/faraday_env_spec.rb +188 -0
  44. data/spec/request_drivers/faraday_spec.rb +87 -83
  45. data/spec/request_drivers/grape_request_spec.rb +280 -0
  46. data/spec/request_drivers/http_spec.rb +190 -0
  47. data/spec/request_drivers/httpi_spec.rb +59 -59
  48. data/spec/request_drivers/net_http_spec.rb +70 -66
  49. data/spec/request_drivers/rack_spec.rb +101 -97
  50. data/spec/request_drivers/rest_client_spec.rb +218 -144
  51. data/spec/spec_helper.rb +15 -12
  52. metadata +144 -83
  53. data/.travis.yml +0 -40
  54. data/Gemfile.lock +0 -115
  55. data/gemfiles/rails_23.gemfile +0 -9
  56. data/gemfiles/rails_23.gemfile.lock +0 -70
  57. data/gemfiles/rails_30.gemfile +0 -9
  58. data/gemfiles/rails_30.gemfile.lock +0 -92
  59. data/gemfiles/rails_31.gemfile +0 -9
  60. data/gemfiles/rails_31.gemfile.lock +0 -98
  61. data/gemfiles/rails_32.gemfile +0 -9
  62. data/gemfiles/rails_32.gemfile.lock +0 -97
  63. data/gemfiles/rails_4.gemfile +0 -9
  64. data/gemfiles/rails_4.gemfile.lock +0 -94
  65. data/gemfiles/rails_41.gemfile +0 -9
  66. data/gemfiles/rails_41.gemfile.lock +0 -98
  67. data/gemfiles/rails_42.gemfile +0 -9
  68. data/gemfiles/rails_42.gemfile.lock +0 -115
@@ -1,12 +1,9 @@
1
1
  # give access to RestClient @processed_headers
2
- module RestClient;class Request;attr_accessor :processed_headers;end;end
2
+ module RestClient; class Request; attr_accessor :processed_headers; end; end
3
3
 
4
4
  module ApiAuth
5
-
6
5
  module RequestDrivers # :nodoc:
7
-
8
6
  class RestClientRequest # :nodoc:
9
-
10
7
  include ApiAuth::Helpers
11
8
 
12
9
  def initialize(request)
@@ -16,31 +13,31 @@ module ApiAuth
16
13
  end
17
14
 
18
15
  def set_auth_header(header)
19
- @request.headers.merge!({ "Authorization" => header })
16
+ @request.headers['Authorization'] = header
20
17
  save_headers # enforce update of processed_headers based on last updated headers
21
18
  @request
22
19
  end
23
20
 
24
- def calculated_md5
21
+ def calculated_hash
25
22
  if @request.payload
26
23
  body = @request.payload.read
27
24
  @request.payload.instance_variable_get(:@stream).seek(0)
28
25
  else
29
26
  body = ''
30
27
  end
31
- md5_base64digest(body)
28
+ sha256_base64digest(body)
32
29
  end
33
30
 
34
- def populate_content_md5
35
- if [:post, :put].include?(@request.method)
36
- @request.headers["Content-MD5"] = calculated_md5
37
- save_headers
38
- end
31
+ def populate_content_hash
32
+ return unless %w[post put].include?(@request.method.to_s)
33
+
34
+ @request.headers['X-Authorization-Content-SHA256'] = calculated_hash
35
+ save_headers
39
36
  end
40
37
 
41
- def md5_mismatch?
42
- if [:post, :put].include?(@request.method)
43
- calculated_md5 != content_md5
38
+ def content_hash_mismatch?
39
+ if %w[post put].include?(@request.method.to_s)
40
+ calculated_hash != content_hash
44
41
  else
45
42
  false
46
43
  end
@@ -55,13 +52,15 @@ module ApiAuth
55
52
  end
56
53
 
57
54
  def content_type
58
- value = find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE))
59
- value.nil? ? "": value
55
+ find_header(%w[CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE])
60
56
  end
61
57
 
62
- def content_md5
63
- value = find_header(%w(CONTENT-MD5 CONTENT_MD5))
64
- value.nil? ? "" : value
58
+ def content_hash
59
+ find_header(%w[X-AUTHORIZATION-CONTENT-SHA256])
60
+ end
61
+
62
+ def original_uri
63
+ find_header(%w[X-ORIGINAL-URI X_ORIGINAL_URI HTTP_X_ORIGINAL_URI])
65
64
  end
66
65
 
67
66
  def request_uri
@@ -69,32 +68,28 @@ module ApiAuth
69
68
  end
70
69
 
71
70
  def set_date
72
- @request.headers.merge!({ "DATE" => Time.now.utc.httpdate })
71
+ @request.headers['DATE'] = Time.now.utc.httpdate
73
72
  save_headers
74
73
  end
75
74
 
76
75
  def timestamp
77
- value = find_header(%w(DATE HTTP_DATE))
78
- value.nil? ? "" : value
76
+ find_header(%w[DATE HTTP_DATE])
79
77
  end
80
78
 
81
79
  def authorization_header
82
- find_header %w(Authorization AUTHORIZATION HTTP_AUTHORIZATION)
80
+ find_header %w[Authorization AUTHORIZATION HTTP_AUTHORIZATION]
83
81
  end
84
82
 
85
- private
83
+ private
86
84
 
87
85
  def find_header(keys)
88
- keys.map {|key| @headers[key] }.compact.first
86
+ keys.map { |key| @headers[key] }.compact.first
89
87
  end
90
88
 
91
89
  def save_headers
92
90
  @request.processed_headers = @request.make_headers(@request.headers)
93
91
  @headers = fetch_headers
94
92
  end
95
-
96
93
  end
97
-
98
94
  end
99
-
100
95
  end
data/lib/api_auth.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'openssl'
2
2
  require 'base64'
3
+ require 'time'
3
4
 
4
5
  require 'api_auth/errors'
5
6
  require 'api_auth/helpers'
@@ -8,10 +9,13 @@ require 'api_auth/request_drivers/net_http'
8
9
  require 'api_auth/request_drivers/curb'
9
10
  require 'api_auth/request_drivers/rest_client'
10
11
  require 'api_auth/request_drivers/action_controller'
12
+ require 'api_auth/request_drivers/grape_request'
11
13
  require 'api_auth/request_drivers/action_dispatch'
12
14
  require 'api_auth/request_drivers/rack'
13
15
  require 'api_auth/request_drivers/httpi'
14
16
  require 'api_auth/request_drivers/faraday'
17
+ require 'api_auth/request_drivers/faraday_env'
18
+ require 'api_auth/request_drivers/http'
15
19
 
16
20
  require 'api_auth/headers'
17
21
  require 'api_auth/base'
@@ -0,0 +1,35 @@
1
+ require 'api_auth'
2
+
3
+ module Faraday
4
+ module ApiAuth
5
+ # Request middleware for Faraday. It takes the same arguments as ApiAuth.sign!.
6
+ #
7
+ # You will usually need to include it after the other middlewares since ApiAuth needs to hash
8
+ # the final request.
9
+ #
10
+ # Usage:
11
+ #
12
+ # ```ruby
13
+ # require 'faraday/api_auth'
14
+ #
15
+ # conn = Faraday.new do |f|
16
+ # f.request :api_auth, access_id, secret_key
17
+ # # Alternatively:
18
+ # # f.use Faraday::ApiAuth::Middleware, access_id, secret_key
19
+ # end
20
+ # ```
21
+ #
22
+ class Middleware < Faraday::Middleware
23
+ def initialize(app, access_id, secret_key, options = {})
24
+ super(app)
25
+ @access_id = access_id
26
+ @secret_key = secret_key
27
+ @options = options
28
+ end
29
+
30
+ def on_request(env)
31
+ ::ApiAuth.sign!(env, @access_id, @secret_key, @options)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,8 @@
1
+ require_relative 'api_auth/middleware'
2
+
3
+ module Faraday
4
+ # Integrate ApiAuth into Faraday.
5
+ module ApiAuth
6
+ Faraday::Request.register_middleware(api_auth: Middleware)
7
+ end
8
+ end
@@ -1,170 +1,209 @@
1
- # encoding: UTF-8
2
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
1
+ require 'spec_helper'
3
2
 
4
- describe "ApiAuth" do
5
-
6
- describe "generating secret keys" do
7
-
8
- it "should generate secret keys" do
3
+ describe 'ApiAuth' do
4
+ describe 'generating secret keys' do
5
+ it 'should generate secret keys' do
9
6
  ApiAuth.generate_secret_key
10
7
  end
11
8
 
12
- it "should generate secret keys that are 88 characters" do
9
+ it 'should generate secret keys that are 88 characters' do
13
10
  expect(ApiAuth.generate_secret_key.size).to be(88)
14
11
  end
15
12
 
16
- it "should generate keys that have a Hamming Distance of at least 65" do
13
+ it 'should generate keys that have a Hamming Distance of at least 65' do
17
14
  key1 = ApiAuth.generate_secret_key
18
15
  key2 = ApiAuth.generate_secret_key
19
16
  expect(Amatch::Hamming.new(key1).match(key2)).to be > 65
20
17
  end
21
-
22
18
  end
23
19
 
24
- def hmac(secret_key, request, canonical_string = nil)
20
+ def hmac(secret_key, request, canonical_string = nil, digest = 'sha1')
25
21
  canonical_string ||= ApiAuth::Headers.new(request).canonical_string
26
- digest = OpenSSL::Digest.new('sha1')
22
+ digest = OpenSSL::Digest.new(digest)
27
23
  ApiAuth.b64_encode(OpenSSL::HMAC.digest(digest, secret_key, canonical_string))
28
24
  end
29
25
 
30
- describe ".sign!" do
31
- let(:request){ RestClient::Request.new(:url => "http://google.com", :method => :get) }
32
- let(:headers){ ApiAuth::Headers.new(request) }
26
+ describe '.sign!' do
27
+ let(:request) { RestClient::Request.new(url: 'https://google.com', method: :get) }
28
+ let(:headers) { ApiAuth::Headers.new(request) }
33
29
 
34
- it "generates date header before signing" do
30
+ it 'generates date header before signing' do
35
31
  expect(ApiAuth::Headers).to receive(:new).and_return(headers)
36
32
 
37
33
  expect(headers).to receive(:set_date).ordered
38
34
  expect(headers).to receive(:sign_header).ordered
39
35
 
40
- ApiAuth.sign!(request, "abc", "123")
36
+ ApiAuth.sign!(request, 'abc', '123')
41
37
  end
42
38
 
43
- it "generates content-md5 header before signing" do
39
+ it 'generates X-Authorization-Content-SHA256 header before signing' do
44
40
  expect(ApiAuth::Headers).to receive(:new).and_return(headers)
45
- expect(headers).to receive(:calculate_md5).ordered
41
+ expect(headers).to receive(:calculate_hash).ordered
46
42
  expect(headers).to receive(:sign_header).ordered
47
43
 
48
- ApiAuth.sign!(request, "abc", "123")
44
+ ApiAuth.sign!(request, 'abc', '123')
49
45
  end
50
46
 
51
- it "returns the same request object back" do
52
- expect(ApiAuth.sign!(request, "abc", "123")).to be request
47
+ it 'returns the same request object back' do
48
+ expect(ApiAuth.sign!(request, 'abc', '123')).to be request
53
49
  end
54
50
 
55
- it "calculates the hmac_signature as expected" do
56
- ApiAuth.sign!(request, "1044", "123")
57
- signature = hmac("123", request)
51
+ it 'calculates the hmac_signature as expected' do
52
+ ApiAuth.sign!(request, '1044', '123')
53
+ signature = hmac('123', request)
58
54
  expect(request.headers['Authorization']).to eq("APIAuth 1044:#{signature}")
59
55
  end
60
56
 
61
- context "when passed the with_http_method option" do
62
- let(:request){
63
- Net::HTTP::Put.new("/resource.xml?foo=bar&bar=foo",
64
- 'content-type' => 'text/plain',
65
- 'content-md5' => '1B2M2Y8AsgTpgAmY7PhCfg==',
66
- 'date' => Time.now.utc.httpdate
67
- )
68
- }
57
+ context 'when passed the hmac digest option' do
58
+ let(:request) do
59
+ Net::HTTP::Put.new('/resource.xml?foo=bar&bar=foo',
60
+ 'content-type' => 'text/plain',
61
+ 'content-hash' => '47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=',
62
+ 'date' => Time.now.utc.httpdate)
63
+ end
69
64
 
70
- let(:canonical_string){ ApiAuth::Headers.new(request).canonical_string_with_http_method }
65
+ let(:canonical_string) { ApiAuth::Headers.new(request).canonical_string }
71
66
 
72
- it "calculates the hmac_signature with http method" do
73
- ApiAuth.sign!(request, "1044", "123", { :with_http_method => true })
74
- signature = hmac("123", request, canonical_string)
75
- expect(request['Authorization']).to eq("APIAuth 1044:#{signature}")
67
+ it 'calculates the hmac_signature with http method' do
68
+ ApiAuth.sign!(request, '1044', '123', digest: 'sha256')
69
+ signature = hmac('123', request, canonical_string, 'sha256')
70
+ expect(request['Authorization']).to eq("APIAuth-HMAC-SHA256 1044:#{signature}")
76
71
  end
77
72
  end
78
73
  end
79
74
 
80
- describe ".authentic?" do
81
- let(:request){
82
- new_request = Net::HTTP::Put.new("/resource.xml?foo=bar&bar=foo",
83
- 'content-type' => 'text/plain',
84
- 'content-md5' => '1B2M2Y8AsgTpgAmY7PhCfg==',
85
- 'date' => Time.now.utc.httpdate
86
- )
75
+ describe '.authentic?' do
76
+ let(:request) do
77
+ Net::HTTP::Put.new('/resource.xml?foo=bar&bar=foo',
78
+ 'content-type' => 'text/plain',
79
+ 'X-Authorization-Content-SHA256' => '47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=',
80
+ 'date' => Time.now.utc.httpdate)
81
+ end
87
82
 
88
- signature = hmac("123", new_request)
89
- new_request["Authorization"] = "APIAuth 1044:#{signature}"
90
- new_request
91
- }
83
+ let(:signed_request) do
84
+ signature = hmac('123', request)
85
+ request['Authorization'] = "APIAuth 1044:#{signature}"
86
+ request
87
+ end
92
88
 
93
- it "validates that the signature in the request header matches the way we sign it" do
94
- expect(ApiAuth.authentic?(request, "123")).to eq true
89
+ it 'validates that the signature in the request header matches the way we sign it' do
90
+ expect(ApiAuth.authentic?(signed_request, '123')).to eq true
95
91
  end
96
92
 
97
- it "fails to validate a non matching signature" do
98
- expect(ApiAuth.authentic?(request, "456")).to eq false
93
+ it 'fails to validate a non matching signature' do
94
+ expect(ApiAuth.authentic?(signed_request, '456')).to eq false
99
95
  end
100
96
 
101
- it "fails to validate non matching md5" do
102
- request['content-md5'] = '12345'
103
- expect(ApiAuth.authentic?(request, "123")).to eq false
97
+ it 'fails to validate non matching hash' do
98
+ request['X-Authorization-Content-SHA256'] = '12345'
99
+ expect(ApiAuth.authentic?(signed_request, '123')).to eq false
104
100
  end
105
101
 
106
- it "fails to validate expired requests" do
102
+ it 'fails to validate expired requests' do
107
103
  request['date'] = 16.minutes.ago.utc.httpdate
108
- expect(ApiAuth.authentic?(request, "123")).to eq false
104
+ expect(ApiAuth.authentic?(signed_request, '123')).to eq false
109
105
  end
110
106
 
111
- it "fails to validate if the date is invalid" do
112
- request['date'] = "٢٠١٤-٠٩-٠٨ ١٦:٣١:١٤ +٠٣٠٠"
113
- expect(ApiAuth.authentic?(request, "123")).to eq false
107
+ it 'fails to validate far future requests' do
108
+ request['date'] = 16.minutes.from_now.utc.httpdate
109
+ expect(ApiAuth.authentic?(signed_request, '123')).to eq false
114
110
  end
115
111
 
116
- context "canonical string contains the http_method" do
117
- let(:request){
118
- new_request = Net::HTTP::Put.new("/resource.xml?foo=bar&bar=foo",
119
- 'content-type' => 'text/plain',
120
- 'content-md5' => '1B2M2Y8AsgTpgAmY7PhCfg==',
121
- 'date' => Time.now.utc.httpdate
122
- )
123
- canonical_string = ApiAuth::Headers.new(new_request).canonical_string_with_http_method
124
- signature = hmac("123", new_request, canonical_string)
125
- new_request["Authorization"] = "APIAuth 1044:#{signature}"
112
+ it 'fails to validate if the date is invalid' do
113
+ request['date'] = '٢٠١٤-٠٩-٠٨ ١٦:٣١:١٤ +٠٣٠٠'
114
+ expect(ApiAuth.authentic?(signed_request, '123')).to eq false
115
+ end
116
+
117
+ it 'fails to validate if the request method differs' do
118
+ canonical_string = ApiAuth::Headers.new(request).canonical_string('POST')
119
+ signature = hmac('123', request, canonical_string)
120
+ request['Authorization'] = "APIAuth 1044:#{signature}"
121
+ expect(ApiAuth.authentic?(request, '123')).to eq false
122
+ end
123
+
124
+ context 'when passed the hmac digest option' do
125
+ let(:request) do
126
+ new_request = Net::HTTP::Put.new('/resource.xml?foo=bar&bar=foo',
127
+ 'content-type' => 'text/plain',
128
+ 'X-Authorization-Content-SHA256' => '47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=',
129
+ 'date' => Time.now.utc.httpdate)
130
+ canonical_string = ApiAuth::Headers.new(new_request).canonical_string
131
+ signature = hmac('123', new_request, canonical_string, 'sha256')
132
+ new_request['Authorization'] = "APIAuth-HMAC-#{digest} 1044:#{signature}"
126
133
  new_request
127
- }
134
+ end
128
135
 
129
- it "validates for canonical_strings containing the http_method" do
130
- expect(ApiAuth.authentic?(request, "123")).to eq true
136
+ context 'valid request digest' do
137
+ let(:digest) { 'SHA256' }
138
+
139
+ context 'matching client digest' do
140
+ it 'validates matching digest' do
141
+ expect(ApiAuth.authentic?(request, '123', digest: 'sha256')).to eq true
142
+ end
143
+ end
144
+
145
+ context 'different client digest' do
146
+ it 'raises an exception' do
147
+ expect { ApiAuth.authentic?(request, '123', digest: 'sha512') }.to raise_error(ApiAuth::InvalidRequestDigest)
148
+ end
149
+ end
131
150
  end
132
151
 
133
- it "fails to validate if the request method differs" do
134
- canonical_string = ApiAuth::Headers.new(request).canonical_string_with_http_method('POST')
135
- signature = hmac("123", request, canonical_string)
136
- request["Authorization"] = "APIAuth 1044:#{signature}"
137
- expect(ApiAuth.authentic?(request, "123")).to eq false
152
+ context 'invalid request digest' do
153
+ let(:digest) { 'SHA111' }
154
+
155
+ it 'fails validation' do
156
+ expect(ApiAuth.authentic?(request, '123', digest: 'sha111')).to eq false
157
+ end
158
+ end
159
+ end
160
+
161
+ context 'when passed the clock_skew option' do
162
+ it 'fails to validate expired requests' do
163
+ request['date'] = 90.seconds.ago.utc.httpdate
164
+ expect(ApiAuth.authentic?(signed_request, '123', clock_skew: 60.seconds)).to eq false
165
+ end
166
+
167
+ it 'fails to validate far future requests' do
168
+ request['date'] = 90.seconds.from_now.utc.httpdate
169
+ expect(ApiAuth.authentic?(signed_request, '123', clock_skew: 60.seconds)).to eq false
170
+ end
171
+ end
172
+
173
+ context 'when passed the headers_to_sign option' do
174
+ it 'validates the request' do
175
+ request['X-Forwarded-For'] = '192.168.1.1'
176
+ expect(ApiAuth.authentic?(signed_request, '123', headers_to_sign: %w[HTTP_X_FORWARDED_FOR])).to eq true
138
177
  end
139
178
  end
140
179
  end
141
180
 
142
- describe ".access_id" do
143
- context "normal APIAuth Auth header" do
144
- let(:request){
181
+ describe '.access_id' do
182
+ context 'normal APIAuth Auth header' do
183
+ let(:request) do
145
184
  RestClient::Request.new(
146
- :url => "http://google.com",
147
- :method => :get,
148
- :headers => {:authorization => "APIAuth 1044:aGVsbG8gd29ybGQ="}
185
+ url: 'https://google.com',
186
+ method: :get,
187
+ headers: { authorization: 'APIAuth 1044:aGVsbG8gd29ybGQ=' }
149
188
  )
150
- }
189
+ end
151
190
 
152
- it "parses it from the Auth Header" do
153
- expect(ApiAuth.access_id(request)).to eq("1044")
191
+ it 'parses it from the Auth Header' do
192
+ expect(ApiAuth.access_id(request)).to eq('1044')
154
193
  end
155
194
  end
156
195
 
157
- context "Corporate prefixed APIAuth header" do
158
- let(:request){
196
+ context 'Corporate prefixed APIAuth header' do
197
+ let(:request) do
159
198
  RestClient::Request.new(
160
- :url => "http://google.com",
161
- :method => :get,
162
- :headers => {:authorization => "Corporate APIAuth 1044:aGVsbG8gd29ybGQ="}
199
+ url: 'https://google.com',
200
+ method: :get,
201
+ headers: { authorization: 'Corporate APIAuth 1044:aGVsbG8gd29ybGQ=' }
163
202
  )
164
- }
203
+ end
165
204
 
166
- it "parses it from the Auth Header" do
167
- expect(ApiAuth.access_id(request)).to eq("1044")
205
+ it 'parses it from the Auth Header' do
206
+ expect(ApiAuth.access_id(request)).to eq('1044')
168
207
  end
169
208
  end
170
209
  end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+ require 'faraday/api_auth'
3
+
4
+ describe Faraday::ApiAuth::Middleware do
5
+ it 'adds the Authorization headers' do
6
+ conn = Faraday.new('http://localhost/') do |f|
7
+ f.request :api_auth, 'foo', 'secret', digest: 'sha256'
8
+ f.adapter :test do |stub|
9
+ stub.get('http://localhost/test') do |env|
10
+ [200, {}, env.request_headers['Authorization']]
11
+ end
12
+ end
13
+ end
14
+ response = conn.get('test', nil, { 'Date' => 'Tue, 02 Aug 2022 09:29:24 GMT' })
15
+ expect(response.body).to eq 'APIAuth-HMAC-SHA256 foo:Tn/lIZ9kphcO32DwG4wFHenqBt37miDEIkA5ykLgGiQ='
16
+ end
17
+ end