doorkeeper 5.3.3 → 5.6.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (247) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +216 -9
  3. data/README.md +30 -21
  4. data/app/controllers/doorkeeper/application_controller.rb +1 -0
  5. data/app/controllers/doorkeeper/applications_controller.rb +4 -4
  6. data/app/controllers/doorkeeper/authorizations_controller.rb +66 -22
  7. data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
  8. data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
  9. data/app/controllers/doorkeeper/tokens_controller.rb +73 -25
  10. data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
  11. data/app/views/doorkeeper/applications/_form.html.erb +1 -1
  12. data/app/views/doorkeeper/applications/show.html.erb +35 -14
  13. data/app/views/doorkeeper/authorizations/error.html.erb +3 -1
  14. data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
  15. data/app/views/doorkeeper/authorizations/new.html.erb +16 -14
  16. data/config/locales/en.yml +9 -2
  17. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  18. data/lib/doorkeeper/config/option.rb +26 -14
  19. data/lib/doorkeeper/config/validations.rb +53 -0
  20. data/lib/doorkeeper/config.rb +182 -134
  21. data/lib/doorkeeper/engine.rb +10 -3
  22. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  23. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  24. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  25. data/lib/doorkeeper/grant_flow.rb +45 -0
  26. data/lib/doorkeeper/grape/helpers.rb +1 -1
  27. data/lib/doorkeeper/helpers/controller.rb +9 -5
  28. data/lib/doorkeeper/models/access_grant_mixin.rb +22 -19
  29. data/lib/doorkeeper/models/access_token_mixin.rb +115 -52
  30. data/lib/doorkeeper/models/application_mixin.rb +5 -4
  31. data/lib/doorkeeper/models/concerns/expirable.rb +1 -1
  32. data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
  33. data/lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb +30 -0
  34. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  35. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  36. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  37. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  38. data/lib/doorkeeper/oauth/authorization/code.rb +25 -6
  39. data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
  40. data/lib/doorkeeper/oauth/authorization/token.rb +24 -16
  41. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  42. data/lib/doorkeeper/oauth/authorization_code_request.rb +34 -21
  43. data/lib/doorkeeper/oauth/base_request.rb +19 -26
  44. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  45. data/lib/doorkeeper/oauth/client.rb +1 -1
  46. data/lib/doorkeeper/oauth/client_credentials/creator.rb +31 -15
  47. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +4 -2
  48. data/lib/doorkeeper/oauth/client_credentials/validator.rb +5 -4
  49. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  50. data/lib/doorkeeper/oauth/code_request.rb +4 -4
  51. data/lib/doorkeeper/oauth/code_response.rb +22 -12
  52. data/lib/doorkeeper/oauth/error_response.rb +7 -9
  53. data/lib/doorkeeper/oauth/forbidden_token_response.rb +2 -1
  54. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +2 -8
  55. data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -2
  56. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +4 -22
  57. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  58. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  59. data/lib/doorkeeper/oauth/password_access_token_request.rb +26 -8
  60. data/lib/doorkeeper/oauth/pre_authorization.rb +65 -33
  61. data/lib/doorkeeper/oauth/refresh_token_request.rb +42 -25
  62. data/lib/doorkeeper/oauth/token.rb +5 -6
  63. data/lib/doorkeeper/oauth/token_introspection.rb +8 -12
  64. data/lib/doorkeeper/oauth/token_request.rb +3 -3
  65. data/lib/doorkeeper/oauth/token_response.rb +2 -3
  66. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +14 -4
  67. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +34 -4
  68. data/lib/doorkeeper/orm/active_record/mixins/application.rb +28 -5
  69. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +6 -1
  70. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +5 -2
  71. data/lib/doorkeeper/orm/active_record.rb +30 -38
  72. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  73. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  74. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  75. data/lib/doorkeeper/rails/routes.rb +25 -22
  76. data/lib/doorkeeper/rake/db.rake +3 -3
  77. data/lib/doorkeeper/request/password.rb +1 -0
  78. data/lib/doorkeeper/request/refresh_token.rb +2 -1
  79. data/lib/doorkeeper/request/strategy.rb +2 -2
  80. data/lib/doorkeeper/request.rb +49 -12
  81. data/lib/doorkeeper/server.rb +4 -4
  82. data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
  83. data/lib/doorkeeper/version.rb +2 -6
  84. data/lib/doorkeeper.rb +181 -81
  85. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  86. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  87. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
  88. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  89. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  90. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  91. data/lib/generators/doorkeeper/templates/initializer.rb +73 -17
  92. data/lib/generators/doorkeeper/templates/migration.rb.erb +28 -9
  93. metadata +48 -316
  94. data/Appraisals +0 -40
  95. data/CODE_OF_CONDUCT.md +0 -46
  96. data/CONTRIBUTING.md +0 -49
  97. data/Dangerfile +0 -67
  98. data/Dockerfile +0 -29
  99. data/Gemfile +0 -25
  100. data/NEWS.md +0 -1
  101. data/RELEASING.md +0 -11
  102. data/Rakefile +0 -28
  103. data/SECURITY.md +0 -15
  104. data/UPGRADE.md +0 -2
  105. data/bin/console +0 -16
  106. data/doorkeeper.gemspec +0 -42
  107. data/gemfiles/rails_5_0.gemfile +0 -18
  108. data/gemfiles/rails_5_1.gemfile +0 -18
  109. data/gemfiles/rails_5_2.gemfile +0 -18
  110. data/gemfiles/rails_6_0.gemfile +0 -18
  111. data/gemfiles/rails_master.gemfile +0 -18
  112. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  113. data/spec/controllers/applications_controller_spec.rb +0 -274
  114. data/spec/controllers/authorizations_controller_spec.rb +0 -608
  115. data/spec/controllers/protected_resources_controller_spec.rb +0 -361
  116. data/spec/controllers/token_info_controller_spec.rb +0 -50
  117. data/spec/controllers/tokens_controller_spec.rb +0 -498
  118. data/spec/dummy/Rakefile +0 -9
  119. data/spec/dummy/app/assets/config/manifest.js +0 -2
  120. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  121. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  122. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  123. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  124. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  125. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  126. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  127. data/spec/dummy/app/models/user.rb +0 -7
  128. data/spec/dummy/app/views/home/index.html.erb +0 -0
  129. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  130. data/spec/dummy/config/application.rb +0 -49
  131. data/spec/dummy/config/boot.rb +0 -7
  132. data/spec/dummy/config/database.yml +0 -15
  133. data/spec/dummy/config/environment.rb +0 -5
  134. data/spec/dummy/config/environments/development.rb +0 -31
  135. data/spec/dummy/config/environments/production.rb +0 -64
  136. data/spec/dummy/config/environments/test.rb +0 -45
  137. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  138. data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
  139. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  140. data/spec/dummy/config/initializers/session_store.rb +0 -10
  141. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  142. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  143. data/spec/dummy/config/routes.rb +0 -13
  144. data/spec/dummy/config.ru +0 -6
  145. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  146. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  147. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  148. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  149. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  150. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  151. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  152. data/spec/dummy/db/schema.rb +0 -68
  153. data/spec/dummy/public/404.html +0 -26
  154. data/spec/dummy/public/422.html +0 -26
  155. data/spec/dummy/public/500.html +0 -26
  156. data/spec/dummy/public/favicon.ico +0 -0
  157. data/spec/dummy/script/rails +0 -9
  158. data/spec/factories.rb +0 -30
  159. data/spec/generators/application_owner_generator_spec.rb +0 -28
  160. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  161. data/spec/generators/install_generator_spec.rb +0 -36
  162. data/spec/generators/migration_generator_spec.rb +0 -28
  163. data/spec/generators/pkce_generator_spec.rb +0 -28
  164. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  165. data/spec/generators/templates/routes.rb +0 -4
  166. data/spec/generators/views_generator_spec.rb +0 -29
  167. data/spec/grape/grape_integration_spec.rb +0 -137
  168. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  169. data/spec/lib/config_spec.rb +0 -809
  170. data/spec/lib/doorkeeper_spec.rb +0 -27
  171. data/spec/lib/models/expirable_spec.rb +0 -61
  172. data/spec/lib/models/reusable_spec.rb +0 -40
  173. data/spec/lib/models/revocable_spec.rb +0 -59
  174. data/spec/lib/models/scopes_spec.rb +0 -53
  175. data/spec/lib/models/secret_storable_spec.rb +0 -135
  176. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  177. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -170
  178. data/spec/lib/oauth/base_request_spec.rb +0 -224
  179. data/spec/lib/oauth/base_response_spec.rb +0 -45
  180. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  181. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -134
  182. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  183. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  184. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  185. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -107
  186. data/spec/lib/oauth/client_spec.rb +0 -38
  187. data/spec/lib/oauth/code_request_spec.rb +0 -46
  188. data/spec/lib/oauth/code_response_spec.rb +0 -32
  189. data/spec/lib/oauth/error_response_spec.rb +0 -64
  190. data/spec/lib/oauth/error_spec.rb +0 -21
  191. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
  192. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
  193. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  194. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  195. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
  196. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
  197. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -190
  198. data/spec/lib/oauth/pre_authorization_spec.rb +0 -223
  199. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
  200. data/spec/lib/oauth/scopes_spec.rb +0 -146
  201. data/spec/lib/oauth/token_request_spec.rb +0 -157
  202. data/spec/lib/oauth/token_response_spec.rb +0 -84
  203. data/spec/lib/oauth/token_spec.rb +0 -156
  204. data/spec/lib/request/strategy_spec.rb +0 -54
  205. data/spec/lib/secret_storing/base_spec.rb +0 -60
  206. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  207. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  208. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  209. data/spec/lib/server_spec.rb +0 -49
  210. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  211. data/spec/models/doorkeeper/access_grant_spec.rb +0 -161
  212. data/spec/models/doorkeeper/access_token_spec.rb +0 -622
  213. data/spec/models/doorkeeper/application_spec.rb +0 -482
  214. data/spec/requests/applications/applications_request_spec.rb +0 -259
  215. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  216. data/spec/requests/endpoints/authorization_spec.rb +0 -91
  217. data/spec/requests/endpoints/token_spec.rb +0 -75
  218. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
  219. data/spec/requests/flows/authorization_code_spec.rb +0 -525
  220. data/spec/requests/flows/client_credentials_spec.rb +0 -166
  221. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  222. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  223. data/spec/requests/flows/password_spec.rb +0 -316
  224. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  225. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  226. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  227. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  228. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  229. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  230. data/spec/routing/default_routes_spec.rb +0 -41
  231. data/spec/routing/scoped_routes_spec.rb +0 -47
  232. data/spec/spec_helper.rb +0 -54
  233. data/spec/spec_helper_integration.rb +0 -4
  234. data/spec/support/dependencies/factory_bot.rb +0 -4
  235. data/spec/support/doorkeeper_rspec.rb +0 -22
  236. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  237. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  238. data/spec/support/helpers/config_helper.rb +0 -11
  239. data/spec/support/helpers/model_helper.rb +0 -78
  240. data/spec/support/helpers/request_spec_helper.rb +0 -110
  241. data/spec/support/helpers/url_helper.rb +0 -62
  242. data/spec/support/orm/active_record.rb +0 -5
  243. data/spec/support/shared/controllers_shared_context.rb +0 -133
  244. data/spec/support/shared/hashing_shared_context.rb +0 -36
  245. data/spec/support/shared/models_shared_examples.rb +0 -54
  246. data/spec/validators/redirect_uri_validator_spec.rb +0 -183
  247. data/spec/version/version_spec.rb +0 -17
@@ -1,482 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "bcrypt"
5
-
6
- describe Doorkeeper::Application do
7
- let(:require_owner) { Doorkeeper.config.instance_variable_set("@confirm_application_owner", true) }
8
- let(:unset_require_owner) { Doorkeeper.config.instance_variable_set("@confirm_application_owner", false) }
9
- let(:new_application) { FactoryBot.build(:application) }
10
-
11
- let(:uid) { SecureRandom.hex(8) }
12
- let(:secret) { SecureRandom.hex(8) }
13
-
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
35
-
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
41
-
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
47
-
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
54
-
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
61
-
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
67
-
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
73
-
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
79
-
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
85
-
86
- context "application_owner is enabled" do
87
- before do
88
- Doorkeeper.configure do
89
- orm DOORKEEPER_ORM
90
- enable_application_owner
91
- end
92
- end
93
-
94
- context "application owner is not required" do
95
- before(:each) do
96
- unset_require_owner
97
- end
98
-
99
- it "is valid given valid attributes" do
100
- expect(new_application).to be_valid
101
- end
102
- end
103
-
104
- context "application owner is required" do
105
- before do
106
- require_owner
107
- @owner = FactoryBot.build_stubbed(:doorkeeper_testing_user)
108
- end
109
-
110
- it "is invalid without an owner" do
111
- expect(new_application).not_to be_valid
112
- end
113
-
114
- it "is valid with an owner" do
115
- new_application.owner = @owner
116
- expect(new_application).to be_valid
117
- end
118
- end
119
- end
120
-
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]
126
- end
127
- end
128
-
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
133
- end
134
- end
135
-
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]
140
- end
141
- end
142
-
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
147
- end
148
- end
149
-
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
155
- end
156
- end
157
-
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
162
- end
163
- end
164
- end
165
-
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 }
170
-
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
176
-
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"
183
- end
184
- end
185
-
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
191
- end
192
- end
193
-
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)
197
-
198
- lookup = described_class.by_uid_and_secret(app.uid, app.plaintext_secret)
199
- expect(lookup).to eq(app)
200
- end
201
-
202
- context "with fallback enabled" do
203
- include_context "with token hashing and fallback lookup enabled"
204
-
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)
208
-
209
- lookup = described_class.by_uid_and_secret(app.uid, app.plaintext_secret)
210
- expect(lookup).to eq(app)
211
- end
212
- end
213
-
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
223
- end
224
-
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
- )
233
-
234
- expect { new_application.destroy }.to change { Doorkeeper::AccessGrant.count }.by(-1)
235
- end
236
-
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)
243
- end
244
- end
245
-
246
- describe "#ordered_by" do
247
- let(:applications) { FactoryBot.create_list(:application, 5) }
248
-
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)
253
- end
254
- end
255
-
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)
260
- end
261
- end
262
- end
263
-
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")
269
- 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")
275
- end
276
- end
277
- end
278
-
279
- describe "#renew_secret" do
280
- let(:app) { FactoryBot.create :application }
281
-
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)
286
- end
287
- end
288
-
289
- describe "#authorized_for" do
290
- let(:resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
291
- let(:other_resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
292
-
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
296
-
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
308
-
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
317
-
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
330
-
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])
344
- end
345
- end
346
-
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)
355
-
356
- described_class.revoke_tokens_and_grants_for(application_id, resource_owner)
357
- end
358
- end
359
-
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
369
- app = FactoryBot.create :application
370
- authenticated = described_class.by_uid_and_secret(app.uid, "bad")
371
- expect(authenticated).to eq(nil)
372
- end
373
- end
374
- end
375
-
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)
382
- 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)
389
- end
390
- end
391
- end
392
- end
393
-
394
- describe "#confidential?" do
395
- subject { FactoryBot.create(:application, confidential: confidential).confidential? }
396
-
397
- context "when application is private/confidential" do
398
- let(:confidential) { true }
399
- it { expect(subject).to eq(true) }
400
- end
401
-
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
415
-
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
422
- end
423
- end
424
-
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
433
-
434
- it "includes application UID if it's public" do
435
- app = FactoryBot.create :application, secret: "123123123", confidential: false
436
-
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
- )
443
- end
444
-
445
- 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
- )
452
- end
453
- end
454
-
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
464
- end
465
- 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
- end
481
- end
482
- end