lockbox_middleware 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +2 -2
- data/lib/lockbox_middleware.rb +3 -1
- data/spec/lib/lockbox_middleware_spec.rb +51 -2
- data/spec/support/helper_methods.rb +1 -1
- metadata +3 -3
data/LICENSE
CHANGED
@@ -15,10 +15,10 @@ modification, are permitted provided that the following conditions are met:
|
|
15
15
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
16
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
17
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
-
DISCLAIMED. IN NO EVENT SHALL
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE DEMOCRATIC NATIONAL COMMITTEE BE LIABLE FOR ANY
|
19
19
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
20
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
21
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
22
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
23
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
-
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/lib/lockbox_middleware.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'httparty'
|
2
2
|
require 'lockbox_cache'
|
3
3
|
require 'auth-hmac'
|
4
|
+
require 'digest/md5'
|
4
5
|
|
5
6
|
class LockBox
|
6
7
|
include HTTParty
|
@@ -129,7 +130,8 @@ class LockBox
|
|
129
130
|
headers = {}
|
130
131
|
headers['Referer'] = "#{env['rack.url_scheme']}://#{env['SERVER_NAME']}#{env['PATH_INFO']}"
|
131
132
|
headers['Referer'] << "?#{env['QUERY_STRING']}" unless env['QUERY_STRING'].blank?
|
132
|
-
|
133
|
+
headers['X-Referer-Content-MD5'] = Digest::MD5.hexdigest(Rack::Request.new(env).body.read) if env['CONTENT_TYPE']
|
134
|
+
{'Content-Type' => 'CONTENT_TYPE', 'Date' => 'HTTP_DATE', 'Method' => 'REQUEST_METHOD', 'Authorization' => 'HTTP_AUTHORIZATION'}.each_pair do |h,e|
|
133
135
|
headers["X-Referer-#{h}"] = env[e] unless env[e].blank?
|
134
136
|
end
|
135
137
|
headers
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rack/test'
|
3
3
|
require 'lockbox_middleware'
|
4
|
+
require 'digest/md5'
|
5
|
+
require 'cgi'
|
4
6
|
|
5
7
|
describe 'LockBox' do
|
6
8
|
include Rack::Test::Methods
|
@@ -194,7 +196,7 @@ describe 'LockBox' do
|
|
194
196
|
|
195
197
|
end
|
196
198
|
|
197
|
-
context "hitting API actions with HMAC auth" do
|
199
|
+
context "hitting API actions via GET requests with HMAC auth" do
|
198
200
|
before :each do
|
199
201
|
successful_response = mock("MockResponse")
|
200
202
|
successful_response.stubs(:code).returns(200)
|
@@ -236,7 +238,54 @@ describe 'LockBox' do
|
|
236
238
|
last_response.status.should == 401
|
237
239
|
end
|
238
240
|
end
|
239
|
-
|
241
|
+
|
242
|
+
context "hitting API actions via POST requests with HMAC auth" do
|
243
|
+
before :each do
|
244
|
+
@content = "" # TODO: Rack::Test sucks at some stuff, like setting the request body when making a POST
|
245
|
+
@content_md5 = Digest::MD5.hexdigest(CGI::escape(@content))
|
246
|
+
|
247
|
+
successful_response = mock("MockResponse")
|
248
|
+
successful_response.stubs(:code).returns(200)
|
249
|
+
successful_response.stubs(:headers).returns({'Cache-Control' => 'public, no-cache'})
|
250
|
+
Time.stubs(:now).returns(Time.parse("2010-05-10 16:30:00 EDT"))
|
251
|
+
valid_headers = {'X-Referer-Method' => 'POST', 'X-Referer-Content-Type' => 'application/x-www-form-urlencoded', 'X-Referer-Date' => [Time.now.httpdate], 'X-Referer-Authorization' => ['AuthHMAC key-id:+qPzK7cJdJbhsiCRcXa8A8LLrF8='], 'Referer' => 'http://example.org/api/some_controller/some_action', 'X-Referer-Content-MD5' => @content_md5}
|
252
|
+
LockBox.stubs(:get).with("/authentication/hmac", {:headers => valid_headers, :request => {:application_name => 'test'}}).returns(successful_response)
|
253
|
+
|
254
|
+
bad_response = mock("MockResponse")
|
255
|
+
bad_response.stubs(:code).returns(401)
|
256
|
+
bad_response.stubs(:headers).returns({'Cache-Control' => 'public, no-cache'})
|
257
|
+
invalid_headers = {'X-Referer-Method' => 'POST', 'X-Referer-Content-Type' => 'application/x-www-form-urlencoded', 'X-Referer-Date' => [Time.now.httpdate], 'X-Referer-Authorization' => ['AuthHMAC key-id:u2Jlv0f6ZG59HQNGk+Bgq3/vHvM='], 'Referer' => 'http://example.org/api/some_controller/some_action', 'X-Referer-Content-MD5' => @content_md5}
|
258
|
+
LockBox.stubs(:get).with("/authentication/hmac", {:headers => invalid_headers, :request => {:application_name => 'test'}}).returns(bad_response)
|
259
|
+
|
260
|
+
@path = "/api/some_controller/some_action"
|
261
|
+
|
262
|
+
hmac_request = Net::HTTP::Post.new(@path, {'Date' => Time.now.httpdate})
|
263
|
+
hmac_request.body = @content
|
264
|
+
store = mock("MockStore")
|
265
|
+
store.stubs(:[]).with('key-id').returns("123456")
|
266
|
+
authhmac = AuthHMAC.new(store)
|
267
|
+
authhmac.sign!(hmac_request, 'key-id')
|
268
|
+
@hmac_headers = hmac_request.to_hash
|
269
|
+
end
|
270
|
+
|
271
|
+
it "should return 200 for an HMAC request with a valid auth header" do
|
272
|
+
@hmac_headers.each_pair do |key,value|
|
273
|
+
header key, value
|
274
|
+
end
|
275
|
+
post @path, @content
|
276
|
+
last_response.status.should == 200
|
277
|
+
end
|
278
|
+
|
279
|
+
it "should return 401 for an HMAC request with an invalid auth header" do
|
280
|
+
@hmac_headers['authorization'] = ['AuthHMAC key-id:u2Jlv0f6ZG59HQNGk+Bgq3/vHvM=']
|
281
|
+
@hmac_headers.each_pair do |key,value|
|
282
|
+
header key, value
|
283
|
+
end
|
284
|
+
post @path, @content
|
285
|
+
last_response.status.should == 401
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
240
289
|
context "hitting actions without API" do
|
241
290
|
|
242
291
|
it "should not try to authenticate a request that doesn't start with /api" do
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 1.3.
|
8
|
+
- 1
|
9
|
+
version: 1.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Chris Gill
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2010-08-
|
20
|
+
date: 2010-08-11 00:00:00 -04:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|