doorkeeper 5.2.6 → 5.3.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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +2 -2
  3. data/CHANGELOG.md +15 -14
  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 +3 -3
  8. data/app/controllers/doorkeeper/authorizations_controller.rb +2 -2
  9. data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
  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.rb +2 -3
  16. data/lib/doorkeeper/config.rb +71 -39
  17. data/lib/doorkeeper/grape/helpers.rb +1 -1
  18. data/lib/doorkeeper/helpers/controller.rb +10 -8
  19. data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
  20. data/lib/doorkeeper/models/access_token_mixin.rb +55 -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 +7 -5
  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.rb +3 -3
  48. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  49. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  50. data/lib/doorkeeper/orm/active_record/application.rb +3 -155
  51. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
  52. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
  53. data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
  54. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +3 -3
  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.rb +1 -1
  59. data/lib/doorkeeper/request/authorization_code.rb +3 -3
  60. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  61. data/lib/doorkeeper/request/password.rb +2 -2
  62. data/lib/doorkeeper/request/refresh_token.rb +3 -3
  63. data/lib/doorkeeper/server.rb +1 -1
  64. data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
  65. data/lib/doorkeeper/version.rb +2 -2
  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 -8
  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 +61 -21
  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 +295 -373
  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
@@ -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
@@ -3,480 +3,402 @@
3
3
  require "spec_helper"
4
4
  require "bcrypt"
5
5
 
6
- describe Doorkeeper::Application do
7
- let(:require_owner) { Doorkeeper.configuration.instance_variable_set("@confirm_application_owner", true) }
8
- let(:unset_require_owner) { Doorkeeper.configuration.instance_variable_set("@confirm_application_owner", false) }
9
- let(:new_application) { FactoryBot.build(:application) }
6
+ module Doorkeeper
7
+ describe Application do
8
+ let(:clazz) { Doorkeeper::Application }
9
+ let(:require_owner) { Doorkeeper.configuration.instance_variable_set("@confirm_application_owner", true) }
10
+ let(:unset_require_owner) { Doorkeeper.configuration.instance_variable_set("@confirm_application_owner", false) }
11
+ let(:new_application) { FactoryBot.build(:application) }
10
12
 
11
- let(:uid) { SecureRandom.hex(8) }
12
- let(:secret) { SecureRandom.hex(8) }
13
+ let(:uid) { SecureRandom.hex(8) }
14
+ let(:secret) { SecureRandom.hex(8) }
13
15
 
14
- it "is invalid without a name" do
15
- new_application.name = nil
16
- expect(new_application).not_to be_valid
17
- end
18
-
19
- it "is invalid without determining confidentiality" do
20
- new_application.confidential = nil
21
- expect(new_application).not_to be_valid
22
- end
23
-
24
- it "generates uid on create" do
25
- expect(new_application.uid).to be_nil
26
- new_application.save
27
- expect(new_application.uid).not_to be_nil
28
- end
29
-
30
- it "generates uid on create if an empty string" do
31
- new_application.uid = ""
32
- new_application.save
33
- expect(new_application.uid).not_to be_blank
34
- end
16
+ it "is invalid without a name" do
17
+ new_application.name = nil
18
+ expect(new_application).not_to be_valid
19
+ end
35
20
 
36
- it "generates uid on create unless one is set" do
37
- new_application.uid = uid
38
- new_application.save
39
- expect(new_application.uid).to eq(uid)
40
- end
21
+ it "is invalid without determining confidentiality" do
22
+ new_application.confidential = nil
23
+ expect(new_application).not_to be_valid
24
+ end
41
25
 
42
- it "is invalid without uid" do
43
- new_application.save
44
- new_application.uid = nil
45
- expect(new_application).not_to be_valid
46
- end
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
47
31
 
48
- it "checks uniqueness of uid" do
49
- app1 = FactoryBot.create(:application)
50
- app2 = FactoryBot.create(:application)
51
- app2.uid = app1.uid
52
- expect(app2).not_to be_valid
53
- end
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
54
37
 
55
- it "expects database to throw an error when uids are the same" do
56
- app1 = FactoryBot.create(:application)
57
- app2 = FactoryBot.create(:application)
58
- app2.uid = app1.uid
59
- expect { app2.save!(validate: false) }.to raise_error(uniqueness_error)
60
- end
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
61
43
 
62
- it "generate secret on create" do
63
- expect(new_application.secret).to be_nil
64
- new_application.save
65
- expect(new_application.secret).not_to be_nil
66
- end
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
67
49
 
68
- it "generate secret on create if is blank string" do
69
- new_application.secret = ""
70
- new_application.save
71
- expect(new_application.secret).not_to be_blank
72
- end
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
73
56
 
74
- it "generate secret on create unless one is set" do
75
- new_application.secret = secret
76
- new_application.save
77
- expect(new_application.secret).to eq(secret)
78
- end
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
79
63
 
80
- it "is invalid without secret" do
81
- new_application.save
82
- new_application.secret = nil
83
- expect(new_application).not_to be_valid
84
- end
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
85
69
 
86
- context "application_owner is enabled" do
87
- before do
88
- Doorkeeper.configure do
89
- orm DOORKEEPER_ORM
90
- enable_application_owner
91
- end
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
92
74
  end
93
75
 
94
- context "application owner is not required" do
95
- before(:each) do
96
- unset_require_owner
97
- end
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
98
81
 
99
- it "is valid given valid attributes" do
100
- expect(new_application).to be_valid
101
- end
82
+ it "is invalid without secret" do
83
+ new_application.save
84
+ new_application.secret = nil
85
+ expect(new_application).not_to be_valid
102
86
  end
103
87
 
104
- context "application owner is required" do
88
+ context "application_owner is enabled" do
105
89
  before do
106
- require_owner
107
- @owner = FactoryBot.build_stubbed(:doorkeeper_testing_user)
90
+ Doorkeeper.configure do
91
+ orm DOORKEEPER_ORM
92
+ enable_application_owner
93
+ end
108
94
  end
109
95
 
110
- it "is invalid without an owner" do
111
- expect(new_application).not_to be_valid
112
- end
96
+ context "application owner is not required" do
97
+ before(:each) do
98
+ unset_require_owner
99
+ end
113
100
 
114
- it "is valid with an owner" do
115
- new_application.owner = @owner
116
- expect(new_application).to be_valid
101
+ it "is valid given valid attributes" do
102
+ expect(new_application).to be_valid
103
+ end
117
104
  end
118
- end
119
- end
120
105
 
121
- context "redirect URI" do
122
- context "when grant flows allow blank redirect URI" do
123
- before do
124
- Doorkeeper.configure do
125
- grant_flows %w[password client_credentials]
106
+ context "application owner is required" do
107
+ before(:each) do
108
+ require_owner
109
+ @owner = FactoryBot.build_stubbed(:doorkeeper_testing_user)
126
110
  end
127
- end
128
111
 
129
- it "is valid without redirect_uri" do
130
- new_application.save
131
- new_application.redirect_uri = nil
132
- expect(new_application).to be_valid
112
+ it "is invalid without an owner" do
113
+ expect(new_application).not_to be_valid
114
+ end
115
+
116
+ it "is valid with an owner" do
117
+ new_application.owner = @owner
118
+ expect(new_application).to be_valid
119
+ end
133
120
  end
134
121
  end
135
122
 
136
- context "when grant flows require redirect URI" do
137
- before do
138
- Doorkeeper.configure do
139
- grant_flows %w[password client_credentials authorization_code]
123
+ context "redirect URI" do
124
+ context "when grant flows allow blank redirect URI" do
125
+ before do
126
+ Doorkeeper.configure do
127
+ grant_flows %w[password client_credentials]
128
+ end
140
129
  end
141
- end
142
130
 
143
- it "is invalid without redirect_uri" do
144
- new_application.save
145
- new_application.redirect_uri = nil
146
- expect(new_application).not_to be_valid
131
+ it "is valid without redirect_uri" do
132
+ new_application.save
133
+ new_application.redirect_uri = nil
134
+ expect(new_application).to be_valid
135
+ end
147
136
  end
148
- end
149
137
 
150
- context "when blank URI option disabled" do
151
- before do
152
- Doorkeeper.configure do
153
- grant_flows %w[password client_credentials]
154
- allow_blank_redirect_uri false
138
+ context "when grant flows require redirect URI" do
139
+ before do
140
+ Doorkeeper.configure do
141
+ grant_flows %w[password client_credentials authorization_code]
142
+ end
143
+ end
144
+
145
+ it "is invalid without redirect_uri" do
146
+ new_application.save
147
+ new_application.redirect_uri = nil
148
+ expect(new_application).not_to be_valid
155
149
  end
156
150
  end
157
151
 
158
- it "is invalid without redirect_uri" do
159
- new_application.save
160
- new_application.redirect_uri = nil
161
- expect(new_application).not_to be_valid
152
+ context "when blank URI option disabled" do
153
+ before do
154
+ Doorkeeper.configure do
155
+ grant_flows %w[password client_credentials]
156
+ allow_blank_redirect_uri false
157
+ end
158
+ end
159
+
160
+ it "is invalid without redirect_uri" do
161
+ new_application.save
162
+ new_application.redirect_uri = nil
163
+ expect(new_application).not_to be_valid
164
+ end
162
165
  end
163
166
  end
164
- end
165
167
 
166
- context "with hashing enabled" do
167
- include_context "with application hashing enabled"
168
- let(:app) { FactoryBot.create :application }
169
- let(:default_strategy) { Doorkeeper::SecretStoring::Sha256Hash }
168
+ context "with hashing enabled" do
169
+ include_context "with application hashing enabled"
170
+ let(:app) { FactoryBot.create :application }
171
+ let(:default_strategy) { Doorkeeper::SecretStoring::Sha256Hash }
170
172
 
171
- it "uses SHA256 to avoid additional dependencies" do
172
- # Ensure token was generated
173
- app.validate
174
- expect(app.secret).to eq(default_strategy.transform_secret(app.plaintext_secret))
175
- end
173
+ it "uses SHA256 to avoid additional dependencies" do
174
+ # Ensure token was generated
175
+ app.validate
176
+ expect(app.secret).to eq(default_strategy.transform_secret(app.plaintext_secret))
177
+ end
176
178
 
177
- context "when bcrypt strategy is configured" do
178
- # In this text context, we have bcrypt loaded so `bcrypt_present?`
179
- # will always be true
180
- before do
181
- Doorkeeper.configure do
182
- hash_application_secrets using: "Doorkeeper::SecretStoring::BCrypt"
179
+ context "when bcrypt strategy is configured" do
180
+ # In this text context, we have bcrypt loaded so `bcrypt_present?`
181
+ # will always be true
182
+ before do
183
+ Doorkeeper.configure do
184
+ hash_application_secrets using: "Doorkeeper::SecretStoring::BCrypt"
185
+ end
183
186
  end
184
- end
185
187
 
186
- it "holds a volatile plaintext and BCrypt secret" do
187
- expect(app.secret_strategy).to eq Doorkeeper::SecretStoring::BCrypt
188
- expect(app.plaintext_secret).to be_a(String)
189
- expect(app.secret).not_to eq(app.plaintext_secret)
190
- expect { ::BCrypt::Password.create(app.secret) }.not_to raise_error
188
+ it "holds a volatile plaintext and BCrypt secret" do
189
+ expect(app.secret_strategy).to eq Doorkeeper::SecretStoring::BCrypt
190
+ expect(app.plaintext_secret).to be_a(String)
191
+ expect(app.secret).not_to eq(app.plaintext_secret)
192
+ expect { ::BCrypt::Password.create(app.secret) }.not_to raise_error
193
+ end
191
194
  end
192
- end
193
195
 
194
- it "does not fallback to plain lookup by default" do
195
- lookup = described_class.by_uid_and_secret(app.uid, app.secret)
196
- expect(lookup).to eq(nil)
196
+ it "does not fallback to plain lookup by default" do
197
+ lookup = clazz.by_uid_and_secret(app.uid, app.secret)
198
+ expect(lookup).to eq(nil)
197
199
 
198
- lookup = described_class.by_uid_and_secret(app.uid, app.plaintext_secret)
199
- expect(lookup).to eq(app)
200
- end
200
+ lookup = clazz.by_uid_and_secret(app.uid, app.plaintext_secret)
201
+ expect(lookup).to eq(app)
202
+ end
201
203
 
202
- context "with fallback enabled" do
203
- include_context "with token hashing and fallback lookup enabled"
204
+ context "with fallback enabled" do
205
+ include_context "with token hashing and fallback lookup enabled"
204
206
 
205
- it "provides plain and hashed lookup" do
206
- lookup = described_class.by_uid_and_secret(app.uid, app.secret)
207
- expect(lookup).to eq(app)
207
+ it "provides plain and hashed lookup" do
208
+ lookup = clazz.by_uid_and_secret(app.uid, app.secret)
209
+ expect(lookup).to eq(app)
208
210
 
209
- lookup = described_class.by_uid_and_secret(app.uid, app.plaintext_secret)
210
- expect(lookup).to eq(app)
211
+ lookup = clazz.by_uid_and_secret(app.uid, app.plaintext_secret)
212
+ expect(lookup).to eq(app)
213
+ end
211
214
  end
212
- end
213
215
 
214
- it "does not provide access to secret after loading" do
215
- lookup = described_class.by_uid_and_secret(app.uid, app.plaintext_secret)
216
- expect(lookup.plaintext_secret).to be_nil
217
- end
218
- end
219
-
220
- describe "destroy related models on cascade" do
221
- before(:each) do
222
- new_application.save
216
+ it "does not provide access to secret after loading" do
217
+ lookup = clazz.by_uid_and_secret(app.uid, app.plaintext_secret)
218
+ expect(lookup.plaintext_secret).to be_nil
219
+ end
223
220
  end
224
221
 
225
- let(:resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
226
-
227
- it "should destroy its access grants" do
228
- FactoryBot.create(
229
- :access_grant,
230
- application: new_application,
231
- resource_owner_id: resource_owner.id,
232
- )
222
+ describe "destroy related models on cascade" do
223
+ before(:each) do
224
+ new_application.save
225
+ end
233
226
 
234
- expect { new_application.destroy }.to change { Doorkeeper::AccessGrant.count }.by(-1)
235
- end
227
+ it "should destroy its access grants" do
228
+ FactoryBot.create(:access_grant, application: new_application)
229
+ expect { new_application.destroy }.to change { Doorkeeper::AccessGrant.count }.by(-1)
230
+ end
236
231
 
237
- it "should destroy its access tokens" do
238
- FactoryBot.create(:access_token, application: new_application)
239
- FactoryBot.create(:access_token, application: new_application, revoked_at: Time.now.utc)
240
- expect do
241
- new_application.destroy
242
- end.to change { Doorkeeper::AccessToken.count }.by(-2)
232
+ it "should destroy its access tokens" do
233
+ FactoryBot.create(:access_token, application: new_application)
234
+ FactoryBot.create(:access_token, application: new_application, revoked_at: Time.now.utc)
235
+ expect do
236
+ new_application.destroy
237
+ end.to change { Doorkeeper::AccessToken.count }.by(-2)
238
+ end
243
239
  end
244
- end
245
240
 
246
- describe "#ordered_by" do
247
- let(:applications) { FactoryBot.create_list(:application, 5) }
241
+ describe "#ordered_by" do
242
+ let(:applications) { FactoryBot.create_list(:application, 5) }
248
243
 
249
- context "when a direction is not specified" do
250
- it "calls order with a default order of asc" do
251
- names = applications.map(&:name).sort
252
- expect(described_class.ordered_by(:name).map(&:name)).to eq(names)
244
+ context "when a direction is not specified" do
245
+ it "calls order with a default order of asc" do
246
+ names = applications.map(&:name).sort
247
+ expect(Application.ordered_by(:name).map(&:name)).to eq(names)
248
+ end
253
249
  end
254
- end
255
250
 
256
- context "when a direction is specified" do
257
- it "calls order with specified direction" do
258
- names = applications.map(&:name).sort.reverse
259
- expect(described_class.ordered_by(:name, :desc).map(&:name)).to eq(names)
251
+ context "when a direction is specified" do
252
+ it "calls order with specified direction" do
253
+ names = applications.map(&:name).sort.reverse
254
+ expect(Application.ordered_by(:name, :desc).map(&:name)).to eq(names)
255
+ end
260
256
  end
261
257
  end
262
- end
263
258
 
264
- describe "#redirect_uri=" do
265
- context "when array of valid redirect_uris" do
266
- it "should join by newline" do
267
- new_application.redirect_uri = ["http://localhost/callback1", "http://localhost/callback2"]
268
- expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
259
+ describe "#redirect_uri=" do
260
+ context "when array of valid redirect_uris" do
261
+ it "should join by newline" do
262
+ new_application.redirect_uri = ["http://localhost/callback1", "http://localhost/callback2"]
263
+ expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
264
+ end
269
265
  end
270
- end
271
- context "when string of valid redirect_uris" do
272
- it "should store as-is" do
273
- new_application.redirect_uri = "http://localhost/callback1\nhttp://localhost/callback2"
274
- expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
266
+ context "when string of valid redirect_uris" do
267
+ it "should store as-is" do
268
+ new_application.redirect_uri = "http://localhost/callback1\nhttp://localhost/callback2"
269
+ expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
270
+ end
275
271
  end
276
272
  end
277
- end
278
273
 
279
- describe "#renew_secret" do
280
- let(:app) { FactoryBot.create :application }
274
+ describe "#renew_secret" do
275
+ let(:app) { FactoryBot.create :application }
281
276
 
282
- it "should generate a new secret" do
283
- old_secret = app.secret
284
- app.renew_secret
285
- expect(old_secret).not_to eq(app.secret)
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
286
282
  end
287
- end
288
283
 
289
- describe "#authorized_for" do
290
- let(:resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
291
- let(:other_resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
284
+ describe "#authorized_for" do
285
+ let(:resource_owner) { double(:resource_owner, id: 10) }
292
286
 
293
- it "is empty if the application is not authorized for anyone" do
294
- expect(described_class.authorized_for(resource_owner)).to be_empty
295
- end
287
+ it "is empty if the application is not authorized for anyone" do
288
+ expect(Application.authorized_for(resource_owner)).to be_empty
289
+ end
296
290
 
297
- it "returns only application for a specific resource owner" do
298
- FactoryBot.create(
299
- :access_token,
300
- resource_owner_id: other_resource_owner.id,
301
- )
302
- token = FactoryBot.create(
303
- :access_token,
304
- resource_owner_id: resource_owner.id,
305
- )
306
- expect(described_class.authorized_for(resource_owner)).to eq([token.application])
307
- end
291
+ it "returns only application for a specific resource owner" do
292
+ FactoryBot.create(:access_token, resource_owner_id: resource_owner.id + 1)
293
+ token = FactoryBot.create(:access_token, resource_owner_id: resource_owner.id)
294
+ expect(Application.authorized_for(resource_owner)).to eq([token.application])
295
+ end
308
296
 
309
- it "excludes revoked tokens" do
310
- FactoryBot.create(
311
- :access_token,
312
- resource_owner_id: resource_owner.id,
313
- revoked_at: 2.days.ago,
314
- )
315
- expect(described_class.authorized_for(resource_owner)).to be_empty
316
- end
297
+ it "excludes revoked tokens" do
298
+ FactoryBot.create(:access_token, resource_owner_id: resource_owner.id, revoked_at: 2.days.ago)
299
+ expect(Application.authorized_for(resource_owner)).to be_empty
300
+ end
317
301
 
318
- it "returns all applications that have been authorized" do
319
- token1 = FactoryBot.create(
320
- :access_token,
321
- resource_owner_id: resource_owner.id,
322
- )
323
- token2 = FactoryBot.create(
324
- :access_token,
325
- resource_owner_id: resource_owner.id,
326
- )
327
- expect(described_class.authorized_for(resource_owner))
328
- .to eq([token1.application, token2.application])
329
- end
302
+ it "returns all applications that have been authorized" do
303
+ token1 = FactoryBot.create(:access_token, resource_owner_id: resource_owner.id)
304
+ token2 = FactoryBot.create(:access_token, resource_owner_id: resource_owner.id)
305
+ expect(Application.authorized_for(resource_owner)).to eq([token1.application, token2.application])
306
+ end
330
307
 
331
- it "returns only one application even if it has been authorized twice" do
332
- application = FactoryBot.create(:application)
333
- FactoryBot.create(
334
- :access_token,
335
- resource_owner_id: resource_owner.id,
336
- application: application,
337
- )
338
- FactoryBot.create(
339
- :access_token,
340
- resource_owner_id: resource_owner.id,
341
- application: application,
342
- )
343
- expect(described_class.authorized_for(resource_owner)).to eq([application])
308
+ it "returns only one application even if it has been authorized twice" do
309
+ application = FactoryBot.create(:application)
310
+ FactoryBot.create(:access_token, resource_owner_id: resource_owner.id, application: application)
311
+ FactoryBot.create(:access_token, resource_owner_id: resource_owner.id, application: application)
312
+ expect(Application.authorized_for(resource_owner)).to eq([application])
313
+ end
344
314
  end
345
- end
346
315
 
347
- describe "#revoke_tokens_and_grants_for" do
348
- it "revokes all access tokens and access grants" do
349
- application_id = 42
350
- resource_owner = double
351
- expect(Doorkeeper::AccessToken)
352
- .to receive(:revoke_all_for).with(application_id, resource_owner)
353
- expect(Doorkeeper::AccessGrant)
354
- .to receive(:revoke_all_for).with(application_id, resource_owner)
316
+ describe "#revoke_tokens_and_grants_for" do
317
+ it "revokes all access tokens and access grants" do
318
+ application_id = 42
319
+ resource_owner = double
320
+ expect(Doorkeeper::AccessToken)
321
+ .to receive(:revoke_all_for).with(application_id, resource_owner)
322
+ expect(Doorkeeper::AccessGrant)
323
+ .to receive(:revoke_all_for).with(application_id, resource_owner)
355
324
 
356
- described_class.revoke_tokens_and_grants_for(application_id, resource_owner)
325
+ Application.revoke_tokens_and_grants_for(application_id, resource_owner)
326
+ end
357
327
  end
358
- end
359
328
 
360
- describe "#by_uid_and_secret" do
361
- context "when application is private/confidential" do
362
- it "finds the application via uid/secret" do
363
- app = FactoryBot.create :application
364
- authenticated = described_class.by_uid_and_secret(app.uid, app.secret)
365
- expect(authenticated).to eq(app)
366
- end
367
- context "when secret is wrong" do
368
- it "should not find the application" do
329
+ describe "#by_uid_and_secret" do
330
+ context "when application is private/confidential" do
331
+ it "finds the application via uid/secret" do
369
332
  app = FactoryBot.create :application
370
- authenticated = described_class.by_uid_and_secret(app.uid, "bad")
371
- expect(authenticated).to eq(nil)
333
+ authenticated = Application.by_uid_and_secret(app.uid, app.secret)
334
+ expect(authenticated).to eq(app)
335
+ end
336
+ context "when secret is wrong" do
337
+ it "should not find the application" do
338
+ app = FactoryBot.create :application
339
+ authenticated = Application.by_uid_and_secret(app.uid, "bad")
340
+ expect(authenticated).to eq(nil)
341
+ end
372
342
  end
373
343
  end
374
- end
375
344
 
376
- context "when application is public/non-confidential" do
377
- context "when secret is blank" do
378
- it "should find the application" do
379
- app = FactoryBot.create :application, confidential: false
380
- authenticated = described_class.by_uid_and_secret(app.uid, nil)
381
- expect(authenticated).to eq(app)
345
+ context "when application is public/non-confidential" do
346
+ context "when secret is blank" do
347
+ it "should find the application" do
348
+ app = FactoryBot.create :application, confidential: false
349
+ authenticated = Application.by_uid_and_secret(app.uid, nil)
350
+ expect(authenticated).to eq(app)
351
+ end
382
352
  end
383
- end
384
- context "when secret is wrong" do
385
- it "should not find the application" do
386
- app = FactoryBot.create :application, confidential: false
387
- authenticated = described_class.by_uid_and_secret(app.uid, "bad")
388
- expect(authenticated).to eq(nil)
353
+ context "when secret is wrong" do
354
+ it "should not find the application" do
355
+ app = FactoryBot.create :application, confidential: false
356
+ authenticated = Application.by_uid_and_secret(app.uid, "bad")
357
+ expect(authenticated).to eq(nil)
358
+ end
389
359
  end
390
360
  end
391
361
  end
392
- end
393
-
394
- describe "#confidential?" do
395
- subject { FactoryBot.create(:application, confidential: confidential).confidential? }
396
362
 
397
- context "when application is private/confidential" do
398
- let(:confidential) { true }
399
- it { expect(subject).to eq(true) }
400
- end
363
+ describe "#confidential?" do
364
+ subject { FactoryBot.create(:application, confidential: confidential).confidential? }
401
365
 
402
- context "when application is public/non-confidential" do
403
- let(:confidential) { false }
404
- it { expect(subject).to eq(false) }
405
- end
406
- end
407
-
408
- describe "#as_json" do
409
- let(:app) { FactoryBot.create :application, secret: "123123123" }
410
-
411
- before do
412
- allow(Doorkeeper.configuration)
413
- .to receive(:application_secret_strategy).and_return(Doorkeeper::SecretStoring::Plain)
414
- end
366
+ context "when application is private/confidential" do
367
+ let(:confidential) { true }
368
+ it { expect(subject).to eq(true) }
369
+ end
415
370
 
416
- # AR specific feature
417
- if DOORKEEPER_ORM == :active_record
418
- it "correctly works with #to_json" do
419
- ActiveRecord::Base.include_root_in_json = true
420
- expect(app.to_json(include_root_in_json: true)).to match(/application.+?:\{/)
421
- ActiveRecord::Base.include_root_in_json = false
371
+ context "when application is public/non-confidential" do
372
+ let(:confidential) { false }
373
+ it { expect(subject).to eq(false) }
422
374
  end
423
375
  end
424
376
 
425
- context "when called without authorized resource owner" do
426
- it "includes minimal set of attributes" do
427
- expect(app.as_json).to match(
428
- "id" => app.id,
429
- "name" => app.name,
430
- "created_at" => an_instance_of(String),
431
- )
432
- end
377
+ describe "#as_json" do
378
+ let(:app) { FactoryBot.create :application, secret: "123123123" }
433
379
 
434
- it "includes application UID if it's public" do
435
- app = FactoryBot.create :application, secret: "123123123", confidential: false
380
+ before do
381
+ allow(Doorkeeper.configuration)
382
+ .to receive(:application_secret_strategy).and_return(Doorkeeper::SecretStoring::Plain)
383
+ end
436
384
 
437
- expect(app.as_json).to match(
438
- "id" => app.id,
439
- "name" => app.name,
440
- "created_at" => an_instance_of(String),
441
- "uid" => app.uid,
442
- )
385
+ it "includes plaintext secret" do
386
+ expect(app.as_json).to include("secret" => "123123123")
443
387
  end
444
388
 
445
389
  it "respects custom options" do
446
- expect(app.as_json(except: :id)).not_to include("id")
447
- expect(app.as_json(only: %i[name created_at secret]))
448
- .to match(
449
- "name" => app.name,
450
- "created_at" => an_instance_of(String),
451
- )
390
+ expect(app.as_json(except: :secret)).not_to include("secret")
391
+ expect(app.as_json(only: :id)).to match("id" => app.id)
452
392
  end
453
- end
454
393
 
455
- context "when called with authorized resource owner" do
456
- let(:owner) { FactoryBot.create(:doorkeeper_testing_user) }
457
- let(:other_owner) { FactoryBot.create(:doorkeeper_testing_user) }
458
- let(:app) { FactoryBot.create(:application, secret: "123123123", owner: owner) }
459
-
460
- before do
461
- Doorkeeper.configure do
462
- orm DOORKEEPER_ORM
463
- enable_application_owner confirmation: false
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
464
400
  end
465
401
  end
466
-
467
- it "includes all the attributes" do
468
- expect(app.as_json(current_resource_owner: owner))
469
- .to include(
470
- "secret" => "123123123",
471
- "redirect_uri" => app.redirect_uri,
472
- "uid" => app.uid,
473
- )
474
- end
475
-
476
- it "doesn't include unsafe attributes if current owner isn't the same as owner" do
477
- expect(app.as_json(current_resource_owner: other_owner))
478
- .not_to include("redirect_uri")
479
- end
480
402
  end
481
403
  end
482
404
  end