doorkeeper 5.2.0.rc2 → 5.2.0.rc3

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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +1 -1
  3. data/CHANGELOG.md +15 -2
  4. data/Gemfile +1 -1
  5. data/README.md +9 -1
  6. data/app/controllers/doorkeeper/application_metal_controller.rb +1 -1
  7. data/app/controllers/doorkeeper/authorizations_controller.rb +11 -9
  8. data/config/locales/en.yml +5 -1
  9. data/doorkeeper.gemspec +8 -0
  10. data/gemfiles/rails_6_0.gemfile +1 -1
  11. data/lib/doorkeeper.rb +1 -0
  12. data/lib/doorkeeper/config.rb +41 -2
  13. data/lib/doorkeeper/errors.rb +13 -18
  14. data/lib/doorkeeper/helpers/controller.rb +6 -2
  15. data/lib/doorkeeper/oauth/authorization/code.rb +1 -5
  16. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -9
  17. data/lib/doorkeeper/oauth/base_request.rb +2 -0
  18. data/lib/doorkeeper/oauth/client_credentials/validation.rb +8 -0
  19. data/lib/doorkeeper/oauth/code_request.rb +5 -11
  20. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  21. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -2
  22. data/lib/doorkeeper/oauth/pre_authorization.rb +70 -37
  23. data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -2
  24. data/lib/doorkeeper/oauth/token_introspection.rb +4 -1
  25. data/lib/doorkeeper/oauth/token_request.rb +4 -18
  26. data/lib/doorkeeper/orm/active_record.rb +2 -2
  27. data/lib/doorkeeper/orm/active_record/application.rb +1 -1
  28. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
  29. data/lib/doorkeeper/request.rb +6 -11
  30. data/lib/doorkeeper/request/authorization_code.rb +2 -0
  31. data/lib/doorkeeper/server.rb +2 -6
  32. data/lib/doorkeeper/version.rb +1 -1
  33. data/lib/generators/doorkeeper/templates/initializer.rb +33 -2
  34. data/lib/generators/doorkeeper/templates/migration.rb.erb +1 -1
  35. data/spec/controllers/authorizations_controller_spec.rb +127 -61
  36. data/spec/controllers/protected_resources_controller_spec.rb +3 -3
  37. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +1 -1
  38. data/spec/lib/config_spec.rb +17 -0
  39. data/spec/lib/oauth/authorization_code_request_spec.rb +11 -1
  40. data/spec/lib/oauth/base_request_spec.rb +33 -16
  41. data/spec/lib/oauth/code_request_spec.rb +27 -28
  42. data/spec/lib/oauth/invalid_request_response_spec.rb +75 -0
  43. data/spec/lib/oauth/pre_authorization_spec.rb +80 -55
  44. data/spec/lib/oauth/refresh_token_request_spec.rb +1 -0
  45. data/spec/lib/oauth/token_request_spec.rb +20 -17
  46. data/spec/lib/server_spec.rb +0 -12
  47. data/spec/requests/endpoints/authorization_spec.rb +21 -5
  48. data/spec/requests/endpoints/token_spec.rb +1 -1
  49. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
  50. data/spec/requests/flows/authorization_code_spec.rb +77 -23
  51. data/spec/requests/flows/client_credentials_spec.rb +38 -0
  52. data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
  53. data/spec/requests/flows/implicit_grant_spec.rb +9 -8
  54. data/spec/requests/flows/password_spec.rb +37 -0
  55. data/spec/requests/flows/refresh_token_spec.rb +1 -1
  56. data/spec/support/helpers/request_spec_helper.rb +14 -2
  57. data/spec/validators/redirect_uri_validator_spec.rb +1 -1
  58. metadata +12 -4
  59. data/app/validators/redirect_uri_validator.rb +0 -60
@@ -10,12 +10,6 @@ describe Doorkeeper::Server do
10
10
  end
11
11
 
12
12
  describe ".authorization_request" do
13
- it "raises error when strategy does not exist" do
14
- expect do
15
- subject.authorization_request(:duh)
16
- end.to raise_error(Doorkeeper::Errors::InvalidAuthorizationStrategy)
17
- end
18
-
19
13
  it "raises error when strategy does not match phase" do
20
14
  expect do
21
15
  subject.token_request(:code)
@@ -29,12 +23,6 @@ describe Doorkeeper::Server do
29
23
  .and_return(["authorization_code"])
30
24
  end
31
25
 
32
- it "raises error when using the disabled Implicit strategy" do
33
- expect do
34
- subject.authorization_request(:token)
35
- end.to raise_error(Doorkeeper::Errors::InvalidAuthorizationStrategy)
36
- end
37
-
38
26
  it "raises error when using the disabled Client Credentials strategy" do
39
27
  expect do
40
28
  subject.token_request(:client_credentials)
@@ -4,6 +4,7 @@ require "spec_helper"
4
4
 
5
5
  feature "Authorization endpoint" do
6
6
  background do
7
+ default_scopes_exist :default
7
8
  config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
8
9
  client_exists(name: "MyApp")
9
10
  end
@@ -34,16 +35,31 @@ feature "Authorization endpoint" do
34
35
  end
35
36
  end
36
37
 
37
- context "with a invalid request" do
38
+ context "with a invalid request's param" do
38
39
  background do
39
40
  create_resource_owner
40
41
  sign_in
41
42
  end
42
43
 
43
- scenario "displays the related error" do
44
- visit authorization_endpoint_url(client: @client, response_type: "")
45
- i_should_not_see "Authorize"
46
- i_should_see_translated_error_message :unsupported_response_type
44
+ context "when missing required param" do
45
+ scenario "displays invalid_request error when missing client" do
46
+ visit authorization_endpoint_url(client: nil, response_type: "code")
47
+ i_should_not_see "Authorize"
48
+ i_should_see_translated_invalid_request_error_message :missing_param, :client_id
49
+ end
50
+
51
+ scenario "displays invalid_request error when missing response_type param" do
52
+ visit authorization_endpoint_url(client: @client, response_type: "")
53
+ i_should_not_see "Authorize"
54
+ i_should_see_translated_invalid_request_error_message :missing_param, :response_type
55
+ end
56
+
57
+ scenario "displays invalid_request error when missing scope param and authorization server has no default scopes" do
58
+ config_is_set(:default_scopes, [])
59
+ visit authorization_endpoint_url(client: @client, response_type: "code", scope: "")
60
+ i_should_not_see "Authorize"
61
+ i_should_see_translated_invalid_request_error_message :missing_param, :scope
62
+ end
47
63
  end
48
64
 
49
65
  scenario "displays unsupported_response_type error when using a disabled response type" do
@@ -70,6 +70,6 @@ describe "Token endpoint" do
70
70
 
71
71
  should_not_have_json "access_token"
72
72
  should_have_json "error", "invalid_request"
73
- should_have_json "error_description", translated_error_message("invalid_request")
73
+ should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :grant_type)
74
74
  end
75
75
  end
@@ -5,6 +5,7 @@ require "spec_helper"
5
5
  feature "Authorization Code Flow Errors" do
6
6
  let(:client_params) { {} }
7
7
  background do
8
+ default_scopes_exist :default
8
9
  config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
9
10
  client_exists client_params
10
11
  create_resource_owner
@@ -4,6 +4,7 @@ require "spec_helper"
4
4
 
5
5
  feature "Authorization Code Flow" do
6
6
  background do
7
+ default_scopes_exist :default
7
8
  config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
8
9
  client_exists
9
10
  create_resource_owner
@@ -23,6 +24,39 @@ feature "Authorization Code Flow" do
23
24
  url_should_not_have_param("error")
24
25
  end
25
26
 
27
+ context "when configured to check application supported grant flow" do
28
+ before do
29
+ config_is_set(:allow_grant_flow_for_client, ->(_grant_flow, client) { client.name == "admin" })
30
+ end
31
+
32
+ scenario "forbids the request when doesn't satisfy condition" do
33
+ @client.update(name: "sample app")
34
+
35
+ visit authorization_endpoint_url(client: @client)
36
+
37
+ i_should_see_translated_error_message("unauthorized_client")
38
+ end
39
+
40
+ scenario "allows the request when satisfies condition" do
41
+ @client.update(name: "admin")
42
+
43
+ visit authorization_endpoint_url(client: @client)
44
+ i_should_not_see_translated_error_message("unauthorized_client")
45
+ click_on "Authorize"
46
+
47
+ authorization_code = Doorkeeper::AccessGrant.first.token
48
+ create_access_token authorization_code, @client
49
+
50
+ access_token_should_exist_for(@client, @resource_owner)
51
+
52
+ should_not_have_json "error"
53
+
54
+ should_have_json "access_token", Doorkeeper::AccessToken.first.token
55
+ should_have_json "token_type", "Bearer"
56
+ should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
57
+ end
58
+ end
59
+
26
60
  context "with grant hashing enabled" do
27
61
  background do
28
62
  config_is_set(:token_secret_strategy, ::Doorkeeper::SecretStoring::Sha256Hash)
@@ -83,6 +117,17 @@ feature "Authorization Code Flow" do
83
117
  url_should_not_have_param("code_challenge_method")
84
118
  end
85
119
 
120
+ scenario "resource owner requests an access token without authorization code" do
121
+ create_access_token "", @client
122
+
123
+ access_token_should_not_exist
124
+
125
+ expect(Doorkeeper::AccessToken.count).to be_zero
126
+
127
+ should_have_json "error", "invalid_request"
128
+ should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :code)
129
+ end
130
+
86
131
  scenario "resource owner requests an access token with authorization code" do
87
132
  visit authorization_endpoint_url(client: @client)
88
133
  click_on "Authorize"
@@ -110,6 +155,7 @@ feature "Authorization Code Flow" do
110
155
  expect(Doorkeeper::AccessToken.count).to be_zero
111
156
 
112
157
  should_have_json "error", "invalid_client"
158
+ should_have_json "error_description", translated_error_message(:invalid_client)
113
159
  end
114
160
 
115
161
  scenario "resource owner requests an access token with authorization code but without client id" do
@@ -123,6 +169,7 @@ feature "Authorization Code Flow" do
123
169
  expect(Doorkeeper::AccessToken.count).to be_zero
124
170
 
125
171
  should_have_json "error", "invalid_client"
172
+ should_have_json "error_description", translated_error_message(:invalid_client)
126
173
  end
127
174
 
128
175
  scenario "silently authorizes if matching token exists" do
@@ -165,6 +212,7 @@ feature "Authorization Code Flow" do
165
212
  create_access_token authorization_code, @client, code_verifier
166
213
 
167
214
  should_have_json "error", "invalid_grant"
215
+ should_have_json "error_description", translated_error_message(:invalid_grant)
168
216
  end
169
217
 
170
218
  scenario "mobile app requests an access token with authorization code and plain code challenge method" do
@@ -187,17 +235,32 @@ feature "Authorization Code Flow" do
187
235
  should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
188
236
  end
189
237
 
190
- scenario "mobile app requests an access token with authorization code and code_challenge" do
238
+ scenario "mobile app requests an access token with authorization code but without code_verifier" do
191
239
  visit authorization_endpoint_url(client: @client,
192
- code_challenge: code_verifier,
240
+ code_challenge: code_challenge,
193
241
  code_challenge_method: "plain")
194
242
  click_on "Authorize"
195
243
 
196
244
  authorization_code = current_params["code"]
197
- create_access_token authorization_code, @client, code_verifier: nil
245
+ create_access_token authorization_code, @client, nil
246
+
247
+ should_not_have_json "access_token"
248
+ should_have_json "error", "invalid_request"
249
+ should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :code_verifier)
250
+ end
251
+
252
+ 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")
256
+ click_on "Authorize"
257
+
258
+ authorization_code = current_params["code"]
259
+ create_access_token authorization_code, @client, "wrong_code_verifier"
198
260
 
199
261
  should_not_have_json "access_token"
200
262
  should_have_json "error", "invalid_grant"
263
+ should_have_json "error_description", translated_error_message(:invalid_grant)
201
264
  end
202
265
  end
203
266
 
@@ -238,19 +301,6 @@ feature "Authorization Code Flow" do
238
301
  should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
239
302
  end
240
303
 
241
- scenario "mobile app requests an access token with authorization code and without code_verifier" do
242
- visit authorization_endpoint_url(
243
- client: @client,
244
- code_challenge: code_challenge,
245
- code_challenge_method: "S256"
246
- )
247
- click_on "Authorize"
248
- authorization_code = current_params["code"]
249
- create_access_token authorization_code, @client
250
- should_have_json "error", "invalid_request"
251
- should_not_have_json "access_token"
252
- end
253
-
254
304
  scenario "mobile app requests an access token with authorization code and without secret" do
255
305
  visit authorization_endpoint_url(
256
306
  client: @client,
@@ -262,8 +312,9 @@ feature "Authorization Code Flow" do
262
312
  authorization_code = current_params["code"]
263
313
  page.driver.post token_endpoint_url(code: authorization_code, client_id: @client.uid,
264
314
  redirect_uri: @client.redirect_uri, code_verifier: code_verifier)
265
- should_have_json "error", "invalid_client"
266
315
  should_not_have_json "access_token"
316
+ should_have_json "error", "invalid_client"
317
+ should_have_json "error_description", translated_error_message(:invalid_client)
267
318
  end
268
319
 
269
320
  scenario "mobile app requests an access token with authorization code and without secret but is marked as not confidential" do
@@ -298,6 +349,7 @@ feature "Authorization Code Flow" do
298
349
 
299
350
  should_not_have_json "access_token"
300
351
  should_have_json "error", "invalid_request"
352
+ should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :code_verifier)
301
353
  end
302
354
 
303
355
  scenario "mobile app requests an access token with authorization code with wrong verifier" do
@@ -313,6 +365,7 @@ feature "Authorization Code Flow" do
313
365
 
314
366
  should_not_have_json "access_token"
315
367
  should_have_json "error", "invalid_grant"
368
+ should_have_json "error_description", translated_error_message(:invalid_grant)
316
369
  end
317
370
 
318
371
  scenario "code_challenge_mehthod in token request is totally ignored" do
@@ -333,6 +386,7 @@ feature "Authorization Code Flow" do
333
386
 
334
387
  should_not_have_json "access_token"
335
388
  should_have_json "error", "invalid_grant"
389
+ should_have_json "error_description", translated_error_message(:invalid_grant)
336
390
  end
337
391
 
338
392
  scenario "expects to set code_challenge_method explicitely without fallback" do
@@ -344,16 +398,15 @@ feature "Authorization Code Flow" do
344
398
 
345
399
  context "when application scopes are present and no scope is passed" do
346
400
  background do
347
- @client.update(scopes: "public write read")
401
+ @client.update(scopes: "public write read default")
348
402
  end
349
403
 
350
- scenario "access grant has no scope" do
404
+ scenario "scope is invalid because default scope is different from application scope" do
351
405
  default_scopes_exist :admin
352
406
  visit authorization_endpoint_url(client: @client)
353
- click_on "Authorize"
354
- access_grant_should_exist_for(@client, @resource_owner)
355
- grant = Doorkeeper::AccessGrant.first
356
- expect(grant.scopes).to be_empty
407
+ response_status_should_be 200
408
+ i_should_not_see "Authorize"
409
+ i_should_see_translated_error_message :invalid_scope
357
410
  end
358
411
 
359
412
  scenario "access grant have scopes which are common in application scopees and default scopes" do
@@ -454,6 +507,7 @@ describe "Authorization Code Flow" do
454
507
 
455
508
  should_not_have_json "access_token"
456
509
  should_have_json "error", "invalid_grant"
510
+ should_have_json "error_description", translated_error_message(:invalid_grant)
457
511
  end
458
512
  end
459
513
  end
@@ -66,6 +66,44 @@ describe "Client Credentials Request" do
66
66
  end
67
67
  end
68
68
 
69
+ context "when configured to check application supported grant flow" do
70
+ before do
71
+ Doorkeeper.configuration.instance_variable_set(
72
+ :@allow_grant_flow_for_client,
73
+ ->(_grant_flow, client) { client.name == "admin" }
74
+ )
75
+ end
76
+
77
+ scenario "forbids the request when doesn't satisfy condition" do
78
+ client.update(name: "sample app")
79
+
80
+ headers = authorization client.uid, client.secret
81
+ params = { grant_type: "client_credentials" }
82
+
83
+ post "/oauth/token", params: params, headers: headers
84
+
85
+ should_have_json "error", "unauthorized_client"
86
+ should_have_json "error_description", translated_error_message(:unauthorized_client)
87
+ end
88
+
89
+ scenario "allows the request when satisfies condition" do
90
+ client.update(name: "admin")
91
+
92
+ headers = authorization client.uid, client.secret
93
+ params = { grant_type: "client_credentials" }
94
+
95
+ post "/oauth/token", params: params, headers: headers
96
+
97
+ should_have_json "access_token", Doorkeeper::AccessToken.first.token
98
+ should_have_json_within "expires_in", Doorkeeper.configuration.access_token_expires_in, 1
99
+ should_not_have_json "scope"
100
+ should_not_have_json "refresh_token"
101
+
102
+ should_not_have_json "error"
103
+ should_not_have_json "error_description"
104
+ end
105
+ end
106
+
69
107
  context "when application scopes contain some of the default scopes and no scope is passed" do
70
108
  before do
71
109
  client.update(scopes: "read write public")
@@ -4,6 +4,7 @@ require "spec_helper"
4
4
 
5
5
  feature "Implicit Grant Flow Errors" do
6
6
  background do
7
+ default_scopes_exist :default
7
8
  config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
8
9
  config_is_set(:grant_flows, ["implicit"])
9
10
  client_exists
@@ -15,20 +16,31 @@ feature "Implicit Grant Flow Errors" do
15
16
  access_token_should_not_exist
16
17
  end
17
18
 
18
- [
19
- %i[client_id invalid_client],
20
- %i[redirect_uri invalid_redirect_uri],
21
- ].each do |error|
22
- scenario "displays #{error.last} error for invalid #{error.first}" do
23
- visit authorization_endpoint_url(client: @client, error.first => "invalid", response_type: "token")
19
+ context "when validate client_id param" do
20
+ scenario "displays invalid_client error for invalid client_id" do
21
+ visit authorization_endpoint_url(client_id: "invalid", response_type: "token")
24
22
  i_should_not_see "Authorize"
25
- i_should_see_translated_error_message error.last
23
+ i_should_see_translated_error_message :invalid_client
26
24
  end
27
25
 
28
- scenario "displays #{error.last} error when #{error.first} is missing" do
29
- visit authorization_endpoint_url(client: @client, error.first => "", response_type: "token")
26
+ scenario "displays invalid_request error when client_id is missing" do
27
+ visit authorization_endpoint_url(client_id: "", response_type: "token")
30
28
  i_should_not_see "Authorize"
31
- i_should_see_translated_error_message error.last
29
+ i_should_see_translated_invalid_request_error_message :missing_param, :client_id
30
+ end
31
+ end
32
+
33
+ context "when validate redirect_uri param" do
34
+ scenario "displays invalid_redirect_uri error for invalid redirect_uri" do
35
+ visit authorization_endpoint_url(client: @client, redirect_uri: "invalid", response_type: "token")
36
+ i_should_not_see "Authorize"
37
+ i_should_see_translated_error_message :invalid_redirect_uri
38
+ end
39
+
40
+ scenario "displays invalid_redirect_uri error when redirect_uri is missing" do
41
+ visit authorization_endpoint_url(client: @client, redirect_uri: "", response_type: "token")
42
+ i_should_not_see "Authorize"
43
+ i_should_see_translated_error_message :invalid_redirect_uri
32
44
  end
33
45
  end
34
46
  end
@@ -4,6 +4,7 @@ require "spec_helper"
4
4
 
5
5
  feature "Implicit Grant Flow (feature spec)" do
6
6
  background do
7
+ default_scopes_exist :default
7
8
  config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
8
9
  config_is_set(:grant_flows, ["implicit"])
9
10
  client_exists
@@ -25,16 +26,15 @@ feature "Implicit Grant Flow (feature spec)" do
25
26
  @client.update(scopes: "public write read")
26
27
  end
27
28
 
28
- scenario "access token has no scopes" do
29
+ scenario "scope is invalid because default scope is different from application scope" do
29
30
  default_scopes_exist :admin
30
31
  visit authorization_endpoint_url(client: @client, response_type: "token")
31
- click_on "Authorize"
32
- access_token_should_exist_for @client, @resource_owner
33
- token = Doorkeeper::AccessToken.first
34
- expect(token.scopes).to be_empty
32
+ response_status_should_be 200
33
+ i_should_not_see "Authorize"
34
+ i_should_see_translated_error_message :invalid_scope
35
35
  end
36
36
 
37
- scenario "access token has scopes which are common in application scopees and default scopes" do
37
+ scenario "access token has scopes which are common in application scopes and default scopes" do
38
38
  default_scopes_exist :public, :write
39
39
  visit authorization_endpoint_url(client: @client, response_type: "token")
40
40
  click_on "Authorize"
@@ -46,6 +46,7 @@ end
46
46
 
47
47
  describe "Implicit Grant Flow (request spec)" do
48
48
  before do
49
+ default_scopes_exist :default
49
50
  config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
50
51
  config_is_set(:grant_flows, ["implicit"])
51
52
  client_exists
@@ -56,7 +57,7 @@ describe "Implicit Grant Flow (request spec)" do
56
57
  it "should return a new token each request" do
57
58
  allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(false)
58
59
 
59
- token = client_is_authorized(@client, @resource_owner)
60
+ token = client_is_authorized(@client, @resource_owner, scopes: "default")
60
61
 
61
62
  post "/oauth/authorize",
62
63
  params: {
@@ -73,7 +74,7 @@ describe "Implicit Grant Flow (request spec)" do
73
74
  it "should return the same token if it is still accessible" do
74
75
  allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
75
76
 
76
- token = client_is_authorized(@client, @resource_owner)
77
+ token = client_is_authorized(@client, @resource_owner, scopes: "default")
77
78
 
78
79
  post "/oauth/authorize",
79
80
  params: {
@@ -31,6 +31,43 @@ describe "Resource Owner Password Credentials Flow" do
31
31
  context "with non-confidential/public client" do
32
32
  let(:client_attributes) { { confidential: false } }
33
33
 
34
+ context "when configured to check application supported grant flow" do
35
+ before do
36
+ Doorkeeper.configuration.instance_variable_set(
37
+ :@allow_grant_flow_for_client,
38
+ ->(_grant_flow, client) { client.name == "admin" }
39
+ )
40
+ end
41
+
42
+ scenario "forbids the request when doesn't satisfy condition" do
43
+ @client.update(name: "sample app")
44
+
45
+ expect do
46
+ post password_token_endpoint_url(
47
+ client_id: @client.uid,
48
+ client_secret: "foobar",
49
+ resource_owner: @resource_owner
50
+ )
51
+ end.not_to(change { Doorkeeper::AccessToken.count })
52
+
53
+ expect(response.status).to eq(401)
54
+ should_have_json "error", "invalid_client"
55
+ end
56
+
57
+ scenario "allows the request when satisfies condition" do
58
+ @client.update(name: "admin")
59
+
60
+ expect do
61
+ post password_token_endpoint_url(client_id: @client.uid, resource_owner: @resource_owner)
62
+ end.to change { Doorkeeper::AccessToken.count }.by(1)
63
+
64
+ token = Doorkeeper::AccessToken.first
65
+
66
+ expect(token.application_id).to eq @client.id
67
+ should_have_json "access_token", token.token
68
+ end
69
+ end
70
+
34
71
  context "when client_secret absent" do
35
72
  it "should issue new token" do
36
73
  expect do