lockbox_middleware 1.3.0 → 1.3.1
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.
- 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
|