rack-authenticate 0.2.0 → 0.3.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.
@@ -11,14 +11,15 @@ module Rack
|
|
11
11
|
@ajax = options[:ajax]
|
12
12
|
end
|
13
13
|
|
14
|
-
def request_signature_headers(method, url,
|
14
|
+
def request_signature_headers(method, url, content = nil)
|
15
15
|
{}.tap do |headers|
|
16
16
|
headers[date_header_field] = date = Time.now.httpdate
|
17
17
|
request = [method.to_s.upcase, url, date]
|
18
18
|
|
19
|
-
if
|
19
|
+
if content
|
20
|
+
content_md5 = Digest::MD5.hexdigest(content)
|
20
21
|
headers['Content-MD5'] = content_md5
|
21
|
-
request
|
22
|
+
request << content_md5
|
22
23
|
end
|
23
24
|
|
24
25
|
digest = HMAC::SHA1.hexdigest(secret_key, request.join("\n"))
|
@@ -34,16 +35,6 @@ module Rack
|
|
34
35
|
# Thus, we allow the custom X-Authorization-Date header to be used instead of Date.
|
35
36
|
@ajax ? 'X-Authorization-Date' : 'Date'
|
36
37
|
end
|
37
|
-
|
38
|
-
def content_md5_for(content_type, content)
|
39
|
-
if content_type.nil? && content.nil?
|
40
|
-
# no-op
|
41
|
-
elsif content_type && content
|
42
|
-
Digest::MD5.hexdigest(content)
|
43
|
-
else
|
44
|
-
raise ArgumentError.new("Both content_type and content must be given or neither.")
|
45
|
-
end
|
46
|
-
end
|
47
38
|
end
|
48
39
|
end
|
49
40
|
end
|
@@ -54,7 +54,7 @@ module Rack
|
|
54
54
|
return false unless date
|
55
55
|
|
56
56
|
if has_content?
|
57
|
-
content_md5.to_s != ''
|
57
|
+
content_md5.to_s != ''
|
58
58
|
else
|
59
59
|
true
|
60
60
|
end
|
@@ -85,7 +85,7 @@ module Rack
|
|
85
85
|
|
86
86
|
def canonicalized_request
|
87
87
|
parts = [ request.request_method, request.url, date ]
|
88
|
-
parts
|
88
|
+
parts << content_md5 if has_content?
|
89
89
|
parts.join("\n")
|
90
90
|
end
|
91
91
|
|
@@ -20,18 +20,6 @@ module Rack
|
|
20
20
|
subject { Client.new(access_id, secret_key, options) }
|
21
21
|
|
22
22
|
describe "#request_signature_headers" do
|
23
|
-
it 'raises an Argument error if given a content type but not content' do
|
24
|
-
expect {
|
25
|
-
subject.request_signature_headers("get", "http://foo.com/", "text/plain", nil)
|
26
|
-
}.to raise_error(ArgumentError)
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'raises an Argument error if given a content but no content type' do
|
30
|
-
expect {
|
31
|
-
subject.request_signature_headers("get", "http://foo.com/", nil, "content")
|
32
|
-
}.to raise_error(ArgumentError)
|
33
|
-
end
|
34
|
-
|
35
23
|
it 'returns the auth header using the HMAC digest' do
|
36
24
|
HMAC::SHA1.stub(:hexdigest => 'the-hex-digest')
|
37
25
|
headers = subject.request_signature_headers("get", "http://foo.com/")
|
@@ -108,23 +96,23 @@ module Rack
|
|
108
96
|
end
|
109
97
|
|
110
98
|
it 'returns the Content-MD5 header in the headers hash' do
|
111
|
-
headers = subject.request_signature_headers("get", "http://foo.com/bar?q=buzz", "
|
99
|
+
headers = subject.request_signature_headers("get", "http://foo.com/bar?q=buzz", "content")
|
112
100
|
headers.should include('Content-MD5' => content_md5)
|
113
101
|
end
|
114
102
|
|
115
103
|
it 'generates the Content-MD5 based on the content' do
|
116
104
|
Digest::MD5.should_receive(:hexdigest).with("content")
|
117
|
-
subject.request_signature_headers("get", "http://foo.com/bar?q=buzz", "
|
105
|
+
subject.request_signature_headers("get", "http://foo.com/bar?q=buzz", "content")
|
118
106
|
end
|
119
107
|
|
120
|
-
it 'uses the content
|
108
|
+
it 'uses the content md5 in the digest' do
|
121
109
|
HMAC::SHA1.should_receive(:hexdigest) do |key, request|
|
122
110
|
parts = request.split("\n")
|
123
|
-
parts.should have(
|
124
|
-
parts.last
|
111
|
+
parts.should have(4).parts
|
112
|
+
parts.last.should eq('the-content-md5')
|
125
113
|
end
|
126
114
|
|
127
|
-
subject.request_signature_headers("get", "http://foo.com/bar?q=buzz", "
|
115
|
+
subject.request_signature_headers("get", "http://foo.com/bar?q=buzz", "content")
|
128
116
|
end
|
129
117
|
end
|
130
118
|
end
|
@@ -85,16 +85,14 @@ module Rack
|
|
85
85
|
Auth.new(basic_env).canonicalized_request
|
86
86
|
end
|
87
87
|
|
88
|
-
it 'includes the content MD5
|
88
|
+
it 'includes the content MD5 when it is present' do
|
89
89
|
basic_env['CONTENT_LENGTH'] = '10'
|
90
90
|
basic_env['HTTP_CONTENT_MD5'] = content_md5
|
91
|
-
basic_env['CONTENT_TYPE'] = 'text/plain'
|
92
91
|
|
93
92
|
Auth.new(basic_env).canonicalized_request.split("\n").should eq([
|
94
93
|
'GET',
|
95
94
|
'http://example.org/foo/bar',
|
96
95
|
http_date,
|
97
|
-
'text/plain',
|
98
96
|
content_md5
|
99
97
|
])
|
100
98
|
end
|
@@ -155,19 +153,12 @@ module Rack
|
|
155
153
|
context 'for a request with a body' do
|
156
154
|
let(:env) { basic_env.merge('CONTENT_LENGTH' => '10') }
|
157
155
|
|
158
|
-
it 'returns true if it has a content
|
156
|
+
it 'returns true if it has a content MD5' do
|
159
157
|
basic_env['HTTP_CONTENT_MD5'] = content_md5
|
160
|
-
basic_env['CONTENT_TYPE'] = 'text/plain'
|
161
158
|
should have_all_required_parts
|
162
159
|
end
|
163
160
|
|
164
161
|
it 'returns false if it lacks the content md5 header' do
|
165
|
-
basic_env['CONTENT_TYPE'] = 'text/plain'
|
166
|
-
should_not have_all_required_parts
|
167
|
-
end
|
168
|
-
|
169
|
-
it 'returns false if it lacks the content type header' do
|
170
|
-
basic_env['HTTP_CONTENT_MD5'] = content_md5
|
171
162
|
should_not have_all_required_parts
|
172
163
|
end
|
173
164
|
end
|
@@ -349,7 +340,7 @@ module Rack
|
|
349
340
|
|
350
341
|
it 'generates the same signature as the client', :no_timecop do
|
351
342
|
client = Client.new('abc', hmac_auth_creds['abc'])
|
352
|
-
client.request_signature_headers('post', 'http://example.org/foo',
|
343
|
+
client.request_signature_headers('post', 'http://example.org/foo', "some content").each do |key, value|
|
353
344
|
header key, value
|
354
345
|
end
|
355
346
|
|
@@ -360,7 +351,7 @@ module Rack
|
|
360
351
|
|
361
352
|
it 'generates the same signature as an AJAX client', :no_timecop do
|
362
353
|
client = Client.new('abc', hmac_auth_creds['abc'], :ajax => true)
|
363
|
-
client.request_signature_headers('post', 'http://example.org/foo',
|
354
|
+
client.request_signature_headers('post', 'http://example.org/foo', "some content").each do |key, value|
|
364
355
|
header key, value
|
365
356
|
end
|
366
357
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-authenticate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-19 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ruby-hmac
|
16
|
-
requirement: &
|
16
|
+
requirement: &2156269640 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.4.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2156269640
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &2156267980 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 2.8.0.rc1
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2156267980
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rack-test
|
38
|
-
requirement: &
|
38
|
+
requirement: &2156267060 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.6.1
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2156267060
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: timecop
|
49
|
-
requirement: &
|
49
|
+
requirement: &2156266080 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 0.3.5
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *2156266080
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rake
|
60
|
-
requirement: &
|
60
|
+
requirement: &2156265000 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,7 +65,7 @@ dependencies:
|
|
65
65
|
version: 0.9.2.2
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *2156265000
|
69
69
|
description: A rack middleware that authenticates requests either using basic auth
|
70
70
|
or via signed HMAC.
|
71
71
|
email:
|
@@ -108,12 +108,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
108
|
- - ! '>='
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
+
segments:
|
112
|
+
- 0
|
113
|
+
hash: 496392540953768214
|
111
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
115
|
none: false
|
113
116
|
requirements:
|
114
117
|
- - ! '>='
|
115
118
|
- !ruby/object:Gem::Version
|
116
119
|
version: '0'
|
120
|
+
segments:
|
121
|
+
- 0
|
122
|
+
hash: 496392540953768214
|
117
123
|
requirements: []
|
118
124
|
rubyforge_project: rack-authenticate
|
119
125
|
rubygems_version: 1.8.6
|