doorkeeper 5.3.0 → 5.4.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 (225) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +97 -1
  3. data/README.md +6 -4
  4. data/app/controllers/doorkeeper/applications_controller.rb +7 -7
  5. data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
  6. data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
  7. data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
  8. data/app/views/doorkeeper/applications/_form.html.erb +1 -1
  9. data/app/views/doorkeeper/applications/show.html.erb +19 -2
  10. data/config/locales/en.yml +3 -1
  11. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  12. data/lib/doorkeeper/config/option.rb +28 -14
  13. data/lib/doorkeeper/config.rb +65 -35
  14. data/lib/doorkeeper/engine.rb +1 -1
  15. data/lib/doorkeeper/grape/helpers.rb +1 -1
  16. data/lib/doorkeeper/helpers/controller.rb +4 -4
  17. data/lib/doorkeeper/models/access_grant_mixin.rb +20 -16
  18. data/lib/doorkeeper/models/access_token_mixin.rb +110 -46
  19. data/lib/doorkeeper/models/application_mixin.rb +5 -4
  20. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  21. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  22. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  23. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  24. data/lib/doorkeeper/oauth/authorization/code.rb +15 -6
  25. data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
  26. data/lib/doorkeeper/oauth/authorization/token.rb +8 -12
  27. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  28. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
  29. data/lib/doorkeeper/oauth/base_request.rb +11 -19
  30. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  31. data/lib/doorkeeper/oauth/client.rb +1 -1
  32. data/lib/doorkeeper/oauth/client_credentials/creator.rb +26 -8
  33. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  34. data/lib/doorkeeper/oauth/client_credentials/validator.rb +4 -2
  35. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  36. data/lib/doorkeeper/oauth/code_request.rb +3 -3
  37. data/lib/doorkeeper/oauth/code_response.rb +6 -2
  38. data/lib/doorkeeper/oauth/error_response.rb +2 -4
  39. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
  40. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  41. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  42. data/lib/doorkeeper/oauth/password_access_token_request.rb +4 -6
  43. data/lib/doorkeeper/oauth/pre_authorization.rb +36 -30
  44. data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
  45. data/lib/doorkeeper/oauth/token.rb +5 -6
  46. data/lib/doorkeeper/oauth/token_introspection.rb +4 -8
  47. data/lib/doorkeeper/oauth/token_request.rb +3 -3
  48. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  49. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +8 -3
  50. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +7 -3
  51. data/lib/doorkeeper/orm/active_record/mixins/application.rb +69 -10
  52. data/lib/doorkeeper/orm/active_record.rb +10 -2
  53. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  54. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  55. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  56. data/lib/doorkeeper/rails/routes.rb +13 -17
  57. data/lib/doorkeeper/request/refresh_token.rb +2 -1
  58. data/lib/doorkeeper/request/strategy.rb +2 -2
  59. data/lib/doorkeeper/server.rb +4 -4
  60. data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
  61. data/lib/doorkeeper/version.rb +1 -1
  62. data/lib/doorkeeper.rb +106 -79
  63. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  64. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  65. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
  66. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  67. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  68. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  69. data/lib/generators/doorkeeper/templates/initializer.rb +47 -3
  70. data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
  71. metadata +12 -295
  72. data/Appraisals +0 -40
  73. data/CODE_OF_CONDUCT.md +0 -46
  74. data/CONTRIBUTING.md +0 -49
  75. data/Dangerfile +0 -67
  76. data/Dockerfile +0 -29
  77. data/Gemfile +0 -25
  78. data/NEWS.md +0 -1
  79. data/RELEASING.md +0 -11
  80. data/Rakefile +0 -28
  81. data/SECURITY.md +0 -15
  82. data/UPGRADE.md +0 -2
  83. data/bin/console +0 -16
  84. data/doorkeeper.gemspec +0 -42
  85. data/gemfiles/rails_5_0.gemfile +0 -18
  86. data/gemfiles/rails_5_1.gemfile +0 -18
  87. data/gemfiles/rails_5_2.gemfile +0 -18
  88. data/gemfiles/rails_6_0.gemfile +0 -18
  89. data/gemfiles/rails_master.gemfile +0 -18
  90. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  91. data/spec/controllers/applications_controller_spec.rb +0 -274
  92. data/spec/controllers/authorizations_controller_spec.rb +0 -608
  93. data/spec/controllers/protected_resources_controller_spec.rb +0 -361
  94. data/spec/controllers/token_info_controller_spec.rb +0 -50
  95. data/spec/controllers/tokens_controller_spec.rb +0 -498
  96. data/spec/dummy/Rakefile +0 -9
  97. data/spec/dummy/app/assets/config/manifest.js +0 -2
  98. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  99. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  100. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  101. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  102. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  103. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  104. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  105. data/spec/dummy/app/models/user.rb +0 -7
  106. data/spec/dummy/app/views/home/index.html.erb +0 -0
  107. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  108. data/spec/dummy/config/application.rb +0 -49
  109. data/spec/dummy/config/boot.rb +0 -7
  110. data/spec/dummy/config/database.yml +0 -15
  111. data/spec/dummy/config/environment.rb +0 -5
  112. data/spec/dummy/config/environments/development.rb +0 -31
  113. data/spec/dummy/config/environments/production.rb +0 -64
  114. data/spec/dummy/config/environments/test.rb +0 -45
  115. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  116. data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
  117. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  118. data/spec/dummy/config/initializers/session_store.rb +0 -10
  119. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  120. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  121. data/spec/dummy/config/routes.rb +0 -13
  122. data/spec/dummy/config.ru +0 -6
  123. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  124. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  125. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  126. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  127. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  128. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  129. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  130. data/spec/dummy/db/schema.rb +0 -68
  131. data/spec/dummy/public/404.html +0 -26
  132. data/spec/dummy/public/422.html +0 -26
  133. data/spec/dummy/public/500.html +0 -26
  134. data/spec/dummy/public/favicon.ico +0 -0
  135. data/spec/dummy/script/rails +0 -9
  136. data/spec/factories.rb +0 -30
  137. data/spec/generators/application_owner_generator_spec.rb +0 -28
  138. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  139. data/spec/generators/install_generator_spec.rb +0 -36
  140. data/spec/generators/migration_generator_spec.rb +0 -28
  141. data/spec/generators/pkce_generator_spec.rb +0 -28
  142. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  143. data/spec/generators/templates/routes.rb +0 -4
  144. data/spec/generators/views_generator_spec.rb +0 -29
  145. data/spec/grape/grape_integration_spec.rb +0 -137
  146. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  147. data/spec/lib/config_spec.rb +0 -794
  148. data/spec/lib/doorkeeper_spec.rb +0 -27
  149. data/spec/lib/models/expirable_spec.rb +0 -61
  150. data/spec/lib/models/reusable_spec.rb +0 -40
  151. data/spec/lib/models/revocable_spec.rb +0 -59
  152. data/spec/lib/models/scopes_spec.rb +0 -53
  153. data/spec/lib/models/secret_storable_spec.rb +0 -135
  154. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  155. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -170
  156. data/spec/lib/oauth/base_request_spec.rb +0 -224
  157. data/spec/lib/oauth/base_response_spec.rb +0 -45
  158. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  159. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -134
  160. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  161. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  162. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  163. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -107
  164. data/spec/lib/oauth/client_spec.rb +0 -38
  165. data/spec/lib/oauth/code_request_spec.rb +0 -46
  166. data/spec/lib/oauth/code_response_spec.rb +0 -32
  167. data/spec/lib/oauth/error_response_spec.rb +0 -64
  168. data/spec/lib/oauth/error_spec.rb +0 -21
  169. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
  170. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
  171. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  172. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  173. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
  174. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
  175. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -190
  176. data/spec/lib/oauth/pre_authorization_spec.rb +0 -223
  177. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
  178. data/spec/lib/oauth/scopes_spec.rb +0 -146
  179. data/spec/lib/oauth/token_request_spec.rb +0 -157
  180. data/spec/lib/oauth/token_response_spec.rb +0 -84
  181. data/spec/lib/oauth/token_spec.rb +0 -156
  182. data/spec/lib/request/strategy_spec.rb +0 -54
  183. data/spec/lib/secret_storing/base_spec.rb +0 -60
  184. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  185. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  186. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  187. data/spec/lib/server_spec.rb +0 -49
  188. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  189. data/spec/models/doorkeeper/access_grant_spec.rb +0 -161
  190. data/spec/models/doorkeeper/access_token_spec.rb +0 -622
  191. data/spec/models/doorkeeper/application_spec.rb +0 -404
  192. data/spec/requests/applications/applications_request_spec.rb +0 -259
  193. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  194. data/spec/requests/endpoints/authorization_spec.rb +0 -91
  195. data/spec/requests/endpoints/token_spec.rb +0 -75
  196. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
  197. data/spec/requests/flows/authorization_code_spec.rb +0 -525
  198. data/spec/requests/flows/client_credentials_spec.rb +0 -166
  199. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  200. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  201. data/spec/requests/flows/password_spec.rb +0 -316
  202. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  203. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  204. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  205. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  206. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  207. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  208. data/spec/routing/default_routes_spec.rb +0 -41
  209. data/spec/routing/scoped_routes_spec.rb +0 -47
  210. data/spec/spec_helper.rb +0 -54
  211. data/spec/spec_helper_integration.rb +0 -4
  212. data/spec/support/dependencies/factory_bot.rb +0 -4
  213. data/spec/support/doorkeeper_rspec.rb +0 -22
  214. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  215. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  216. data/spec/support/helpers/config_helper.rb +0 -11
  217. data/spec/support/helpers/model_helper.rb +0 -78
  218. data/spec/support/helpers/request_spec_helper.rb +0 -110
  219. data/spec/support/helpers/url_helper.rb +0 -62
  220. data/spec/support/orm/active_record.rb +0 -5
  221. data/spec/support/shared/controllers_shared_context.rb +0 -133
  222. data/spec/support/shared/hashing_shared_context.rb +0 -36
  223. data/spec/support/shared/models_shared_examples.rb +0 -54
  224. data/spec/validators/redirect_uri_validator_spec.rb +0 -183
  225. data/spec/version/version_spec.rb +0 -17
@@ -1,404 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "bcrypt"
5
-
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) }
12
-
13
- let(:uid) { SecureRandom.hex(8) }
14
- let(:secret) { SecureRandom.hex(8) }
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
-
88
- context "application_owner is enabled" do
89
- before do
90
- Doorkeeper.configure do
91
- orm DOORKEEPER_ORM
92
- enable_application_owner
93
- end
94
- end
95
-
96
- context "application owner is not required" do
97
- before(:each) do
98
- unset_require_owner
99
- end
100
-
101
- it "is valid given valid attributes" do
102
- expect(new_application).to be_valid
103
- end
104
- end
105
-
106
- context "application owner is required" do
107
- before(:each) do
108
- require_owner
109
- @owner = FactoryBot.build_stubbed(:doorkeeper_testing_user)
110
- end
111
-
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
120
- end
121
- end
122
-
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
129
- end
130
-
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
136
- end
137
-
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
149
- end
150
- end
151
-
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
165
- end
166
- end
167
-
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 }
172
-
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
178
-
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
186
- end
187
-
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
194
- end
195
-
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)
199
-
200
- lookup = clazz.by_uid_and_secret(app.uid, app.plaintext_secret)
201
- expect(lookup).to eq(app)
202
- end
203
-
204
- context "with fallback enabled" do
205
- include_context "with token hashing and fallback lookup enabled"
206
-
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)
210
-
211
- lookup = clazz.by_uid_and_secret(app.uid, app.plaintext_secret)
212
- expect(lookup).to eq(app)
213
- end
214
- end
215
-
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
220
- end
221
-
222
- describe "destroy related models on cascade" do
223
- before(:each) do
224
- new_application.save
225
- end
226
-
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
231
-
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
239
- end
240
-
241
- describe "#ordered_by" do
242
- let(:applications) { FactoryBot.create_list(:application, 5) }
243
-
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
249
- end
250
-
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
256
- end
257
- end
258
-
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
265
- end
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
271
- end
272
- end
273
-
274
- describe "#renew_secret" do
275
- let(:app) { FactoryBot.create :application }
276
-
277
- it "should generate a new secret" do
278
- old_secret = app.secret
279
- app.renew_secret
280
- expect(old_secret).not_to eq(app.secret)
281
- end
282
- end
283
-
284
- describe "#authorized_for" do
285
- let(:resource_owner) { double(:resource_owner, id: 10) }
286
-
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
290
-
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
296
-
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
301
-
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
307
-
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
314
- end
315
-
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)
324
-
325
- Application.revoke_tokens_and_grants_for(application_id, resource_owner)
326
- end
327
- end
328
-
329
- describe "#by_uid_and_secret" do
330
- context "when application is private/confidential" do
331
- it "finds the application via uid/secret" do
332
- app = FactoryBot.create :application
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
342
- end
343
- end
344
-
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
352
- end
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
359
- end
360
- end
361
- end
362
-
363
- describe "#confidential?" do
364
- subject { FactoryBot.create(:application, confidential: confidential).confidential? }
365
-
366
- context "when application is private/confidential" do
367
- let(:confidential) { true }
368
- it { expect(subject).to eq(true) }
369
- end
370
-
371
- context "when application is public/non-confidential" do
372
- let(:confidential) { false }
373
- it { expect(subject).to eq(false) }
374
- end
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
403
- end
404
- end
@@ -1,259 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- feature "Adding applications" do
6
- context "in application form" do
7
- background do
8
- i_am_logged_in
9
- visit "/oauth/applications/new"
10
- end
11
-
12
- scenario "adding a valid app" do
13
- fill_in "doorkeeper_application[name]", with: "My Application"
14
- fill_in "doorkeeper_application[redirect_uri]",
15
- with: "https://example.com"
16
-
17
- click_button "Submit"
18
- i_should_see "Application created"
19
- i_should_see "My Application"
20
- end
21
-
22
- scenario "adding invalid app" do
23
- click_button "Submit"
24
- i_should_see "Whoops! Check your form for possible errors"
25
- end
26
-
27
- scenario "adding app ignoring bad scope" do
28
- config_is_set("enforce_configured_scopes", false)
29
-
30
- fill_in "doorkeeper_application[name]", with: "My Application"
31
- fill_in "doorkeeper_application[redirect_uri]",
32
- with: "https://example.com"
33
- fill_in "doorkeeper_application[scopes]", with: "blahblah"
34
-
35
- click_button "Submit"
36
- i_should_see "Application created"
37
- i_should_see "My Application"
38
- end
39
-
40
- scenario "adding app validating bad scope" do
41
- config_is_set("enforce_configured_scopes", true)
42
-
43
- fill_in "doorkeeper_application[name]", with: "My Application"
44
- fill_in "doorkeeper_application[redirect_uri]",
45
- with: "https://example.com"
46
- fill_in "doorkeeper_application[scopes]", with: "blahblah"
47
-
48
- click_button "Submit"
49
- i_should_see "Whoops! Check your form for possible errors"
50
- end
51
-
52
- scenario "adding app validating scope, blank scope is accepted" do
53
- config_is_set("enforce_configured_scopes", true)
54
-
55
- fill_in "doorkeeper_application[name]", with: "My Application"
56
- fill_in "doorkeeper_application[redirect_uri]",
57
- with: "https://example.com"
58
- fill_in "doorkeeper_application[scopes]", with: ""
59
-
60
- click_button "Submit"
61
- i_should_see "Application created"
62
- i_should_see "My Application"
63
- end
64
-
65
- scenario "adding app validating scope, multiple scopes configured" do
66
- config_is_set("enforce_configured_scopes", true)
67
- scopes = Doorkeeper::OAuth::Scopes.from_array(%w[read write admin])
68
- config_is_set("optional_scopes", scopes)
69
-
70
- fill_in "doorkeeper_application[name]", with: "My Application"
71
- fill_in "doorkeeper_application[redirect_uri]",
72
- with: "https://example.com"
73
- fill_in "doorkeeper_application[scopes]", with: "read write"
74
-
75
- click_button "Submit"
76
- i_should_see "Application created"
77
- i_should_see "My Application"
78
- end
79
-
80
- scenario "adding app validating scope, bad scope with multiple scopes configured" do
81
- config_is_set("enforce_configured_scopes", true)
82
- scopes = Doorkeeper::OAuth::Scopes.from_array(%w[read write admin])
83
- config_is_set("optional_scopes", scopes)
84
-
85
- fill_in "doorkeeper_application[name]", with: "My Application"
86
- fill_in "doorkeeper_application[redirect_uri]",
87
- with: "https://example.com"
88
- fill_in "doorkeeper_application[scopes]", with: "read blah"
89
-
90
- click_button "Submit"
91
- i_should_see "Whoops! Check your form for possible errors"
92
- i_should_see Regexp.new(
93
- I18n.t("activerecord.errors.models.doorkeeper/application.attributes.scopes.not_match_configured"),
94
- true,
95
- )
96
- end
97
-
98
- context "redirect URI" do
99
- scenario "adding app with blank redirect URI when configured flows requires redirect uri" do
100
- config_is_set("grant_flows", %w[authorization_code implicit client_credentials])
101
-
102
- fill_in "doorkeeper_application[name]", with: "My Application"
103
- fill_in "doorkeeper_application[redirect_uri]",
104
- with: ""
105
-
106
- click_button "Submit"
107
- i_should_see "Whoops! Check your form for possible errors"
108
- end
109
-
110
- scenario "adding app with blank redirect URI when configured flows without redirect uri" do
111
- config_is_set("grant_flows", %w[client_credentials password])
112
-
113
- # Visit it once again to consider grant flows
114
- visit "/oauth/applications/new"
115
-
116
- i_should_see I18n.t("doorkeeper.applications.help.blank_redirect_uri")
117
-
118
- fill_in "doorkeeper_application[name]", with: "My Application"
119
- fill_in "doorkeeper_application[redirect_uri]",
120
- with: ""
121
-
122
- click_button "Submit"
123
- i_should_see "Application created"
124
- i_should_see "My Application"
125
- end
126
- end
127
- end
128
- end
129
-
130
- feature "Listing applications" do
131
- background do
132
- i_am_logged_in
133
-
134
- FactoryBot.create :application, name: "Oauth Dude"
135
- FactoryBot.create :application, name: "Awesome App"
136
- end
137
-
138
- scenario "application list" do
139
- visit "/oauth/applications"
140
-
141
- i_should_see "Awesome App"
142
- i_should_see "Oauth Dude"
143
- end
144
- end
145
-
146
- feature "Renders assets" do
147
- scenario "admin stylesheets" do
148
- visit "/assets/doorkeeper/admin/application.css"
149
-
150
- i_should_see "Bootstrap"
151
- i_should_see ".doorkeeper-admin"
152
- end
153
-
154
- scenario "application stylesheets" do
155
- visit "/assets/doorkeeper/application.css"
156
-
157
- i_should_see "Bootstrap"
158
- i_should_see "#oauth-permissions"
159
- i_should_see "#container"
160
- end
161
- end
162
-
163
- feature "Show application" do
164
- given :app do
165
- i_am_logged_in
166
-
167
- FactoryBot.create :application, name: "Just another oauth app"
168
- end
169
-
170
- scenario "visiting application page" do
171
- visit "/oauth/applications/#{app.id}"
172
-
173
- i_should_see "Just another oauth app"
174
- end
175
- end
176
-
177
- feature "Edit application" do
178
- let :app do
179
- FactoryBot.create :application, name: "OMG my app"
180
- end
181
-
182
- background do
183
- i_am_logged_in
184
-
185
- visit "/oauth/applications/#{app.id}/edit"
186
- end
187
-
188
- scenario "updating a valid app" do
189
- fill_in "doorkeeper_application[name]", with: "Serious app"
190
- click_button "Submit"
191
-
192
- i_should_see "Application updated"
193
- i_should_see "Serious app"
194
- i_should_not_see "OMG my app"
195
- end
196
-
197
- scenario "updating an invalid app" do
198
- fill_in "doorkeeper_application[name]", with: ""
199
- click_button "Submit"
200
-
201
- i_should_see "Whoops! Check your form for possible errors"
202
- end
203
- end
204
-
205
- feature "Remove application" do
206
- background do
207
- i_am_logged_in
208
-
209
- @app = FactoryBot.create :application
210
- end
211
-
212
- scenario "deleting an application from list" do
213
- visit "/oauth/applications"
214
-
215
- i_should_see @app.name
216
-
217
- within(:css, "tr#application_#{@app.id}") do
218
- click_button "Destroy"
219
- end
220
-
221
- i_should_see "Application deleted"
222
- i_should_not_see @app.name
223
- end
224
-
225
- scenario "deleting an application from show" do
226
- visit "/oauth/applications/#{@app.id}"
227
- click_button "Destroy"
228
-
229
- i_should_see "Application deleted"
230
- end
231
- end
232
-
233
- context "when admin authenticator block is default" do
234
- let(:app) { FactoryBot.create :application, name: "app" }
235
-
236
- feature "application list" do
237
- scenario "fails with forbidden" do
238
- visit "/oauth/applications"
239
-
240
- should_have_status 403
241
- end
242
- end
243
-
244
- feature "adding an app" do
245
- scenario "fails with forbidden" do
246
- visit "/oauth/applications/new"
247
-
248
- should_have_status 403
249
- end
250
- end
251
-
252
- feature "editing an app" do
253
- scenario "fails with forbidden" do
254
- visit "/oauth/applications/#{app.id}/edit"
255
-
256
- should_have_status 403
257
- end
258
- end
259
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- feature "Authorized applications" do
6
- background do
7
- @user = User.create!(name: "Joe", password: "sekret")
8
- @client = client_exists(name: "Amazing Client App")
9
- resource_owner_is_authenticated @user
10
- client_is_authorized @client, @user
11
- end
12
-
13
- scenario "display user's authorized applications" do
14
- visit "/oauth/authorized_applications"
15
- i_should_see "Amazing Client App"
16
- end
17
-
18
- scenario "do not display other user's authorized applications" do
19
- client = client_exists(name: "Another Client App")
20
- client_is_authorized client, User.create!(name: "Joe", password: "sekret")
21
- visit "/oauth/authorized_applications"
22
- i_should_not_see "Another Client App"
23
- end
24
-
25
- scenario "user revoke access to application" do
26
- visit "/oauth/authorized_applications"
27
- i_should_see "Amazing Client App"
28
- click_on "Revoke"
29
- i_should_see "Application revoked"
30
- i_should_not_see "Amazing Client App"
31
- end
32
- end