api-auth 1.3.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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