doorkeeper 5.2.2 → 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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +2 -2
  3. data/CHANGELOG.md +29 -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/gemfiles/rails_5_0.gemfile +2 -2
  11. data/gemfiles/rails_5_1.gemfile +2 -2
  12. data/gemfiles/rails_5_2.gemfile +2 -2
  13. data/gemfiles/rails_6_0.gemfile +2 -2
  14. data/gemfiles/rails_master.gemfile +2 -2
  15. data/lib/doorkeeper/config.rb +71 -38
  16. data/lib/doorkeeper/grape/helpers.rb +1 -1
  17. data/lib/doorkeeper/helpers/controller.rb +10 -8
  18. data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
  19. data/lib/doorkeeper/models/access_token_mixin.rb +56 -18
  20. data/lib/doorkeeper/models/application_mixin.rb +3 -3
  21. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  22. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  23. data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
  24. data/lib/doorkeeper/oauth/authorization/code.rb +4 -4
  25. data/lib/doorkeeper/oauth/authorization/token.rb +9 -6
  26. data/lib/doorkeeper/oauth/authorization_code_request.rb +13 -6
  27. data/lib/doorkeeper/oauth/base_request.rb +8 -4
  28. data/lib/doorkeeper/oauth/client.rb +7 -8
  29. data/lib/doorkeeper/oauth/client_credentials/creator.rb +16 -9
  30. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
  31. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +4 -4
  32. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
  33. data/lib/doorkeeper/oauth/code_response.rb +2 -2
  34. data/lib/doorkeeper/oauth/error.rb +1 -1
  35. data/lib/doorkeeper/oauth/error_response.rb +5 -5
  36. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
  37. data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
  38. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -1
  39. data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
  40. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
  41. data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -3
  42. data/lib/doorkeeper/oauth/pre_authorization.rb +12 -7
  43. data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -5
  44. data/lib/doorkeeper/oauth/token.rb +2 -2
  45. data/lib/doorkeeper/oauth/token_introspection.rb +6 -6
  46. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  47. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  48. data/lib/doorkeeper/orm/active_record/application.rb +5 -95
  49. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
  50. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
  51. data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
  52. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +3 -3
  53. data/lib/doorkeeper/orm/active_record.rb +3 -4
  54. data/lib/doorkeeper/rails/helpers.rb +4 -4
  55. data/lib/doorkeeper/rails/routes.rb +5 -7
  56. data/lib/doorkeeper/rake/db.rake +3 -3
  57. data/lib/doorkeeper/request/authorization_code.rb +3 -3
  58. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  59. data/lib/doorkeeper/request/password.rb +2 -2
  60. data/lib/doorkeeper/request/refresh_token.rb +3 -3
  61. data/lib/doorkeeper/request.rb +1 -1
  62. data/lib/doorkeeper/server.rb +1 -1
  63. data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
  64. data/lib/doorkeeper/version.rb +2 -2
  65. data/lib/doorkeeper.rb +2 -3
  66. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  67. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  68. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  69. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  70. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
  71. data/lib/generators/doorkeeper/templates/initializer.rb +39 -0
  72. data/spec/controllers/application_metal_controller_spec.rb +1 -1
  73. data/spec/controllers/applications_controller_spec.rb +3 -2
  74. data/spec/controllers/authorizations_controller_spec.rb +18 -18
  75. data/spec/controllers/protected_resources_controller_spec.rb +25 -17
  76. data/spec/controllers/token_info_controller_spec.rb +1 -1
  77. data/spec/controllers/tokens_controller_spec.rb +1 -1
  78. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
  79. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
  80. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
  81. data/spec/generators/install_generator_spec.rb +1 -1
  82. data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
  83. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  84. data/spec/lib/config_spec.rb +62 -7
  85. data/spec/lib/doorkeeper_spec.rb +1 -1
  86. data/spec/lib/models/revocable_spec.rb +3 -3
  87. data/spec/lib/oauth/authorization_code_request_spec.rb +127 -125
  88. data/spec/lib/oauth/base_request_spec.rb +160 -158
  89. data/spec/lib/oauth/base_response_spec.rb +27 -29
  90. data/spec/lib/oauth/client/credentials_spec.rb +1 -1
  91. data/spec/lib/oauth/client_credentials/creator_spec.rb +42 -5
  92. data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
  93. data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
  94. data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
  95. data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
  96. data/spec/lib/oauth/client_spec.rb +26 -26
  97. data/spec/lib/oauth/code_request_spec.rb +34 -34
  98. data/spec/lib/oauth/code_response_spec.rb +21 -25
  99. data/spec/lib/oauth/error_response_spec.rb +42 -44
  100. data/spec/lib/oauth/error_spec.rb +12 -14
  101. data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
  102. data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
  103. data/spec/lib/oauth/invalid_request_response_spec.rb +48 -50
  104. data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
  105. data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
  106. data/spec/lib/oauth/pre_authorization_spec.rb +159 -161
  107. data/spec/lib/oauth/refresh_token_request_spec.rb +138 -139
  108. data/spec/lib/oauth/scopes_spec.rb +104 -106
  109. data/spec/lib/oauth/token_request_spec.rb +115 -111
  110. data/spec/lib/oauth/token_response_spec.rb +71 -73
  111. data/spec/lib/oauth/token_spec.rb +121 -123
  112. data/spec/models/doorkeeper/access_grant_spec.rb +3 -5
  113. data/spec/models/doorkeeper/access_token_spec.rb +7 -7
  114. data/spec/models/doorkeeper/application_spec.rb +104 -77
  115. data/spec/requests/applications/applications_request_spec.rb +1 -1
  116. data/spec/requests/endpoints/authorization_spec.rb +5 -3
  117. data/spec/requests/flows/authorization_code_spec.rb +34 -22
  118. data/spec/requests/flows/client_credentials_spec.rb +1 -1
  119. data/spec/requests/flows/password_spec.rb +32 -12
  120. data/spec/requests/flows/refresh_token_spec.rb +19 -19
  121. data/spec/requests/flows/revoke_token_spec.rb +18 -12
  122. data/spec/spec_helper.rb +1 -4
  123. data/spec/support/shared/controllers_shared_context.rb +33 -23
  124. data/spec/validators/redirect_uri_validator_spec.rb +1 -1
  125. metadata +6 -5
  126. data/spec/support/http_method_shim.rb +0 -29
@@ -7,152 +7,150 @@ module Doorkeeper
7
7
  class AccessToken
8
8
  end
9
9
  end
10
+ end
10
11
 
11
- module OAuth
12
- describe Token do
13
- describe :from_request do
14
- let(:request) { double.as_null_object }
12
+ describe Doorkeeper::OAuth::Token do
13
+ describe ".from_request" do
14
+ let(:request) { double.as_null_object }
15
15
 
16
- let(:method) do
17
- ->(*) { "token-value" }
18
- end
16
+ let(:method) do
17
+ ->(*) { "token-value" }
18
+ end
19
19
 
20
- it "accepts anything that responds to #call" do
21
- expect(method).to receive(:call).with(request)
22
- Token.from_request request, method
23
- end
20
+ it "accepts anything that responds to #call" do
21
+ expect(method).to receive(:call).with(request)
22
+ described_class.from_request request, method
23
+ end
24
24
 
25
- it "delegates methods received as symbols to Token class" do
26
- expect(Token).to receive(:from_params).with(request)
27
- Token.from_request request, :from_params
28
- end
25
+ it "delegates methods received as symbols to described_class class" do
26
+ expect(described_class).to receive(:from_params).with(request)
27
+ described_class.from_request request, :from_params
28
+ end
29
29
 
30
- it "stops at the first credentials found" do
31
- not_called_method = double
32
- expect(not_called_method).not_to receive(:call)
33
- Token.from_request request, ->(_r) {}, method, not_called_method
34
- end
30
+ it "stops at the first credentials found" do
31
+ not_called_method = double
32
+ expect(not_called_method).not_to receive(:call)
33
+ described_class.from_request request, ->(_r) {}, method, not_called_method
34
+ end
35
35
 
36
- it "returns the credential from extractor method" do
37
- credentials = Token.from_request request, method
38
- expect(credentials).to eq("token-value")
39
- end
40
- end
36
+ it "returns the credential from extractor method" do
37
+ credentials = described_class.from_request request, method
38
+ expect(credentials).to eq("token-value")
39
+ end
40
+ end
41
41
 
42
- describe :from_access_token_param do
43
- it "returns token from access_token parameter" do
44
- request = double parameters: { access_token: "some-token" }
45
- token = Token.from_access_token_param(request)
46
- expect(token).to eq("some-token")
47
- end
48
- end
42
+ describe ".from_access_token_param" do
43
+ it "returns token from access_token parameter" do
44
+ request = double parameters: { access_token: "some-token" }
45
+ token = described_class.from_access_token_param(request)
46
+ expect(token).to eq("some-token")
47
+ end
48
+ end
49
49
 
50
- describe :from_bearer_param do
51
- it "returns token from bearer_token parameter" do
52
- request = double parameters: { bearer_token: "some-token" }
53
- token = Token.from_bearer_param(request)
54
- expect(token).to eq("some-token")
55
- end
56
- end
50
+ describe ".from_bearer_param" do
51
+ it "returns token from bearer_token parameter" do
52
+ request = double parameters: { bearer_token: "some-token" }
53
+ token = described_class.from_bearer_param(request)
54
+ expect(token).to eq("some-token")
55
+ end
56
+ end
57
57
 
58
- describe :from_bearer_authorization do
59
- it "returns token from capitalized authorization bearer" do
60
- request = double authorization: "Bearer SomeToken"
61
- token = Token.from_bearer_authorization(request)
62
- expect(token).to eq("SomeToken")
63
- end
58
+ describe ".from_bearer_authorization" do
59
+ it "returns token from capitalized authorization bearer" do
60
+ request = double authorization: "Bearer SomeToken"
61
+ token = described_class.from_bearer_authorization(request)
62
+ expect(token).to eq("SomeToken")
63
+ end
64
64
 
65
- it "returns token from lowercased authorization bearer" do
66
- request = double authorization: "bearer SomeToken"
67
- token = Token.from_bearer_authorization(request)
68
- expect(token).to eq("SomeToken")
69
- end
65
+ it "returns token from lowercased authorization bearer" do
66
+ request = double authorization: "bearer SomeToken"
67
+ token = described_class.from_bearer_authorization(request)
68
+ expect(token).to eq("SomeToken")
69
+ end
70
70
 
71
- it "does not return token if authorization is not bearer" do
72
- request = double authorization: "MAC SomeToken"
73
- token = Token.from_bearer_authorization(request)
74
- expect(token).to be_blank
75
- end
76
- end
71
+ it "does not return token if authorization is not bearer" do
72
+ request = double authorization: "MAC SomeToken"
73
+ token = described_class.from_bearer_authorization(request)
74
+ expect(token).to be_blank
75
+ end
76
+ end
77
77
 
78
- describe :from_basic_authorization do
79
- it "returns token from capitalized authorization basic" do
80
- request = double authorization: "Basic #{Base64.encode64 "SomeToken:"}"
81
- token = Token.from_basic_authorization(request)
82
- expect(token).to eq("SomeToken")
83
- end
78
+ describe ".from_basic_authorization" do
79
+ it "returns token from capitalized authorization basic" do
80
+ request = double authorization: "Basic #{Base64.encode64 "SomeToken:"}"
81
+ token = described_class.from_basic_authorization(request)
82
+ expect(token).to eq("SomeToken")
83
+ end
84
84
 
85
- it "returns token from lowercased authorization basic" do
86
- request = double authorization: "basic #{Base64.encode64 "SomeToken:"}"
87
- token = Token.from_basic_authorization(request)
88
- expect(token).to eq("SomeToken")
89
- end
85
+ it "returns token from lowercased authorization basic" do
86
+ request = double authorization: "basic #{Base64.encode64 "SomeToken:"}"
87
+ token = described_class.from_basic_authorization(request)
88
+ expect(token).to eq("SomeToken")
89
+ end
90
90
 
91
- it "does not return token if authorization is not basic" do
92
- request = double authorization: "MAC #{Base64.encode64 "SomeToken:"}"
93
- token = Token.from_basic_authorization(request)
94
- expect(token).to be_blank
91
+ it "does not return token if authorization is not basic" do
92
+ request = double authorization: "MAC #{Base64.encode64 "SomeToken:"}"
93
+ token = described_class.from_basic_authorization(request)
94
+ expect(token).to be_blank
95
+ end
96
+ end
97
+
98
+ describe ".authenticate" do
99
+ context "refresh tokens are disabled (default)" do
100
+ context "refresh tokens are enabled" do
101
+ it "does not revoke previous refresh_token if token was found" do
102
+ token = ->(_r) { "token" }
103
+ expect(
104
+ Doorkeeper::AccessToken,
105
+ ).to receive(:by_token).with("token").and_return(token)
106
+ expect(token).not_to receive(:revoke_previous_refresh_token!)
107
+ described_class.authenticate double, token
95
108
  end
96
109
  end
97
110
 
98
- describe :authenticate do
99
- context "refresh tokens are disabled (default)" do
100
- context "refresh tokens are enabled" do
101
- it "does not revoke previous refresh_token if token was found" do
102
- token = ->(_r) { "token" }
103
- expect(
104
- AccessToken
105
- ).to receive(:by_token).with("token").and_return(token)
106
- expect(token).not_to receive(:revoke_previous_refresh_token!)
107
- Token.authenticate double, token
108
- end
109
- end
110
-
111
- it "calls the finder if token was returned" do
112
- token = ->(_r) { "token" }
113
- expect(AccessToken).to receive(:by_token).with("token")
114
- Token.authenticate double, token
115
- end
116
- end
111
+ it "calls the finder if token was returned" do
112
+ token = ->(_r) { "token" }
113
+ expect(Doorkeeper::AccessToken).to receive(:by_token).with("token")
114
+ described_class.authenticate double, token
115
+ end
116
+ end
117
117
 
118
- context "token hashing is enabled" do
119
- include_context "with token hashing enabled"
118
+ context "token hashing is enabled" do
119
+ include_context "with token hashing enabled"
120
120
 
121
- let(:hashed_token) { hashed_or_plain_token_func.call("token") }
122
- let(:token) { ->(_r) { "token" } }
121
+ let(:hashed_token) { hashed_or_plain_token_func.call("token") }
122
+ let(:token) { ->(_r) { "token" } }
123
123
 
124
- it "searches with the hashed token" do
125
- expect(
126
- AccessToken
127
- ).to receive(:find_by).with(token: hashed_token).and_return(token)
128
- Token.authenticate double, token
129
- end
130
- end
124
+ it "searches with the hashed token" do
125
+ expect(
126
+ Doorkeeper::AccessToken,
127
+ ).to receive(:find_by).with(token: hashed_token).and_return(token)
128
+ described_class.authenticate double, token
129
+ end
130
+ end
131
131
 
132
- context "refresh tokens are enabled" do
133
- before do
134
- Doorkeeper.configure do
135
- orm DOORKEEPER_ORM
136
- use_refresh_token
137
- end
138
- end
139
-
140
- it "revokes previous refresh_token if token was found" do
141
- token = ->(_r) { "token" }
142
- expect(
143
- AccessToken
144
- ).to receive(:by_token).with("token").and_return(token)
145
- expect(token).to receive(:revoke_previous_refresh_token!)
146
- Token.authenticate double, token
147
- end
148
-
149
- it "calls the finder if token was returned" do
150
- token = ->(_r) { "token" }
151
- expect(AccessToken).to receive(:by_token).with("token")
152
- Token.authenticate double, token
153
- end
132
+ context "refresh tokens are enabled" do
133
+ before do
134
+ Doorkeeper.configure do
135
+ orm DOORKEEPER_ORM
136
+ use_refresh_token
154
137
  end
155
138
  end
139
+
140
+ it "revokes previous refresh_token if token was found" do
141
+ token = ->(_r) { "token" }
142
+ expect(
143
+ Doorkeeper::AccessToken,
144
+ ).to receive(:by_token).with("token").and_return(token)
145
+ expect(token).to receive(:revoke_previous_refresh_token!)
146
+ described_class.authenticate double, token
147
+ end
148
+
149
+ it "calls the finder if token was returned" do
150
+ token = ->(_r) { "token" }
151
+ expect(Doorkeeper::AccessToken).to receive(:by_token).with("token")
152
+ described_class.authenticate double, token
153
+ end
156
154
  end
157
155
  end
158
156
  end
@@ -81,9 +81,7 @@ describe Doorkeeper::AccessGrant do
81
81
  )
82
82
 
83
83
  # Not all the ORM support :id PK
84
- if grant.respond_to?(:id)
85
- expect(clazz.by_token(plain_text_token).id).to eq(grant.id)
86
- end
84
+ expect(clazz.by_token(plain_text_token).id).to eq(grant.id) if grant.respond_to?(:id)
87
85
 
88
86
  # And it modifies the token value
89
87
  grant.reload
@@ -141,7 +139,7 @@ describe Doorkeeper::AccessGrant do
141
139
  it "matches application" do
142
140
  access_grant_for_different_app = FactoryBot.create(
143
141
  :access_grant,
144
- default_attributes.merge(application: FactoryBot.create(:application))
142
+ default_attributes.merge(application: FactoryBot.create(:application)),
145
143
  )
146
144
 
147
145
  described_class.revoke_all_for(application.id, resource_owner)
@@ -152,7 +150,7 @@ describe Doorkeeper::AccessGrant do
152
150
  it "matches resource owner" do
153
151
  access_grant_for_different_owner = FactoryBot.create(
154
152
  :access_grant,
155
- default_attributes.merge(resource_owner_id: 90)
153
+ default_attributes.merge(resource_owner_id: 90),
156
154
  )
157
155
 
158
156
  described_class.revoke_all_for application.id, resource_owner
@@ -212,7 +212,7 @@ module Doorkeeper
212
212
  end
213
213
 
214
214
  expect { FactoryBot.create :access_token }.to(
215
- raise_error(Doorkeeper::Errors::UnableToGenerateToken)
215
+ raise_error(Doorkeeper::Errors::UnableToGenerateToken),
216
216
  )
217
217
  end
218
218
 
@@ -234,7 +234,7 @@ module Doorkeeper
234
234
  end
235
235
 
236
236
  expect { FactoryBot.create :access_token }.to(
237
- raise_error(LoadError)
237
+ raise_error(LoadError),
238
238
  )
239
239
  end
240
240
 
@@ -245,7 +245,7 @@ module Doorkeeper
245
245
  end
246
246
 
247
247
  expect { FactoryBot.create :access_token }.to(
248
- raise_error(Doorkeeper::Errors::TokenGeneratorNotFound, /NotReal/)
248
+ raise_error(Doorkeeper::Errors::TokenGeneratorNotFound, /NotReal/),
249
249
  )
250
250
  end
251
251
  end
@@ -468,7 +468,7 @@ module Doorkeeper
468
468
  it "matches application" do
469
469
  access_token_for_different_app = FactoryBot.create(
470
470
  :access_token,
471
- default_attributes.merge(application: FactoryBot.create(:application))
471
+ default_attributes.merge(application: FactoryBot.create(:application)),
472
472
  )
473
473
 
474
474
  AccessToken.revoke_all_for application.id, resource_owner
@@ -479,7 +479,7 @@ module Doorkeeper
479
479
  it "matches resource owner" do
480
480
  access_token_for_different_owner = FactoryBot.create(
481
481
  :access_token,
482
- default_attributes.merge(resource_owner_id: 90)
482
+ default_attributes.merge(resource_owner_id: 90),
483
483
  )
484
484
 
485
485
  AccessToken.revoke_all_for application.id, resource_owner
@@ -561,7 +561,7 @@ module Doorkeeper
561
561
 
562
562
  it "excludes tokens with scopes that are not present in server scopes" do
563
563
  FactoryBot.create :access_token, default_attributes.merge(
564
- application: application, scopes: "public read"
564
+ application: application, scopes: "public read",
565
565
  )
566
566
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
567
567
  expect(last_token).to be_nil
@@ -570,7 +570,7 @@ module Doorkeeper
570
570
  it "excludes tokens with scopes that are not present in application scopes" do
571
571
  application = FactoryBot.create :application, scopes: "private read"
572
572
  FactoryBot.create :access_token, default_attributes.merge(
573
- application: application
573
+ application: application,
574
574
  )
575
575
  last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
576
576
  expect(last_token).to be_nil
@@ -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
@@ -281,7 +281,7 @@ module Doorkeeper
281
281
  end
282
282
  end
283
283
 
284
- describe :authorized_for do
284
+ describe "#authorized_for" do
285
285
  let(:resource_owner) { double(:resource_owner, id: 10) }
286
286
 
287
287
  it "is empty if the application is not authorized for anyone" do
@@ -313,7 +313,7 @@ module Doorkeeper
313
313
  end
314
314
  end
315
315
 
316
- describe :revoke_tokens_and_grants_for do
316
+ describe "#revoke_tokens_and_grants_for" do
317
317
  it "revokes all access tokens and access grants" do
318
318
  application_id = 42
319
319
  resource_owner = double
@@ -326,7 +326,7 @@ module Doorkeeper
326
326
  end
327
327
  end
328
328
 
329
- describe :by_uid_and_secret do
329
+ describe "#by_uid_and_secret" do
330
330
  context "when application is private/confidential" do
331
331
  it "finds the application via uid/secret" do
332
332
  app = FactoryBot.create :application
@@ -360,7 +360,7 @@ module Doorkeeper
360
360
  end
361
361
  end
362
362
 
363
- describe :confidential? do
363
+ describe "#confidential?" do
364
364
  subject { FactoryBot.create(:application, confidential: confidential).confidential? }
365
365
 
366
366
  context "when application is private/confidential" do
@@ -373,5 +373,32 @@ module Doorkeeper
373
373
  it { expect(subject).to eq(false) }
374
374
  end
375
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
376
403
  end
377
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