oauth-plugin 0.4.0.pre7 → 0.4.0.rc1
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/CHANGELOG +6 -0
- data/README.rdoc +92 -28
- data/generators/oauth_provider/templates/oauth2_token.rb +16 -2
- data/generators/oauth_provider/templates/oauth2_token_spec.rb +28 -5
- data/generators/oauth_provider/templates/oauth2_verifier.rb +15 -8
- data/generators/oauth_provider/templates/oauth2_verifier_spec.rb +21 -31
- data/lib/generators/active_record/oauth_provider_templates/oauth2_token.rb +16 -1
- data/lib/generators/active_record/oauth_provider_templates/oauth2_verifier.rb +9 -2
- data/lib/generators/erb/oauth_provider_templates/authorize.html.erb +1 -1
- data/lib/generators/erb/oauth_provider_templates/edit.html.erb +1 -1
- data/lib/generators/erb/oauth_provider_templates/new.html.erb +1 -1
- data/lib/generators/erb/oauth_provider_templates/oauth2_authorize.html.erb +1 -1
- data/lib/generators/haml/oauth_provider_templates/authorize.html.haml +1 -1
- data/lib/generators/haml/oauth_provider_templates/edit.html.haml +1 -1
- data/lib/generators/haml/oauth_provider_templates/new.html.haml +1 -1
- data/lib/generators/haml/oauth_provider_templates/oauth2_authorize.html.haml +1 -1
- data/lib/generators/mongoid/oauth_provider_templates/oauth2_token.rb +16 -1
- data/lib/generators/mongoid/oauth_provider_templates/oauth2_verifier.rb +12 -2
- data/lib/generators/rspec/templates/oauth2_token_spec.rb +24 -1
- data/lib/generators/rspec/templates/oauth2_verifier_spec.rb +15 -25
- data/lib/oauth/controllers/provider_controller.rb +13 -13
- data/lib/oauth/rack/oauth_filter.rb +3 -2
- data/lib/oauth-plugin/version.rb +1 -1
- data/spec/rack/oauth_filter_spec.rb +137 -70
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
0.4.0-rc1
|
2
|
+
PLEASE help test this so we can mark it as final
|
3
|
+
- Update to OAuth2 draft 22 which is likely the final release. [pelle] ACTION REQUIRED BY YOU, see README.
|
4
|
+
- Update forms to work with rails 3.1 [morgz]
|
5
|
+
- Allow nil callbacks for oob in OAuth 1.0a [Shaliko Usubov]
|
6
|
+
- OAuthFilter:oauth2_token to rejects headers that explicitly state oauth_version="1.0" [KentonWhite]
|
1
7
|
0.4.0-pre7
|
2
8
|
- OAuth 1 requests using query or form encoded parameters where being interpreted as OAuth2 [pelleb]
|
3
9
|
- OAuth 2 requests were not checking for invalidated tokens. Please upgrade for this if you offer OAuth 2 [rymai]
|
data/README.rdoc
CHANGED
@@ -4,24 +4,88 @@ This is a plugin for implementing OAuth Providers and Consumers in Rails applica
|
|
4
4
|
|
5
5
|
We support the revised OAuth 1.0a specs at:
|
6
6
|
|
7
|
-
http://
|
7
|
+
http://tools.ietf.org/html/rfc5849
|
8
8
|
|
9
9
|
As well as support for OAuth 2.0:
|
10
10
|
|
11
|
-
http://tools.ietf.org/html/draft-ietf-oauth-v2-
|
11
|
+
http://tools.ietf.org/html/draft-ietf-oauth-v2-22
|
12
12
|
|
13
|
-
|
13
|
+
Find out more on the OAuth site at:
|
14
14
|
|
15
15
|
http://oauth.net
|
16
16
|
|
17
|
-
|
17
|
+
== IMPORTANT note for people upgrading the provider
|
18
18
|
|
19
|
-
|
19
|
+
There are several changes to the latest OAuth 2.0 spec which requires a couple of changes to 2 models which you are REQUIRED to update manually if you are supporting OAuth2.
|
20
|
+
|
21
|
+
https://github.com/pelle/oauth-plugin/blob/master/lib/generators/active_record/oauth_provider_templates/oauth2_token.rb
|
22
|
+
|
23
|
+
class Oauth2Token < AccessToken
|
24
|
+
attr_accessor :state
|
25
|
+
def as_json(options={})
|
26
|
+
d = {:access_token=>token, :token_type => 'bearer'}
|
27
|
+
d[:expires_in] = expires_in if expires_at
|
28
|
+
d
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_query
|
32
|
+
q = "access_token=#{token}&token_type=bearer"
|
33
|
+
q << "&state=#{URI.escape(state)}" if @state
|
34
|
+
q << "&expires_in=#{expires_in}" if expires_at
|
35
|
+
q << "&scope=#{URI.escape(scope)}" if scope
|
36
|
+
q
|
37
|
+
end
|
38
|
+
|
39
|
+
def expires_in
|
40
|
+
expires_at.to_i - Time.now.to_i
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
https://github.com/pelle/oauth-plugin/blob/master/lib/generators/active_record/oauth_provider_templates/oauth2_verifier.rb
|
46
|
+
|
47
|
+
class Oauth2Verifier < OauthToken
|
48
|
+
validates_presence_of :user
|
49
|
+
attr_accessor :state
|
50
|
+
|
51
|
+
def exchange!(params={})
|
52
|
+
OauthToken.transaction do
|
53
|
+
token = Oauth2Token.create! :user=>user,:client_application=>client_application, :scope => scope
|
54
|
+
invalidate!
|
55
|
+
token
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def code
|
60
|
+
token
|
61
|
+
end
|
62
|
+
|
63
|
+
def redirect_url
|
64
|
+
callback_url
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_query
|
68
|
+
q = "code=#{token}"
|
69
|
+
q << "&state=#{URI.escape(state)}" if @state
|
70
|
+
q
|
71
|
+
end
|
72
|
+
|
73
|
+
protected
|
74
|
+
|
75
|
+
def generate_keys
|
76
|
+
self.token = OAuth::Helper.generate_key(20)[0,20]
|
77
|
+
self.expires_at = 10.minutes.from_now
|
78
|
+
self.authorized_at = Time.now
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
There are matching specs for these which you may want to move into your project as well.
|
20
84
|
|
21
85
|
== Requirements
|
22
86
|
|
23
87
|
You need to install the oauth gem (0.4.4) which is the core OAuth ruby library. It will likely NOT work on any previous version of the gem.
|
24
|
-
|
88
|
+
|
25
89
|
gem install oauth
|
26
90
|
|
27
91
|
== Installation (Rails 3.0)
|
@@ -39,7 +103,7 @@ And install it:
|
|
39
103
|
The plugin can now be installed as an gem from github, which is the easiest way to keep it up to date.
|
40
104
|
|
41
105
|
gem install oauth-plugin --pre
|
42
|
-
|
106
|
+
|
43
107
|
You should add the following in the gem dependency section of environment.rb
|
44
108
|
|
45
109
|
config.gem "oauth"
|
@@ -72,7 +136,7 @@ It requires an authentication framework such as acts_as_authenticated, restful_a
|
|
72
136
|
A big change over previous versions is that we now use a rack filter. You have to install this in your application.rb file:
|
73
137
|
|
74
138
|
require 'oauth/rack/oauth_filter'
|
75
|
-
config.middleware.use OAuth::Rack::OAuthFilter
|
139
|
+
config.middleware.use OAuth::Rack::OAuthFilter
|
76
140
|
|
77
141
|
|
78
142
|
=== Generator Options
|
@@ -107,7 +171,7 @@ It requires an authentication framework such as acts_as_authenticated, restful_a
|
|
107
171
|
By default the generator generates RSpec and ERB templates. The generator can instead create Test::Unit and/or HAML templates. To do this use the following options:
|
108
172
|
|
109
173
|
./script/generate oauth_provider --test-unit --haml
|
110
|
-
|
174
|
+
|
111
175
|
These can of course be used individually as well.
|
112
176
|
|
113
177
|
=== User Model
|
@@ -120,7 +184,7 @@ Add the following lines to your user model:
|
|
120
184
|
=== Migrate database
|
121
185
|
|
122
186
|
The database is defined in:
|
123
|
-
|
187
|
+
|
124
188
|
db/migrate/XXX_create_oauth_tables.rb
|
125
189
|
|
126
190
|
Run them as any other normal migration in rails with:
|
@@ -173,14 +237,14 @@ Then change the create_request_token method to the following:
|
|
173
237
|
|
174
238
|
=== Changes in request_token.rb
|
175
239
|
|
176
|
-
The RequestToken contains the bulk of the changes so it's easiest to list it in it's entirety. Mainly we need to add support for the oauth_verifier parameter and also tell the client that we support OAuth 1.0a.
|
240
|
+
The RequestToken contains the bulk of the changes so it's easiest to list it in it's entirety. Mainly we need to add support for the oauth_verifier parameter and also tell the client that we support OAuth 1.0a.
|
177
241
|
|
178
242
|
Make sure it looks like this:
|
179
243
|
|
180
244
|
class RequestToken < OauthToken
|
181
|
-
|
245
|
+
|
182
246
|
attr_accessor :provided_oauth_verifier
|
183
|
-
|
247
|
+
|
184
248
|
def authorize!(user)
|
185
249
|
return false if authorized?
|
186
250
|
self.user = user
|
@@ -188,18 +252,18 @@ Make sure it looks like this:
|
|
188
252
|
self.verifier=OAuth::Helper.generate_key(16)[0,20] unless oauth10?
|
189
253
|
self.save
|
190
254
|
end
|
191
|
-
|
255
|
+
|
192
256
|
def exchange!
|
193
257
|
return false unless authorized?
|
194
258
|
return false unless oauth10? || verifier == provided_oauth_verifier
|
195
|
-
|
259
|
+
|
196
260
|
RequestToken.transaction do
|
197
261
|
access_token = AccessToken.create(:user => user, :client_application => client_application)
|
198
262
|
invalidate!
|
199
263
|
access_token
|
200
264
|
end
|
201
265
|
end
|
202
|
-
|
266
|
+
|
203
267
|
def to_query
|
204
268
|
if oauth10?
|
205
269
|
super
|
@@ -207,11 +271,11 @@ Make sure it looks like this:
|
|
207
271
|
"#{super}&oauth_callback_confirmed = true"
|
208
272
|
end
|
209
273
|
end
|
210
|
-
|
274
|
+
|
211
275
|
def oob?
|
212
276
|
self.callback_url == 'oob'
|
213
277
|
end
|
214
|
-
|
278
|
+
|
215
279
|
def oauth10?
|
216
280
|
(defined? OAUTH_10_SUPPORT) && OAUTH_10_SUPPORT && self.callback_url.blank?
|
217
281
|
end
|
@@ -220,12 +284,12 @@ Make sure it looks like this:
|
|
220
284
|
|
221
285
|
=== Changes in oauth_controller
|
222
286
|
|
223
|
-
All you need to do here is the change the authorize action to use the request_token callback url and add the oauth_verifier to the callback url.
|
287
|
+
All you need to do here is the change the authorize action to use the request_token callback url and add the oauth_verifier to the callback url.
|
224
288
|
|
225
289
|
def authorize
|
226
290
|
@token = ::RequestToken.find_by_token params[:oauth_token]
|
227
|
-
unless @token.invalidated?
|
228
|
-
if request.post?
|
291
|
+
unless @token.invalidated?
|
292
|
+
if request.post?
|
229
293
|
if params[:authorize] == '1'
|
230
294
|
@token.authorize!(current_user)
|
231
295
|
if @token.oauth10?
|
@@ -233,7 +297,7 @@ All you need to do here is the change the authorize action to use the request_to
|
|
233
297
|
else
|
234
298
|
@redirect_url = @token.oob? ? @token.client_application.callback_url : @token.callback_url
|
235
299
|
end
|
236
|
-
|
300
|
+
|
237
301
|
if @redirect_url
|
238
302
|
if @token.oauth10?
|
239
303
|
redirect_to "#{@redirect_url}?oauth_token=#{@token.token}"
|
@@ -305,7 +369,7 @@ You could add application specific information to the OauthToken and ClientAppli
|
|
305
369
|
The oauth_consumer generator creates a controller to manage the authentication flow between your application and any number of external OAuth secured applications that you wish to connect to.
|
306
370
|
|
307
371
|
To run it in Rails 3 simply run:
|
308
|
-
|
372
|
+
|
309
373
|
rails g oauth_consumer
|
310
374
|
|
311
375
|
In previous versions:
|
@@ -320,7 +384,7 @@ By default the generator generates ERB templates. The generator can instead crea
|
|
320
384
|
|
321
385
|
./script/generate oauth_consumer --haml
|
322
386
|
|
323
|
-
Rails 3 respects your application defaults, see the oauth provider generator section above for more info.
|
387
|
+
Rails 3 respects your application defaults, see the oauth provider generator section above for more info.
|
324
388
|
|
325
389
|
=== Configuration
|
326
390
|
|
@@ -346,13 +410,13 @@ Add entries to OAUTH_CREDENTIALS for all OAuth Applications you wish to connect
|
|
346
410
|
:key => "",
|
347
411
|
:secret => "",
|
348
412
|
:options = {
|
349
|
-
:site => "http://hourfeed.com"
|
413
|
+
:site => "http://hourfeed.com"
|
350
414
|
}
|
351
415
|
},
|
352
416
|
:nu_bux => {
|
353
417
|
:key => "",
|
354
418
|
:secret => "",
|
355
|
-
:super_class => "OpenTransactToken", # if a OAuth service follows a particular standard
|
419
|
+
:super_class => "OpenTransactToken", # if a OAuth service follows a particular standard
|
356
420
|
# with a token implementation you can set the superclass
|
357
421
|
# to use
|
358
422
|
:options => {
|
@@ -402,7 +466,7 @@ These can be found in lib/oauth/models/consulers/services. Contributions will be
|
|
402
466
|
To connect a user to an external service link or redirect them to:
|
403
467
|
|
404
468
|
/oauth_consumers/[SERVICE_NAME]
|
405
|
-
|
469
|
+
|
406
470
|
Where SERVICE_NAME is the name you set in the OAUTH_CREDENTIALS hash. This will request the request token and redirect the user to the services authorization screen. When the user accepts the get redirected back to:
|
407
471
|
|
408
472
|
/oauth_consumers/[SERVICE_NAME]/callback
|
@@ -420,7 +484,7 @@ This is designed to let your local javascript apps access remote OAuth apis. You
|
|
420
484
|
:client => :oauth_gem, # :twitter_gem or :oauth_gem (defaults to :twitter_gem)
|
421
485
|
:expose => true # set to true to expose client via the web
|
422
486
|
}
|
423
|
-
|
487
|
+
|
424
488
|
Once the user has authorized your application, you can access the client APIs via:
|
425
489
|
|
426
490
|
/oauth_consumers/[SERVICE_NAME]/client/[ENDPOINT]
|
@@ -1,6 +1,20 @@
|
|
1
1
|
class Oauth2Token < AccessToken
|
2
|
-
|
2
|
+
attr_accessor :state
|
3
3
|
def as_json(options={})
|
4
|
-
{:access_token =>
|
4
|
+
d = {:access_token=>token, :token_type => 'bearer'}
|
5
|
+
d[:expires_in] = expires_in if expires_at
|
6
|
+
d
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_query
|
10
|
+
q = "access_token=#{token}&token_type=bearer"
|
11
|
+
q << "&state=#{URI.escape(state)}" if @state
|
12
|
+
q << "&expires_in=#{expires_in}" if expires_at
|
13
|
+
q << "&scope=#{URI.escape(scope)}" if scope
|
14
|
+
q
|
15
|
+
end
|
16
|
+
|
17
|
+
def expires_in
|
18
|
+
expires_at.to_i - Time.now.to_i
|
5
19
|
end
|
6
20
|
end
|
@@ -5,25 +5,48 @@ describe Oauth2Token do
|
|
5
5
|
before(:each) do
|
6
6
|
@token = Oauth2Token.create :client_application => client_applications(:one), :user=>users(:aaron)
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
it "should be valid" do
|
10
10
|
@token.should be_valid
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
it "should have a token" do
|
14
14
|
@token.token.should_not be_nil
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
it "should have a secret" do
|
18
18
|
@token.secret.should_not be_nil
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it "should be authorized" do
|
22
22
|
@token.should be_authorized
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it "should not be invalidated" do
|
26
26
|
@token.should_not be_invalidated
|
27
27
|
end
|
28
28
|
|
29
|
+
it "should generate correct json and query strong" do
|
30
|
+
@token.as_json.should == {:access_token => @token.token, :token_type => 'bearer'}
|
31
|
+
@token.to_query.should == "access_token=#{@token.token}&token_type=bearer"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should generate correct json and query string and include state in query if present" do
|
35
|
+
@token.state = 'bb bb'
|
36
|
+
@token.as_json.should == {:access_token => @token.token, :token_type => 'bearer'}
|
37
|
+
@token.to_query.should == "access_token=#{@token.token}&token_type=bearer&state=bb%20bb"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should generate correct json and query string and include scope in query if present" do
|
41
|
+
@token.scope = 'bbbb aaaa'
|
42
|
+
@token.as_json.should == {:access_token => @token.token, :token_type => 'bearer'}
|
43
|
+
@token.to_query.should == "access_token=#{@token.token}&token_type=bearer&scope=bbbb%20aaaa"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should generate correct json and include expires_in if present" do
|
47
|
+
@token.expires_at = 1.hour.from_now
|
48
|
+
@token.as_json.should == { :access_token => @token.token, :token_type => 'bearer', :expires_in => 3600 }
|
49
|
+
@token.to_query.should == "access_token=#{@token.token}&token_type=bearer&expires_in=3600"
|
50
|
+
end
|
51
|
+
|
29
52
|
end
|
@@ -1,28 +1,35 @@
|
|
1
1
|
class Oauth2Verifier < OauthToken
|
2
2
|
validates_presence_of :user
|
3
|
-
|
3
|
+
attr_accessor :state
|
4
|
+
|
4
5
|
def exchange!(params={})
|
5
6
|
OauthToken.transaction do
|
6
|
-
token = Oauth2Token.create! :user=>user,:client_application=>client_application
|
7
|
+
token = Oauth2Token.create! :user=>user,:client_application=>client_application, :scope => scope
|
7
8
|
invalidate!
|
8
9
|
token
|
9
10
|
end
|
10
11
|
end
|
11
|
-
|
12
|
+
|
12
13
|
def code
|
13
14
|
token
|
14
15
|
end
|
15
|
-
|
16
|
+
|
16
17
|
def redirect_url
|
17
18
|
callback_url
|
18
19
|
end
|
19
|
-
|
20
|
+
|
21
|
+
def to_query
|
22
|
+
q = "code=#{token}"
|
23
|
+
q << "&state=#{URI.escape(state)}" if @state
|
24
|
+
q
|
25
|
+
end
|
26
|
+
|
20
27
|
protected
|
21
|
-
|
28
|
+
|
22
29
|
def generate_keys
|
23
30
|
self.token = OAuth::Helper.generate_key(20)[0,20]
|
24
|
-
self.
|
31
|
+
self.expires_at = 10.minutes.from_now
|
25
32
|
self.authorized_at = Time.now
|
26
33
|
end
|
27
|
-
|
34
|
+
|
28
35
|
end
|
@@ -3,52 +3,42 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
3
3
|
describe Oauth2Verifier do
|
4
4
|
fixtures :client_applications, :users, :oauth_tokens
|
5
5
|
before(:each) do
|
6
|
-
@verifier = Oauth2Verifier.create :client_application => client_applications(:one), :user=>users(:aaron)
|
6
|
+
@verifier = Oauth2Verifier.create :client_application => client_applications(:one), :user=>users(:aaron), :scope => "bbbb aaaa"
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
it "should be valid" do
|
10
10
|
@verifier.should be_valid
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
it "should have a code" do
|
14
14
|
@verifier.code.should_not be_nil
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
it "should not have a secret" do
|
18
18
|
@verifier.secret.should be_nil
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it "should be authorized" do
|
22
22
|
@verifier.should be_authorized
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it "should not be invalidated" do
|
26
26
|
@verifier.should_not be_invalidated
|
27
27
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
@token.client_application.should == @verifier.client_application
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should be authorized" do
|
47
|
-
@token.should be_authorized
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should not be invalidated" do
|
51
|
-
@token.should_not be_invalidated
|
52
|
-
end
|
28
|
+
|
29
|
+
it "should generate query string" do
|
30
|
+
@verifier.to_query.should == "code=#{@verifier.code}"
|
31
|
+
@verifier.state="bbbb aaaa"
|
32
|
+
@verifier.to_query.should == "code=#{@verifier.code}&state=bbbb%20aaaa"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should properly exchange for token" do
|
36
|
+
@token = @verifier.exchange!
|
37
|
+
@verifier.should be_invalidated
|
38
|
+
@token.user.should==@verifier.user
|
39
|
+
@token.client_application.should == @verifier.client_application
|
40
|
+
@token.should be_authorized
|
41
|
+
@token.should_not be_invalidated
|
42
|
+
@token.scope.should == @verifier.scope
|
53
43
|
end
|
54
44
|
end
|
@@ -1,5 +1,20 @@
|
|
1
1
|
class Oauth2Token < AccessToken
|
2
|
+
attr_accessor :state
|
2
3
|
def as_json(options={})
|
3
|
-
{:access_token=>token}
|
4
|
+
d = {:access_token=>token, :token_type => 'bearer'}
|
5
|
+
d[:expires_in] = expires_in if expires_at
|
6
|
+
d
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_query
|
10
|
+
q = "access_token=#{token}&token_type=bearer"
|
11
|
+
q << "&state=#{URI.escape(state)}" if @state
|
12
|
+
q << "&expires_in=#{expires_in}" if expires_at
|
13
|
+
q << "&scope=#{URI.escape(scope)}" if scope
|
14
|
+
q
|
15
|
+
end
|
16
|
+
|
17
|
+
def expires_in
|
18
|
+
expires_at.to_i - Time.now.to_i
|
4
19
|
end
|
5
20
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
class Oauth2Verifier < OauthToken
|
2
2
|
validates_presence_of :user
|
3
|
+
attr_accessor :state
|
3
4
|
|
4
5
|
def exchange!(params={})
|
5
6
|
OauthToken.transaction do
|
6
|
-
token = Oauth2Token.create! :user=>user,:client_application=>client_application
|
7
|
+
token = Oauth2Token.create! :user=>user,:client_application=>client_application, :scope => scope
|
7
8
|
invalidate!
|
8
9
|
token
|
9
10
|
end
|
@@ -17,11 +18,17 @@ class Oauth2Verifier < OauthToken
|
|
17
18
|
callback_url
|
18
19
|
end
|
19
20
|
|
21
|
+
def to_query
|
22
|
+
q = "code=#{token}"
|
23
|
+
q << "&state=#{URI.escape(state)}" if @state
|
24
|
+
q
|
25
|
+
end
|
26
|
+
|
20
27
|
protected
|
21
28
|
|
22
29
|
def generate_keys
|
23
30
|
self.token = OAuth::Helper.generate_key(20)[0,20]
|
24
|
-
self.
|
31
|
+
self.expires_at = 10.minutes.from_now
|
25
32
|
self.authorized_at = Time.now
|
26
33
|
end
|
27
34
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<h1>Authorize access to your account</h1>
|
2
2
|
<p>Would you like to authorize <%%= link_to @token.client_application.name,@token.client_application.url %> (<%%= link_to @token.client_application.url,@token.client_application.url %>) to access your account?</p>
|
3
|
-
|
3
|
+
<%%= form_tag authorize_url do %>
|
4
4
|
<%%= hidden_field_tag "oauth_token", @token.token %>
|
5
5
|
<%%- if params[:oauth_callback] -%>
|
6
6
|
<%%= hidden_field_tag "oauth_callback", params[:oauth_callback] %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<h1>Edit your application</h1>
|
2
|
-
|
2
|
+
<%%= form_for :client_application, @client_application, :url => oauth_client_path(@client_application), :html => {:method => :put} do |f| %>
|
3
3
|
<%%= render :partial => "form", :locals => { :f => f } %>
|
4
4
|
<%%= submit_tag "Edit" %>
|
5
5
|
<%% end %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<h1>Register a new application</h1>
|
2
|
-
|
2
|
+
<%%= form_for :client_application, :url => { :action => :create } do |f| %>
|
3
3
|
<%%= render :partial => "form", :locals => { :f => f } %>
|
4
4
|
<%%= submit_tag "Register" %>
|
5
5
|
<%% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<h1>Authorize access to your account</h1>
|
2
2
|
<p>Would you like to authorize <%%= link_to @token.client_application.name,@token.client_application.url %> (<%%= link_to @token.client_application.url,@token.client_application.url %>) to access your account?</p>
|
3
|
-
|
3
|
+
<%%= form_tag authorize_url do %>
|
4
4
|
<%%= hidden_field_tag "response_type", params[:response_type]%>
|
5
5
|
<%%= hidden_field_tag "client_id", params[:client_id]%>
|
6
6
|
<%%= hidden_field_tag "redirect_uri", params[:redirect_uri]%>
|
@@ -5,7 +5,7 @@
|
|
5
5
|
(
|
6
6
|
= link_to @token.client_application.url,@token.client_application.url
|
7
7
|
) to access your account?
|
8
|
-
|
8
|
+
= form_tag authorize_url do
|
9
9
|
= hidden_field_tag "oauth_token", @token.token
|
10
10
|
- if params[:oauth_callback]
|
11
11
|
= hidden_field_tag "oauth_callback", params[:oauth_callback]
|
@@ -5,7 +5,7 @@
|
|
5
5
|
(
|
6
6
|
= link_to @client_application.url,@client_application.url
|
7
7
|
) to access your account?
|
8
|
-
|
8
|
+
= form_tag authorize_url do
|
9
9
|
= hidden_field_tag "response_type", params[:response_type]
|
10
10
|
= hidden_field_tag "client_id", params[:client_id]
|
11
11
|
= hidden_field_tag "redirect_uri", params[:redirect_uri]
|
@@ -1,5 +1,20 @@
|
|
1
1
|
class Oauth2Token < AccessToken
|
2
|
+
attr_accessor :state
|
2
3
|
def as_json(options={})
|
3
|
-
{:access_token=>token}
|
4
|
+
d = {:access_token=>token, :token_type => 'bearer'}
|
5
|
+
d[:expires_in] = expires_in if expires_at
|
6
|
+
d
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_query
|
10
|
+
q = "access_token=#{token}&token_type=bearer"
|
11
|
+
q << "&state=#{URI.escape(state)}" if @state
|
12
|
+
q << "&expires_in=#{expires_in}" if expires_at
|
13
|
+
q << "&scope=#{URI.escape(scope)}" if scope
|
14
|
+
q
|
15
|
+
end
|
16
|
+
|
17
|
+
def expires_in
|
18
|
+
expires_at.to_i - Time.now.to_i
|
4
19
|
end
|
5
20
|
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
class Oauth2Verifier < OauthToken
|
2
2
|
validates_presence_of :user
|
3
|
+
attr_accessor :state
|
3
4
|
|
4
5
|
def exchange!(params={})
|
5
|
-
|
6
|
+
OauthToken.transaction do
|
7
|
+
token = Oauth2Token.create! :user=>user,:client_application=>client_application, :scope => scope
|
6
8
|
invalidate!
|
9
|
+
token
|
7
10
|
end
|
8
11
|
end
|
9
12
|
|
@@ -15,11 +18,18 @@ class Oauth2Verifier < OauthToken
|
|
15
18
|
callback_url
|
16
19
|
end
|
17
20
|
|
21
|
+
def to_query
|
22
|
+
q = "code=#{token}"
|
23
|
+
q << "&state=#{URI.escape(state)}" if @state
|
24
|
+
q
|
25
|
+
end
|
26
|
+
|
18
27
|
protected
|
19
28
|
|
20
29
|
def generate_keys
|
21
30
|
self.token = OAuth::Helper.generate_key(20)[0,20]
|
22
|
-
self.
|
31
|
+
self.expires_at = 10.minutes.from_now
|
23
32
|
self.authorized_at = Time.now
|
24
33
|
end
|
34
|
+
|
25
35
|
end
|
@@ -26,4 +26,27 @@ describe Oauth2Token do
|
|
26
26
|
@token.should_not be_invalidated
|
27
27
|
end
|
28
28
|
|
29
|
-
|
29
|
+
it "should generate correct json and query strong" do
|
30
|
+
@token.as_json.should == {:access_token => @token.token, :token_type => 'bearer'}
|
31
|
+
@token.to_query.should == "access_token=#{@token.token}&token_type=bearer"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should generate correct json and query string and include state in query if present" do
|
35
|
+
@token.state = 'bb bb'
|
36
|
+
@token.as_json.should == {:access_token => @token.token, :token_type => 'bearer'}
|
37
|
+
@token.to_query.should == "access_token=#{@token.token}&token_type=bearer&state=bb%20bb"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should generate correct json and query string and include scope in query if present" do
|
41
|
+
@token.scope = 'bbbb aaaa'
|
42
|
+
@token.as_json.should == {:access_token => @token.token, :token_type => 'bearer'}
|
43
|
+
@token.to_query.should == "access_token=#{@token.token}&token_type=bearer&scope=bbbb%20aaaa"
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should generate correct json and include expires_in if present" do
|
47
|
+
@token.expires_at = 1.hour.from_now
|
48
|
+
@token.as_json.should == { :access_token => @token.token, :token_type => 'bearer', :expires_in => 3600 }
|
49
|
+
@token.to_query.should == "access_token=#{@token.token}&token_type=bearer&expires_in=3600"
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
3
3
|
describe Oauth2Verifier do
|
4
4
|
fixtures :client_applications, :users, :oauth_tokens
|
5
5
|
before(:each) do
|
6
|
-
@verifier = Oauth2Verifier.create :client_application => client_applications(:one), :user=>users(:aaron)
|
6
|
+
@verifier = Oauth2Verifier.create :client_application => client_applications(:one), :user=>users(:aaron), :scope => "bbbb aaaa"
|
7
7
|
end
|
8
8
|
|
9
9
|
it "should be valid" do
|
@@ -26,29 +26,19 @@ describe Oauth2Verifier do
|
|
26
26
|
@verifier.should_not be_invalidated
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
it "should invalidate verifier" do
|
35
|
-
@verifier.should be_invalidated
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should set user on token" do
|
39
|
-
@token.user.should==@verifier.user
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should set client application on token" do
|
43
|
-
@token.client_application.should == @verifier.client_application
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should be authorized" do
|
47
|
-
@token.should be_authorized
|
48
|
-
end
|
29
|
+
it "should generate query string" do
|
30
|
+
@verifier.to_query.should == "code=#{@verifier.code}"
|
31
|
+
@verifier.state="bbbb aaaa"
|
32
|
+
@verifier.to_query.should == "code=#{@verifier.code}&state=bbbb%20aaaa"
|
33
|
+
end
|
49
34
|
|
50
|
-
|
51
|
-
|
52
|
-
|
35
|
+
it "should properly exchange for token" do
|
36
|
+
@token = @verifier.exchange!
|
37
|
+
@verifier.should be_invalidated
|
38
|
+
@token.user.should==@verifier.user
|
39
|
+
@token.client_application.should == @verifier.client_application
|
40
|
+
@token.should be_authorized
|
41
|
+
@token.should_not be_invalidated
|
42
|
+
@token.scope.should == @verifier.scope
|
53
43
|
end
|
54
|
-
end
|
44
|
+
end
|
@@ -100,7 +100,8 @@ module OAuth
|
|
100
100
|
if request.post?
|
101
101
|
if user_authorizes_token?
|
102
102
|
@token.authorize!(current_user)
|
103
|
-
|
103
|
+
callback_url = @token.oob? ? @token.client_application.callback_url : @token.callback_url
|
104
|
+
@redirect_url = URI.parse(callback_url) unless callback_url.blank?
|
104
105
|
|
105
106
|
unless @redirect_url.to_s.blank?
|
106
107
|
@redirect_url.query = @redirect_url.query.blank? ?
|
@@ -122,15 +123,13 @@ module OAuth
|
|
122
123
|
|
123
124
|
def oauth2_authorize_code
|
124
125
|
@client_application = ClientApplication.find_by_key params[:client_id]
|
126
|
+
# Using ||= allows us to override this and customize the verification_code and call super to handle the rest
|
127
|
+
@token ||= Oauth2Verifier.new :client_application=>@client_application, :user=>current_user, :callback_url=>@redirect_url.to_s, :scope => params[:scope], :state => params[:state]
|
125
128
|
if request.post?
|
126
|
-
@redirect_url = URI.parse(params[:redirect_uri] || @client_application.callback_url)
|
127
|
-
if user_authorizes_token?
|
128
|
-
@verification_code = Oauth2Verifier.create :client_application=>@client_application, :user=>current_user, :callback_url=>@redirect_url.to_s
|
129
|
-
|
129
|
+
@redirect_url = URI.parse(params[:redirect_uri] || @client_application.callback_url) if params[:redirect_uri] || @client_application.callback_url
|
130
|
+
if user_authorizes_token? && @token.save
|
130
131
|
unless @redirect_url.to_s.blank?
|
131
|
-
@redirect_url.query = @redirect_url.query.blank? ?
|
132
|
-
"code=#{@verification_code.code}" :
|
133
|
-
@redirect_url.query + "&code=#{@verification_code.code}"
|
132
|
+
@redirect_url.query = @redirect_url.query.blank? ? @token.to_query : @redirect_url.query + @token.to_query
|
134
133
|
redirect_to @redirect_url.to_s
|
135
134
|
else
|
136
135
|
render :action => "authorize_success"
|
@@ -152,12 +151,12 @@ module OAuth
|
|
152
151
|
|
153
152
|
def oauth2_authorize_token
|
154
153
|
@client_application = ClientApplication.find_by_key params[:client_id]
|
154
|
+
@token = Oauth2Token.new :client_application=>@client_application, :user=>current_user, :scope=>params[:scope]
|
155
155
|
if request.post?
|
156
156
|
@redirect_url = URI.parse(params[:redirect_uri] || @client_application.callback_url)
|
157
|
-
if user_authorizes_token?
|
158
|
-
@token = Oauth2Token.create :client_application=>@client_application, :user=>current_user, :scope=>params[:scope]
|
157
|
+
if user_authorizes_token? && @token.save
|
159
158
|
unless @redirect_url.to_s.blank?
|
160
|
-
redirect_to "#{@redirect_url.to_s}
|
159
|
+
redirect_to "#{@redirect_url.to_s}##{@token.to_query}"
|
161
160
|
else
|
162
161
|
render :action => "authorize_success"
|
163
162
|
end
|
@@ -176,7 +175,7 @@ module OAuth
|
|
176
175
|
end
|
177
176
|
end
|
178
177
|
|
179
|
-
# http://tools.ietf.org/html/draft-ietf-oauth-v2-
|
178
|
+
# http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.1.1
|
180
179
|
def oauth2_token_authorization_code
|
181
180
|
@verification_code = @client_application.oauth2_verifiers.find_by_token params[:code]
|
182
181
|
unless @verification_code
|
@@ -191,7 +190,7 @@ module OAuth
|
|
191
190
|
render :json=>@token
|
192
191
|
end
|
193
192
|
|
194
|
-
# http://tools.ietf.org/html/draft-ietf-oauth-v2-
|
193
|
+
# http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.1.2
|
195
194
|
def oauth2_token_password
|
196
195
|
@user = authenticate_user( params[:username], params[:password])
|
197
196
|
unless @user
|
@@ -221,6 +220,7 @@ module OAuth
|
|
221
220
|
def oauth2_error(error="invalid_grant")
|
222
221
|
render :json=>{:error=>error}.to_json
|
223
222
|
end
|
223
|
+
|
224
224
|
end
|
225
225
|
end
|
226
226
|
end
|
@@ -83,9 +83,10 @@ module OAuth
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def oauth2_token(request)
|
86
|
-
(request.params["oauth_token"] && !request.params["oauth_signature"] ? request.params["oauth_token"] : nil ) ||
|
86
|
+
request.params['bearer_token'] || request.params['access_token'] || (request.params["oauth_token"] && !request.params["oauth_signature"] ? request.params["oauth_token"] : nil ) ||
|
87
87
|
request.env["HTTP_AUTHORIZATION"] &&
|
88
|
-
request.env["HTTP_AUTHORIZATION"][
|
88
|
+
!request.env["HTTP_AUTHORIZATION"][/(oauth_version="1.0")/] &&
|
89
|
+
request.env["HTTP_AUTHORIZATION"][/^(Bearer|OAuth|Token) ([^\s]*)$/, 2]
|
89
90
|
end
|
90
91
|
end
|
91
92
|
end
|
data/lib/oauth-plugin/version.rb
CHANGED
@@ -28,39 +28,72 @@ describe OAuth::Rack::OAuthFilter do
|
|
28
28
|
response = MultiJson.decode(last_response.body)
|
29
29
|
response.should == {}
|
30
30
|
end
|
31
|
+
|
32
|
+
describe 'OAuth1' do
|
33
|
+
describe 'with optional white space' do
|
34
|
+
it "should sign with consumer" do
|
35
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="amrLDyFE2AMztx5fOYDD1OEqWps6Mc2mAR5qyO44Rj8", oauth_signature="KCSg0RUfVFUcyhrgJo580H8ey0c%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295039581", oauth_version="1.0"'}
|
36
|
+
last_response.should be_ok
|
37
|
+
response = MultiJson.decode(last_response.body)
|
38
|
+
response.should == {"client_application" => "my_consumer", "oauth_version"=>1, "strategies"=>["two_legged"]}
|
39
|
+
end
|
31
40
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
41
|
+
it "should sign with oauth 1 access token" do
|
42
|
+
client_application = ClientApplication.new "my_consumer"
|
43
|
+
ClientApplication.stub!(:find_by_key).and_return(client_application)
|
44
|
+
client_application.tokens.stub!(:first).and_return(AccessToken.new("my_token"))
|
45
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY", oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295040394", oauth_token="my_token", oauth_version="1.0"'}
|
46
|
+
last_response.should be_ok
|
47
|
+
response = MultiJson.decode(last_response.body)
|
48
|
+
response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","token","oauth10_access_token"]}
|
49
|
+
end
|
38
50
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
51
|
+
it "should sign with oauth 1 request token" do
|
52
|
+
client_application = ClientApplication.new "my_consumer"
|
53
|
+
ClientApplication.stub!(:find_by_key).and_return(client_application)
|
54
|
+
client_application.tokens.stub!(:first).and_return(RequestToken.new("my_token"))
|
55
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer", oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY", oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1295040394", oauth_token="my_token", oauth_version="1.0"'}
|
56
|
+
last_response.should be_ok
|
57
|
+
response = MultiJson.decode(last_response.body)
|
58
|
+
response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","oauth10_request_token"]}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'without optional white space' do
|
63
|
+
it "should sign with consumer" do
|
64
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer",oauth_nonce="amrLDyFE2AMztx5fOYDD1OEqWps6Mc2mAR5qyO44Rj8",oauth_signature="KCSg0RUfVFUcyhrgJo580H8ey0c%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1295039581",oauth_version="1.0"'}
|
65
|
+
last_response.should be_ok
|
66
|
+
response = MultiJson.decode(last_response.body)
|
67
|
+
response.should == {"client_application" => "my_consumer", "oauth_version"=>1, "strategies"=>["two_legged"]}
|
68
|
+
end
|
48
69
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
70
|
+
it "should sign with oauth 1 access token" do
|
71
|
+
client_application = ClientApplication.new "my_consumer"
|
72
|
+
ClientApplication.stub!(:find_by_key).and_return(client_application)
|
73
|
+
client_application.tokens.stub!(:first).and_return(AccessToken.new("my_token"))
|
74
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer",oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY",oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1295040394",oauth_token="my_token",oauth_version="1.0"'}
|
75
|
+
last_response.should be_ok
|
76
|
+
response = MultiJson.decode(last_response.body)
|
77
|
+
response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","token","oauth10_access_token"]}
|
78
|
+
end
|
58
79
|
|
80
|
+
it "should sign with oauth 1 request token" do
|
81
|
+
client_application = ClientApplication.new "my_consumer"
|
82
|
+
ClientApplication.stub!(:find_by_key).and_return(client_application)
|
83
|
+
client_application.tokens.stub!(:first).and_return(RequestToken.new("my_token"))
|
84
|
+
get '/',{},{"HTTP_AUTHORIZATION"=>'OAuth oauth_consumer_key="my_consumer",oauth_nonce="oiFHXoN0172eigBBUfgaZLdQg7ycGekv8iTdfkCStY",oauth_signature="y35B2DqTWaNlzNX0p4wv%2FJAGzg8%3D",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1295040394",oauth_token="my_token",oauth_version="1.0"'}
|
85
|
+
last_response.should be_ok
|
86
|
+
response = MultiJson.decode(last_response.body)
|
87
|
+
response.should == {"client_application" => "my_consumer", "oauth_token"=>"my_token","oauth_version"=>1, "strategies"=>["oauth10_token","oauth10_request_token"]}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
59
92
|
describe "OAuth2" do
|
60
93
|
describe "token given through a HTTP Auth Header" do
|
61
94
|
context "authorized and non-invalidated token" do
|
62
95
|
it "authenticates" do
|
63
|
-
get '/', {}, { "HTTP_AUTHORIZATION" => "
|
96
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "Bearer valid_token" }
|
64
97
|
last_response.should be_ok
|
65
98
|
response = MultiJson.decode(last_response.body)
|
66
99
|
response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] }
|
@@ -69,7 +102,7 @@ describe OAuth::Rack::OAuthFilter do
|
|
69
102
|
|
70
103
|
context "non-authorized token" do
|
71
104
|
it "doesn't authenticate" do
|
72
|
-
get '/', {}, { "HTTP_AUTHORIZATION" => "
|
105
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "Bearer not_authorized" }
|
73
106
|
last_response.should be_ok
|
74
107
|
response = MultiJson.decode(last_response.body)
|
75
108
|
response.should == {}
|
@@ -78,7 +111,7 @@ describe OAuth::Rack::OAuthFilter do
|
|
78
111
|
|
79
112
|
context "authorized and invalidated token" do
|
80
113
|
it "doesn't authenticate with an invalidated token" do
|
81
|
-
get '/', {}, { "HTTP_AUTHORIZATION" => "
|
114
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "Bearer invalidated" }
|
82
115
|
last_response.should be_ok
|
83
116
|
response = MultiJson.decode(last_response.body)
|
84
117
|
response.should == {}
|
@@ -86,6 +119,37 @@ describe OAuth::Rack::OAuthFilter do
|
|
86
119
|
end
|
87
120
|
end
|
88
121
|
|
122
|
+
describe "OAuth2 pre Bearer" do
|
123
|
+
describe "token given through a HTTP Auth Header" do
|
124
|
+
context "authorized and non-invalidated token" do
|
125
|
+
it "authenticates" do
|
126
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "OAuth valid_token" }
|
127
|
+
last_response.should be_ok
|
128
|
+
response = MultiJson.decode(last_response.body)
|
129
|
+
response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "non-authorized token" do
|
134
|
+
it "doesn't authenticate" do
|
135
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "OAuth not_authorized" }
|
136
|
+
last_response.should be_ok
|
137
|
+
response = MultiJson.decode(last_response.body)
|
138
|
+
response.should == {}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "authorized and invalidated token" do
|
143
|
+
it "doesn't authenticate with an invalidated token" do
|
144
|
+
get '/', {}, { "HTTP_AUTHORIZATION" => "OAuth invalidated" }
|
145
|
+
last_response.should be_ok
|
146
|
+
response = MultiJson.decode(last_response.body)
|
147
|
+
response.should == {}
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
89
153
|
describe "token given through a HTTP Auth Header following the OAuth2 pre draft" do
|
90
154
|
context "authorized and non-invalidated token" do
|
91
155
|
it "authenticates" do
|
@@ -115,60 +179,63 @@ describe OAuth::Rack::OAuthFilter do
|
|
115
179
|
end
|
116
180
|
end
|
117
181
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
182
|
+
['bearer_token', 'access_token', 'oauth_token'].each do |name|
|
183
|
+
describe "token given through the query parameter '#{name}'" do
|
184
|
+
context "authorized and non-invalidated token" do
|
185
|
+
it "authenticates" do
|
186
|
+
get "/?#{name}=valid_token"
|
187
|
+
|
188
|
+
last_response.should be_ok
|
189
|
+
response = MultiJson.decode(last_response.body)
|
190
|
+
response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] }
|
191
|
+
end
|
125
192
|
end
|
126
|
-
end
|
127
193
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
194
|
+
context "non-authorized token" do
|
195
|
+
it "doesn't authenticate" do
|
196
|
+
get "/?#{name}=not_authorized"
|
197
|
+
last_response.should be_ok
|
198
|
+
response = MultiJson.decode(last_response.body)
|
199
|
+
response.should == {}
|
200
|
+
end
|
134
201
|
end
|
135
|
-
end
|
136
202
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
203
|
+
context "authorized and invalidated token" do
|
204
|
+
it "doesn't authenticate with an invalidated token" do
|
205
|
+
get "/?#{name}=invalidated"
|
206
|
+
last_response.should be_ok
|
207
|
+
response = MultiJson.decode(last_response.body)
|
208
|
+
response.should == {}
|
209
|
+
end
|
143
210
|
end
|
144
211
|
end
|
145
|
-
end
|
146
212
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
213
|
+
describe "token given through the post parameter '#{name}'" do
|
214
|
+
context "authorized and non-invalidated token" do
|
215
|
+
it "authenticates" do
|
216
|
+
post '/', name => 'valid_token'
|
217
|
+
last_response.should be_ok
|
218
|
+
response = MultiJson.decode(last_response.body)
|
219
|
+
response.should == { "oauth_token" => "valid_token", "oauth_version" => 2, "strategies"=> ["oauth20_token", "token"] }
|
220
|
+
end
|
154
221
|
end
|
155
|
-
end
|
156
222
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
223
|
+
context "non-authorized token" do
|
224
|
+
it "doesn't authenticate" do
|
225
|
+
post '/', name => 'not_authorized'
|
226
|
+
last_response.should be_ok
|
227
|
+
response = MultiJson.decode(last_response.body)
|
228
|
+
response.should == {}
|
229
|
+
end
|
163
230
|
end
|
164
|
-
end
|
165
231
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
232
|
+
context "authorized and invalidated token" do
|
233
|
+
it "doesn't authenticate with an invalidated token" do
|
234
|
+
post '/', name => 'invalidated'
|
235
|
+
last_response.should be_ok
|
236
|
+
response = MultiJson.decode(last_response.body)
|
237
|
+
response.should == {}
|
238
|
+
end
|
172
239
|
end
|
173
240
|
end
|
174
241
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: oauth-plugin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 0.4.0.
|
5
|
+
version: 0.4.0.rc1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Pelle Braendgaard
|
@@ -327,7 +327,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
327
327
|
requirements: []
|
328
328
|
|
329
329
|
rubyforge_project: oauth
|
330
|
-
rubygems_version: 1.8.
|
330
|
+
rubygems_version: 1.8.11
|
331
331
|
signing_key:
|
332
332
|
specification_version: 3
|
333
333
|
summary: Ruby on Rails Plugin for OAuth Provider and Consumer
|