doorkeeper 4.4.3 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of doorkeeper might be problematic. Click here for more details.

Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitlab-ci.yml +16 -0
  4. data/.travis.yml +2 -0
  5. data/Appraisals +2 -2
  6. data/Gemfile +1 -1
  7. data/NEWS.md +61 -8
  8. data/README.md +92 -9
  9. data/Rakefile +6 -0
  10. data/UPGRADE.md +2 -0
  11. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  12. data/app/controllers/doorkeeper/application_controller.rb +4 -3
  13. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -0
  14. data/app/controllers/doorkeeper/applications_controller.rb +42 -22
  15. data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
  16. data/app/controllers/doorkeeper/authorized_applications_controller.rb +19 -2
  17. data/app/controllers/doorkeeper/tokens_controller.rb +2 -6
  18. data/app/helpers/doorkeeper/dashboard_helper.rb +7 -7
  19. data/app/validators/redirect_uri_validator.rb +3 -2
  20. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  21. data/app/views/doorkeeper/applications/_form.html.erb +25 -24
  22. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  23. data/app/views/doorkeeper/applications/index.html.erb +17 -7
  24. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  25. data/app/views/doorkeeper/applications/show.html.erb +6 -6
  26. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  27. data/app/views/doorkeeper/authorizations/new.html.erb +4 -0
  28. data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
  29. data/config/locales/en.yml +10 -1
  30. data/doorkeeper.gemspec +18 -20
  31. data/gemfiles/rails_5_2.gemfile +1 -1
  32. data/gemfiles/rails_master.gemfile +4 -1
  33. data/lib/doorkeeper/config.rb +75 -39
  34. data/lib/doorkeeper/engine.rb +4 -0
  35. data/lib/doorkeeper/errors.rb +2 -5
  36. data/lib/doorkeeper/grape/helpers.rb +1 -1
  37. data/lib/doorkeeper/helpers/controller.rb +7 -2
  38. data/lib/doorkeeper/models/access_grant_mixin.rb +71 -0
  39. data/lib/doorkeeper/models/access_token_mixin.rb +39 -22
  40. data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
  41. data/lib/doorkeeper/oauth/authorization/code.rb +31 -8
  42. data/lib/doorkeeper/oauth/authorization/context.rb +15 -0
  43. data/lib/doorkeeper/oauth/authorization/token.rb +36 -14
  44. data/lib/doorkeeper/oauth/authorization_code_request.rb +27 -2
  45. data/lib/doorkeeper/oauth/base_request.rb +20 -9
  46. data/lib/doorkeeper/oauth/client/credentials.rb +1 -1
  47. data/lib/doorkeeper/oauth/client.rb +0 -2
  48. data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -1
  49. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +6 -3
  50. data/lib/doorkeeper/oauth/client_credentials/validation.rb +4 -6
  51. data/lib/doorkeeper/oauth/client_credentials_request.rb +0 -4
  52. data/lib/doorkeeper/oauth/error_response.rb +11 -3
  53. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +0 -8
  54. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -4
  55. data/lib/doorkeeper/oauth/pre_authorization.rb +41 -11
  56. data/lib/doorkeeper/oauth/refresh_token_request.rb +6 -1
  57. data/lib/doorkeeper/oauth/scopes.rb +1 -1
  58. data/lib/doorkeeper/oauth/token.rb +5 -2
  59. data/lib/doorkeeper/oauth/token_introspection.rb +2 -2
  60. data/lib/doorkeeper/oauth/token_response.rb +4 -2
  61. data/lib/doorkeeper/oauth.rb +13 -0
  62. data/lib/doorkeeper/orm/active_record/application.rb +22 -14
  63. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
  64. data/lib/doorkeeper/orm/active_record.rb +2 -0
  65. data/lib/doorkeeper/rails/helpers.rb +2 -4
  66. data/lib/doorkeeper/rails/routes.rb +14 -6
  67. data/lib/doorkeeper/rake/db.rake +40 -0
  68. data/lib/doorkeeper/rake/setup.rake +6 -0
  69. data/lib/doorkeeper/rake.rb +14 -0
  70. data/lib/doorkeeper/request/authorization_code.rb +0 -2
  71. data/lib/doorkeeper/request/client_credentials.rb +0 -2
  72. data/lib/doorkeeper/request/code.rb +0 -2
  73. data/lib/doorkeeper/request/password.rb +0 -2
  74. data/lib/doorkeeper/request/refresh_token.rb +0 -2
  75. data/lib/doorkeeper/request/token.rb +0 -2
  76. data/lib/doorkeeper/request.rb +28 -35
  77. data/lib/doorkeeper/version.rb +5 -25
  78. data/lib/doorkeeper.rb +19 -17
  79. data/lib/generators/doorkeeper/application_owner_generator.rb +23 -18
  80. data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
  81. data/lib/generators/doorkeeper/install_generator.rb +17 -9
  82. data/lib/generators/doorkeeper/migration_generator.rb +23 -18
  83. data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
  84. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -24
  85. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  86. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
  87. data/lib/generators/doorkeeper/templates/initializer.rb +76 -11
  88. data/lib/generators/doorkeeper/views_generator.rb +3 -1
  89. data/spec/controllers/application_metal_controller_spec.rb +50 -0
  90. data/spec/controllers/applications_controller_spec.rb +126 -13
  91. data/spec/controllers/authorizations_controller_spec.rb +277 -47
  92. data/spec/controllers/protected_resources_controller_spec.rb +16 -16
  93. data/spec/controllers/token_info_controller_spec.rb +4 -12
  94. data/spec/controllers/tokens_controller_spec.rb +13 -15
  95. data/spec/dummy/app/assets/config/manifest.js +2 -0
  96. data/spec/dummy/config/environments/test.rb +4 -5
  97. data/spec/dummy/config/initializers/doorkeeper.rb +10 -5
  98. data/spec/dummy/config/initializers/new_framework_defaults.rb +4 -0
  99. data/spec/dummy/config/routes.rb +3 -42
  100. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
  101. data/spec/dummy/db/migrate/{20180210183654_add_confidential_to_application.rb → 20180210183654_add_confidential_to_applications.rb} +1 -1
  102. data/spec/dummy/db/schema.rb +36 -36
  103. data/spec/generators/application_owner_generator_spec.rb +1 -1
  104. data/spec/generators/confidential_applications_generator_spec.rb +45 -0
  105. data/spec/generators/install_generator_spec.rb +1 -1
  106. data/spec/generators/migration_generator_spec.rb +1 -1
  107. data/spec/generators/pkce_generator_spec.rb +43 -0
  108. data/spec/generators/previous_refresh_token_generator_spec.rb +1 -1
  109. data/spec/generators/views_generator_spec.rb +1 -1
  110. data/spec/grape/grape_integration_spec.rb +1 -1
  111. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  112. data/spec/lib/config_spec.rb +80 -31
  113. data/spec/lib/doorkeeper_spec.rb +1 -126
  114. data/spec/lib/models/expirable_spec.rb +0 -3
  115. data/spec/lib/models/revocable_spec.rb +0 -2
  116. data/spec/lib/models/scopes_spec.rb +0 -4
  117. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
  118. data/spec/lib/oauth/authorization_code_request_spec.rb +9 -2
  119. data/spec/lib/oauth/base_request_spec.rb +40 -2
  120. data/spec/lib/oauth/base_response_spec.rb +1 -1
  121. data/spec/lib/oauth/client/credentials_spec.rb +1 -3
  122. data/spec/lib/oauth/client_credentials/creator_spec.rb +5 -1
  123. data/spec/lib/oauth/client_credentials/issuer_spec.rb +26 -7
  124. data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -3
  125. data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
  126. data/spec/lib/oauth/client_credentials_request_spec.rb +3 -5
  127. data/spec/lib/oauth/client_spec.rb +0 -3
  128. data/spec/lib/oauth/code_request_spec.rb +4 -2
  129. data/spec/lib/oauth/error_response_spec.rb +0 -3
  130. data/spec/lib/oauth/error_spec.rb +0 -2
  131. data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
  132. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -3
  133. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
  134. data/spec/lib/oauth/helpers/uri_checker_spec.rb +5 -7
  135. data/spec/lib/oauth/invalid_token_response_spec.rb +1 -4
  136. data/spec/lib/oauth/password_access_token_request_spec.rb +37 -2
  137. data/spec/lib/oauth/pre_authorization_spec.rb +33 -4
  138. data/spec/lib/oauth/refresh_token_request_spec.rb +11 -7
  139. data/spec/lib/oauth/scopes_spec.rb +0 -3
  140. data/spec/lib/oauth/token_request_spec.rb +4 -5
  141. data/spec/lib/oauth/token_response_spec.rb +0 -1
  142. data/spec/lib/oauth/token_spec.rb +37 -14
  143. data/spec/lib/orm/active_record/stale_records_cleaner_spec.rb +79 -0
  144. data/spec/lib/request/strategy_spec.rb +0 -1
  145. data/spec/lib/server_spec.rb +1 -1
  146. data/spec/models/doorkeeper/access_grant_spec.rb +44 -1
  147. data/spec/models/doorkeeper/access_token_spec.rb +66 -22
  148. data/spec/models/doorkeeper/application_spec.rb +14 -47
  149. data/spec/requests/applications/applications_request_spec.rb +134 -1
  150. data/spec/requests/applications/authorized_applications_spec.rb +1 -1
  151. data/spec/requests/endpoints/authorization_spec.rb +1 -1
  152. data/spec/requests/endpoints/token_spec.rb +7 -5
  153. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -1
  154. data/spec/requests/flows/authorization_code_spec.rb +197 -1
  155. data/spec/requests/flows/client_credentials_spec.rb +46 -6
  156. data/spec/requests/flows/implicit_grant_errors_spec.rb +1 -1
  157. data/spec/requests/flows/implicit_grant_spec.rb +38 -11
  158. data/spec/requests/flows/password_spec.rb +56 -2
  159. data/spec/requests/flows/refresh_token_spec.rb +2 -2
  160. data/spec/requests/flows/revoke_token_spec.rb +11 -11
  161. data/spec/requests/flows/skip_authorization_spec.rb +16 -11
  162. data/spec/requests/protected_resources/metal_spec.rb +1 -1
  163. data/spec/requests/protected_resources/private_api_spec.rb +1 -1
  164. data/spec/routing/custom_controller_routes_spec.rb +59 -7
  165. data/spec/routing/default_routes_spec.rb +2 -2
  166. data/spec/routing/scoped_routes_spec.rb +16 -2
  167. data/spec/spec_helper.rb +54 -3
  168. data/spec/spec_helper_integration.rb +2 -74
  169. data/spec/support/dependencies/{factory_girl.rb → factory_bot.rb} +0 -0
  170. data/spec/support/doorkeeper_rspec.rb +19 -0
  171. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  172. data/spec/support/helpers/request_spec_helper.rb +10 -2
  173. data/spec/support/helpers/url_helper.rb +7 -3
  174. data/spec/support/http_method_shim.rb +12 -16
  175. data/spec/validators/redirect_uri_validator_spec.rb +7 -1
  176. data/spec/version/version_spec.rb +3 -3
  177. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  178. metadata +37 -33
  179. data/lib/generators/doorkeeper/add_client_confidentiality_generator.rb +0 -31
  180. data/lib/generators/doorkeeper/templates/add_confidential_to_application_migration.rb.erb +0 -11
  181. data/spec/controllers/application_metal_controller.rb +0 -10
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper
4
4
  describe AccessToken do
@@ -144,7 +144,7 @@ module Doorkeeper
144
144
  end
145
145
 
146
146
  module CustomGeneratorArgs
147
- def self.generate(opts = {})
147
+ def self.generate(_opts = {})
148
148
  raise LoadError, 'custom behaviour'
149
149
  end
150
150
  end
@@ -218,7 +218,7 @@ module Doorkeeper
218
218
  context 'with default parameters' do
219
219
 
220
220
  let(:resource_owner_id) { 100 }
221
- let(:application) { FactoryBot.create :application }
221
+ let(:application) { FactoryBot.create :application }
222
222
  let(:default_attributes) do
223
223
  { application: application, resource_owner_id: resource_owner_id }
224
224
  end
@@ -306,15 +306,25 @@ module Doorkeeper
306
306
  end
307
307
 
308
308
  it 'matches application' do
309
- FactoryBot.create :access_token, default_attributes.merge(application: FactoryBot.create(:application))
309
+ access_token_for_different_app = FactoryBot.create(
310
+ :access_token,
311
+ default_attributes.merge(application: FactoryBot.create(:application))
312
+ )
313
+
310
314
  AccessToken.revoke_all_for application.id, resource_owner
311
- expect(AccessToken.all).not_to be_empty
315
+
316
+ expect(access_token_for_different_app.reload).not_to be_revoked
312
317
  end
313
318
 
314
319
  it 'matches resource owner' do
315
- FactoryBot.create :access_token, default_attributes.merge(resource_owner_id: 90)
320
+ access_token_for_different_owner = FactoryBot.create(
321
+ :access_token,
322
+ default_attributes.merge(resource_owner_id: 90)
323
+ )
324
+
316
325
  AccessToken.revoke_all_for application.id, resource_owner
317
- expect(AccessToken.all).not_to be_empty
326
+
327
+ expect(access_token_for_different_owner.reload).not_to be_revoked
318
328
  end
319
329
  end
320
330
 
@@ -330,6 +340,10 @@ module Doorkeeper
330
340
  }
331
341
  end
332
342
 
343
+ before do
344
+ default_scopes_exist(*scopes.all)
345
+ end
346
+
333
347
  it 'returns only one token' do
334
348
  token = FactoryBot.create :access_token, default_attributes
335
349
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
@@ -355,37 +369,45 @@ module Doorkeeper
355
369
  expect(last_token).to be_nil
356
370
  end
357
371
 
358
- it 'matches the application' do
372
+ it "excludes tokens with a different application" do
359
373
  FactoryBot.create :access_token, default_attributes.merge(application: FactoryBot.create(:application))
360
374
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
361
375
  expect(last_token).to be_nil
362
376
  end
363
377
 
364
- it 'matches the resource owner' do
378
+ it "excludes tokens with a different resource owner" do
365
379
  FactoryBot.create :access_token, default_attributes.merge(resource_owner_id: 2)
366
380
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
367
381
  expect(last_token).to be_nil
368
382
  end
369
383
 
370
- it 'matches token with fewer scopes' do
384
+ it "excludes tokens with fewer scopes" do
371
385
  FactoryBot.create :access_token, default_attributes.merge(scopes: 'public')
372
386
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
373
387
  expect(last_token).to be_nil
374
388
  end
375
389
 
376
- it 'matches token with different scopes' do
390
+ it 'excludes tokens with different scopes' do
377
391
  FactoryBot.create :access_token, default_attributes.merge(scopes: 'public email')
378
392
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
379
393
  expect(last_token).to be_nil
380
394
  end
381
395
 
382
- it 'matches token with more scopes' do
396
+ it 'excludes tokens with additional scopes' do
383
397
  FactoryBot.create :access_token, default_attributes.merge(scopes: 'public write email')
384
398
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
385
399
  expect(last_token).to be_nil
386
400
  end
387
401
 
388
- it 'matches application scopes' do
402
+ it 'excludes tokens with scopes that are not present in server scopes' do
403
+ FactoryBot.create :access_token, default_attributes.merge(
404
+ application: application, scopes: 'public read'
405
+ )
406
+ last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
407
+ expect(last_token).to be_nil
408
+ end
409
+
410
+ it 'excludes tokens with scopes that are not present in application scopes' do
389
411
  application = FactoryBot.create :application, scopes: "private read"
390
412
  FactoryBot.create :access_token, default_attributes.merge(
391
413
  application: application
@@ -394,25 +416,47 @@ module Doorkeeper
394
416
  expect(last_token).to be_nil
395
417
  end
396
418
 
397
- it 'returns the last created token' do
419
+ it 'does not match token if empty scope requested and token/app scopes present' do
420
+ application = FactoryBot.create :application, scopes: "sample:scope"
421
+ app_params = {
422
+ application_id: application.id, scopes: "sample:scope",
423
+ resource_owner_id: 100
424
+ }
425
+ FactoryBot.create :access_token, app_params
426
+ empty_scopes = Doorkeeper::OAuth::Scopes.from_string("")
427
+ last_token = AccessToken.matching_token_for(application, 100, empty_scopes)
428
+ expect(last_token).to be_nil
429
+ end
430
+
431
+ it 'matches token if empty scope requested and no token scopes present' do
432
+ empty_scopes = Doorkeeper::OAuth::Scopes.from_string("")
433
+ token = FactoryBot.create :access_token, default_attributes.merge(scopes: empty_scopes)
434
+ last_token = AccessToken.matching_token_for(application, 100, empty_scopes)
435
+ expect(last_token).to eq(token)
436
+ end
437
+
438
+ it 'returns the last matching token' do
398
439
  FactoryBot.create :access_token, default_attributes.merge(created_at: 1.day.ago)
399
- token = FactoryBot.create :access_token, default_attributes
440
+ matching_token = FactoryBot.create :access_token, default_attributes
441
+ FactoryBot.create :access_token, default_attributes.merge(scopes: 'public')
442
+
400
443
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
401
- expect(last_token).to eq(token)
444
+ expect(last_token).to eq(matching_token)
402
445
  end
446
+ end
403
447
 
404
- it 'returns as_json hash' do
405
- token = FactoryBot.create :access_token, default_attributes
448
+ describe "#as_json" do
449
+ it "returns as_json hash" do
450
+ token = FactoryBot.create :access_token
406
451
  token_hash = {
407
452
  resource_owner_id: token.resource_owner_id,
408
- scopes: token.scopes,
409
- expires_in_seconds: token.expires_in_seconds,
453
+ scope: token.scopes,
454
+ expires_in: token.expires_in_seconds,
410
455
  application: { uid: token.application.uid },
411
- created_at: token.created_at.to_i,
456
+ created_at: token.created_at.to_i
412
457
  }
413
458
  expect(token.as_json).to eq token_hash
414
459
  end
415
460
  end
416
-
417
461
  end
418
462
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module Doorkeeper
4
4
  describe Application do
@@ -206,6 +206,19 @@ module Doorkeeper
206
206
  end
207
207
  end
208
208
 
209
+ describe :revoke_tokens_and_grants_for do
210
+ it 'revokes all access tokens and access grants' do
211
+ application_id = 42
212
+ resource_owner = double
213
+ expect(Doorkeeper::AccessToken).
214
+ to receive(:revoke_all_for).with(application_id, resource_owner)
215
+ expect(Doorkeeper::AccessGrant).
216
+ to receive(:revoke_all_for).with(application_id, resource_owner)
217
+
218
+ Application.revoke_tokens_and_grants_for(application_id, resource_owner)
219
+ end
220
+ end
221
+
209
222
  describe :by_uid_and_secret do
210
223
  context "when application is private/confidential" do
211
224
  it "finds the application via uid/secret" do
@@ -253,51 +266,5 @@ module Doorkeeper
253
266
  it { expect(subject).to eq(false) }
254
267
  end
255
268
  end
256
-
257
- describe :confidential do
258
- subject { FactoryBot.create(:application, confidential: confidential).confidential }
259
-
260
- context 'when application is private/confidential' do
261
- let(:confidential) { true }
262
- it { expect(subject).to eq(true) }
263
- end
264
-
265
- context 'when application is public/non-confidential' do
266
- let(:confidential) { false }
267
- it { expect(subject).to eq(false) }
268
- end
269
-
270
- context 'when the application does not support confidentiality' do
271
- let(:confidential) { false }
272
-
273
- before { allow(Application).to receive(:supports_confidentiality?).and_return(false) }
274
-
275
- it 'warns of the CVE' do
276
- expect(ActiveSupport::Deprecation).to receive(:warn).with(
277
- 'You are susceptible to security bug ' \
278
- 'CVE-2018-1000211. Please follow instructions outlined in ' \
279
- 'Doorkeeper::CVE_2018_1000211_WARNING'
280
- )
281
- Application.new.confidential
282
- end
283
-
284
- it { expect(subject).to eq(true) }
285
- end
286
- end
287
-
288
- describe :supports_confidentiality? do
289
- context 'when no column' do
290
- it 'returns false' do
291
- expect(Application).to receive(:column_names).and_return(%w[foo bar])
292
- expect(Application.supports_confidentiality?).to eq(false)
293
- end
294
- end
295
- context 'when column' do
296
- it 'returns true' do
297
- expect(Application).to receive(:column_names).and_return(%w[foo bar confidential])
298
- expect(Application.supports_confidentiality?).to eq(true)
299
- end
300
- end
301
- end
302
269
  end
303
270
  end
@@ -1,8 +1,9 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  feature 'Adding applications' do
4
4
  context 'in application form' do
5
5
  background do
6
+ i_am_logged_in
6
7
  visit '/oauth/applications/new'
7
8
  end
8
9
 
@@ -20,29 +21,123 @@ feature 'Adding applications' do
20
21
  click_button 'Submit'
21
22
  i_should_see 'Whoops! Check your form for possible errors'
22
23
  end
24
+
25
+ scenario "adding app ignoring bad scope" do
26
+ config_is_set("enforce_configured_scopes", false)
27
+
28
+ fill_in "doorkeeper_application[name]", with: "My Application"
29
+ fill_in "doorkeeper_application[redirect_uri]",
30
+ with: "https://example.com"
31
+ fill_in "doorkeeper_application[scopes]", with: "blahblah"
32
+
33
+ click_button "Submit"
34
+ i_should_see "Application created"
35
+ i_should_see "My Application"
36
+ end
37
+
38
+ scenario "adding app validating bad scope" do
39
+ config_is_set("enforce_configured_scopes", true)
40
+
41
+ fill_in "doorkeeper_application[name]", with: "My Application"
42
+ fill_in "doorkeeper_application[redirect_uri]",
43
+ with: "https://example.com"
44
+ fill_in "doorkeeper_application[scopes]", with: "blahblah"
45
+
46
+ click_button "Submit"
47
+ i_should_see "Whoops! Check your form for possible errors"
48
+ end
49
+
50
+ scenario "adding app validating scope, blank scope is accepted" do
51
+ config_is_set("enforce_configured_scopes", true)
52
+
53
+ fill_in "doorkeeper_application[name]", with: "My Application"
54
+ fill_in "doorkeeper_application[redirect_uri]",
55
+ with: "https://example.com"
56
+ fill_in "doorkeeper_application[scopes]", with: ""
57
+
58
+ click_button "Submit"
59
+ i_should_see "Application created"
60
+ i_should_see "My Application"
61
+ end
62
+
63
+ scenario "adding app validating scope, multiple scopes configured" do
64
+ config_is_set("enforce_configured_scopes", true)
65
+ scopes = Doorkeeper::OAuth::Scopes.from_array(%w(read write admin))
66
+ config_is_set("optional_scopes", scopes)
67
+
68
+ fill_in "doorkeeper_application[name]", with: "My Application"
69
+ fill_in "doorkeeper_application[redirect_uri]",
70
+ with: "https://example.com"
71
+ fill_in "doorkeeper_application[scopes]", with: "read write"
72
+
73
+ click_button "Submit"
74
+ i_should_see "Application created"
75
+ i_should_see "My Application"
76
+ end
77
+
78
+ scenario "adding app validating scope, bad scope with multiple scopes configured" do
79
+ config_is_set("enforce_configured_scopes", true)
80
+ scopes = Doorkeeper::OAuth::Scopes.from_array(%w(read write admin))
81
+ config_is_set("optional_scopes", scopes)
82
+
83
+ fill_in "doorkeeper_application[name]", with: "My Application"
84
+ fill_in "doorkeeper_application[redirect_uri]",
85
+ with: "https://example.com"
86
+ fill_in "doorkeeper_application[scopes]", with: "read blah"
87
+
88
+ click_button "Submit"
89
+ i_should_see "Whoops! Check your form for possible errors"
90
+ i_should_see Regexp.new(
91
+ I18n.t('activerecord.errors.models.doorkeeper/application.attributes.scopes.not_match_configured'),
92
+ true
93
+ )
94
+ end
23
95
  end
24
96
  end
25
97
 
26
98
  feature 'Listing applications' do
27
99
  background do
100
+ i_am_logged_in
101
+
28
102
  FactoryBot.create :application, name: 'Oauth Dude'
29
103
  FactoryBot.create :application, name: 'Awesome App'
30
104
  end
31
105
 
32
106
  scenario 'application list' do
33
107
  visit '/oauth/applications'
108
+
34
109
  i_should_see 'Awesome App'
35
110
  i_should_see 'Oauth Dude'
36
111
  end
37
112
  end
38
113
 
114
+ feature 'Renders assets' do
115
+ scenario 'admin stylesheets' do
116
+ visit '/assets/doorkeeper/admin/application.css'
117
+
118
+ i_should_see 'Bootstrap'
119
+ i_should_see '.doorkeeper-admin'
120
+ end
121
+
122
+ scenario 'application stylesheets' do
123
+ visit '/assets/doorkeeper/application.css'
124
+
125
+ i_should_see 'Bootstrap'
126
+ i_should_see '#oauth-permissions'
127
+ i_should_see '#container'
128
+ end
129
+ end
130
+
39
131
  feature 'Show application' do
40
132
  given :app do
133
+ i_am_logged_in
134
+
41
135
  FactoryBot.create :application, name: 'Just another oauth app'
42
136
  end
43
137
 
44
138
  scenario 'visiting application page' do
45
139
  visit "/oauth/applications/#{app.id}"
140
+
46
141
  i_should_see 'Just another oauth app'
47
142
  end
48
143
  end
@@ -53,12 +148,15 @@ feature 'Edit application' do
53
148
  end
54
149
 
55
150
  background do
151
+ i_am_logged_in
152
+
56
153
  visit "/oauth/applications/#{app.id}/edit"
57
154
  end
58
155
 
59
156
  scenario 'updating a valid app' do
60
157
  fill_in 'doorkeeper_application[name]', with: 'Serious app'
61
158
  click_button 'Submit'
159
+
62
160
  i_should_see 'Application updated'
63
161
  i_should_see 'Serious app'
64
162
  i_should_not_see 'OMG my app'
@@ -67,21 +165,27 @@ feature 'Edit application' do
67
165
  scenario 'updating an invalid app' do
68
166
  fill_in 'doorkeeper_application[name]', with: ''
69
167
  click_button 'Submit'
168
+
70
169
  i_should_see 'Whoops! Check your form for possible errors'
71
170
  end
72
171
  end
73
172
 
74
173
  feature 'Remove application' do
75
174
  background do
175
+ i_am_logged_in
176
+
76
177
  @app = FactoryBot.create :application
77
178
  end
78
179
 
79
180
  scenario 'deleting an application from list' do
80
181
  visit '/oauth/applications'
182
+
81
183
  i_should_see @app.name
184
+
82
185
  within(:css, "tr#application_#{@app.id}") do
83
186
  click_button 'Destroy'
84
187
  end
188
+
85
189
  i_should_see 'Application deleted'
86
190
  i_should_not_see @app.name
87
191
  end
@@ -89,6 +193,35 @@ feature 'Remove application' do
89
193
  scenario 'deleting an application from show' do
90
194
  visit "/oauth/applications/#{@app.id}"
91
195
  click_button 'Destroy'
196
+
92
197
  i_should_see 'Application deleted'
93
198
  end
94
199
  end
200
+
201
+ context 'when admin authenticator block is default' do
202
+ let(:app) { FactoryBot.create :application, name: 'app' }
203
+
204
+ feature 'application list' do
205
+ scenario 'fails with forbidden' do
206
+ visit '/oauth/applications'
207
+
208
+ should_have_status 403
209
+ end
210
+ end
211
+
212
+ feature 'adding an app' do
213
+ scenario 'fails with forbidden' do
214
+ visit '/oauth/applications/new'
215
+
216
+ should_have_status 403
217
+ end
218
+ end
219
+
220
+ feature 'editing an app' do
221
+ scenario 'fails with forbidden' do
222
+ visit "/oauth/applications/#{app.id}/edit"
223
+
224
+ should_have_status 403
225
+ end
226
+ end
227
+ end
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  feature 'Authorized applications' do
4
4
  background do
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  feature 'Authorization endpoint' do
4
4
  background do
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe 'Token endpoint' do
4
4
  before do
@@ -21,10 +21,12 @@ describe 'Token endpoint' do
21
21
  end
22
22
 
23
23
  it 'accepts client credentials with basic auth header' do
24
- post token_endpoint_url(
25
- code: @authorization.token,
26
- redirect_uri: @client.redirect_uri
27
- ), {}, 'HTTP_AUTHORIZATION' => basic_auth_header_for_client(@client)
24
+ post token_endpoint_url,
25
+ params: {
26
+ code: @authorization.token,
27
+ redirect_uri: @client.redirect_uri
28
+ },
29
+ headers: { 'HTTP_AUTHORIZATION' => basic_auth_header_for_client(@client) }
28
30
 
29
31
  should_have_json 'access_token', Doorkeeper::AccessToken.first.token
30
32
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  feature 'Authorization Code Flow Errors' do
4
4
  let(:client_params) { {} }