doorkeeper 5.2.0 → 5.3.0

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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +2 -2
  3. data/CHANGELOG.md +40 -2
  4. data/Gemfile +2 -2
  5. data/app/controllers/doorkeeper/application_controller.rb +2 -2
  6. data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
  7. data/app/controllers/doorkeeper/applications_controller.rb +0 -1
  8. data/app/controllers/doorkeeper/authorizations_controller.rb +2 -2
  9. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  10. data/config/locales/en.yml +1 -1
  11. data/gemfiles/rails_5_0.gemfile +2 -2
  12. data/gemfiles/rails_5_1.gemfile +2 -2
  13. data/gemfiles/rails_5_2.gemfile +2 -2
  14. data/gemfiles/rails_6_0.gemfile +2 -2
  15. data/gemfiles/rails_master.gemfile +2 -2
  16. data/lib/doorkeeper/config.rb +71 -38
  17. data/lib/doorkeeper/grape/helpers.rb +1 -1
  18. data/lib/doorkeeper/helpers/controller.rb +12 -8
  19. data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
  20. data/lib/doorkeeper/models/access_token_mixin.rb +56 -18
  21. data/lib/doorkeeper/models/application_mixin.rb +3 -3
  22. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  23. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  24. data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
  25. data/lib/doorkeeper/oauth/authorization/code.rb +4 -4
  26. data/lib/doorkeeper/oauth/authorization/token.rb +9 -6
  27. data/lib/doorkeeper/oauth/authorization_code_request.rb +13 -6
  28. data/lib/doorkeeper/oauth/base_request.rb +8 -4
  29. data/lib/doorkeeper/oauth/client.rb +7 -8
  30. data/lib/doorkeeper/oauth/client_credentials/creator.rb +16 -9
  31. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
  32. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +4 -4
  33. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
  34. data/lib/doorkeeper/oauth/code_response.rb +2 -2
  35. data/lib/doorkeeper/oauth/error.rb +1 -1
  36. data/lib/doorkeeper/oauth/error_response.rb +5 -5
  37. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
  38. data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
  39. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -1
  40. data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
  41. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
  42. data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -3
  43. data/lib/doorkeeper/oauth/pre_authorization.rb +12 -7
  44. data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -5
  45. data/lib/doorkeeper/oauth/token.rb +2 -2
  46. data/lib/doorkeeper/oauth/token_introspection.rb +6 -6
  47. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  48. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  49. data/lib/doorkeeper/orm/active_record/application.rb +5 -89
  50. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
  51. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
  52. data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
  53. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +3 -3
  54. data/lib/doorkeeper/orm/active_record.rb +3 -4
  55. data/lib/doorkeeper/rails/helpers.rb +4 -4
  56. data/lib/doorkeeper/rails/routes.rb +5 -7
  57. data/lib/doorkeeper/rake/db.rake +3 -3
  58. data/lib/doorkeeper/request/authorization_code.rb +3 -3
  59. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  60. data/lib/doorkeeper/request/password.rb +2 -2
  61. data/lib/doorkeeper/request/refresh_token.rb +3 -3
  62. data/lib/doorkeeper/request.rb +1 -1
  63. data/lib/doorkeeper/server.rb +1 -1
  64. data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
  65. data/lib/doorkeeper/version.rb +1 -1
  66. data/lib/doorkeeper.rb +2 -3
  67. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  68. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  69. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  70. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  71. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
  72. data/lib/generators/doorkeeper/templates/initializer.rb +39 -0
  73. data/spec/controllers/application_metal_controller_spec.rb +1 -1
  74. data/spec/controllers/applications_controller_spec.rb +3 -2
  75. data/spec/controllers/authorizations_controller_spec.rb +20 -18
  76. data/spec/controllers/protected_resources_controller_spec.rb +25 -17
  77. data/spec/controllers/token_info_controller_spec.rb +1 -1
  78. data/spec/controllers/tokens_controller_spec.rb +1 -1
  79. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
  80. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
  81. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
  82. data/spec/generators/install_generator_spec.rb +1 -1
  83. data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
  84. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  85. data/spec/lib/config_spec.rb +62 -7
  86. data/spec/lib/doorkeeper_spec.rb +1 -1
  87. data/spec/lib/models/revocable_spec.rb +3 -3
  88. data/spec/lib/oauth/authorization_code_request_spec.rb +127 -123
  89. data/spec/lib/oauth/base_request_spec.rb +160 -158
  90. data/spec/lib/oauth/base_response_spec.rb +27 -29
  91. data/spec/lib/oauth/client/credentials_spec.rb +1 -1
  92. data/spec/lib/oauth/client_credentials/creator_spec.rb +42 -5
  93. data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
  94. data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
  95. data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
  96. data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
  97. data/spec/lib/oauth/client_spec.rb +26 -26
  98. data/spec/lib/oauth/code_request_spec.rb +34 -34
  99. data/spec/lib/oauth/code_response_spec.rb +21 -25
  100. data/spec/lib/oauth/error_response_spec.rb +42 -44
  101. data/spec/lib/oauth/error_spec.rb +12 -14
  102. data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
  103. data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
  104. data/spec/lib/oauth/invalid_request_response_spec.rb +48 -50
  105. data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
  106. data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
  107. data/spec/lib/oauth/pre_authorization_spec.rb +159 -161
  108. data/spec/lib/oauth/refresh_token_request_spec.rb +138 -139
  109. data/spec/lib/oauth/scopes_spec.rb +104 -106
  110. data/spec/lib/oauth/token_request_spec.rb +115 -111
  111. data/spec/lib/oauth/token_response_spec.rb +71 -73
  112. data/spec/lib/oauth/token_spec.rb +121 -123
  113. data/spec/models/doorkeeper/access_grant_spec.rb +21 -4
  114. data/spec/models/doorkeeper/access_token_spec.rb +42 -11
  115. data/spec/models/doorkeeper/application_spec.rb +114 -77
  116. data/spec/requests/applications/applications_request_spec.rb +1 -1
  117. data/spec/requests/endpoints/authorization_spec.rb +5 -3
  118. data/spec/requests/flows/authorization_code_spec.rb +34 -22
  119. data/spec/requests/flows/client_credentials_spec.rb +1 -1
  120. data/spec/requests/flows/password_spec.rb +32 -12
  121. data/spec/requests/flows/refresh_token_spec.rb +19 -19
  122. data/spec/requests/flows/revoke_token_spec.rb +18 -12
  123. data/spec/spec_helper.rb +1 -4
  124. data/spec/support/shared/controllers_shared_context.rb +33 -23
  125. data/spec/validators/redirect_uri_validator_spec.rb +1 -1
  126. metadata +6 -5
  127. data/spec/support/http_method_shim.rb +0 -29
@@ -13,6 +13,78 @@ module Doorkeeper
13
13
  let(:uid) { SecureRandom.hex(8) }
14
14
  let(:secret) { SecureRandom.hex(8) }
15
15
 
16
+ it "is invalid without a name" do
17
+ new_application.name = nil
18
+ expect(new_application).not_to be_valid
19
+ end
20
+
21
+ it "is invalid without determining confidentiality" do
22
+ new_application.confidential = nil
23
+ expect(new_application).not_to be_valid
24
+ end
25
+
26
+ it "generates uid on create" do
27
+ expect(new_application.uid).to be_nil
28
+ new_application.save
29
+ expect(new_application.uid).not_to be_nil
30
+ end
31
+
32
+ it "generates uid on create if an empty string" do
33
+ new_application.uid = ""
34
+ new_application.save
35
+ expect(new_application.uid).not_to be_blank
36
+ end
37
+
38
+ it "generates uid on create unless one is set" do
39
+ new_application.uid = uid
40
+ new_application.save
41
+ expect(new_application.uid).to eq(uid)
42
+ end
43
+
44
+ it "is invalid without uid" do
45
+ new_application.save
46
+ new_application.uid = nil
47
+ expect(new_application).not_to be_valid
48
+ end
49
+
50
+ it "checks uniqueness of uid" do
51
+ app1 = FactoryBot.create(:application)
52
+ app2 = FactoryBot.create(:application)
53
+ app2.uid = app1.uid
54
+ expect(app2).not_to be_valid
55
+ end
56
+
57
+ it "expects database to throw an error when uids are the same" do
58
+ app1 = FactoryBot.create(:application)
59
+ app2 = FactoryBot.create(:application)
60
+ app2.uid = app1.uid
61
+ expect { app2.save!(validate: false) }.to raise_error(uniqueness_error)
62
+ end
63
+
64
+ it "generate secret on create" do
65
+ expect(new_application.secret).to be_nil
66
+ new_application.save
67
+ expect(new_application.secret).not_to be_nil
68
+ end
69
+
70
+ it "generate secret on create if is blank string" do
71
+ new_application.secret = ""
72
+ new_application.save
73
+ expect(new_application.secret).not_to be_blank
74
+ end
75
+
76
+ it "generate secret on create unless one is set" do
77
+ new_application.secret = secret
78
+ new_application.save
79
+ expect(new_application.secret).to eq(secret)
80
+ end
81
+
82
+ it "is invalid without secret" do
83
+ new_application.save
84
+ new_application.secret = nil
85
+ expect(new_application).not_to be_valid
86
+ end
87
+
16
88
  context "application_owner is enabled" do
17
89
  before do
18
90
  Doorkeeper.configure do
@@ -48,40 +120,6 @@ module Doorkeeper
48
120
  end
49
121
  end
50
122
 
51
- it "is invalid without a name" do
52
- new_application.name = nil
53
- expect(new_application).not_to be_valid
54
- end
55
-
56
- it "is invalid without determining confidentiality" do
57
- new_application.confidential = nil
58
- expect(new_application).not_to be_valid
59
- end
60
-
61
- it "generates uid on create" do
62
- expect(new_application.uid).to be_nil
63
- new_application.save
64
- expect(new_application.uid).not_to be_nil
65
- end
66
-
67
- it "generates uid on create if an empty string" do
68
- new_application.uid = ""
69
- new_application.save
70
- expect(new_application.uid).not_to be_blank
71
- end
72
-
73
- it "generates uid on create unless one is set" do
74
- new_application.uid = uid
75
- new_application.save
76
- expect(new_application.uid).to eq(uid)
77
- end
78
-
79
- it "is invalid without uid" do
80
- new_application.save
81
- new_application.uid = nil
82
- expect(new_application).not_to be_valid
83
- end
84
-
85
123
  context "redirect URI" do
86
124
  context "when grant flows allow blank redirect URI" do
87
125
  before do
@@ -127,44 +165,6 @@ module Doorkeeper
127
165
  end
128
166
  end
129
167
 
130
- it "checks uniqueness of uid" do
131
- app1 = FactoryBot.create(:application)
132
- app2 = FactoryBot.create(:application)
133
- app2.uid = app1.uid
134
- expect(app2).not_to be_valid
135
- end
136
-
137
- it "expects database to throw an error when uids are the same" do
138
- app1 = FactoryBot.create(:application)
139
- app2 = FactoryBot.create(:application)
140
- app2.uid = app1.uid
141
- expect { app2.save!(validate: false) }.to raise_error(uniqueness_error)
142
- end
143
-
144
- it "generate secret on create" do
145
- expect(new_application.secret).to be_nil
146
- new_application.save
147
- expect(new_application.secret).not_to be_nil
148
- end
149
-
150
- it "generate secret on create if is blank string" do
151
- new_application.secret = ""
152
- new_application.save
153
- expect(new_application.secret).not_to be_blank
154
- end
155
-
156
- it "generate secret on create unless one is set" do
157
- new_application.secret = secret
158
- new_application.save
159
- expect(new_application.secret).to eq(secret)
160
- end
161
-
162
- it "is invalid without secret" do
163
- new_application.save
164
- new_application.secret = nil
165
- expect(new_application).not_to be_valid
166
- end
167
-
168
168
  context "with hashing enabled" do
169
169
  include_context "with application hashing enabled"
170
170
  let(:app) { FactoryBot.create :application }
@@ -238,7 +238,7 @@ module Doorkeeper
238
238
  end
239
239
  end
240
240
 
241
- describe :ordered_by do
241
+ describe "#ordered_by" do
242
242
  let(:applications) { FactoryBot.create_list(:application, 5) }
243
243
 
244
244
  context "when a direction is not specified" do
@@ -271,7 +271,17 @@ module Doorkeeper
271
271
  end
272
272
  end
273
273
 
274
- describe :authorized_for do
274
+ describe "#renew_secret" do
275
+ let(:app) { FactoryBot.create :application }
276
+
277
+ it "should generate a new secret" do
278
+ old_secret = app.secret
279
+ app.renew_secret
280
+ expect(old_secret).not_to eq(app.secret)
281
+ end
282
+ end
283
+
284
+ describe "#authorized_for" do
275
285
  let(:resource_owner) { double(:resource_owner, id: 10) }
276
286
 
277
287
  it "is empty if the application is not authorized for anyone" do
@@ -303,7 +313,7 @@ module Doorkeeper
303
313
  end
304
314
  end
305
315
 
306
- describe :revoke_tokens_and_grants_for do
316
+ describe "#revoke_tokens_and_grants_for" do
307
317
  it "revokes all access tokens and access grants" do
308
318
  application_id = 42
309
319
  resource_owner = double
@@ -316,7 +326,7 @@ module Doorkeeper
316
326
  end
317
327
  end
318
328
 
319
- describe :by_uid_and_secret do
329
+ describe "#by_uid_and_secret" do
320
330
  context "when application is private/confidential" do
321
331
  it "finds the application via uid/secret" do
322
332
  app = FactoryBot.create :application
@@ -350,7 +360,7 @@ module Doorkeeper
350
360
  end
351
361
  end
352
362
 
353
- describe :confidential? do
363
+ describe "#confidential?" do
354
364
  subject { FactoryBot.create(:application, confidential: confidential).confidential? }
355
365
 
356
366
  context "when application is private/confidential" do
@@ -363,5 +373,32 @@ module Doorkeeper
363
373
  it { expect(subject).to eq(false) }
364
374
  end
365
375
  end
376
+
377
+ describe "#as_json" do
378
+ let(:app) { FactoryBot.create :application, secret: "123123123" }
379
+
380
+ before do
381
+ allow(Doorkeeper.configuration)
382
+ .to receive(:application_secret_strategy).and_return(Doorkeeper::SecretStoring::Plain)
383
+ end
384
+
385
+ it "includes plaintext secret" do
386
+ expect(app.as_json).to include("secret" => "123123123")
387
+ end
388
+
389
+ it "respects custom options" do
390
+ expect(app.as_json(except: :secret)).not_to include("secret")
391
+ expect(app.as_json(only: :id)).to match("id" => app.id)
392
+ end
393
+
394
+ # AR specific
395
+ if DOORKEEPER_ORM == :active_record
396
+ it "correctly works with #to_json" do
397
+ ActiveRecord::Base.include_root_in_json = true
398
+ expect(app.to_json(include_root_in_json: true)).to match(/application.+?:\{/)
399
+ ActiveRecord::Base.include_root_in_json = false
400
+ end
401
+ end
402
+ end
366
403
  end
367
404
  end
@@ -91,7 +91,7 @@ feature "Adding applications" do
91
91
  i_should_see "Whoops! Check your form for possible errors"
92
92
  i_should_see Regexp.new(
93
93
  I18n.t("activerecord.errors.models.doorkeeper/application.attributes.scopes.not_match_configured"),
94
- true
94
+ true,
95
95
  )
96
96
  end
97
97
 
@@ -79,9 +79,11 @@ feature "Authorization endpoint" do
79
79
  scenario "raises exception on forged requests" do
80
80
  allowing_forgery_protection do
81
81
  expect do
82
- page.driver.post authorization_endpoint_url(client_id: @client.uid,
83
- redirect_uri: @client.redirect_uri,
84
- response_type: "code")
82
+ page.driver.post authorization_endpoint_url(
83
+ client_id: @client.uid,
84
+ redirect_uri: @client.redirect_uri,
85
+ response_type: "code",
86
+ )
85
87
  end.to raise_error(ActionController::InvalidAuthenticityToken)
86
88
  end
87
89
  end
@@ -149,8 +149,10 @@ feature "Authorization Code Flow" do
149
149
  click_on "Authorize"
150
150
 
151
151
  authorization_code = Doorkeeper::AccessGrant.first.token
152
- page.driver.post token_endpoint_url(code: authorization_code, client_id: @client.uid,
153
- redirect_uri: @client.redirect_uri)
152
+ page.driver.post token_endpoint_url(
153
+ code: authorization_code, client_id: @client.uid,
154
+ redirect_uri: @client.redirect_uri,
155
+ )
154
156
 
155
157
  expect(Doorkeeper::AccessToken.count).to be_zero
156
158
 
@@ -163,8 +165,10 @@ feature "Authorization Code Flow" do
163
165
  click_on "Authorize"
164
166
 
165
167
  authorization_code = Doorkeeper::AccessGrant.first.token
166
- page.driver.post token_endpoint_url(code: authorization_code, client_secret: @client.secret,
167
- redirect_uri: @client.redirect_uri)
168
+ page.driver.post token_endpoint_url(
169
+ code: authorization_code, client_secret: @client.secret,
170
+ redirect_uri: @client.redirect_uri,
171
+ )
168
172
 
169
173
  expect(Doorkeeper::AccessToken.count).to be_zero
170
174
 
@@ -195,7 +199,7 @@ feature "Authorization Code Flow" do
195
199
  visit authorization_endpoint_url(
196
200
  client: @client,
197
201
  code_challenge: code_challenge,
198
- code_challenge_method: "plain"
202
+ code_challenge_method: "plain",
199
203
  )
200
204
  click_on "Authorize"
201
205
 
@@ -219,7 +223,7 @@ feature "Authorization Code Flow" do
219
223
  visit authorization_endpoint_url(
220
224
  client: @client,
221
225
  code_challenge: code_challenge,
222
- code_challenge_method: "plain"
226
+ code_challenge_method: "plain",
223
227
  )
224
228
  click_on "Authorize"
225
229
 
@@ -236,9 +240,11 @@ feature "Authorization Code Flow" do
236
240
  end
237
241
 
238
242
  scenario "mobile app requests an access token with authorization code but without code_verifier" do
239
- visit authorization_endpoint_url(client: @client,
240
- code_challenge: code_challenge,
241
- code_challenge_method: "plain")
243
+ visit authorization_endpoint_url(
244
+ client: @client,
245
+ code_challenge: code_challenge,
246
+ code_challenge_method: "plain",
247
+ )
242
248
  click_on "Authorize"
243
249
 
244
250
  authorization_code = current_params["code"]
@@ -250,9 +256,11 @@ feature "Authorization Code Flow" do
250
256
  end
251
257
 
252
258
  scenario "mobile app requests an access token with authorization code with wrong code_verifier" do
253
- visit authorization_endpoint_url(client: @client,
254
- code_challenge: code_challenge,
255
- code_challenge_method: "plain")
259
+ visit authorization_endpoint_url(
260
+ client: @client,
261
+ code_challenge: code_challenge,
262
+ code_challenge_method: "plain",
263
+ )
256
264
  click_on "Authorize"
257
265
 
258
266
  authorization_code = current_params["code"]
@@ -272,7 +280,7 @@ feature "Authorization Code Flow" do
272
280
  visit authorization_endpoint_url(
273
281
  client: @client,
274
282
  code_challenge: code_challenge,
275
- code_challenge_method: "S256"
283
+ code_challenge_method: "S256",
276
284
  )
277
285
  click_on "Authorize"
278
286
 
@@ -285,7 +293,7 @@ feature "Authorization Code Flow" do
285
293
  visit authorization_endpoint_url(
286
294
  client: @client,
287
295
  code_challenge: code_challenge,
288
- code_challenge_method: "S256"
296
+ code_challenge_method: "S256",
289
297
  )
290
298
  click_on "Authorize"
291
299
 
@@ -305,13 +313,17 @@ feature "Authorization Code Flow" do
305
313
  visit authorization_endpoint_url(
306
314
  client: @client,
307
315
  code_challenge: code_challenge,
308
- code_challenge_method: "S256"
316
+ code_challenge_method: "S256",
309
317
  )
310
318
  click_on "Authorize"
311
319
 
312
320
  authorization_code = current_params["code"]
313
- page.driver.post token_endpoint_url(code: authorization_code, client_id: @client.uid,
314
- redirect_uri: @client.redirect_uri, code_verifier: code_verifier)
321
+ page.driver.post token_endpoint_url(
322
+ code: authorization_code,
323
+ client_id: @client.uid,
324
+ redirect_uri: @client.redirect_uri,
325
+ code_verifier: code_verifier,
326
+ )
315
327
  should_not_have_json "access_token"
316
328
  should_have_json "error", "invalid_client"
317
329
  should_have_json "error_description", translated_error_message(:invalid_client)
@@ -327,7 +339,7 @@ feature "Authorization Code Flow" do
327
339
  code: authorization_code,
328
340
  client_id: @client.uid,
329
341
  redirect_uri: @client.redirect_uri,
330
- code_verifier: code_verifier
342
+ code_verifier: code_verifier,
331
343
  )
332
344
  should_not_have_json "error"
333
345
 
@@ -340,7 +352,7 @@ feature "Authorization Code Flow" do
340
352
  visit authorization_endpoint_url(
341
353
  client: @client,
342
354
  code_challenge: code_challenge,
343
- code_challenge_method: "S256"
355
+ code_challenge_method: "S256",
344
356
  )
345
357
  click_on "Authorize"
346
358
 
@@ -356,7 +368,7 @@ feature "Authorization Code Flow" do
356
368
  visit authorization_endpoint_url(
357
369
  client: @client,
358
370
  code_challenge: code_challenge,
359
- code_challenge_method: "S256"
371
+ code_challenge_method: "S256",
360
372
  )
361
373
  click_on "Authorize"
362
374
 
@@ -372,7 +384,7 @@ feature "Authorization Code Flow" do
372
384
  visit authorization_endpoint_url(
373
385
  client: @client,
374
386
  code_challenge: code_challenge,
375
- code_challenge_method: "S256"
387
+ code_challenge_method: "S256",
376
388
  )
377
389
  click_on "Authorize"
378
390
 
@@ -381,7 +393,7 @@ feature "Authorization Code Flow" do
381
393
  code: authorization_code,
382
394
  client: @client,
383
395
  code_verifier: code_challenge,
384
- code_challenge_method: "plain"
396
+ code_challenge_method: "plain",
385
397
  )
386
398
 
387
399
  should_not_have_json "access_token"
@@ -70,7 +70,7 @@ describe "Client Credentials Request" do
70
70
  before do
71
71
  Doorkeeper.configuration.instance_variable_set(
72
72
  :@allow_grant_flow_for_client,
73
- ->(_grant_flow, client) { client.name == "admin" }
73
+ ->(_grant_flow, client) { client.name == "admin" },
74
74
  )
75
75
  end
76
76
 
@@ -35,7 +35,7 @@ describe "Resource Owner Password Credentials Flow" do
35
35
  before do
36
36
  Doorkeeper.configuration.instance_variable_set(
37
37
  :@allow_grant_flow_for_client,
38
- ->(_grant_flow, client) { client.name == "admin" }
38
+ ->(_grant_flow, client) { client.name == "admin" },
39
39
  )
40
40
  end
41
41
 
@@ -46,7 +46,7 @@ describe "Resource Owner Password Credentials Flow" do
46
46
  post password_token_endpoint_url(
47
47
  client_id: @client.uid,
48
48
  client_secret: "foobar",
49
- resource_owner: @resource_owner
49
+ resource_owner: @resource_owner,
50
50
  )
51
51
  end.not_to(change { Doorkeeper::AccessToken.count })
52
52
 
@@ -99,7 +99,7 @@ describe "Resource Owner Password Credentials Flow" do
99
99
  post password_token_endpoint_url(
100
100
  client_id: @client.uid,
101
101
  client_secret: "foobar",
102
- resource_owner: @resource_owner
102
+ resource_owner: @resource_owner,
103
103
  )
104
104
  end.not_to(change { Doorkeeper::AccessToken.count })
105
105
 
@@ -241,9 +241,11 @@ describe "Resource Owner Password Credentials Flow" do
241
241
 
242
242
  context "with invalid scopes" do
243
243
  subject do
244
- post password_token_endpoint_url(client: @client,
245
- resource_owner: @resource_owner,
246
- scope: "random")
244
+ post password_token_endpoint_url(
245
+ client: @client,
246
+ resource_owner: @resource_owner,
247
+ scope: "random",
248
+ )
247
249
  end
248
250
 
249
251
  it "should not issue new token" do
@@ -263,9 +265,11 @@ describe "Resource Owner Password Credentials Flow" do
263
265
  context "with invalid user credentials" do
264
266
  it "should not issue new token with bad password" do
265
267
  expect do
266
- post password_token_endpoint_url(client: @client,
267
- resource_owner_username: @resource_owner.name,
268
- resource_owner_password: "wrongpassword")
268
+ post password_token_endpoint_url(
269
+ client: @client,
270
+ resource_owner_username: @resource_owner.name,
271
+ resource_owner_password: "wrongpassword",
272
+ )
269
273
  end.to_not(change { Doorkeeper::AccessToken.count })
270
274
  end
271
275
 
@@ -274,14 +278,30 @@ describe "Resource Owner Password Credentials Flow" do
274
278
  post password_token_endpoint_url(client: @client)
275
279
  end.to_not(change { Doorkeeper::AccessToken.count })
276
280
  end
281
+
282
+ it "should not issue new token if resource_owner_from_credentials returned false or nil" do
283
+ config_is_set(:resource_owner_from_credentials) { false }
284
+
285
+ expect do
286
+ post password_token_endpoint_url(client: @client)
287
+ end.to_not(change { Doorkeeper::AccessToken.count })
288
+
289
+ config_is_set(:resource_owner_from_credentials) { nil }
290
+
291
+ expect do
292
+ post password_token_endpoint_url(client: @client)
293
+ end.to_not(change { Doorkeeper::AccessToken.count })
294
+ end
277
295
  end
278
296
 
279
297
  context "with invalid confidential client credentials" do
280
298
  it "should not issue new token with bad client credentials" do
281
299
  expect do
282
- post password_token_endpoint_url(client_id: @client.uid,
283
- client_secret: "bad_secret",
284
- resource_owner: @resource_owner)
300
+ post password_token_endpoint_url(
301
+ client_id: @client.uid,
302
+ client_secret: "bad_secret",
303
+ resource_owner: @resource_owner,
304
+ )
285
305
  end.to_not(change { Doorkeeper::AccessToken.count })
286
306
  end
287
307
  end
@@ -44,17 +44,17 @@ describe "Refresh Token Flow" do
44
44
  :access_token,
45
45
  application: @client,
46
46
  resource_owner_id: 1,
47
- use_refresh_token: true
47
+ use_refresh_token: true,
48
48
  )
49
49
  end
50
50
 
51
51
  context "refresh_token revoked on use" do
52
52
  it "client request a token with refresh token" do
53
53
  post refresh_token_endpoint_url(
54
- client: @client, refresh_token: @token.refresh_token
54
+ client: @client, refresh_token: @token.refresh_token,
55
55
  )
56
56
  should_have_json(
57
- "refresh_token", Doorkeeper::AccessToken.last.refresh_token
57
+ "refresh_token", Doorkeeper::AccessToken.last.refresh_token,
58
58
  )
59
59
  expect(@token.reload).not_to be_revoked
60
60
  end
@@ -62,10 +62,10 @@ describe "Refresh Token Flow" do
62
62
  it "client request a token with expired access token" do
63
63
  @token.update_attribute :expires_in, -100
64
64
  post refresh_token_endpoint_url(
65
- client: @client, refresh_token: @token.refresh_token
65
+ client: @client, refresh_token: @token.refresh_token,
66
66
  )
67
67
  should_have_json(
68
- "refresh_token", Doorkeeper::AccessToken.last.refresh_token
68
+ "refresh_token", Doorkeeper::AccessToken.last.refresh_token,
69
69
  )
70
70
  expect(@token.reload).not_to be_revoked
71
71
  end
@@ -78,10 +78,10 @@ describe "Refresh Token Flow" do
78
78
 
79
79
  it "client request a token with refresh token" do
80
80
  post refresh_token_endpoint_url(
81
- client: @client, refresh_token: @token.refresh_token
81
+ client: @client, refresh_token: @token.refresh_token,
82
82
  )
83
83
  should_have_json(
84
- "refresh_token", Doorkeeper::AccessToken.last.refresh_token
84
+ "refresh_token", Doorkeeper::AccessToken.last.refresh_token,
85
85
  )
86
86
  expect(@token.reload).to be_revoked
87
87
  end
@@ -89,10 +89,10 @@ describe "Refresh Token Flow" do
89
89
  it "client request a token with expired access token" do
90
90
  @token.update_attribute :expires_in, -100
91
91
  post refresh_token_endpoint_url(
92
- client: @client, refresh_token: @token.refresh_token
92
+ client: @client, refresh_token: @token.refresh_token,
93
93
  )
94
94
  should_have_json(
95
- "refresh_token", Doorkeeper::AccessToken.last.refresh_token
95
+ "refresh_token", Doorkeeper::AccessToken.last.refresh_token,
96
96
  )
97
97
  expect(@token.reload).to be_revoked
98
98
  end
@@ -102,7 +102,7 @@ describe "Refresh Token Flow" do
102
102
  let(:public_client) do
103
103
  FactoryBot.create(
104
104
  :application,
105
- confidential: false
105
+ confidential: false,
106
106
  )
107
107
  end
108
108
 
@@ -111,7 +111,7 @@ describe "Refresh Token Flow" do
111
111
  :access_token,
112
112
  application: @client,
113
113
  resource_owner_id: 1,
114
- use_refresh_token: true
114
+ use_refresh_token: true,
115
115
  )
116
116
  end
117
117
 
@@ -120,14 +120,14 @@ describe "Refresh Token Flow" do
120
120
  :access_token,
121
121
  application: public_client,
122
122
  resource_owner_id: 1,
123
- use_refresh_token: true
123
+ use_refresh_token: true,
124
124
  )
125
125
  end
126
126
 
127
127
  it "issues a new token without client_secret when refresh token was issued to a public client" do
128
128
  post refresh_token_endpoint_url(
129
129
  client_id: public_client.uid,
130
- refresh_token: token_for_public_client.refresh_token
130
+ refresh_token: token_for_public_client.refresh_token,
131
131
  )
132
132
 
133
133
  new_token = Doorkeeper::AccessToken.last
@@ -146,7 +146,7 @@ describe "Refresh Token Flow" do
146
146
  post refresh_token_endpoint_url(
147
147
  client_id: "1",
148
148
  client_secret: "1",
149
- refresh_token: token_for_private_client.refresh_token
149
+ refresh_token: token_for_private_client.refresh_token,
150
150
  )
151
151
 
152
152
  should_not_have_json "refresh_token"
@@ -185,7 +185,7 @@ describe "Refresh Token Flow" do
185
185
  end
186
186
  create_resource_owner
187
187
  _another_token = post password_token_endpoint_url(
188
- client: @client, resource_owner: @resource_owner
188
+ client: @client, resource_owner: @resource_owner,
189
189
  )
190
190
  last_token.update_attribute :created_at, 5.seconds.ago
191
191
 
@@ -193,7 +193,7 @@ describe "Refresh Token Flow" do
193
193
  :access_token,
194
194
  application: @client,
195
195
  resource_owner_id: @resource_owner.id,
196
- use_refresh_token: true
196
+ use_refresh_token: true,
197
197
  )
198
198
  @token.update_attribute :expires_in, -100
199
199
  end
@@ -201,7 +201,7 @@ describe "Refresh Token Flow" do
201
201
  context "refresh_token revoked on use" do
202
202
  it "client request a token after creating another token with the same user" do
203
203
  post refresh_token_endpoint_url(
204
- client: @client, refresh_token: @token.refresh_token
204
+ client: @client, refresh_token: @token.refresh_token,
205
205
  )
206
206
 
207
207
  should_have_json "refresh_token", last_token.refresh_token
@@ -216,7 +216,7 @@ describe "Refresh Token Flow" do
216
216
 
217
217
  it "client request a token after creating another token with the same user" do
218
218
  post refresh_token_endpoint_url(
219
- client: @client, refresh_token: @token.refresh_token
219
+ client: @client, refresh_token: @token.refresh_token,
220
220
  )
221
221
 
222
222
  should_have_json "refresh_token", last_token.refresh_token
@@ -226,7 +226,7 @@ describe "Refresh Token Flow" do
226
226
 
227
227
  def last_token
228
228
  Doorkeeper::AccessToken.last_authorized_token_for(
229
- @client.id, @resource_owner.id
229
+ @client.id, @resource_owner.id,
230
230
  )
231
231
  end
232
232
  end