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 ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile CHANGED
@@ -8,4 +8,6 @@ gem 'json'
8
8
 
9
9
  group :test, :development do
10
10
  gem 'halorgium-auth-hmac'
11
+ gem 'rack-client'
12
+ gem 'rack-contrib'
11
13
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ey_api_hmac (0.0.1)
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
@@ -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
- #a Server middleware to validate requests, setup with a block to lookup the auth_key based on auth_id
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
- ApiHMAC.authenticate!(env) do |auth_id|
15
- @lookup.call(env, auth_id)
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
- #a Server middleware to validate requests, setup with a class that responds_to :find_by_auth_id, :id, :auth_key
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 "no #{klass} consumer #{auth_id.inspect}"
47
+ raise HmacAuthFail
30
48
  end
31
49
  end
50
+
32
51
  super(app, &lookup)
33
52
  end
34
53
  end
35
54
 
36
- #the Client middleware that's used to add authentication to requests
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
@@ -1,5 +1,5 @@
1
1
  module EY
2
2
  module ApiHMAC
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
  end
5
5
  end
@@ -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
- AuthHMAC.sign!(@request, "my-key-id", "secret")
44
- @request['Authorization'].should == @expected
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
@@ -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
@@ -69,5 +69,4 @@ describe EY::ApiHMAC do
69
69
  # signature – HMAC digest of the other parameters and url (using the API secret)
70
70
 
71
71
  end
72
-
73
- end
72
+ end
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: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
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-17 00:00:00 Z
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.8.8
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