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
@@ -0,0 +1,280 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApiAuth::RequestDrivers::GrapeRequest do
4
+ let(:default_method) { 'PUT' }
5
+ let(:default_params) do
6
+ { 'message' => "hello\nworld" }
7
+ end
8
+ let(:default_options) do
9
+ {
10
+ method: method,
11
+ params: params
12
+ }
13
+ end
14
+ let(:default_env) do
15
+ Rack::MockRequest.env_for('/', options)
16
+ end
17
+ let(:method) { default_method }
18
+ let(:params) { default_params }
19
+ let(:options) { default_options.merge(request_headers) }
20
+ let(:env) { default_env }
21
+
22
+ let(:request) do
23
+ Grape::Request.new(env)
24
+ end
25
+
26
+ let(:timestamp) { Time.now.utc.httpdate }
27
+ let(:request_headers) do
28
+ {
29
+ 'HTTP_X_AUTHORIZATION' => 'APIAuth 1044:12345',
30
+ 'HTTP_X_AUTHORIZATION_CONTENT_SHA256' => 'bxVSdFeR6aHBtw7+EBi5Bt8KllUZpUutOg9ChQmaSPA=',
31
+ 'HTTP_X_HMAC_CONTENT_TYPE' => 'text/plain',
32
+ 'HTTP_X_HMAC_DATE' => timestamp
33
+ }
34
+ end
35
+
36
+ subject(:driven_request) { ApiAuth::RequestDrivers::GrapeRequest.new(request) }
37
+
38
+ describe 'getting headers correctly' do
39
+ it 'gets the content_type' do
40
+ expect(driven_request.content_type).to eq('text/plain')
41
+ end
42
+
43
+ it 'gets the content_hash' do
44
+ expect(driven_request.content_hash).to eq('bxVSdFeR6aHBtw7+EBi5Bt8KllUZpUutOg9ChQmaSPA=')
45
+ end
46
+
47
+ it 'gets the request_uri' do
48
+ expect(driven_request.request_uri).to eq('http://example.org/')
49
+ end
50
+
51
+ it 'gets the timestamp' do
52
+ expect(driven_request.timestamp).to eq(timestamp)
53
+ end
54
+
55
+ it 'gets the authorization_header' do
56
+ expect(driven_request.authorization_header).to eq('APIAuth 1044:12345')
57
+ end
58
+
59
+ describe '#calculated_hash' do
60
+ it 'calculates hash from the body' do
61
+ expect(driven_request.calculated_hash).to eq('bxVSdFeR6aHBtw7+EBi5Bt8KllUZpUutOg9ChQmaSPA=')
62
+ end
63
+
64
+ context 'no body' do
65
+ let(:params) { {} }
66
+
67
+ it 'treats no body as empty string' do
68
+ expect(driven_request.calculated_hash).to eq('47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=')
69
+ end
70
+ end
71
+ end
72
+
73
+ describe 'http_method' do
74
+ context 'when put request' do
75
+ let(:method) { 'put' }
76
+
77
+ it 'returns upcased put' do
78
+ expect(driven_request.http_method).to eq('PUT')
79
+ end
80
+ end
81
+
82
+ context 'when get request' do
83
+ let(:method) { 'get' }
84
+
85
+ it 'returns upcased get' do
86
+ expect(driven_request.http_method).to eq('GET')
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ describe 'setting headers correctly' do
93
+ let(:request_headers) do
94
+ {
95
+ 'HTTP_X_HMAC_CONTENT_TYPE' => 'text/plain'
96
+ }
97
+ end
98
+
99
+ describe '#populate_content_hash' do
100
+ context 'when getting' do
101
+ let(:method) { 'get' }
102
+
103
+ it "doesn't populate content hash" do
104
+ driven_request.populate_content_hash
105
+ expect(request.headers['X-Authorization-Content-Sha256']).to be_nil
106
+ end
107
+ end
108
+
109
+ context 'when posting' do
110
+ let(:method) { 'post' }
111
+
112
+ it 'populates content bash' do
113
+ driven_request.populate_content_hash
114
+ expect(request.headers['X-Authorization-Content-Sha256']).to eq('bxVSdFeR6aHBtw7+EBi5Bt8KllUZpUutOg9ChQmaSPA=')
115
+ end
116
+
117
+ it 'refreshes the cached headers' do
118
+ driven_request.populate_content_hash
119
+ expect(driven_request.content_hash).to eq('bxVSdFeR6aHBtw7+EBi5Bt8KllUZpUutOg9ChQmaSPA=')
120
+ end
121
+ end
122
+
123
+ context 'when putting' do
124
+ let(:method) { 'put' }
125
+
126
+ it 'populates content hash' do
127
+ driven_request.populate_content_hash
128
+ expect(request.headers['X-Authorization-Content-Sha256']).to eq('bxVSdFeR6aHBtw7+EBi5Bt8KllUZpUutOg9ChQmaSPA=')
129
+ end
130
+
131
+ it 'refreshes the cached headers' do
132
+ driven_request.populate_content_hash
133
+ expect(driven_request.content_hash).to eq('bxVSdFeR6aHBtw7+EBi5Bt8KllUZpUutOg9ChQmaSPA=')
134
+ end
135
+ end
136
+
137
+ context 'when deleting' do
138
+ let(:method) { 'delete' }
139
+
140
+ it "doesn't populate content hash" do
141
+ driven_request.populate_content_hash
142
+ expect(request.headers['X-Authorization-Content-Sha256']).to be_nil
143
+ end
144
+ end
145
+ end
146
+
147
+ describe '#set_date' do
148
+ before do
149
+ allow(Time).to receive_message_chain(:now, :utc, :httpdate).and_return(timestamp)
150
+ end
151
+
152
+ it 'sets the date header of the request' do
153
+ allow(Time).to receive_message_chain(:now, :utc, :httpdate).and_return(timestamp)
154
+ driven_request.set_date
155
+ expect(request.headers['Date']).to eq(timestamp)
156
+ end
157
+
158
+ it 'refreshes the cached headers' do
159
+ driven_request.set_date
160
+ expect(driven_request.timestamp).to eq(timestamp)
161
+ end
162
+ end
163
+
164
+ describe '#set_auth_header' do
165
+ it 'sets the auth header' do
166
+ driven_request.set_auth_header('APIAuth 1044:54321')
167
+ expect(request.headers['Authorization']).to eq('APIAuth 1044:54321')
168
+ end
169
+ end
170
+ end
171
+
172
+ describe 'content_hash_mismatch?' do
173
+ context 'when getting' do
174
+ let(:method) { 'get' }
175
+
176
+ it 'is false' do
177
+ expect(driven_request.content_hash_mismatch?).to be false
178
+ end
179
+ end
180
+
181
+ context 'when posting' do
182
+ let(:method) { 'post' }
183
+
184
+ context 'when calculated matches sent' do
185
+ it 'is false' do
186
+ expect(driven_request.content_hash_mismatch?).to be false
187
+ end
188
+ end
189
+
190
+ context "when calculated doesn't match sent" do
191
+ let(:params) { { 'message' => 'hello only' } }
192
+
193
+ it 'is true' do
194
+ expect(driven_request.content_hash_mismatch?).to be true
195
+ end
196
+ end
197
+ end
198
+
199
+ context 'when putting' do
200
+ let(:method) { 'put' }
201
+
202
+ context 'when calculated matches sent' do
203
+ it 'is false' do
204
+ puts driven_request.calculated_hash
205
+ expect(driven_request.content_hash_mismatch?).to be false
206
+ end
207
+ end
208
+
209
+ context "when calculated doesn't match sent" do
210
+ let(:params) { { 'message' => 'hello only' } }
211
+ it 'is true' do
212
+ expect(driven_request.content_hash_mismatch?).to be true
213
+ end
214
+ end
215
+ end
216
+
217
+ context 'when deleting' do
218
+ let(:method) { 'delete' }
219
+
220
+ it 'is false' do
221
+ expect(driven_request.content_hash_mismatch?).to be false
222
+ end
223
+ end
224
+ end
225
+
226
+ describe 'authentics?' do
227
+ let(:request_headers) { {} }
228
+ let(:signed_request) do
229
+ ApiAuth.sign!(request, '1044', '123')
230
+ end
231
+
232
+ context 'when getting' do
233
+ let(:method) { 'get' }
234
+
235
+ it 'validates that the signature in the request header matches the way we sign it' do
236
+ expect(ApiAuth.authentic?(signed_request, '123')).to eq true
237
+ end
238
+ end
239
+
240
+ context 'when posting' do
241
+ let(:method) { 'post' }
242
+
243
+ it 'validates that the signature in the request header matches the way we sign it' do
244
+ expect(ApiAuth.authentic?(signed_request, '123')).to eq true
245
+ end
246
+ end
247
+
248
+ context 'when putting' do
249
+ let(:method) { 'put' }
250
+
251
+ let(:signed_request) do
252
+ ApiAuth.sign!(request, '1044', '123')
253
+ end
254
+
255
+ it 'validates that the signature in the request header matches the way we sign it' do
256
+ expect(ApiAuth.authentic?(signed_request, '123')).to eq true
257
+ end
258
+ end
259
+
260
+ context 'when deleting' do
261
+ let(:method) { 'delete' }
262
+
263
+ let(:signed_request) do
264
+ ApiAuth.sign!(request, '1044', '123')
265
+ end
266
+
267
+ it 'validates that the signature in the request header matches the way we sign it' do
268
+ expect(ApiAuth.authentic?(signed_request, '123')).to eq true
269
+ end
270
+ end
271
+ end
272
+
273
+ describe 'fetch_headers' do
274
+ it 'returns request headers' do
275
+ expect(driven_request.fetch_headers).to include(
276
+ 'CONTENT_TYPE' => 'application/x-www-form-urlencoded'
277
+ )
278
+ end
279
+ end
280
+ end
@@ -0,0 +1,190 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApiAuth::RequestDrivers::HttpRequest do
4
+ let(:timestamp) { Time.now.utc.httpdate }
5
+
6
+ let(:request) do
7
+ HTTP::Request.new(
8
+ verb: verb,
9
+ uri: uri,
10
+ headers: headers,
11
+ body: body
12
+ )
13
+ end
14
+
15
+ let(:verb) { :put }
16
+ let(:uri) { 'https://localhost/resource.xml?foo=bar&bar=foo' }
17
+ let(:body) { "hello\nworld" }
18
+
19
+ let(:headers) do
20
+ {
21
+ 'Authorization' => 'APIAuth 1044:12345',
22
+ 'X-Authorization-Content-SHA256' => '47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=',
23
+ 'content-type' => 'text/plain',
24
+ 'date' => timestamp
25
+ }
26
+ end
27
+
28
+ subject(:driven_request) { described_class.new(request) }
29
+
30
+ describe 'getting headers correctly' do
31
+ it 'gets the content_type' do
32
+ expect(driven_request.content_type).to eq('text/plain')
33
+ end
34
+
35
+ it 'gets the content_hash' do
36
+ expect(driven_request.content_hash).to eq('47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=')
37
+ end
38
+
39
+ it 'gets the request_uri' do
40
+ expect(driven_request.request_uri).to eq('/resource.xml?foo=bar&bar=foo')
41
+ end
42
+
43
+ it 'gets the timestamp' do
44
+ expect(driven_request.timestamp).to eq(timestamp)
45
+ end
46
+
47
+ it 'gets the authorization_header' do
48
+ expect(driven_request.authorization_header).to eq('APIAuth 1044:12345')
49
+ end
50
+
51
+ describe '#calculated_hash' do
52
+ it 'calculates hash from the body' do
53
+ expect(driven_request.calculated_hash).to eq('JsYKYdAdtYNspw/v1EpqAWYgQTyO9fJZpsVhLU9507g=')
54
+ expect(driven_request.body.bytesize).to eq(11)
55
+ end
56
+
57
+ context 'no body' do
58
+ let(:body) { nil }
59
+
60
+ it 'treats no body as empty string' do
61
+ expect(driven_request.calculated_hash).to eq('47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=')
62
+ expect(driven_request.body.bytesize).to eq(0)
63
+ end
64
+ end
65
+
66
+ context 'multipart content' do
67
+ let(:body) { File.new('spec/fixtures/upload.png') }
68
+
69
+ it 'calculates correctly for multipart content' do
70
+ expect(driven_request.calculated_hash).to eq('AlKDe7kjMQhuKgKuNG8I7GA93MasHcaVJkJLaUT7+dY=')
71
+ expect(driven_request.body.bytesize).to eq(5112)
72
+ end
73
+ end
74
+ end
75
+
76
+ describe 'http_method' do
77
+ context 'when put request' do
78
+ let(:verb) { :put }
79
+
80
+ it 'returns upcased put' do
81
+ expect(driven_request.http_method).to eq('PUT')
82
+ end
83
+ end
84
+
85
+ context 'when get request' do
86
+ let(:verb) { :get }
87
+
88
+ it 'returns upcased get' do
89
+ expect(driven_request.http_method).to eq('GET')
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ describe 'setting headers correctly' do
96
+ let(:headers) do
97
+ {
98
+ 'content-type' => 'text/plain'
99
+ }
100
+ end
101
+
102
+ describe '#populate_content_hash' do
103
+ context 'when request type has no body' do
104
+ let(:verb) { :get }
105
+
106
+ it "doesn't populate content hash" do
107
+ driven_request.populate_content_hash
108
+ expect(request['X-Authorization-Content-SHA256']).to be_nil
109
+ end
110
+ end
111
+
112
+ context 'when request type has a body' do
113
+ let(:verb) { :put }
114
+
115
+ it 'populates content hash' do
116
+ driven_request.populate_content_hash
117
+ expect(request['X-Authorization-Content-SHA256']).to eq('JsYKYdAdtYNspw/v1EpqAWYgQTyO9fJZpsVhLU9507g=')
118
+ end
119
+
120
+ it 'refreshes the cached headers' do
121
+ driven_request.populate_content_hash
122
+ expect(driven_request.content_hash).to eq('JsYKYdAdtYNspw/v1EpqAWYgQTyO9fJZpsVhLU9507g=')
123
+ end
124
+ end
125
+ end
126
+
127
+ describe '#set_date' do
128
+ before do
129
+ allow(Time).to receive_message_chain(:now, :utc, :httpdate).and_return(timestamp)
130
+ end
131
+
132
+ it 'sets the date header of the request' do
133
+ driven_request.set_date
134
+ expect(request['DATE']).to eq(timestamp)
135
+ end
136
+
137
+ it 'refreshes the cached headers' do
138
+ driven_request.set_date
139
+ expect(driven_request.timestamp).to eq(timestamp)
140
+ end
141
+ end
142
+
143
+ describe '#set_auth_header' do
144
+ it 'sets the auth header' do
145
+ driven_request.set_auth_header('APIAuth 1044:54321')
146
+ expect(request['Authorization']).to eq('APIAuth 1044:54321')
147
+ end
148
+ end
149
+ end
150
+
151
+ describe 'content_hash_mismatch?' do
152
+ context 'when request type has no body' do
153
+ let(:verb) { :get }
154
+
155
+ it 'is false' do
156
+ expect(driven_request.content_hash_mismatch?).to be false
157
+ end
158
+ end
159
+
160
+ context 'when request type has a body' do
161
+ let(:verb) { :put }
162
+
163
+ context 'when calculated matches sent' do
164
+ before do
165
+ request['X-Authorization-Content-SHA256'] = 'JsYKYdAdtYNspw/v1EpqAWYgQTyO9fJZpsVhLU9507g='
166
+ end
167
+
168
+ it 'is false' do
169
+ expect(driven_request.content_hash_mismatch?).to be false
170
+ end
171
+ end
172
+
173
+ context "when calculated doesn't match sent" do
174
+ before do
175
+ request['X-Authorization-Content-SHA256'] = '3'
176
+ end
177
+
178
+ it 'is true' do
179
+ expect(driven_request.content_hash_mismatch?).to be true
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ describe 'fetch_headers' do
186
+ it 'returns request headers' do
187
+ expect(driven_request.fetch_headers).to include('CONTENT-TYPE' => 'text/plain')
188
+ end
189
+ end
190
+ end
@@ -1,160 +1,160 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ApiAuth::RequestDrivers::HttpiRequest do
4
-
5
- let(:timestamp){ Time.now.utc.httpdate }
4
+ let(:timestamp) { Time.now.utc.httpdate }
6
5
 
7
6
  let(:request) do
8
- httpi_request = HTTPI::Request.new("http://localhost/resource.xml?foo=bar&bar=foo")
9
- httpi_request.headers.merge!({
10
- 'Authorization' => 'APIAuth 1044:12345',
11
- 'content-md5' => '1B2M2Y8AsgTpgAmY7PhCfg==',
12
- 'content-type' => 'text/plain',
13
- 'date' => timestamp
14
- })
7
+ httpi_request = HTTPI::Request.new('https://localhost/resource.xml?foo=bar&bar=foo')
8
+ httpi_request.headers.merge!('Authorization' => 'APIAuth 1044:12345',
9
+ 'X-Authorization-Content-SHA256' => '47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=',
10
+ 'content-type' => 'text/plain',
11
+ 'date' => timestamp)
15
12
  httpi_request.body = "hello\nworld"
16
13
  httpi_request
17
14
  end
18
15
 
19
- subject(:driven_request){ ApiAuth::RequestDrivers::HttpiRequest.new(request) }
16
+ subject(:driven_request) { ApiAuth::RequestDrivers::HttpiRequest.new(request) }
20
17
 
21
- describe "getting headers correctly" do
22
- it "gets the content_type" do
18
+ describe 'getting headers correctly' do
19
+ it 'gets the content_type' do
23
20
  expect(driven_request.content_type).to eq('text/plain')
24
21
  end
25
22
 
26
- it "gets the content_md5" do
27
- expect(driven_request.content_md5).to eq('1B2M2Y8AsgTpgAmY7PhCfg==')
23
+ it 'gets the content_hash' do
24
+ expect(driven_request.content_hash).to eq('47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=')
28
25
  end
29
26
 
30
- it "gets the request_uri" do
27
+ it 'gets the request_uri' do
31
28
  expect(driven_request.request_uri).to eq('/resource.xml?foo=bar&bar=foo')
32
29
  end
33
30
 
34
- it "gets the timestamp" do
31
+ it 'gets the timestamp' do
35
32
  expect(driven_request.timestamp).to eq(timestamp)
36
33
  end
37
34
 
38
- it "gets the authorization_header" do
35
+ it 'gets the authorization_header' do
39
36
  expect(driven_request.authorization_header).to eq('APIAuth 1044:12345')
40
37
  end
41
38
 
42
- describe "#calculated_md5" do
43
- it "calculates md5 from the body" do
44
- expect(driven_request.calculated_md5).to eq('kZXQvrKoieG+Be1rsZVINw==')
39
+ describe '#calculated_hash' do
40
+ it 'calculates hash from the body' do
41
+ expect(driven_request.calculated_hash).to eq('JsYKYdAdtYNspw/v1EpqAWYgQTyO9fJZpsVhLU9507g=')
45
42
  end
46
43
 
47
- it "treats no body as empty string" do
44
+ it 'treats no body as empty string' do
48
45
  request.body = nil
49
- expect(driven_request.calculated_md5).to eq('1B2M2Y8AsgTpgAmY7PhCfg==')
46
+ expect(driven_request.calculated_hash).to eq('47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=')
50
47
  end
51
48
  end
52
49
 
53
- describe "http_method" do
54
- it "is always nil" do
50
+ describe 'http_method' do
51
+ it 'is always nil' do
55
52
  expect(driven_request.http_method).to be_nil
56
53
  end
57
54
  end
58
55
  end
59
56
 
60
- describe "setting headers correctly" do
57
+ describe 'setting headers correctly' do
61
58
  let(:request) do
62
- httpi_request = HTTPI::Request.new("http://localhost/resource.xml?foo=bar&bar=foo")
63
- httpi_request.headers.merge!({
64
- 'content-type' => 'text/plain'
65
- })
59
+ httpi_request = HTTPI::Request.new('https://localhost/resource.xml?foo=bar&bar=foo')
60
+ httpi_request.headers['content-type'] = 'text/plain'
66
61
  httpi_request
67
62
  end
68
63
 
69
- describe "#populate_content_md5" do
70
- context "when there is no content body" do
64
+ describe '#populate_content_hash' do
65
+ context 'when there is no content body' do
71
66
  before do
72
67
  request.body = nil
73
68
  end
74
69
 
75
- it "doesn't populate content-md5" do
76
- driven_request.populate_content_md5
77
- expect(request.headers["Content-MD5"]).to be_nil
70
+ it "doesn't populate content hash" do
71
+ driven_request.populate_content_hash
72
+ expect(request.headers['X-Authorization-Content-SHA256']).to be_nil
78
73
  end
79
74
  end
80
75
 
81
- context "when there is a content body" do
76
+ context 'when there is a content body' do
82
77
  before do
83
78
  request.body = "hello\nworld"
84
79
  end
85
80
 
86
- it "populates content-md5" do
87
- driven_request.populate_content_md5
88
- expect(request.headers["Content-MD5"]).to eq('kZXQvrKoieG+Be1rsZVINw==')
81
+ it 'populates content hash' do
82
+ driven_request.populate_content_hash
83
+ expect(request.headers['X-Authorization-Content-SHA256']).to eq('JsYKYdAdtYNspw/v1EpqAWYgQTyO9fJZpsVhLU9507g=')
89
84
  end
90
85
 
91
- it "refreshes the cached headers" do
92
- driven_request.populate_content_md5
93
- expect(driven_request.content_md5).to eq('kZXQvrKoieG+Be1rsZVINw==')
86
+ it 'refreshes the cached headers' do
87
+ driven_request.populate_content_hash
88
+ expect(driven_request.content_hash).to eq('JsYKYdAdtYNspw/v1EpqAWYgQTyO9fJZpsVhLU9507g=')
94
89
  end
95
90
  end
96
91
  end
97
92
 
98
- describe "#set_date" do
93
+ describe '#set_date' do
99
94
  before do
100
95
  allow(Time).to receive_message_chain(:now, :utc, :httpdate).and_return(timestamp)
101
96
  end
102
97
 
103
- it "sets the date header of the request" do
98
+ it 'sets the date header of the request' do
104
99
  driven_request.set_date
105
100
  expect(request.headers['DATE']).to eq(timestamp)
106
101
  end
107
102
 
108
- it "refreshes the cached headers" do
103
+ it 'refreshes the cached headers' do
109
104
  driven_request.set_date
110
105
  expect(driven_request.timestamp).to eq(timestamp)
111
106
  end
112
107
  end
113
108
 
114
- describe "#set_auth_header" do
115
- it "sets the auth header" do
109
+ describe '#set_auth_header' do
110
+ it 'sets the auth header' do
116
111
  driven_request.set_auth_header('APIAuth 1044:54321')
117
112
  expect(request.headers['Authorization']).to eq('APIAuth 1044:54321')
118
113
  end
119
114
  end
120
115
  end
121
116
 
122
- describe "md5_mismatch?" do
123
- context "when there is no content body" do
117
+ describe 'content_hash_mismatch?' do
118
+ context 'when there is no content body' do
124
119
  before do
125
120
  request.body = nil
126
121
  end
127
122
 
128
-
129
- it "is false" do
130
- expect(driven_request.md5_mismatch?).to be false
123
+ it 'is false' do
124
+ expect(driven_request.content_hash_mismatch?).to be false
131
125
  end
132
126
  end
133
127
 
134
- context "when there is a content body" do
128
+ context 'when there is a content body' do
135
129
  before do
136
130
  request.body = "hello\nworld"
137
131
  end
138
132
 
139
- context "when calculated matches sent" do
133
+ context 'when calculated matches sent' do
140
134
  before do
141
- request.headers["Content-MD5"] = 'kZXQvrKoieG+Be1rsZVINw=='
135
+ request.headers['X-Authorization-Content-SHA256'] = 'JsYKYdAdtYNspw/v1EpqAWYgQTyO9fJZpsVhLU9507g='
142
136
  end
143
137
 
144
- it "is false" do
145
- expect(driven_request.md5_mismatch?).to be false
138
+ it 'is false' do
139
+ expect(driven_request.content_hash_mismatch?).to be false
146
140
  end
147
141
  end
148
142
 
149
143
  context "when calculated doesn't match sent" do
150
144
  before do
151
- request.headers["Content-MD5"] = "3"
145
+ request.headers['X-Authorization-Content-SHA256'] = '3'
152
146
  end
153
147
 
154
- it "is true" do
155
- expect(driven_request.md5_mismatch?).to be true
148
+ it 'is true' do
149
+ expect(driven_request.content_hash_mismatch?).to be true
156
150
  end
157
151
  end
158
152
  end
159
153
  end
154
+
155
+ describe 'fetch_headers' do
156
+ it 'returns request headers' do
157
+ expect(driven_request.fetch_headers).to include('CONTENT-TYPE' => 'text/plain')
158
+ end
159
+ end
160
160
  end