oauth2-provider 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,24 +2,7 @@ module OAuth2::Provider::Rack
2
2
  class AuthorizationCodeRequest
3
3
  def initialize(params)
4
4
  @params = params
5
- end
6
-
7
- def validate!
8
- unless client_id
9
- raise OAuth2::Provider::Rack::InvalidRequest, 'No client_id provided'
10
- end
11
-
12
- unless client
13
- raise OAuth2::Provider::Rack::InvalidRequest, 'client_id is invalid'
14
- end
15
-
16
- unless redirect_uri
17
- raise OAuth2::Provider::Rack::InvalidRequest, 'No redirect_uri provided'
18
- end
19
-
20
- unless redirect_uri_valid?
21
- raise OAuth2::Provider::Rack::InvalidRequest, 'Provided redirect_uri is invalid'
22
- end
5
+ validate!
23
6
  end
24
7
 
25
8
  def grant!(resource_owner = nil, authorization_expires_at = nil)
@@ -33,6 +16,13 @@ module OAuth2::Provider::Rack
33
16
  throw_response Responses.redirect_with_code(code.code, redirect_uri)
34
17
  end
35
18
 
19
+ def grant_existing!(resource_owner = nil)
20
+ if existing = OAuth2::Provider.authorization_class.allowing(client, resource_owner, scope).first
21
+ code = existing.authorization_codes.create! :redirect_uri => redirect_uri
22
+ throw_response Responses.redirect_with_code(code.code, redirect_uri)
23
+ end
24
+ end
25
+
36
26
  def deny!
37
27
  throw_response Responses.redirect_with_error('access_denied', redirect_uri)
38
28
  end
@@ -63,6 +53,24 @@ module OAuth2::Provider::Rack
63
53
 
64
54
  private
65
55
 
56
+ def validate!
57
+ unless client_id
58
+ raise OAuth2::Provider::Rack::InvalidRequest, 'No client_id provided'
59
+ end
60
+
61
+ unless client
62
+ raise OAuth2::Provider::Rack::InvalidRequest, 'client_id is invalid'
63
+ end
64
+
65
+ unless redirect_uri
66
+ raise OAuth2::Provider::Rack::InvalidRequest, 'No redirect_uri provided'
67
+ end
68
+
69
+ unless redirect_uri_valid?
70
+ raise OAuth2::Provider::Rack::InvalidRequest, 'Provided redirect_uri is invalid'
71
+ end
72
+ end
73
+
66
74
  def throw_response(response)
67
75
  throw :oauth2, response
68
76
  end
@@ -6,7 +6,11 @@ module OAuth2::Provider::Rack::AuthorizationCodesSupport
6
6
  end
7
7
 
8
8
  def block_invalid_authorization_code_requests
9
- oauth2_authorization_request.validate!
9
+ oauth2_authorization_request
10
+ end
11
+
12
+ def regrant_existing_authorizations
13
+ oauth2_authorization_request.grant_existing!
10
14
  end
11
15
 
12
16
  def grant_authorization_code(resource_owner = nil, authorization_expires_at = nil)
@@ -7,11 +7,9 @@ module OAuth2::Provider::Rack
7
7
  def call(env)
8
8
  request = env['oauth2'] = ResourceRequest.new(env)
9
9
 
10
- env['warden'] && env['warden'].custom_failure!
11
-
12
10
  response = catch :oauth2 do
13
11
  if request.path == "/oauth/access_token"
14
- AccessTokenHandler.new(@app, env).process
12
+ handle_access_token_request(env)
15
13
  else
16
14
  @app.call(env)
17
15
  end
@@ -19,5 +17,9 @@ module OAuth2::Provider::Rack
19
17
  rescue InvalidRequest => e
20
18
  [400, {}, e.message]
21
19
  end
20
+
21
+ def handle_access_token_request(env)
22
+ AccessTokenHandler.new(@app, env).process
23
+ end
22
24
  end
23
25
  end
@@ -53,8 +53,9 @@ module OAuth2::Provider::Rack
53
53
  authorization && authorization.resource_owner
54
54
  end
55
55
 
56
- def authentication_required!
57
- throw_response Responses.unauthorized
56
+ def authentication_required!(reason = nil)
57
+ env['warden'] && env['warden'].custom_failure!
58
+ throw_response Responses.unauthorized(reason)
58
59
  end
59
60
 
60
61
  def insufficient_scope!
@@ -78,7 +79,7 @@ module OAuth2::Provider::Rack
78
79
  def block_invalid_token
79
80
  access_token = OAuth2::Provider.access_token_class.find_by_access_token(token)
80
81
  @authorization = access_token.authorization if access_token
81
- throw_response Responses.unauthorized('invalid_token') if access_token.nil? || access_token.expired?
82
+ authentication_required! 'invalid_token' if access_token.nil? || access_token.expired?
82
83
  end
83
84
 
84
85
  private
@@ -1,5 +1,5 @@
1
1
  module OAuth2
2
2
  module Provider
3
- VERSION = "0.0.17"
3
+ VERSION = "0.0.18"
4
4
  end
5
5
  end
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_development_dependency 'rack-test', '~>0.5.7'
25
25
  s.add_development_dependency 'activerecord', '~>3.0.1'
26
26
  s.add_development_dependency 'rspec', '~>2.1.0'
27
+ s.add_development_dependency 'mocha', '~>0.9.12'
27
28
  s.add_development_dependency 'rake', '~>0.8.7'
28
29
  s.add_development_dependency 'sqlite3-ruby', '~>1.3.1'
29
30
  s.add_development_dependency 'timecop', '~>0.3.4'
@@ -106,13 +106,13 @@ describe "A request for a protected resource" do
106
106
  describe "when warden is part of the stack" do
107
107
  it "bypasses warden when no token is passed" do
108
108
  warden = "warden"
109
- warden.should_receive(:custom_failure!)
109
+ warden.expects(:custom_failure!)
110
110
  get "/protected", {}, {'warden' => warden}
111
111
  end
112
112
 
113
113
  it "bypasses warden when token invalid" do
114
114
  warden = "warden"
115
- warden.should_receive(:custom_failure!)
115
+ warden.expects(:custom_failure!)
116
116
  get "/protected", {:oauth_token => 'invalid_token'}, {'warden' => warden}
117
117
  end
118
118
  end
@@ -1,5 +1,115 @@
1
1
  require 'spec_helper'
2
2
 
3
+ describe OAuth2::Provider::Rack::AuthorizationCodeRequest do
4
+ describe "#initialize" do
5
+ before :each do
6
+ @client = OAuth2::Provider.client_class.create! :name => 'client'
7
+ @valid_params = {
8
+ 'client_id' => @client.oauth_identifier,
9
+ 'redirect_uri' => "https://redirect.example.com/callback"
10
+ }
11
+ end
12
+
13
+ describe "with a valid client_id and redirect_uri" do
14
+ it "doesn't raise any exception" do
15
+ lambda {
16
+ OAuth2::Provider::Rack::AuthorizationCodeRequest.new(@valid_params)
17
+ }.should_not raise_error
18
+ end
19
+ end
20
+
21
+ describe "without a client_id" do
22
+ it "raises OAuth2::Provider::Rack::InvalidRequest" do
23
+ lambda {
24
+ OAuth2::Provider::Rack::AuthorizationCodeRequest.new(@valid_params.except('client_id'))
25
+ }.should raise_error(OAuth2::Provider::Rack::InvalidRequest)
26
+ end
27
+ end
28
+
29
+ describe "with an unknown client" do
30
+ it "raises OAuth2::Provider::Rack::InvalidRequest" do
31
+ lambda {
32
+ OAuth2::Provider::Rack::AuthorizationCodeRequest.new(@valid_params.merge(
33
+ 'client_id' => 'unknown'
34
+ ))
35
+ }.should raise_error(OAuth2::Provider::Rack::InvalidRequest)
36
+ end
37
+ end
38
+
39
+ describe "without a redirect_uri" do
40
+ it "raises OAuth2::Provider::Rack::InvalidRequest" do
41
+ lambda {
42
+ OAuth2::Provider::Rack::AuthorizationCodeRequest.new(@valid_params.except('redirect_uri'))
43
+ }.should raise_error(OAuth2::Provider::Rack::InvalidRequest)
44
+ end
45
+ end
46
+
47
+ describe "with a redirect_uri the client regards as invalid" do
48
+ before :each do
49
+ OAuth2::Provider.client_class.stubs(:from_param).returns(@client)
50
+ @client.expects(:allow_redirection?).with(@valid_params['redirect_uri']).returns(false)
51
+ end
52
+
53
+ it "raises OAuth2::Provider::Rack::InvalidRequest" do
54
+ lambda {
55
+ OAuth2::Provider::Rack::AuthorizationCodeRequest.new(@valid_params)
56
+ }.should raise_error(OAuth2::Provider::Rack::InvalidRequest)
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#grant_existing!(resource_owner)" do
62
+ before :each do
63
+ @client = OAuth2::Provider.client_class.create! :name => 'client'
64
+ @owner = create_resource_owner
65
+ @scope = 'a-scope'
66
+ @request = OAuth2::Provider::Rack::AuthorizationCodeRequest.new(
67
+ 'client_id' => @client.oauth_identifier,
68
+ 'redirect_uri' => "https://redirect.example.com/callback",
69
+ 'scope' => @scope
70
+ )
71
+ end
72
+
73
+ describe "when matching authorization exists" do
74
+ before :each do
75
+ @authorization = create_authorization(:client => @client, :resource_owner => @owner, :scope => @scope)
76
+ end
77
+
78
+ it "throws an oauth2 response" do
79
+ lambda {
80
+ @request.grant_existing!(@owner)
81
+ }.should throw_symbol(:oauth2)
82
+ end
83
+
84
+ it "creates an authorization code for the matching authorization" do
85
+ catch :oauth2 do
86
+ @request.grant_existing!(@owner)
87
+ end
88
+ code = @authorization.reload.authorization_codes.first
89
+ code.should_not be_nil
90
+ code.redirect_uri.should eql("https://redirect.example.com/callback")
91
+ end
92
+
93
+ it "includes authorization code in the response" do
94
+ response = catch :oauth2 do
95
+ @request.grant_existing!(@owner)
96
+ end
97
+ code = @authorization.reload.authorization_codes.first
98
+ uri = response[1]["Location"]
99
+ Addressable::URI.parse(uri).query_values['code'].should == code.code
100
+ end
101
+ end
102
+
103
+ describe "when no matching authorization exists" do
104
+ it "returns normally" do
105
+ lambda {
106
+ @request.grant_existing!(@owner)
107
+ }.should_not throw_symbol(:oauth2)
108
+ end
109
+ end
110
+ end
111
+ end
112
+
3
113
  describe OAuth2::Provider::Rack::AuthorizationCodeRequest do
4
114
  before :each do
5
115
  ExampleResourceOwner.destroy_all
@@ -15,7 +125,6 @@ describe OAuth2::Provider::Rack::AuthorizationCodeRequest do
15
125
  action do |env|
16
126
  request = Rack::Request.new(env)
17
127
  env['oauth2.authorization_request'] ||= OAuth2::Provider::Rack::AuthorizationCodeRequest.new(request.params)
18
- env['oauth2.authorization_request'].validate!
19
128
  successful_response
20
129
  end
21
130
 
@@ -73,7 +182,6 @@ describe OAuth2::Provider::Rack::AuthorizationCodeRequest do
73
182
  action do |env|
74
183
  request = Rack::Request.new(env)
75
184
  env['oauth2.authorization_request'] ||= OAuth2::Provider::Rack::AuthorizationCodeRequest.new(request.params)
76
- env['oauth2.authorization_request'].validate!
77
185
  env['oauth2.authorization_request'].invalid_scope!
78
186
  successful_response
79
187
  end
@@ -89,9 +197,8 @@ describe OAuth2::Provider::Rack::AuthorizationCodeRequest do
89
197
  describe "Intercepting invalid requests" do
90
198
  action do |env|
91
199
  request = Rack::Request.new(env)
92
- env['oauth2.authorization_request'] ||= OAuth2::Provider::Rack::AuthorizationCodeRequest.new(request.params)
93
200
  begin
94
- env['oauth2.authorization_request'].validate!
201
+ env['oauth2.authorization_request'] ||= OAuth2::Provider::Rack::AuthorizationCodeRequest.new(request.params)
95
202
  successful_response
96
203
  rescue OAuth2::Provider::Rack::InvalidRequest => e
97
204
  [418, {'Content-Type' => 'text/plain'}, e.to_s]
@@ -119,7 +226,6 @@ describe OAuth2::Provider::Rack::AuthorizationCodeRequest do
119
226
  action do |env|
120
227
  request = Rack::Request.new(env)
121
228
  env['oauth2.authorization_request'] ||= OAuth2::Provider::Rack::AuthorizationCodeRequest.new(request.params)
122
- env['oauth2.authorization_request'].validate!
123
229
  successful_response
124
230
  end
125
231
 
@@ -206,4 +312,4 @@ describe OAuth2::Provider::Rack::AuthorizationCodeRequest do
206
312
 
207
313
  redirects_back_with_error 'access_denied'
208
314
  end
209
- end
315
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::Provider::Rack::Middleware do
4
+ subject do
5
+ ::OAuth2::Provider::Rack::Middleware.new(main_app)
6
+ end
7
+
8
+ def app
9
+ subject
10
+ end
11
+
12
+ describe "in general" do
13
+ let :main_app do
14
+ Proc.new do
15
+ [200, {'Content-Type' => 'text/plain'}, 'Apptastic']
16
+ end
17
+ end
18
+
19
+ it "passes requests to /oauth/access_token to #handle_access_token_request" do
20
+ subject.expects(:handle_access_token_request).returns(
21
+ [418, {'Content-Type' => 'text/plain'}, 'Short and stout']
22
+ )
23
+ get "/oauth/access_token"
24
+ response.status.should eql(418)
25
+ response.body.should eql('Short and stout')
26
+ end
27
+
28
+ it "passes other requests to the main app" do
29
+ get "/any/other/path"
30
+ response.status.should eql(200)
31
+ response.body.should eql('Apptastic')
32
+ end
33
+ end
34
+
35
+ describe "when main app throws :oauth2 response" do
36
+ let :main_app do
37
+ Proc.new do
38
+ throw :oauth2, [418, {'Content-Type' => 'text/plain'}, 'Teapot']
39
+ end
40
+ end
41
+
42
+ it "uses thrown response" do
43
+ get "/any/path"
44
+ response.status.should eql(418)
45
+ response.body.should eql('Teapot')
46
+ end
47
+ end
48
+ end
@@ -21,6 +21,8 @@ RSpec.configure do |config|
21
21
  Timecop.return
22
22
  end
23
23
 
24
+ config.mock_with :mocha
25
+
24
26
  config.include OAuth2::Provider::RSpec::Macros
25
27
  config.include OAuth2::Provider::RSpec::Factories
26
28
  config.include OAuth2::Provider::RSpec::Rack
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oauth2-provider
3
3
  version: !ruby/object:Gem::Version
4
- hash: 61
4
+ hash: 59
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 17
10
- version: 0.0.17
9
+ - 18
10
+ version: 0.0.18
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tom Ward
@@ -15,8 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-31 00:00:00 +01:00
19
- default_executable:
18
+ date: 2011-06-11 00:00:00 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  type: :runtime
@@ -99,6 +98,22 @@ dependencies:
99
98
  - !ruby/object:Gem::Dependency
100
99
  type: :development
101
100
  requirement: &id006 !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ~>
104
+ - !ruby/object:Gem::Version
105
+ hash: 35
106
+ segments:
107
+ - 0
108
+ - 9
109
+ - 12
110
+ version: 0.9.12
111
+ version_requirements: *id006
112
+ name: mocha
113
+ prerelease: false
114
+ - !ruby/object:Gem::Dependency
115
+ type: :development
116
+ requirement: &id007 !ruby/object:Gem::Requirement
102
117
  none: false
103
118
  requirements:
104
119
  - - ~>
@@ -109,12 +124,12 @@ dependencies:
109
124
  - 8
110
125
  - 7
111
126
  version: 0.8.7
112
- version_requirements: *id006
127
+ version_requirements: *id007
113
128
  name: rake
114
129
  prerelease: false
115
130
  - !ruby/object:Gem::Dependency
116
131
  type: :development
117
- requirement: &id007 !ruby/object:Gem::Requirement
132
+ requirement: &id008 !ruby/object:Gem::Requirement
118
133
  none: false
119
134
  requirements:
120
135
  - - ~>
@@ -125,12 +140,12 @@ dependencies:
125
140
  - 3
126
141
  - 1
127
142
  version: 1.3.1
128
- version_requirements: *id007
143
+ version_requirements: *id008
129
144
  name: sqlite3-ruby
130
145
  prerelease: false
131
146
  - !ruby/object:Gem::Dependency
132
147
  type: :development
133
- requirement: &id008 !ruby/object:Gem::Requirement
148
+ requirement: &id009 !ruby/object:Gem::Requirement
134
149
  none: false
135
150
  requirements:
136
151
  - - ~>
@@ -141,12 +156,12 @@ dependencies:
141
156
  - 3
142
157
  - 4
143
158
  version: 0.3.4
144
- version_requirements: *id008
159
+ version_requirements: *id009
145
160
  name: timecop
146
161
  prerelease: false
147
162
  - !ruby/object:Gem::Dependency
148
163
  type: :development
149
- requirement: &id009 !ruby/object:Gem::Requirement
164
+ requirement: &id010 !ruby/object:Gem::Requirement
150
165
  none: false
151
166
  requirements:
152
167
  - - ~>
@@ -157,12 +172,12 @@ dependencies:
157
172
  - 7
158
173
  - 5
159
174
  version: 0.7.5
160
- version_requirements: *id009
175
+ version_requirements: *id010
161
176
  name: yajl-ruby
162
177
  prerelease: false
163
178
  - !ruby/object:Gem::Dependency
164
179
  type: :development
165
- requirement: &id010 !ruby/object:Gem::Requirement
180
+ requirement: &id011 !ruby/object:Gem::Requirement
166
181
  none: false
167
182
  requirements:
168
183
  - - "="
@@ -175,12 +190,12 @@ dependencies:
175
190
  - rc
176
191
  - 6
177
192
  version: 2.0.0.rc.6
178
- version_requirements: *id010
193
+ version_requirements: *id011
179
194
  name: mongoid
180
195
  prerelease: false
181
196
  - !ruby/object:Gem::Dependency
182
197
  type: :development
183
- requirement: &id011 !ruby/object:Gem::Requirement
198
+ requirement: &id012 !ruby/object:Gem::Requirement
184
199
  none: false
185
200
  requirements:
186
201
  - - "="
@@ -191,12 +206,12 @@ dependencies:
191
206
  - 2
192
207
  - 0
193
208
  version: 1.2.0
194
- version_requirements: *id011
209
+ version_requirements: *id012
195
210
  name: bson
196
211
  prerelease: false
197
212
  - !ruby/object:Gem::Dependency
198
213
  type: :development
199
- requirement: &id012 !ruby/object:Gem::Requirement
214
+ requirement: &id013 !ruby/object:Gem::Requirement
200
215
  none: false
201
216
  requirements:
202
217
  - - "="
@@ -207,7 +222,7 @@ dependencies:
207
222
  - 2
208
223
  - 0
209
224
  version: 1.2.0
210
- version_requirements: *id012
225
+ version_requirements: *id013
211
226
  name: bson_ext
212
227
  prerelease: false
213
228
  description: OAuth2 Provider, extracted from api.hashblue.com
@@ -312,6 +327,7 @@ files:
312
327
  - spec/requests/access_tokens_controller_spec.rb
313
328
  - spec/requests/authentication_spec.rb
314
329
  - spec/requests/authorization_code_request_spec.rb
330
+ - spec/requests/middleware_spec.rb
315
331
  - spec/schema.rb
316
332
  - spec/set_backend_env_to_mongoid.rb
317
333
  - spec/spec_helper.rb
@@ -320,7 +336,6 @@ files:
320
336
  - spec/support/macros.rb
321
337
  - spec/support/mongoid_backend.rb
322
338
  - spec/support/rack.rb
323
- has_rdoc: true
324
339
  homepage: http://tomafro.net
325
340
  licenses: []
326
341
 
@@ -350,7 +365,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
350
365
  requirements: []
351
366
 
352
367
  rubyforge_project:
353
- rubygems_version: 1.6.2
368
+ rubygems_version: 1.8.5
354
369
  signing_key:
355
370
  specification_version: 3
356
371
  summary: OAuth2 Provider, extracted from api.hashblue.com
@@ -362,6 +377,7 @@ test_files:
362
377
  - spec/requests/access_tokens_controller_spec.rb
363
378
  - spec/requests/authentication_spec.rb
364
379
  - spec/requests/authorization_code_request_spec.rb
380
+ - spec/requests/middleware_spec.rb
365
381
  - spec/schema.rb
366
382
  - spec/set_backend_env_to_mongoid.rb
367
383
  - spec/spec_helper.rb