api-auth 1.3.2 → 1.4.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +2 -2
  3. data/.travis.yml +4 -0
  4. data/Appraisals +6 -0
  5. data/CHANGELOG.md +36 -0
  6. data/Gemfile.lock +77 -44
  7. data/README.md +15 -8
  8. data/VERSION +1 -1
  9. data/api_auth.gemspec +4 -4
  10. data/gemfiles/rails_23.gemfile +1 -1
  11. data/gemfiles/rails_23.gemfile.lock +19 -11
  12. data/gemfiles/rails_30.gemfile +1 -1
  13. data/gemfiles/rails_30.gemfile.lock +19 -11
  14. data/gemfiles/rails_31.gemfile +1 -1
  15. data/gemfiles/rails_31.gemfile.lock +19 -11
  16. data/gemfiles/rails_32.gemfile +1 -1
  17. data/gemfiles/rails_32.gemfile.lock +19 -11
  18. data/gemfiles/rails_4.gemfile +1 -1
  19. data/gemfiles/rails_4.gemfile.lock +19 -11
  20. data/gemfiles/rails_41.gemfile +1 -1
  21. data/gemfiles/rails_41.gemfile.lock +19 -11
  22. data/gemfiles/rails_42.gemfile +9 -0
  23. data/gemfiles/rails_42.gemfile.lock +115 -0
  24. data/lib/api_auth/base.rb +37 -23
  25. data/lib/api_auth/headers.rb +23 -3
  26. data/lib/api_auth/request_drivers/action_controller.rb +4 -0
  27. data/lib/api_auth/request_drivers/curb.rb +4 -0
  28. data/lib/api_auth/request_drivers/faraday.rb +4 -0
  29. data/lib/api_auth/request_drivers/httpi.rb +5 -1
  30. data/lib/api_auth/request_drivers/net_http.rb +4 -0
  31. data/lib/api_auth/request_drivers/rack.rb +5 -1
  32. data/lib/api_auth/request_drivers/rest_client.rb +4 -0
  33. data/spec/api_auth_spec.rb +112 -628
  34. data/spec/headers_spec.rb +132 -289
  35. data/spec/helpers_spec.rb +2 -2
  36. data/spec/railtie_spec.rb +13 -8
  37. data/spec/request_drivers/action_controller_spec.rb +218 -0
  38. data/spec/request_drivers/action_dispatch_spec.rb +219 -0
  39. data/spec/request_drivers/curb_spec.rb +89 -0
  40. data/spec/request_drivers/faraday_spec.rb +243 -0
  41. data/spec/request_drivers/httpi_spec.rb +147 -0
  42. data/spec/request_drivers/net_http_spec.rb +185 -0
  43. data/spec/request_drivers/rack_spec.rb +288 -0
  44. data/spec/request_drivers/rest_client_spec.rb +311 -0
  45. metadata +44 -19
  46. data/spec/application_helper.rb +0 -2
  47. data/spec/test_helper.rb +0 -2
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApiAuth::RequestDrivers::CurbRequest do
4
+
5
+ let(:timestamp){ Time.now.utc.httpdate }
6
+
7
+ let(:request) do
8
+ headers = {
9
+ 'Authorization' => 'APIAuth 1044:12345',
10
+ 'Content-MD5' => "1B2M2Y8AsgTpgAmY7PhCfg==",
11
+ 'Content-Type' => "text/plain",
12
+ 'Date' => timestamp
13
+ }
14
+ Curl::Easy.new("/resource.xml?foo=bar&bar=foo") do |curl|
15
+ curl.headers = headers
16
+ end
17
+ end
18
+
19
+
20
+ subject(:driven_request){ ApiAuth::RequestDrivers::CurbRequest.new(request) }
21
+
22
+ describe "getting headers correctly" do
23
+ it "gets the content_type" do
24
+ expect(driven_request.content_type).to eq('text/plain')
25
+ end
26
+
27
+ it "gets the content_md5" do
28
+ expect(driven_request.content_md5).to eq('1B2M2Y8AsgTpgAmY7PhCfg==')
29
+ end
30
+
31
+ it "gets the request_uri" do
32
+ expect(driven_request.request_uri).to eq('/resource.xml?foo=bar&bar=foo')
33
+ end
34
+
35
+ it "gets the timestamp" do
36
+ expect(driven_request.timestamp).to eq(timestamp)
37
+ end
38
+
39
+ it "gets the authorization_header" do
40
+ expect(driven_request.authorization_header).to eq('APIAuth 1044:12345')
41
+ end
42
+
43
+ describe "http_method" do
44
+ it "is always nil" do
45
+ expect(driven_request.http_method).to be_nil
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "setting headers correctly" do
51
+ let(:request) do
52
+ headers = {
53
+ 'Content-Type' => "text/plain"
54
+ }
55
+ Curl::Easy.new("/resource.xml?foo=bar&bar=foo") do |curl|
56
+ curl.headers = headers
57
+ end
58
+ end
59
+
60
+ describe "#populate_content_md5" do
61
+ it "is a no-op" do
62
+ expect(driven_request.populate_content_md5).to be_nil
63
+ expect(request.headers['Content-MD5']).to be_nil
64
+ end
65
+
66
+ end
67
+
68
+ describe "#set_date" do
69
+ it "sets the date" do
70
+ allow(Time).to receive_message_chain(:now, :utc, :httpdate).and_return(timestamp)
71
+ driven_request.set_date
72
+ expect(request.headers['DATE']).to eq(timestamp)
73
+ end
74
+ end
75
+
76
+ describe "#set_auth_header" do
77
+ it "sets the auth header" do
78
+ driven_request.set_auth_header('APIAuth 1044:54321')
79
+ expect(request.headers['Authorization']).to eq('APIAuth 1044:54321')
80
+ end
81
+ end
82
+ end
83
+
84
+ describe "md5_mismatch?" do
85
+ it "is always false" do
86
+ expect(driven_request.md5_mismatch?).to be false
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,243 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApiAuth::RequestDrivers::FaradayRequest do
4
+
5
+ let(:timestamp){ Time.now.utc.httpdate }
6
+
7
+ let(:faraday_stubs) do
8
+ Faraday::Adapter::Test::Stubs.new do |stub|
9
+ stub.put('/resource.xml?foo=bar&bar=foo') { [200, {}, ''] }
10
+ stub.get('/resource.xml?foo=bar&bar=foo') { [200, {}, ''] }
11
+ stub.put('/resource.xml') { [200, {}, ''] }
12
+ end
13
+ end
14
+
15
+ let(:faraday_conn) do
16
+ Faraday.new do |builder|
17
+ builder.adapter :test, faraday_stubs
18
+ end
19
+ end
20
+
21
+ let(:request_headers) do
22
+ {
23
+ 'Authorization' => 'APIAuth 1044:12345',
24
+ 'Content-MD5' => "1B2M2Y8AsgTpgAmY7PhCfg==",
25
+ 'content-type' => 'text/plain',
26
+ 'DATE' => timestamp
27
+ }
28
+ end
29
+
30
+ let(:request) do
31
+ faraday_request = nil
32
+
33
+ faraday_conn.put '/resource.xml?foo=bar&bar=foo', "hello\nworld" do |request|
34
+ faraday_request = request
35
+ faraday_request.headers.merge!(request_headers)
36
+ end
37
+
38
+ faraday_request
39
+ end
40
+
41
+ subject(:driven_request){ ApiAuth::RequestDrivers::FaradayRequest.new(request) }
42
+
43
+ describe "getting headers correctly" do
44
+ it "gets the content_type" do
45
+ expect(driven_request.content_type).to eq('text/plain')
46
+ end
47
+
48
+ it "gets the content_md5" do
49
+ expect(driven_request.content_md5).to eq('1B2M2Y8AsgTpgAmY7PhCfg==')
50
+ end
51
+
52
+ it "gets the request_uri" do
53
+ expect(driven_request.request_uri).to eq('/resource.xml?bar=foo&foo=bar')
54
+ end
55
+
56
+ it "gets the timestamp" do
57
+ expect(driven_request.timestamp).to eq(timestamp)
58
+ end
59
+
60
+ it "gets the authorization_header" do
61
+ expect(driven_request.authorization_header).to eq('APIAuth 1044:12345')
62
+ end
63
+
64
+ describe "#calculated_md5" do
65
+ it "calculates md5 from the body" do
66
+ expect(driven_request.calculated_md5).to eq('kZXQvrKoieG+Be1rsZVINw==')
67
+ end
68
+
69
+ it "treats no body as empty string" do
70
+ request.body = nil
71
+ expect(driven_request.calculated_md5).to eq('1B2M2Y8AsgTpgAmY7PhCfg==')
72
+ end
73
+ end
74
+
75
+ describe "http_method" do
76
+ context "when put request" do
77
+ let(:request) do
78
+ faraday_request = nil
79
+
80
+ faraday_conn.put '/resource.xml?foo=bar&bar=foo', "hello\nworld" do |request|
81
+ faraday_request = request
82
+ faraday_request.headers.merge!(request_headers)
83
+ end
84
+
85
+ faraday_request
86
+ end
87
+
88
+ it "returns upcased put" do
89
+ expect(driven_request.http_method).to eq('PUT')
90
+ end
91
+ end
92
+
93
+ context "when get request" do
94
+ let(:request) do
95
+ faraday_request = nil
96
+
97
+ faraday_conn.get '/resource.xml?foo=bar&bar=foo' do |request|
98
+ faraday_request = request
99
+ faraday_request.headers.merge!(request_headers)
100
+ end
101
+
102
+ faraday_request
103
+ end
104
+
105
+ it "returns upcased get" do
106
+ expect(driven_request.http_method).to eq('GET')
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ describe "setting headers correctly" do
113
+ let(:request_headers) do
114
+ {
115
+ 'content-type' => 'text/plain'
116
+ }
117
+ end
118
+
119
+ describe "#populate_content_md5" do
120
+ context "when getting" do
121
+ it "doesn't populate content-md5" do
122
+ request.method = :get
123
+ driven_request.populate_content_md5
124
+ expect(request.headers["Content-MD5"]).to be_nil
125
+ end
126
+ end
127
+
128
+ context "when posting" do
129
+ it "populates content-md5" do
130
+ request.method = :post
131
+ driven_request.populate_content_md5
132
+ expect(request.headers["Content-MD5"]).to eq('kZXQvrKoieG+Be1rsZVINw==')
133
+ end
134
+ end
135
+
136
+ context "when putting" do
137
+ it "populates content-md5" do
138
+ request.method = :put
139
+ driven_request.populate_content_md5
140
+ expect(request.headers["Content-MD5"]).to eq('kZXQvrKoieG+Be1rsZVINw==')
141
+ end
142
+ end
143
+
144
+ context "when deleting" do
145
+ it "doesn't populate content-md5" do
146
+ request.method = :delete
147
+ driven_request.populate_content_md5
148
+ expect(request.headers["Content-MD5"]).to be_nil
149
+ end
150
+ end
151
+
152
+ end
153
+
154
+ describe "#set_date" do
155
+ it "sets the date" do
156
+ allow(Time).to receive_message_chain(:now, :utc, :httpdate).and_return(timestamp)
157
+ driven_request.set_date
158
+ expect(request.headers['DATE']).to eq(timestamp)
159
+ end
160
+ end
161
+
162
+ describe "#set_auth_header" do
163
+ it "sets the auth header" do
164
+ driven_request.set_auth_header('APIAuth 1044:54321')
165
+ expect(request.headers['Authorization']).to eq('APIAuth 1044:54321')
166
+ end
167
+ end
168
+ end
169
+
170
+ describe "md5_mismatch?" do
171
+ context "when getting" do
172
+ before do
173
+ request.method = :get
174
+ end
175
+
176
+ it "is false" do
177
+ expect(driven_request.md5_mismatch?).to be false
178
+ end
179
+ end
180
+
181
+ context "when posting" do
182
+ before do
183
+ request.method = :post
184
+ end
185
+
186
+ context "when calculated matches sent" do
187
+ before do
188
+ request.headers["Content-MD5"] = 'kZXQvrKoieG+Be1rsZVINw=='
189
+ end
190
+
191
+ it "is false" do
192
+ expect(driven_request.md5_mismatch?).to be false
193
+ end
194
+ end
195
+
196
+ context "when calculated doesn't match sent" do
197
+ before do
198
+ request.headers["Content-MD5"] = "3"
199
+ end
200
+
201
+ it "is true" do
202
+ expect(driven_request.md5_mismatch?).to be true
203
+ end
204
+ end
205
+ end
206
+
207
+ context "when putting" do
208
+ before do
209
+ request.method = :put
210
+ end
211
+
212
+ context "when calculated matches sent" do
213
+ before do
214
+ request.headers["Content-MD5"] = 'kZXQvrKoieG+Be1rsZVINw=='
215
+ end
216
+
217
+ it "is false" do
218
+ expect(driven_request.md5_mismatch?).to be false
219
+ end
220
+ end
221
+
222
+ context "when calculated doesn't match sent" do
223
+ before do
224
+ request.headers["Content-MD5"] = "3"
225
+ end
226
+
227
+ it "is true" do
228
+ expect(driven_request.md5_mismatch?).to be true
229
+ end
230
+ end
231
+ end
232
+
233
+ context "when deleting" do
234
+ before do
235
+ request.method = :delete
236
+ end
237
+
238
+ it "is false" do
239
+ expect(driven_request.md5_mismatch?).to be false
240
+ end
241
+ end
242
+ end
243
+ end
@@ -0,0 +1,147 @@
1
+ require 'spec_helper'
2
+
3
+ describe ApiAuth::RequestDrivers::HttpiRequest do
4
+
5
+ let(:timestamp){ Time.now.utc.httpdate }
6
+
7
+ 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
+ })
15
+ httpi_request.body = "hello\nworld"
16
+ httpi_request
17
+ end
18
+
19
+ subject(:driven_request){ ApiAuth::RequestDrivers::HttpiRequest.new(request) }
20
+
21
+ describe "getting headers correctly" do
22
+ it "gets the content_type" do
23
+ expect(driven_request.content_type).to eq('text/plain')
24
+ end
25
+
26
+ it "gets the content_md5" do
27
+ expect(driven_request.content_md5).to eq('1B2M2Y8AsgTpgAmY7PhCfg==')
28
+ end
29
+
30
+ it "gets the request_uri" do
31
+ expect(driven_request.request_uri).to eq('/resource.xml?foo=bar&bar=foo')
32
+ end
33
+
34
+ it "gets the timestamp" do
35
+ expect(driven_request.timestamp).to eq(timestamp)
36
+ end
37
+
38
+ it "gets the authorization_header" do
39
+ expect(driven_request.authorization_header).to eq('APIAuth 1044:12345')
40
+ end
41
+
42
+ describe "#calculated_md5" do
43
+ it "calculates md5 from the body" do
44
+ expect(driven_request.calculated_md5).to eq('kZXQvrKoieG+Be1rsZVINw==')
45
+ end
46
+
47
+ it "treats no body as empty string" do
48
+ request.body = nil
49
+ expect(driven_request.calculated_md5).to eq('1B2M2Y8AsgTpgAmY7PhCfg==')
50
+ end
51
+ end
52
+
53
+ describe "http_method" do
54
+ it "is always nil" do
55
+ expect(driven_request.http_method).to be_nil
56
+ end
57
+ end
58
+ end
59
+
60
+ describe "setting headers correctly" do
61
+ 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
+ })
66
+ httpi_request
67
+ end
68
+
69
+ describe "#populate_content_md5" do
70
+ context "when there is no content body" do
71
+ before do
72
+ request.body = nil
73
+ end
74
+
75
+ it "doesn't populate content-md5" do
76
+ driven_request.populate_content_md5
77
+ expect(request.headers["Content-MD5"]).to be_nil
78
+ end
79
+ end
80
+
81
+ context "when there is a content body" do
82
+ before do
83
+ request.body = "hello\nworld"
84
+ end
85
+
86
+ it "populates content-md5" do
87
+ driven_request.populate_content_md5
88
+ expect(request.headers["Content-MD5"]).to eq('kZXQvrKoieG+Be1rsZVINw==')
89
+ end
90
+ end
91
+ end
92
+
93
+ describe "#set_date" do
94
+ it "sets the date" do
95
+ allow(Time).to receive_message_chain(:now, :utc, :httpdate).and_return(timestamp)
96
+ driven_request.set_date
97
+ expect(request.headers['DATE']).to eq(timestamp)
98
+ end
99
+ end
100
+
101
+ describe "#set_auth_header" do
102
+ it "sets the auth header" do
103
+ driven_request.set_auth_header('APIAuth 1044:54321')
104
+ expect(request.headers['Authorization']).to eq('APIAuth 1044:54321')
105
+ end
106
+ end
107
+ end
108
+
109
+ describe "md5_mismatch?" do
110
+ context "when there is no content body" do
111
+ before do
112
+ request.body = nil
113
+ end
114
+
115
+
116
+ it "is false" do
117
+ expect(driven_request.md5_mismatch?).to be false
118
+ end
119
+ end
120
+
121
+ context "when there is a content body" do
122
+ before do
123
+ request.body = "hello\nworld"
124
+ end
125
+
126
+ context "when calculated matches sent" do
127
+ before do
128
+ request.headers["Content-MD5"] = 'kZXQvrKoieG+Be1rsZVINw=='
129
+ end
130
+
131
+ it "is false" do
132
+ expect(driven_request.md5_mismatch?).to be false
133
+ end
134
+ end
135
+
136
+ context "when calculated doesn't match sent" do
137
+ before do
138
+ request.headers["Content-MD5"] = "3"
139
+ end
140
+
141
+ it "is true" do
142
+ expect(driven_request.md5_mismatch?).to be true
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end