ey_api_hmac 0.0.13 → 0.0.14
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/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
|