ey_api_hmac 0.0.4 → 0.0.5
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/.gitignore +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +5 -1
- data/lib/ey_api_hmac/api_auth.rb +28 -9
- data/lib/ey_api_hmac/version.rb +1 -1
- data/spec/api_auth_spec.rb +73 -7
- data/spec/spec_helper.rb +20 -0
- data/spec/sso_spec.rb +1 -2
- metadata +10 -5
data/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*.gem
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
ey_api_hmac (0.0.
|
|
4
|
+
ey_api_hmac (0.0.5)
|
|
5
5
|
json
|
|
6
6
|
rack-client
|
|
7
7
|
|
|
@@ -14,6 +14,8 @@ GEM
|
|
|
14
14
|
rack (1.3.2)
|
|
15
15
|
rack-client (0.4.0)
|
|
16
16
|
rack (>= 1.0.0)
|
|
17
|
+
rack-contrib (1.1.0)
|
|
18
|
+
rack (>= 0.9.1)
|
|
17
19
|
rake (0.9.2)
|
|
18
20
|
rspec (2.6.0)
|
|
19
21
|
rspec-core (~> 2.6.0)
|
|
@@ -31,5 +33,7 @@ DEPENDENCIES
|
|
|
31
33
|
ey_api_hmac!
|
|
32
34
|
halorgium-auth-hmac
|
|
33
35
|
json
|
|
36
|
+
rack-client
|
|
37
|
+
rack-contrib
|
|
34
38
|
rake
|
|
35
39
|
rspec
|
data/lib/ey_api_hmac/api_auth.rb
CHANGED
|
@@ -1,39 +1,58 @@
|
|
|
1
1
|
module EY
|
|
2
2
|
module ApiHMAC
|
|
3
3
|
module ApiAuth
|
|
4
|
-
CONSUMER = "ey_api_hmac.consumer_id"
|
|
5
4
|
|
|
6
|
-
#
|
|
5
|
+
# Server middleware to validate requests, setup with a block that returns the auth_key given an auth_id
|
|
6
|
+
#
|
|
7
|
+
# To pass authentication information through to your app, be sure to set something in env.
|
|
8
|
+
# Look at EY::ApiHMAC::ApiAuth::Server for an example
|
|
9
|
+
#
|
|
10
|
+
# raise EY::ApiHMAC::HmacAuthFail, "your message" to fail authentication.
|
|
7
11
|
class LookupServer
|
|
8
12
|
def initialize(app, &lookup)
|
|
9
13
|
@app, @lookup = app, lookup
|
|
10
14
|
end
|
|
11
15
|
|
|
12
|
-
#TODO: rescue HmacAuthFail and return 403?
|
|
13
16
|
def call(env)
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
begin
|
|
18
|
+
ApiHMAC.authenticate!(env) do |auth_id|
|
|
19
|
+
@lookup.call(env, auth_id)
|
|
20
|
+
end
|
|
21
|
+
rescue HmacAuthFail
|
|
22
|
+
return [401, {}, ["Authentication failure"]]
|
|
16
23
|
end
|
|
17
24
|
@app.call(env)
|
|
18
25
|
end
|
|
19
26
|
end
|
|
20
27
|
|
|
21
|
-
#
|
|
28
|
+
# Consumer id is set to this env key when using EY::ApiHMAC::ApiAuth::Server
|
|
29
|
+
CONSUMER = "ey_api_hmac.consumer_id"
|
|
30
|
+
|
|
31
|
+
# Server middleware to validate requests
|
|
32
|
+
#
|
|
33
|
+
# Initialize with a class that responds_to :find_by_auth_id, :id, :auth_key
|
|
34
|
+
#
|
|
35
|
+
# Sets env['ey_api_hmac.consumer_id'] to the id of the object returned by class.find_by_auth_id(auth_id)
|
|
22
36
|
class Server < LookupServer
|
|
23
37
|
def initialize(app, klass)
|
|
38
|
+
unless klass.respond_to?(:find_by_auth_id)
|
|
39
|
+
raise ArgumentError, "EY::ApiHMAC::ApiAuth::Server class must respond to find_by_auth_id"
|
|
40
|
+
end
|
|
41
|
+
|
|
24
42
|
lookup = Proc.new do |env, auth_id|
|
|
25
43
|
if consumer = klass.find_by_auth_id(auth_id)
|
|
26
44
|
env[CONSUMER] = consumer.id
|
|
27
45
|
consumer.auth_key
|
|
28
46
|
else
|
|
29
|
-
raise
|
|
47
|
+
raise HmacAuthFail
|
|
30
48
|
end
|
|
31
49
|
end
|
|
50
|
+
|
|
32
51
|
super(app, &lookup)
|
|
33
52
|
end
|
|
34
53
|
end
|
|
35
54
|
|
|
36
|
-
#
|
|
55
|
+
# Client middleware that's used to add authentication to requests.
|
|
37
56
|
class Client
|
|
38
57
|
def initialize(app, auth_id, auth_key)
|
|
39
58
|
@app, @auth_id, @auth_key = app, auth_id, auth_key
|
|
@@ -46,4 +65,4 @@ module EY
|
|
|
46
65
|
|
|
47
66
|
end
|
|
48
67
|
end
|
|
49
|
-
end
|
|
68
|
+
end
|
data/lib/ey_api_hmac/version.rb
CHANGED
data/spec/api_auth_spec.rb
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
1
3
|
require 'ey_api_hmac'
|
|
2
4
|
require 'auth-hmac'
|
|
5
|
+
require 'rack/contrib'
|
|
6
|
+
require 'time'
|
|
3
7
|
|
|
4
8
|
describe EY::ApiHMAC::ApiAuth do
|
|
5
9
|
|
|
@@ -10,8 +14,8 @@ describe EY::ApiHMAC::ApiAuth do
|
|
|
10
14
|
before(:each) do
|
|
11
15
|
@env = {'PATH_INFO' => "/path/to/put",
|
|
12
16
|
'QUERY_STRING' => 'foo=bar&bar=foo',
|
|
13
|
-
'CONTENT_TYPE' => 'text/plain',
|
|
14
|
-
'HTTP_CONTENT_MD5' => 'blahblah',
|
|
17
|
+
'CONTENT_TYPE' => 'text/plain',
|
|
18
|
+
'HTTP_CONTENT_MD5' => 'blahblah',
|
|
15
19
|
'REQUEST_METHOD' => "PUT",
|
|
16
20
|
'HTTP_DATE' => "Thu, 10 Jul 2008 03:29:56 GMT",
|
|
17
21
|
"rack.input" => StringIO.new}
|
|
@@ -40,8 +44,8 @@ describe EY::ApiHMAC::ApiAuth do
|
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
it "signs as expected with AuthHMAC" do
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
AuthHMAC.sign!(@request, "my-key-id", "secret")
|
|
48
|
+
@request['Authorization'].should == @expected
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
it "signs as expected with ApiAuth" do
|
|
@@ -85,13 +89,76 @@ describe EY::ApiHMAC::ApiAuth do
|
|
|
85
89
|
end
|
|
86
90
|
end
|
|
87
91
|
|
|
92
|
+
describe "middleware behavior" do
|
|
93
|
+
MockApp = lambda do |is_found, auth_key|
|
|
94
|
+
Rack::Builder.new do
|
|
95
|
+
use EY::ApiHMAC::ApiAuth::Server, MockAuth.new(is_found, auth_key)
|
|
96
|
+
run lambda { |x| [200, {}, ['Success']] }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def hmac_client(client_auth_key, app)
|
|
101
|
+
client = Rack::Client.new('http://localhost') do
|
|
102
|
+
use Rack::Config do |env|
|
|
103
|
+
env['HTTP_DATE'] = Time.now.httpdate
|
|
104
|
+
end
|
|
105
|
+
use EY::ApiHMAC::ApiAuth::Client, 1, client_auth_key
|
|
106
|
+
run app
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "responds 401 Unauthorized with no authorization" do
|
|
111
|
+
client = Rack::Client.new('http://localhost') do
|
|
112
|
+
run MockApp.call(true, 'key')
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
response = client.get('/')
|
|
116
|
+
response.status.should == 401
|
|
117
|
+
response.body.should_not == 'Success'
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it "works with correct signing" do
|
|
121
|
+
auth_key = 'key'
|
|
122
|
+
is_found = true
|
|
123
|
+
|
|
124
|
+
client = hmac_client(auth_key, MockApp.call(is_found, auth_key))
|
|
125
|
+
|
|
126
|
+
response = client.get('/')
|
|
127
|
+
response.status.should == 200
|
|
128
|
+
response.body.should == 'Success'
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
it "fails when auth_key isn't correct" do
|
|
132
|
+
auth_id = 1
|
|
133
|
+
is_found = true
|
|
134
|
+
|
|
135
|
+
client = hmac_client('wrongkey', MockApp.call(is_found, 'rightkey'))
|
|
136
|
+
|
|
137
|
+
response = client.get('/')
|
|
138
|
+
response.status.should == 401
|
|
139
|
+
response.body.should_not == 'Success'
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "fails when no consumer by that auth_id is found" do
|
|
143
|
+
auth_id = 1
|
|
144
|
+
is_found = false
|
|
145
|
+
auth_key = 'key'
|
|
146
|
+
|
|
147
|
+
client = hmac_client(auth_key, MockApp.call(is_found, auth_key))
|
|
148
|
+
|
|
149
|
+
response = client.get('/')
|
|
150
|
+
response.status.should == 401
|
|
151
|
+
response.body.should_not == 'Success'
|
|
152
|
+
end
|
|
153
|
+
end
|
|
88
154
|
end
|
|
89
155
|
|
|
156
|
+
|
|
90
157
|
describe "without CONTENT_MD5" do
|
|
91
158
|
before do
|
|
92
159
|
@env = {'PATH_INFO' => "/path/to/put",
|
|
93
160
|
'QUERY_STRING' => 'foo=bar&bar=foo',
|
|
94
|
-
'CONTENT_TYPE' => 'text/plain',
|
|
161
|
+
'CONTENT_TYPE' => 'text/plain',
|
|
95
162
|
'REQUEST_METHOD' => "PUT",
|
|
96
163
|
'HTTP_DATE' => "Thu, 10 Jul 2008 03:29:56 GMT",
|
|
97
164
|
"rack.input" => StringIO.new("something, something?")}
|
|
@@ -114,7 +181,6 @@ describe EY::ApiHMAC::ApiAuth do
|
|
|
114
181
|
end
|
|
115
182
|
|
|
116
183
|
end
|
|
117
|
-
|
|
118
184
|
end
|
|
119
185
|
|
|
120
186
|
it "complains when there is no HTTP_DATE" do
|
|
@@ -128,4 +194,4 @@ describe EY::ApiHMAC::ApiAuth do
|
|
|
128
194
|
}.should raise_error(/'HTTP_DATE' header missing and required/)
|
|
129
195
|
end
|
|
130
196
|
|
|
131
|
-
end
|
|
197
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class MockAuth
|
|
2
|
+
def initialize(is_found, auth_key)
|
|
3
|
+
@is_found = is_found
|
|
4
|
+
@auth_key = auth_key
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
attr_reader :auth_key
|
|
8
|
+
|
|
9
|
+
def find_by_auth_id(auth_id)
|
|
10
|
+
if @is_found
|
|
11
|
+
self
|
|
12
|
+
else
|
|
13
|
+
nil
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def id
|
|
18
|
+
1
|
|
19
|
+
end
|
|
20
|
+
end
|
data/spec/sso_spec.rb
CHANGED
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: 21
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 0
|
|
9
|
-
-
|
|
10
|
-
version: 0.0.
|
|
9
|
+
- 5
|
|
10
|
+
version: 0.0.5
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- "Jacob Burkhart & Thorben Schr\xC3\xB6der & David Calavera & others"
|
|
@@ -15,7 +15,8 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2011-08-
|
|
18
|
+
date: 2011-08-18 00:00:00 -07:00
|
|
19
|
+
default_executable:
|
|
19
20
|
dependencies:
|
|
20
21
|
- !ruby/object:Gem::Dependency
|
|
21
22
|
name: rack-client
|
|
@@ -69,6 +70,7 @@ extensions: []
|
|
|
69
70
|
extra_rdoc_files: []
|
|
70
71
|
|
|
71
72
|
files:
|
|
73
|
+
- .gitignore
|
|
72
74
|
- Gemfile
|
|
73
75
|
- Gemfile.lock
|
|
74
76
|
- LICENSE
|
|
@@ -81,7 +83,9 @@ files:
|
|
|
81
83
|
- lib/ey_api_hmac/sso.rb
|
|
82
84
|
- lib/ey_api_hmac/version.rb
|
|
83
85
|
- spec/api_auth_spec.rb
|
|
86
|
+
- spec/spec_helper.rb
|
|
84
87
|
- spec/sso_spec.rb
|
|
88
|
+
has_rdoc: true
|
|
85
89
|
homepage: ""
|
|
86
90
|
licenses: []
|
|
87
91
|
|
|
@@ -111,10 +115,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
111
115
|
requirements: []
|
|
112
116
|
|
|
113
117
|
rubyforge_project: ey_api_hmac
|
|
114
|
-
rubygems_version: 1.
|
|
118
|
+
rubygems_version: 1.4.2
|
|
115
119
|
signing_key:
|
|
116
120
|
specification_version: 3
|
|
117
121
|
summary: HMAC Rack basic implementation for Engine Yard services
|
|
118
122
|
test_files:
|
|
119
123
|
- spec/api_auth_spec.rb
|
|
124
|
+
- spec/spec_helper.rb
|
|
120
125
|
- spec/sso_spec.rb
|