oauth2-provider 0.0.16

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.
Files changed (101) hide show
  1. data/.gitignore +8 -0
  2. data/Gemfile +3 -0
  3. data/README.md +49 -0
  4. data/Rakefile +24 -0
  5. data/examples/client/Gemfile +6 -0
  6. data/examples/client/Gemfile.lock +20 -0
  7. data/examples/client/README +8 -0
  8. data/examples/client/app.rb +59 -0
  9. data/examples/client/config.ru +3 -0
  10. data/examples/client/views/home.haml +3 -0
  11. data/examples/client/views/response.haml +11 -0
  12. data/examples/rails3-example/.gitignore +4 -0
  13. data/examples/rails3-example/Gemfile +10 -0
  14. data/examples/rails3-example/Gemfile.lock +82 -0
  15. data/examples/rails3-example/README +9 -0
  16. data/examples/rails3-example/Rakefile +7 -0
  17. data/examples/rails3-example/app/controllers/account_controller.rb +14 -0
  18. data/examples/rails3-example/app/controllers/application_controller.rb +18 -0
  19. data/examples/rails3-example/app/controllers/authorization_controller.rb +18 -0
  20. data/examples/rails3-example/app/controllers/home_controller.rb +4 -0
  21. data/examples/rails3-example/app/controllers/session_controller.rb +24 -0
  22. data/examples/rails3-example/app/helpers/application_helper.rb +2 -0
  23. data/examples/rails3-example/app/models/account.rb +6 -0
  24. data/examples/rails3-example/app/views/authorization/new.html.erb +5 -0
  25. data/examples/rails3-example/app/views/home/show.html.erb +1 -0
  26. data/examples/rails3-example/app/views/layouts/application.html.erb +16 -0
  27. data/examples/rails3-example/app/views/session/new.html.erb +7 -0
  28. data/examples/rails3-example/config.ru +4 -0
  29. data/examples/rails3-example/config/application.rb +42 -0
  30. data/examples/rails3-example/config/boot.rb +6 -0
  31. data/examples/rails3-example/config/database.yml +22 -0
  32. data/examples/rails3-example/config/environment.rb +5 -0
  33. data/examples/rails3-example/config/environments/development.rb +26 -0
  34. data/examples/rails3-example/config/environments/production.rb +49 -0
  35. data/examples/rails3-example/config/environments/test.rb +35 -0
  36. data/examples/rails3-example/config/initializers/backtrace_silencers.rb +7 -0
  37. data/examples/rails3-example/config/initializers/inflections.rb +10 -0
  38. data/examples/rails3-example/config/initializers/mime_types.rb +5 -0
  39. data/examples/rails3-example/config/initializers/secret_token.rb +7 -0
  40. data/examples/rails3-example/config/initializers/session_store.rb +8 -0
  41. data/examples/rails3-example/config/locales/en.yml +5 -0
  42. data/examples/rails3-example/config/routes.rb +9 -0
  43. data/examples/rails3-example/db/migrate/20110508151935_add_account_table.rb +12 -0
  44. data/examples/rails3-example/db/migrate/20110508151948_add_oauth2_tables.rb +43 -0
  45. data/examples/rails3-example/db/schema.rb +52 -0
  46. data/examples/rails3-example/db/seeds.rb +11 -0
  47. data/examples/rails3-example/doc/README_FOR_APP +2 -0
  48. data/examples/rails3-example/lib/tasks/.gitkeep +0 -0
  49. data/examples/rails3-example/public/404.html +26 -0
  50. data/examples/rails3-example/public/422.html +26 -0
  51. data/examples/rails3-example/public/500.html +26 -0
  52. data/examples/rails3-example/public/favicon.ico +0 -0
  53. data/examples/rails3-example/public/images/rails.png +0 -0
  54. data/examples/rails3-example/public/robots.txt +5 -0
  55. data/examples/rails3-example/public/stylesheets/.gitkeep +0 -0
  56. data/examples/rails3-example/script/rails +6 -0
  57. data/lib/oauth2-provider.rb +3 -0
  58. data/lib/oauth2/provider.rb +39 -0
  59. data/lib/oauth2/provider/models.rb +40 -0
  60. data/lib/oauth2/provider/models/access_token.rb +54 -0
  61. data/lib/oauth2/provider/models/active_record.rb +30 -0
  62. data/lib/oauth2/provider/models/active_record/access_token.rb +13 -0
  63. data/lib/oauth2/provider/models/active_record/authorization.rb +16 -0
  64. data/lib/oauth2/provider/models/active_record/authorization_code.rb +13 -0
  65. data/lib/oauth2/provider/models/active_record/client.rb +15 -0
  66. data/lib/oauth2/provider/models/authorization.rb +40 -0
  67. data/lib/oauth2/provider/models/authorization_code.rb +27 -0
  68. data/lib/oauth2/provider/models/client.rb +28 -0
  69. data/lib/oauth2/provider/models/mongoid.rb +30 -0
  70. data/lib/oauth2/provider/models/mongoid/access_token.rb +40 -0
  71. data/lib/oauth2/provider/models/mongoid/authorization.rb +32 -0
  72. data/lib/oauth2/provider/models/mongoid/authorization_code.rb +43 -0
  73. data/lib/oauth2/provider/models/mongoid/client.rb +40 -0
  74. data/lib/oauth2/provider/rack.rb +11 -0
  75. data/lib/oauth2/provider/rack/access_token_handler.rb +103 -0
  76. data/lib/oauth2/provider/rack/authorization_code_request.rb +74 -0
  77. data/lib/oauth2/provider/rack/authorization_codes_support.rb +25 -0
  78. data/lib/oauth2/provider/rack/middleware.rb +28 -0
  79. data/lib/oauth2/provider/rack/resource_request.rb +91 -0
  80. data/lib/oauth2/provider/rack/responses.rb +34 -0
  81. data/lib/oauth2/provider/rails.rb +37 -0
  82. data/lib/oauth2/provider/rails/controller_authentication.rb +21 -0
  83. data/lib/oauth2/provider/random.rb +30 -0
  84. data/lib/oauth2/provider/version.rb +5 -0
  85. data/oauth2-provider.gemspec +35 -0
  86. data/spec/models/access_token_spec.rb +123 -0
  87. data/spec/models/authorization_code_spec.rb +115 -0
  88. data/spec/models/authorization_spec.rb +110 -0
  89. data/spec/models/client_spec.rb +75 -0
  90. data/spec/requests/access_tokens_controller_spec.rb +360 -0
  91. data/spec/requests/authentication_spec.rb +150 -0
  92. data/spec/requests/authorization_codes_support_spec.rb +157 -0
  93. data/spec/schema.rb +38 -0
  94. data/spec/set_backend_env_to_mongoid.rb +1 -0
  95. data/spec/spec_helper.rb +27 -0
  96. data/spec/support/activerecord_backend.rb +18 -0
  97. data/spec/support/factories.rb +56 -0
  98. data/spec/support/macros.rb +46 -0
  99. data/spec/support/mongoid_backend.rb +34 -0
  100. data/spec/support/rack.rb +32 -0
  101. metadata +373 -0
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe OAuth2::Provider.client_class do
4
+ describe "any instance" do
5
+ subject do
6
+ OAuth2::Provider.client_class.new :name => 'client'
7
+ end
8
+
9
+ it "is valid with a name, oauth identifier and oauth secret" do
10
+ subject.should be_valid
11
+ end
12
+
13
+ it "is invalid without a name" do
14
+ subject.name = nil
15
+ subject.should_not be_valid
16
+ end
17
+
18
+ it "is invalid without an oauth identifier" do
19
+ subject.oauth_identifier = nil
20
+ subject.should_not be_valid
21
+ end
22
+
23
+ it "is invalid without an oauth secret" do
24
+ subject.oauth_secret = nil
25
+ subject.should_not be_valid
26
+ end
27
+
28
+ it "is invalid if oauth_identifier not unique" do
29
+ duplicate = OAuth2::Provider.client_class.create! :name => 'client2'
30
+ subject.oauth_identifier = duplicate.oauth_identifier
31
+ subject.should_not be_valid
32
+ end
33
+
34
+ it "allows any grant type (custom subclasses can override this)" do
35
+ subject.allow_grant_type?('password').should be_true
36
+ subject.allow_grant_type?('authorization_code').should be_true
37
+ end
38
+ end
39
+
40
+ describe "a new instance" do
41
+ subject do
42
+ OAuth2::Provider.client_class.new :name => 'client'
43
+ end
44
+
45
+ it "is assigned a randomly generated oauth identifier" do
46
+ subject.oauth_identifier.should_not be_nil
47
+ OAuth2::Provider.client_class.new.oauth_identifier.should_not be_nil
48
+ subject.oauth_identifier.should_not == OAuth2::Provider.client_class.new.oauth_identifier
49
+ end
50
+
51
+ it "is assigned a randomly generated oauth secret" do
52
+ subject.oauth_secret.should_not be_nil
53
+ OAuth2::Provider.client_class.new.oauth_secret.should_not be_nil
54
+ subject.oauth_secret.should_not == OAuth2::Provider.client_class.new.oauth_secret
55
+ end
56
+
57
+ it "returns nil when to_param called" do
58
+ subject.to_param.should be_nil
59
+ end
60
+ end
61
+
62
+ describe "a saved instance" do
63
+ subject do
64
+ OAuth2::Provider.client_class.create! :name => 'client'
65
+ end
66
+
67
+ it "returns oauth_identifer when to_param called" do
68
+ subject.to_param.should == subject.oauth_identifier
69
+ end
70
+
71
+ it "is findable by calling from_param with its oauth_identifier" do
72
+ subject.should == OAuth2::Provider.client_class.from_param(subject.oauth_identifier)
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,360 @@
1
+ require 'spec_helper'
2
+
3
+ class CustomClient < OAuth2::Provider.client_class
4
+ end
5
+
6
+ class NotAllowedGrantTypeClient < OAuth2::Provider.client_class
7
+ def allow_grant_type?(grant_type)
8
+ false
9
+ end
10
+ end
11
+
12
+ describe "POSTs to /oauth/access_token" do
13
+ before :each do
14
+ @code = create_authorization_code
15
+ @client = @code.authorization.client
16
+ @valid_params = {
17
+ :grant_type => 'authorization_code',
18
+ :client_id => @code.authorization.client.oauth_identifier,
19
+ :client_secret => @code.authorization.client.oauth_secret,
20
+ :code => @code.code,
21
+ :redirect_uri => @code.redirect_uri
22
+ }
23
+ end
24
+
25
+ describe "Any request without a client_id parameter" do
26
+ before :each do
27
+ post "/oauth/access_token", @valid_params.except(:client_id)
28
+ end
29
+
30
+ responds_with_json_error 'invalid_request', :description => "missing 'client_id' parameter", :status => 400
31
+ end
32
+
33
+ describe "Any request without a client_secret parameter" do
34
+ before :each do
35
+ post "/oauth/access_token", @valid_params.except(:client_secret)
36
+ end
37
+
38
+ responds_with_json_error 'invalid_request', :description => "missing 'client_secret' parameter", :status => 400
39
+ end
40
+
41
+ describe "Any request without a grant_type parameter" do
42
+ before :each do
43
+ post "/oauth/access_token", @valid_params.except(:grant_type)
44
+ end
45
+
46
+ responds_with_json_error 'invalid_request', :description => "missing 'grant_type' parameter", :status => 400
47
+ end
48
+
49
+ describe "Any request without several required parameters" do
50
+ before :each do
51
+ post "/oauth/access_token", @valid_params.except(:client_id, :client_secret)
52
+ end
53
+
54
+ responds_with_json_error 'invalid_request', :description => "missing 'client_id', 'client_secret' parameters", :status => 400
55
+ end
56
+
57
+ describe "Any request with an unsupported grant_type" do
58
+ before :each do
59
+ post "/oauth/access_token", @valid_params.merge(:grant_type => 'unsupported')
60
+ end
61
+
62
+ responds_with_json_error 'unsupported_grant_type', :status => 400
63
+ end
64
+
65
+ describe "Any request where the client_id is unknown" do
66
+ before :each do
67
+ post "/oauth/access_token", @valid_params.merge(:client_id => 'unknown')
68
+ end
69
+
70
+ responds_with_json_error 'invalid_client', :status => 400
71
+ end
72
+
73
+ describe "Any request where the client_secret is wrong" do
74
+ before :each do
75
+ post "/oauth/access_token", @valid_params.merge(:client_secret => 'wrongvalue')
76
+ end
77
+
78
+ responds_with_json_error 'invalid_client', :status => 400
79
+ end
80
+
81
+ describe "Any request which doesn't use POST" do
82
+ before :each do
83
+ get "/oauth/access_token", @valid_params
84
+ end
85
+
86
+ it "responds with Method Not Allowed (405), and POST in the Allow header" do
87
+ response.status.should == 405
88
+ response.headers["Allow"].should == "POST"
89
+ end
90
+ end
91
+
92
+ describe "Any request where the client isn't allowed to use the requested grant type" do
93
+ before :each do
94
+ @original_client_class_name = OAuth2::Provider.client_class_name
95
+ OAuth2::Provider.client_class_name = NotAllowedGrantTypeClient.name
96
+ @client = NotAllowedGrantTypeClient.create! :name => 'client'
97
+ @code = create_authorization_code(:authorization => create_authorization(:client => @client))
98
+ @valid_params = {
99
+ :grant_type => 'authorization_code',
100
+ :client_id => @code.authorization.client.oauth_identifier,
101
+ :client_secret => @code.authorization.client.oauth_secret,
102
+ :code => @code.code,
103
+ :redirect_uri => @code.redirect_uri
104
+ }
105
+ post "/oauth/access_token", @valid_params
106
+ end
107
+
108
+ after :each do
109
+ OAuth2::Provider.client_class_name = @original_client_class_name
110
+ end
111
+
112
+ responds_with_json_error 'unauthorized_client', :status => 400
113
+ end
114
+
115
+ describe "A request using the authorization_code grant type" do
116
+ describe "with valid client, code and redirect_uri" do
117
+ before :each do
118
+ post "/oauth/access_token", @valid_params
119
+ end
120
+
121
+ it "responds with claimed access token, refresh token and expiry time in JSON" do
122
+ token = OAuth2::Provider.access_token_class.find_by_access_token(json_from_response["access_token"])
123
+ token.should_not be_nil
124
+ json_from_response["expires_in"].should == token.expires_in
125
+ json_from_response["refresh_token"].should == token.refresh_token
126
+ end
127
+
128
+ it "sets cache-control header to no-store, as response is sensitive" do
129
+ response.headers["Cache-Control"].should =~ /no-store/
130
+ end
131
+
132
+ it "destroys the claimed code, so it can't be used a second time" do
133
+ OAuth2::Provider.authorization_code_class.find_by_id(@code.id).should be_nil
134
+ end
135
+
136
+ it "doesn't include a state in the JSON response" do
137
+ json_from_response.keys.include?("state").should be_false
138
+ end
139
+ end
140
+
141
+ describe "with valid client, code and redirect_uri and an additional state parameter" do
142
+ before :each do
143
+ post "/oauth/access_token", @valid_params.merge(:state => 'some-state-goes-here')
144
+ end
145
+
146
+ it "includes the state in the JSON response" do
147
+ json_from_response["state"].should == 'some-state-goes-here'
148
+ end
149
+ end
150
+
151
+ describe "with an unknown code" do
152
+ before :each do
153
+ post "/oauth/access_token", @valid_params.merge(:code => 'unknown')
154
+ end
155
+
156
+ responds_with_json_error 'invalid_grant', :status => 400
157
+ end
158
+
159
+ describe "with an incorrect redirect uri" do
160
+ before :each do
161
+ post "/oauth/access_token", @valid_params.merge(:redirect_uri => 'https://wrong.example.com')
162
+ end
163
+
164
+ responds_with_json_error 'invalid_grant', :status => 400
165
+ end
166
+
167
+ describe "without a code parameter" do
168
+ before :each do
169
+ post "/oauth/access_token", @valid_params.except(:code)
170
+ end
171
+
172
+ responds_with_json_error 'invalid_request', :status => 400
173
+ end
174
+
175
+ describe "without a redirect_uri parameter" do
176
+ before :each do
177
+ post "/oauth/access_token", @valid_params.except(:redirect_uri)
178
+ end
179
+
180
+ responds_with_json_error 'invalid_request', :status => 400
181
+ end
182
+ end
183
+
184
+ describe "A request using the password grant type" do
185
+ before :each do
186
+ @resource_owner = ExampleResourceOwner.create!(:username => 'name', :password => 'password')
187
+ @valid_params = {
188
+ :grant_type => 'password',
189
+ :client_id => @client.to_param,
190
+ :client_secret => @client.oauth_secret,
191
+ :username => @resource_owner.username,
192
+ :password => @resource_owner.password
193
+ }
194
+ end
195
+
196
+ describe "with valid username and password" do
197
+ before :each do
198
+ post "/oauth/access_token", @valid_params
199
+ end
200
+
201
+ it "responds with access token, refresh token and expiry time in JSON" do
202
+ token = OAuth2::Provider.access_token_class.find_by_access_token(json_from_response["access_token"])
203
+ token.should_not be_nil
204
+ json_from_response["expires_in"].should == token.expires_in
205
+ json_from_response["refresh_token"].should == token.refresh_token
206
+ end
207
+
208
+ it "sets cache-control header to no-store, as response is sensitive" do
209
+ response.headers["Cache-Control"].should =~ /no-store/
210
+ end
211
+
212
+ it "doesn't include a state in the JSON response" do
213
+ json_from_response.keys.include?("state").should be_false
214
+ end
215
+ end
216
+
217
+ describe "with valid username and password and an additional state parameter" do
218
+ before :each do
219
+ post "/oauth/access_token", @valid_params.merge(:state => 'some-state-goes-here')
220
+ end
221
+
222
+ it "includes the state in the JSON response" do
223
+ json_from_response["state"].should == 'some-state-goes-here'
224
+ end
225
+ end
226
+
227
+ describe "with an incorrect username" do
228
+ before :each do
229
+ post "/oauth/access_token", @valid_params.merge(:username => 'wrong')
230
+ end
231
+
232
+ responds_with_json_error 'invalid_grant', :status => 400
233
+ end
234
+
235
+ describe "with an incorrect password" do
236
+ before :each do
237
+ post "/oauth/access_token", @valid_params.merge(:password => 'wrong')
238
+ end
239
+
240
+ responds_with_json_error 'invalid_grant', :status => 400
241
+ end
242
+
243
+ describe "without a username parameter" do
244
+ before :each do
245
+ post "/oauth/access_token", @valid_params.except(:username)
246
+ end
247
+
248
+ responds_with_json_error 'invalid_request', :status => 400
249
+ end
250
+
251
+ describe "without a password parameter" do
252
+ before :each do
253
+ post "/oauth/access_token", @valid_params.except(:password)
254
+ end
255
+
256
+ responds_with_json_error 'invalid_request', :status => 400
257
+ end
258
+ end
259
+
260
+ describe "A request using the refresh token grant type" do
261
+ before :each do
262
+ @token = create_access_token
263
+
264
+ @client = @token.authorization.client
265
+ @valid_params = {
266
+ :grant_type => 'refresh_token',
267
+ :refresh_token => @token.refresh_token,
268
+ :client_id => @client.oauth_identifier,
269
+ :client_secret => @client.oauth_secret
270
+ }
271
+ end
272
+
273
+ describe "with a valid refresh token" do
274
+ before :each do
275
+ post "/oauth/access_token", @valid_params
276
+ end
277
+
278
+ it "responds with refreshed access token, refresh token and expiry time in JSON" do
279
+ token = OAuth2::Provider.access_token_class.find_by_access_token(json_from_response["access_token"])
280
+ token.should_not be_nil
281
+ token.should_not == @token
282
+ json_from_response["expires_in"].should == token.expires_in
283
+ json_from_response["refresh_token"].should == token.refresh_token
284
+ end
285
+ end
286
+
287
+ describe "when the token belongs to a different client" do
288
+ before :each do
289
+ @other_client = OAuth2::Provider.client_class.create! :name => 'client'
290
+ post "/oauth/access_token", @valid_params.merge(:client_id => @other_client.oauth_identifier, :client_secret => @other_client.oauth_secret)
291
+ end
292
+
293
+ responds_with_json_error 'invalid_grant', :status => 400
294
+ end
295
+
296
+ describe "when the token is incorrect" do
297
+ before :each do
298
+ post "/oauth/access_token", @valid_params.merge(:refresh_token => 'incorrect')
299
+ end
300
+
301
+ responds_with_json_error 'invalid_grant', :status => 400
302
+ end
303
+
304
+ describe "without a refresh_token parameter" do
305
+ before :each do
306
+ post "/oauth/access_token", @valid_params.except(:refresh_token)
307
+ end
308
+
309
+ responds_with_json_error 'invalid_request', :status => 400
310
+ end
311
+ end
312
+
313
+ describe "When using a custom client class" do
314
+ before :each do
315
+ @original_client_class_name = OAuth2::Provider.client_class_name
316
+ OAuth2::Provider.client_class_name = "CustomClient"
317
+ @client = CustomClient.create! :name => 'client'
318
+ @client_params = {
319
+ :client_id => @client.to_param,
320
+ :client_secret => @client.oauth_secret,
321
+ }
322
+ end
323
+
324
+ after :each do
325
+ OAuth2::Provider.client_class_name = @original_client_class_name
326
+ end
327
+
328
+ describe "requests using authorization code grant type" do
329
+ before :each do
330
+ @code = create_authorization_code(:authorization => create_authorization(:client => @client))
331
+ @valid_params = @client_params.merge(
332
+ :grant_type => 'authorization_code',
333
+ :code => @code.code,
334
+ :redirect_uri => @code.redirect_uri
335
+ )
336
+ post "/oauth/access_token", @valid_params
337
+ end
338
+
339
+ it "are still successful" do
340
+ response.should be_successful
341
+ end
342
+ end
343
+
344
+ describe "requests using password grant type" do
345
+ before :each do
346
+ @resource_owner = ExampleResourceOwner.create!(:username => 'name', :password => 'password')
347
+ @valid_params = @client_params.merge(
348
+ :grant_type => 'password',
349
+ :username => @resource_owner.username,
350
+ :password => @resource_owner.password
351
+ )
352
+ post "/oauth/access_token", @valid_params
353
+ end
354
+
355
+ it "are still successful" do
356
+ response.should be_successful
357
+ end
358
+ end
359
+ end
360
+ end
@@ -0,0 +1,150 @@
1
+ require 'spec_helper'
2
+
3
+ describe "A request for a protected resource" do
4
+ action do |env|
5
+ env['oauth2'].authenticate_request!(:scope => nil) do
6
+ successful_response
7
+ end
8
+ end
9
+
10
+ before :each do
11
+ @token = create_access_token(
12
+ :authorization => create_authorization(
13
+ :scope => "protected write"
14
+ )
15
+ )
16
+ end
17
+
18
+ describe "with no token passed" do
19
+ before :each do
20
+ get "/protected"
21
+ end
22
+
23
+ responds_with_status 401
24
+ responds_with_header 'WWW-Authenticate', 'OAuth2'
25
+ end
26
+
27
+ describe "with a token passed as an oauth_token parameter" do
28
+ before :each do
29
+ get "/protected", :oauth_token => @token.access_token
30
+ end
31
+
32
+ it "is successful" do
33
+ response.should be_successful
34
+ end
35
+
36
+ it "makes the access token available to the requested action" do
37
+ response.body.should == "Success"
38
+ end
39
+ end
40
+
41
+ describe "with a token passed in an Authorization header" do
42
+ before :each do
43
+ get "/protected", {}, {"HTTP_AUTHORIZATION" => "OAuth #{@token.access_token}"}
44
+ end
45
+
46
+ it "is successful" do
47
+ response.should be_successful
48
+ end
49
+
50
+ it "makes the access token available to the requested action" do
51
+ response.body.should == "Success"
52
+ end
53
+ end
54
+
55
+ describe "with same token passed in both the Authorization header and oauth_token parameter" do
56
+ before :each do
57
+ get "/protected", {:oauth_token => @token.access_token}, {"HTTP_AUTHORIZATION" => "OAuth #{@token.access_token}"}
58
+ end
59
+
60
+ it "is successful" do
61
+ response.should be_successful
62
+ end
63
+
64
+ it "makes the access token available to the requested action" do
65
+ response.body.should == "Success"
66
+ end
67
+ end
68
+
69
+ describe "with different tokens passed in both the Authorization header and oauth_token parameter" do
70
+ before :each do
71
+ get "/protected", {:oauth_token => @token.access_token}, {"HTTP_AUTHORIZATION" => "OAuth DifferentToken"}
72
+ end
73
+
74
+ responds_with_json_error 'invalid_request', :description => 'both authorization header and oauth_token provided, with conflicting tokens', :status => 400
75
+ end
76
+
77
+ describe "with an invalid token" do
78
+ before :each do
79
+ get "/protected", :oauth_token => 'invalid-token'
80
+ end
81
+
82
+ responds_with_status 401
83
+ responds_with_header 'WWW-Authenticate', 'OAuth2 error="invalid_token"'
84
+ end
85
+
86
+ describe "with an expired token that can be refreshed" do
87
+ before :each do
88
+ @token.update_attributes(:expires_at => 1.day.ago)
89
+ get "/protected", :oauth_token => @token.access_token
90
+ end
91
+
92
+ responds_with_status 401
93
+ responds_with_header 'WWW-Authenticate', 'OAuth2 error="invalid_token"'
94
+ end
95
+
96
+ describe "with an expired token that can't be refreshed" do
97
+ before :each do
98
+ @token.update_attributes(:expires_at => 1.day.ago, :refresh_token => nil)
99
+ get "/protected", :oauth_token => @token.access_token
100
+ end
101
+
102
+ responds_with_status 401
103
+ responds_with_header 'WWW-Authenticate', 'OAuth2 error="invalid_token"'
104
+ end
105
+
106
+ describe "when warden is part of the stack" do
107
+ it "bypasses warden when no token is passed" do
108
+ warden = "warden"
109
+ warden.should_receive(:custom_failure!)
110
+ get "/protected", {}, {'warden' => warden}
111
+ end
112
+
113
+ it "bypasses warden when token invalid" do
114
+ warden = "warden"
115
+ warden.should_receive(:custom_failure!)
116
+ get "/protected", {:oauth_token => 'invalid_token'}, {'warden' => warden}
117
+ end
118
+ end
119
+ end
120
+
121
+ describe "A request for a protected resource requiring a specific scope" do
122
+ action do |env|
123
+ env['oauth2'].authenticate_request!(:scope => 'omnipotent') do
124
+ successful_response
125
+ end
126
+ end
127
+
128
+ before :each do
129
+ @token = create_access_token(:authorization => create_authorization(:scope => "omnipotent admin"))
130
+ @insufficient_token = create_access_token(:authorization => create_authorization(:scope => "impotent admin"))
131
+ end
132
+
133
+ describe "made with a token with sufficient scope" do
134
+ before :each do
135
+ get '/protected_by_scope', :oauth_token => @token.access_token
136
+ end
137
+
138
+ it "is successful" do
139
+ response.should be_successful
140
+ end
141
+ end
142
+
143
+ describe "made with a token with insufficient scope" do
144
+ before :each do
145
+ get '/protected_by_scope', :oauth_token => @insufficient_token.access_token
146
+ end
147
+
148
+ responds_with_json_error 'insufficient_scope', :status => 403
149
+ end
150
+ end