oauth2-provider 0.0.17 → 0.0.18

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.
@@ -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