ey_api_hmac 0.0.13 → 0.0.14
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/lib/ey_api_hmac.rb +13 -17
- data/lib/ey_api_hmac/api_auth.rb +3 -3
- data/lib/ey_api_hmac/base_connection.rb +3 -1
- data/lib/ey_api_hmac/sso.rb +2 -2
- data/lib/ey_api_hmac/version.rb +1 -1
- data/spec/api_auth_spec.rb +16 -11
- metadata +4 -4
data/Gemfile.lock
CHANGED
data/lib/ey_api_hmac.rb
CHANGED
@@ -6,27 +6,23 @@ module EY
|
|
6
6
|
module ApiHMAC
|
7
7
|
require 'openssl'
|
8
8
|
|
9
|
-
def self.sign!(env, key_id, secret
|
10
|
-
env["HTTP_AUTHORIZATION"] = auth_string(key_id, signature(env, secret
|
9
|
+
def self.sign!(env, key_id, secret)
|
10
|
+
env["HTTP_AUTHORIZATION"] = auth_string(key_id, signature(env, secret))
|
11
11
|
end
|
12
12
|
|
13
|
-
def self.canonical_string(env
|
13
|
+
def self.canonical_string(env)
|
14
14
|
parts = []
|
15
|
-
|
15
|
+
expect = Proc.new do |var|
|
16
16
|
unless env[var]
|
17
17
|
raise HmacAuthFail, "'#{var}' header missing and required in #{env.inspect}"
|
18
18
|
end
|
19
|
-
|
19
|
+
env[var]
|
20
20
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
parts << generated_md5(env)
|
27
|
-
end
|
28
|
-
adder["HTTP_DATE"]
|
29
|
-
adder["PATH_INFO"]
|
21
|
+
parts << expect["REQUEST_METHOD"]
|
22
|
+
parts << expect["CONTENT_TYPE"]
|
23
|
+
parts << generated_md5(env)
|
24
|
+
parts << expect["HTTP_DATE"]
|
25
|
+
parts << URI.parse(expect["REQUEST_URI"]).path
|
30
26
|
parts.join("\n")
|
31
27
|
end
|
32
28
|
|
@@ -34,8 +30,8 @@ module EY
|
|
34
30
|
"AuthHMAC #{key_id}:#{signature}"
|
35
31
|
end
|
36
32
|
|
37
|
-
def self.signature(env, secret
|
38
|
-
base64digest(canonical_string(env
|
33
|
+
def self.signature(env, secret)
|
34
|
+
base64digest(canonical_string(env), secret)
|
39
35
|
end
|
40
36
|
|
41
37
|
def self.base64digest(data,secret)
|
@@ -55,7 +51,7 @@ module EY
|
|
55
51
|
raise HmacAuthFail, "couldn't find auth for #{access_key_id}"
|
56
52
|
end
|
57
53
|
unless hmac == signature(env, secret)
|
58
|
-
raise HmacAuthFail, "signature mismatch"
|
54
|
+
raise HmacAuthFail, "signature mismatch. Calculated canonical_string: #{canonical_string(env).inspect}"
|
59
55
|
end
|
60
56
|
else
|
61
57
|
raise HmacAuthFail, "no authorization header"
|
data/lib/ey_api_hmac/api_auth.rb
CHANGED
@@ -18,8 +18,8 @@ module EY
|
|
18
18
|
ApiHMAC.authenticate!(env) do |auth_id|
|
19
19
|
@lookup.call(env, auth_id)
|
20
20
|
end
|
21
|
-
rescue HmacAuthFail
|
22
|
-
return [401, {}, ["Authentication failure"]]
|
21
|
+
rescue HmacAuthFail => e
|
22
|
+
return [401, {}, ["Authentication failure: #{e.message}"]]
|
23
23
|
end
|
24
24
|
@app.call(env)
|
25
25
|
end
|
@@ -64,7 +64,7 @@ module EY
|
|
64
64
|
ApiHMAC.sign!(env, @auth_id, @auth_key)
|
65
65
|
tuple = @app.call(env)
|
66
66
|
if tuple.first.to_i == 401
|
67
|
-
raise AuthFailure, "HMAC Authentication Failed."
|
67
|
+
raise AuthFailure, "HMAC Authentication Failed: #{tuple.last}"
|
68
68
|
end
|
69
69
|
tuple
|
70
70
|
end
|
@@ -89,7 +89,9 @@ module EY
|
|
89
89
|
response = nil
|
90
90
|
request_headers = @standard_headers
|
91
91
|
if body
|
92
|
-
|
92
|
+
body_json = body.to_json
|
93
|
+
request_headers["CONTENT_LENGTH"] = body_json.size.to_s
|
94
|
+
response = client.send(method, url, request_headers, body_json)
|
93
95
|
else
|
94
96
|
response = client.send(method, url, request_headers)
|
95
97
|
end
|
data/lib/ey_api_hmac/sso.rb
CHANGED
@@ -6,7 +6,7 @@ module EY
|
|
6
6
|
uri = URI.parse(url)
|
7
7
|
if uri.query
|
8
8
|
extra_params = CGI.parse(uri.query)
|
9
|
-
verify_params!(extra_params, parameters)
|
9
|
+
verify_params!(url, extra_params, parameters)
|
10
10
|
parameters.merge!(extra_params)
|
11
11
|
end
|
12
12
|
uri.query = parameters.sort_by(&:to_s).map {|e| e.map{|str| CGI.escape(str.to_s)}.join '='}.join '&'
|
@@ -28,7 +28,7 @@ module EY
|
|
28
28
|
|
29
29
|
private
|
30
30
|
|
31
|
-
def self.verify_params!(extra_params, parameters)
|
31
|
+
def self.verify_params!(url, extra_params, parameters)
|
32
32
|
illegal_query_params = parameters.keys.map(&:to_s) + ["signature"]
|
33
33
|
extra_params.keys.each do |k|
|
34
34
|
raise ArgumentError, "Got illegal paramter: '#{k}' in '#{url}'" if illegal_query_params.include?(k.to_s)
|
data/lib/ey_api_hmac/version.rb
CHANGED
data/spec/api_auth_spec.rb
CHANGED
@@ -12,15 +12,17 @@ describe EY::ApiHMAC::ApiAuth do
|
|
12
12
|
describe "AuthHMAC working" do
|
13
13
|
|
14
14
|
it "works for documented/realistic example" do
|
15
|
-
|
15
|
+
req_body = %q{{"message":{"message_type":"status","subject":"Everything looks good.","body":null}}}
|
16
|
+
env = {'REQUEST_URI' => "http://example.com/api/1/service_accounts/1324/messages",
|
17
|
+
'PATH_INFO' => "/api/1/service_accounts/1324/messages",
|
16
18
|
'CONTENT_TYPE' => 'application/json',
|
17
19
|
'HTTP_ACCEPT' => 'application/json',
|
18
20
|
'REQUEST_METHOD' => "POST",
|
19
21
|
'HTTP_DATE' => Time.now.httpdate,
|
20
|
-
"rack.input" => StringIO.new(
|
21
|
-
%q{{"message":{"message_type":"status","subject":"Everything looks good.","body":null}}})}
|
22
|
+
"rack.input" => StringIO.new(req_body)}
|
22
23
|
|
23
24
|
puts "before signed: \n#{env.inspect}\n\n"
|
25
|
+
puts "request body: \n#{req_body}\n\n"
|
24
26
|
|
25
27
|
auth_id = "123bc211233eabc"
|
26
28
|
auth_key = "abc474e3fc9bddf6d41236b70cc5a952f3681166e1239214740d13eecd12318f7b8d27123b61eabc"
|
@@ -43,10 +45,11 @@ describe EY::ApiHMAC::ApiAuth do
|
|
43
45
|
end
|
44
46
|
|
45
47
|
before(:each) do
|
46
|
-
@env = {'
|
48
|
+
@env = {'REQUEST_URI' => "http://example.com/path/to/put",
|
49
|
+
'PATH_INFO' => "/path/to/put",
|
47
50
|
'QUERY_STRING' => 'foo=bar&bar=foo',
|
48
51
|
'CONTENT_TYPE' => 'text/plain',
|
49
|
-
'HTTP_CONTENT_MD5' => '
|
52
|
+
'HTTP_CONTENT_MD5' => 'd41d8cd98f00b204e9800998ecf8427e',
|
50
53
|
'REQUEST_METHOD' => "PUT",
|
51
54
|
'HTTP_DATE' => "Thu, 10 Jul 2008 03:29:56 GMT",
|
52
55
|
"rack.input" => StringIO.new}
|
@@ -55,7 +58,7 @@ describe EY::ApiHMAC::ApiAuth do
|
|
55
58
|
|
56
59
|
describe ".canonical_string" do
|
57
60
|
it "should generate a canonical string using default method" do
|
58
|
-
expected = "PUT\ntext/plain\
|
61
|
+
expected = "PUT\ntext/plain\nd41d8cd98f00b204e9800998ecf8427e\nThu, 10 Jul 2008 03:29:56 GMT\n/path/to/put"
|
59
62
|
AuthHMAC.canonical_string(@request).should == expected
|
60
63
|
EY::ApiHMAC.canonical_string(@env).should == expected
|
61
64
|
end
|
@@ -63,7 +66,7 @@ describe EY::ApiHMAC::ApiAuth do
|
|
63
66
|
|
64
67
|
describe ".signature" do
|
65
68
|
it "should generate a valid signature string for a secret" do
|
66
|
-
expected = "
|
69
|
+
expected = "isJ7zHHPrpnSdZ/XbvqxFhVUf0c="
|
67
70
|
AuthHMAC.signature(@request, 'secret').should == expected
|
68
71
|
EY::ApiHMAC.signature(@env, 'secret').should == expected
|
69
72
|
end
|
@@ -71,7 +74,7 @@ describe EY::ApiHMAC::ApiAuth do
|
|
71
74
|
|
72
75
|
describe "sign!" do
|
73
76
|
before do
|
74
|
-
@expected = "AuthHMAC my-key-id:
|
77
|
+
@expected = "AuthHMAC my-key-id:isJ7zHHPrpnSdZ/XbvqxFhVUf0c="
|
75
78
|
end
|
76
79
|
|
77
80
|
it "signs as expected with AuthHMAC" do
|
@@ -184,7 +187,8 @@ describe EY::ApiHMAC::ApiAuth do
|
|
184
187
|
|
185
188
|
describe "without CONTENT_MD5" do
|
186
189
|
before do
|
187
|
-
@env = {'
|
190
|
+
@env = {'REQUEST_URI' => "http://example.com/path/to/put",
|
191
|
+
'PATH_INFO' => "/path/to/put",
|
188
192
|
'QUERY_STRING' => 'foo=bar&bar=foo',
|
189
193
|
'CONTENT_TYPE' => 'text/plain',
|
190
194
|
'REQUEST_METHOD' => "PUT",
|
@@ -212,13 +216,14 @@ describe EY::ApiHMAC::ApiAuth do
|
|
212
216
|
end
|
213
217
|
|
214
218
|
it "complains when there is no HTTP_DATE" do
|
215
|
-
env = {'
|
219
|
+
env = {'REQUEST_URI' => "http://example.com/path/to/put",
|
220
|
+
'PATH_INFO' => "/path/to/put",
|
216
221
|
'QUERY_STRING' => 'foo=bar&bar=foo',
|
217
222
|
'CONTENT_TYPE' => 'text/plain',
|
218
223
|
'REQUEST_METHOD' => "PUT",
|
219
224
|
"rack.input" => StringIO.new}
|
220
225
|
lambda{
|
221
|
-
EY::ApiHMAC.sign!(env, 'my-key-id', 'secret'
|
226
|
+
EY::ApiHMAC.sign!(env, 'my-key-id', 'secret')
|
222
227
|
}.should raise_error(/'HTTP_DATE' header missing and required/)
|
223
228
|
end
|
224
229
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ey_api_hmac
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 14
|
10
|
+
version: 0.0.14
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Jacob Burkhart & Thorben Schr\xC3\xB6der & David Calavera & others"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-10-05 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rack-client
|