doorkeeper 5.1.2 → 5.6.6

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 (272) hide show
  1. checksums.yaml +4 -4
  2. data/{NEWS.md → CHANGELOG.md} +314 -27
  3. data/README.md +39 -22
  4. data/app/controllers/doorkeeper/application_controller.rb +3 -2
  5. data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
  6. data/app/controllers/doorkeeper/applications_controller.rb +5 -4
  7. data/app/controllers/doorkeeper/authorizations_controller.rb +76 -25
  8. data/app/controllers/doorkeeper/authorized_applications_controller.rb +5 -5
  9. data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
  10. data/app/controllers/doorkeeper/tokens_controller.rb +99 -28
  11. data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
  12. data/app/views/doorkeeper/applications/_form.html.erb +1 -7
  13. data/app/views/doorkeeper/applications/show.html.erb +35 -14
  14. data/app/views/doorkeeper/authorizations/error.html.erb +3 -1
  15. data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
  16. data/app/views/doorkeeper/authorizations/new.html.erb +16 -14
  17. data/config/locales/en.yml +16 -3
  18. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  19. data/lib/doorkeeper/config/option.rb +20 -2
  20. data/lib/doorkeeper/config/validations.rb +53 -0
  21. data/lib/doorkeeper/config.rb +300 -136
  22. data/lib/doorkeeper/engine.rb +10 -3
  23. data/lib/doorkeeper/errors.rb +13 -18
  24. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  25. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  26. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  27. data/lib/doorkeeper/grant_flow.rb +45 -0
  28. data/lib/doorkeeper/grape/helpers.rb +7 -3
  29. data/lib/doorkeeper/helpers/controller.rb +36 -11
  30. data/lib/doorkeeper/models/access_grant_mixin.rb +23 -19
  31. data/lib/doorkeeper/models/access_token_mixin.rb +195 -52
  32. data/lib/doorkeeper/models/application_mixin.rb +8 -7
  33. data/lib/doorkeeper/models/concerns/expirable.rb +1 -1
  34. data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
  35. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  36. data/lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb +30 -0
  37. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  38. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  39. data/lib/doorkeeper/models/concerns/revocable.rb +1 -28
  40. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  41. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  42. data/lib/doorkeeper/oauth/authorization/code.rb +31 -14
  43. data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
  44. data/lib/doorkeeper/oauth/authorization/token.rb +30 -19
  45. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  46. data/lib/doorkeeper/oauth/authorization_code_request.rb +51 -22
  47. data/lib/doorkeeper/oauth/base_request.rb +21 -22
  48. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  49. data/lib/doorkeeper/oauth/client.rb +8 -9
  50. data/lib/doorkeeper/oauth/client_credentials/creator.rb +42 -5
  51. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +10 -8
  52. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +14 -5
  53. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  54. data/lib/doorkeeper/oauth/code_request.rb +6 -12
  55. data/lib/doorkeeper/oauth/code_response.rb +24 -14
  56. data/lib/doorkeeper/oauth/error.rb +1 -1
  57. data/lib/doorkeeper/oauth/error_response.rb +11 -13
  58. data/lib/doorkeeper/oauth/forbidden_token_response.rb +2 -1
  59. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +8 -12
  60. data/lib/doorkeeper/oauth/helpers/unique_token.rb +10 -7
  61. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +19 -23
  62. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  63. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  64. data/lib/doorkeeper/oauth/invalid_token_response.rb +7 -4
  65. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  66. data/lib/doorkeeper/oauth/password_access_token_request.rb +34 -11
  67. data/lib/doorkeeper/oauth/pre_authorization.rb +114 -44
  68. data/lib/doorkeeper/oauth/refresh_token_request.rb +54 -34
  69. data/lib/doorkeeper/oauth/token.rb +6 -7
  70. data/lib/doorkeeper/oauth/token_introspection.rb +28 -22
  71. data/lib/doorkeeper/oauth/token_request.rb +6 -20
  72. data/lib/doorkeeper/oauth/token_response.rb +2 -3
  73. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  74. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  75. data/lib/doorkeeper/orm/active_record/application.rb +5 -149
  76. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +63 -0
  77. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +77 -0
  78. data/lib/doorkeeper/orm/active_record/mixins/application.rb +210 -0
  79. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
  80. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +5 -2
  81. data/lib/doorkeeper/orm/active_record.rb +29 -22
  82. data/lib/doorkeeper/rails/helpers.rb +4 -4
  83. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  84. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  85. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  86. data/lib/doorkeeper/rails/routes.rb +28 -27
  87. data/lib/doorkeeper/rake/db.rake +6 -6
  88. data/lib/doorkeeper/request/authorization_code.rb +5 -3
  89. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  90. data/lib/doorkeeper/request/password.rb +3 -2
  91. data/lib/doorkeeper/request/refresh_token.rb +5 -4
  92. data/lib/doorkeeper/request/strategy.rb +2 -2
  93. data/lib/doorkeeper/request.rb +49 -17
  94. data/lib/doorkeeper/server.rb +7 -11
  95. data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
  96. data/lib/doorkeeper/version.rb +2 -6
  97. data/lib/doorkeeper.rb +183 -80
  98. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  99. data/lib/generators/doorkeeper/confidential_applications_generator.rb +2 -2
  100. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  101. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  102. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  103. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +7 -7
  104. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
  105. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  106. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  107. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  108. data/lib/generators/doorkeeper/templates/initializer.rb +230 -50
  109. data/lib/generators/doorkeeper/templates/migration.rb.erb +31 -9
  110. metadata +61 -327
  111. data/.coveralls.yml +0 -1
  112. data/.github/ISSUE_TEMPLATE.md +0 -25
  113. data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  114. data/.gitignore +0 -20
  115. data/.gitlab-ci.yml +0 -16
  116. data/.hound.yml +0 -3
  117. data/.rspec +0 -1
  118. data/.rubocop.yml +0 -50
  119. data/.travis.yml +0 -35
  120. data/Appraisals +0 -40
  121. data/CODE_OF_CONDUCT.md +0 -46
  122. data/CONTRIBUTING.md +0 -47
  123. data/Dangerfile +0 -67
  124. data/Gemfile +0 -24
  125. data/RELEASING.md +0 -10
  126. data/Rakefile +0 -28
  127. data/SECURITY.md +0 -15
  128. data/UPGRADE.md +0 -2
  129. data/app/validators/redirect_uri_validator.rb +0 -50
  130. data/bin/console +0 -16
  131. data/doorkeeper.gemspec +0 -34
  132. data/gemfiles/rails_5_0.gemfile +0 -17
  133. data/gemfiles/rails_5_1.gemfile +0 -17
  134. data/gemfiles/rails_5_2.gemfile +0 -17
  135. data/gemfiles/rails_6_0.gemfile +0 -17
  136. data/gemfiles/rails_master.gemfile +0 -17
  137. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  138. data/spec/controllers/applications_controller_spec.rb +0 -180
  139. data/spec/controllers/authorizations_controller_spec.rb +0 -527
  140. data/spec/controllers/protected_resources_controller_spec.rb +0 -353
  141. data/spec/controllers/token_info_controller_spec.rb +0 -50
  142. data/spec/controllers/tokens_controller_spec.rb +0 -330
  143. data/spec/dummy/Rakefile +0 -9
  144. data/spec/dummy/app/assets/config/manifest.js +0 -2
  145. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  146. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  147. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  148. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  149. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  150. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  151. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  152. data/spec/dummy/app/models/user.rb +0 -7
  153. data/spec/dummy/app/views/home/index.html.erb +0 -0
  154. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  155. data/spec/dummy/config/application.rb +0 -47
  156. data/spec/dummy/config/boot.rb +0 -7
  157. data/spec/dummy/config/database.yml +0 -15
  158. data/spec/dummy/config/environment.rb +0 -5
  159. data/spec/dummy/config/environments/development.rb +0 -31
  160. data/spec/dummy/config/environments/production.rb +0 -64
  161. data/spec/dummy/config/environments/test.rb +0 -45
  162. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  163. data/spec/dummy/config/initializers/doorkeeper.rb +0 -121
  164. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  165. data/spec/dummy/config/initializers/session_store.rb +0 -10
  166. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  167. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  168. data/spec/dummy/config/routes.rb +0 -13
  169. data/spec/dummy/config.ru +0 -6
  170. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  171. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  172. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  173. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  174. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  175. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  176. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  177. data/spec/dummy/db/schema.rb +0 -68
  178. data/spec/dummy/public/404.html +0 -26
  179. data/spec/dummy/public/422.html +0 -26
  180. data/spec/dummy/public/500.html +0 -26
  181. data/spec/dummy/public/favicon.ico +0 -0
  182. data/spec/dummy/script/rails +0 -9
  183. data/spec/factories.rb +0 -30
  184. data/spec/generators/application_owner_generator_spec.rb +0 -28
  185. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  186. data/spec/generators/install_generator_spec.rb +0 -36
  187. data/spec/generators/migration_generator_spec.rb +0 -28
  188. data/spec/generators/pkce_generator_spec.rb +0 -28
  189. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  190. data/spec/generators/templates/routes.rb +0 -4
  191. data/spec/generators/views_generator_spec.rb +0 -29
  192. data/spec/grape/grape_integration_spec.rb +0 -137
  193. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  194. data/spec/lib/config_spec.rb +0 -697
  195. data/spec/lib/doorkeeper_spec.rb +0 -27
  196. data/spec/lib/models/expirable_spec.rb +0 -61
  197. data/spec/lib/models/reusable_spec.rb +0 -40
  198. data/spec/lib/models/revocable_spec.rb +0 -59
  199. data/spec/lib/models/scopes_spec.rb +0 -53
  200. data/spec/lib/models/secret_storable_spec.rb +0 -135
  201. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  202. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -156
  203. data/spec/lib/oauth/base_request_spec.rb +0 -205
  204. data/spec/lib/oauth/base_response_spec.rb +0 -47
  205. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  206. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -94
  207. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  208. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  209. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -29
  210. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -109
  211. data/spec/lib/oauth/client_spec.rb +0 -38
  212. data/spec/lib/oauth/code_request_spec.rb +0 -47
  213. data/spec/lib/oauth/code_response_spec.rb +0 -36
  214. data/spec/lib/oauth/error_response_spec.rb +0 -66
  215. data/spec/lib/oauth/error_spec.rb +0 -23
  216. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -22
  217. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -98
  218. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  219. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -247
  220. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -55
  221. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -192
  222. data/spec/lib/oauth/pre_authorization_spec.rb +0 -215
  223. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
  224. data/spec/lib/oauth/scopes_spec.rb +0 -148
  225. data/spec/lib/oauth/token_request_spec.rb +0 -150
  226. data/spec/lib/oauth/token_response_spec.rb +0 -86
  227. data/spec/lib/oauth/token_spec.rb +0 -158
  228. data/spec/lib/request/strategy_spec.rb +0 -54
  229. data/spec/lib/secret_storing/base_spec.rb +0 -60
  230. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  231. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  232. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  233. data/spec/lib/server_spec.rb +0 -61
  234. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  235. data/spec/models/doorkeeper/access_grant_spec.rb +0 -144
  236. data/spec/models/doorkeeper/access_token_spec.rb +0 -591
  237. data/spec/models/doorkeeper/application_spec.rb +0 -472
  238. data/spec/requests/applications/applications_request_spec.rb +0 -259
  239. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  240. data/spec/requests/endpoints/authorization_spec.rb +0 -73
  241. data/spec/requests/endpoints/token_spec.rb +0 -75
  242. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -78
  243. data/spec/requests/flows/authorization_code_spec.rb +0 -447
  244. data/spec/requests/flows/client_credentials_spec.rb +0 -128
  245. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -34
  246. data/spec/requests/flows/implicit_grant_spec.rb +0 -90
  247. data/spec/requests/flows/password_spec.rb +0 -259
  248. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  249. data/spec/requests/flows/revoke_token_spec.rb +0 -143
  250. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  251. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  252. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  253. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  254. data/spec/routing/default_routes_spec.rb +0 -41
  255. data/spec/routing/scoped_routes_spec.rb +0 -47
  256. data/spec/spec_helper.rb +0 -57
  257. data/spec/spec_helper_integration.rb +0 -4
  258. data/spec/support/dependencies/factory_bot.rb +0 -4
  259. data/spec/support/doorkeeper_rspec.rb +0 -22
  260. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  261. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  262. data/spec/support/helpers/config_helper.rb +0 -11
  263. data/spec/support/helpers/model_helper.rb +0 -78
  264. data/spec/support/helpers/request_spec_helper.rb +0 -98
  265. data/spec/support/helpers/url_helper.rb +0 -62
  266. data/spec/support/http_method_shim.rb +0 -29
  267. data/spec/support/orm/active_record.rb +0 -5
  268. data/spec/support/shared/controllers_shared_context.rb +0 -123
  269. data/spec/support/shared/hashing_shared_context.rb +0 -36
  270. data/spec/support/shared/models_shared_examples.rb +0 -54
  271. data/spec/validators/redirect_uri_validator_spec.rb +0 -158
  272. data/spec/version/version_spec.rb +0 -17
@@ -1,472 +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.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) }
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 "#authorized_for" do
280
- let(:resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
281
- let(:other_resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
282
-
283
- it "is empty if the application is not authorized for anyone" do
284
- expect(described_class.authorized_for(resource_owner)).to be_empty
285
- end
286
-
287
- it "returns only application for a specific resource owner" do
288
- FactoryBot.create(
289
- :access_token,
290
- resource_owner_id: other_resource_owner.id,
291
- )
292
- token = FactoryBot.create(
293
- :access_token,
294
- resource_owner_id: resource_owner.id,
295
- )
296
- expect(described_class.authorized_for(resource_owner)).to eq([token.application])
297
- end
298
-
299
- it "excludes revoked tokens" do
300
- FactoryBot.create(
301
- :access_token,
302
- resource_owner_id: resource_owner.id,
303
- revoked_at: 2.days.ago,
304
- )
305
- expect(described_class.authorized_for(resource_owner)).to be_empty
306
- end
307
-
308
- it "returns all applications that have been authorized" do
309
- token1 = FactoryBot.create(
310
- :access_token,
311
- resource_owner_id: resource_owner.id,
312
- )
313
- token2 = FactoryBot.create(
314
- :access_token,
315
- resource_owner_id: resource_owner.id,
316
- )
317
- expect(described_class.authorized_for(resource_owner))
318
- .to eq([token1.application, token2.application])
319
- end
320
-
321
- it "returns only one application even if it has been authorized twice" do
322
- application = FactoryBot.create(:application)
323
- FactoryBot.create(
324
- :access_token,
325
- resource_owner_id: resource_owner.id,
326
- application: application,
327
- )
328
- FactoryBot.create(
329
- :access_token,
330
- resource_owner_id: resource_owner.id,
331
- application: application,
332
- )
333
- expect(described_class.authorized_for(resource_owner)).to eq([application])
334
- end
335
- end
336
-
337
- describe "#revoke_tokens_and_grants_for" do
338
- it "revokes all access tokens and access grants" do
339
- application_id = 42
340
- resource_owner = double
341
- expect(Doorkeeper::AccessToken)
342
- .to receive(:revoke_all_for).with(application_id, resource_owner)
343
- expect(Doorkeeper::AccessGrant)
344
- .to receive(:revoke_all_for).with(application_id, resource_owner)
345
-
346
- described_class.revoke_tokens_and_grants_for(application_id, resource_owner)
347
- end
348
- end
349
-
350
- describe "#by_uid_and_secret" do
351
- context "when application is private/confidential" do
352
- it "finds the application via uid/secret" do
353
- app = FactoryBot.create :application
354
- authenticated = described_class.by_uid_and_secret(app.uid, app.secret)
355
- expect(authenticated).to eq(app)
356
- end
357
- context "when secret is wrong" do
358
- it "should not find the application" do
359
- app = FactoryBot.create :application
360
- authenticated = described_class.by_uid_and_secret(app.uid, "bad")
361
- expect(authenticated).to eq(nil)
362
- end
363
- end
364
- end
365
-
366
- context "when application is public/non-confidential" do
367
- context "when secret is blank" do
368
- it "should find the application" do
369
- app = FactoryBot.create :application, confidential: false
370
- authenticated = described_class.by_uid_and_secret(app.uid, nil)
371
- expect(authenticated).to eq(app)
372
- end
373
- end
374
- context "when secret is wrong" do
375
- it "should not find the application" do
376
- app = FactoryBot.create :application, confidential: false
377
- authenticated = described_class.by_uid_and_secret(app.uid, "bad")
378
- expect(authenticated).to eq(nil)
379
- end
380
- end
381
- end
382
- end
383
-
384
- describe "#confidential?" do
385
- subject { FactoryBot.create(:application, confidential: confidential).confidential? }
386
-
387
- context "when application is private/confidential" do
388
- let(:confidential) { true }
389
- it { expect(subject).to eq(true) }
390
- end
391
-
392
- context "when application is public/non-confidential" do
393
- let(:confidential) { false }
394
- it { expect(subject).to eq(false) }
395
- end
396
- end
397
-
398
- describe "#as_json" do
399
- let(:app) { FactoryBot.create :application, secret: "123123123" }
400
-
401
- before do
402
- allow(Doorkeeper.configuration)
403
- .to receive(:application_secret_strategy).and_return(Doorkeeper::SecretStoring::Plain)
404
- end
405
-
406
- # AR specific feature
407
- if DOORKEEPER_ORM == :active_record
408
- it "correctly works with #to_json" do
409
- ActiveRecord::Base.include_root_in_json = true
410
- expect(app.to_json(include_root_in_json: true)).to match(/application.+?:\{/)
411
- ActiveRecord::Base.include_root_in_json = false
412
- end
413
- end
414
-
415
- context "when called without authorized resource owner" do
416
- it "includes minimal set of attributes" do
417
- expect(app.as_json).to match(
418
- "id" => app.id,
419
- "name" => app.name,
420
- "created_at" => an_instance_of(String),
421
- )
422
- end
423
-
424
- it "includes application UID if it's public" do
425
- app = FactoryBot.create :application, secret: "123123123", confidential: false
426
-
427
- expect(app.as_json).to match(
428
- "id" => app.id,
429
- "name" => app.name,
430
- "created_at" => an_instance_of(String),
431
- "uid" => app.uid,
432
- )
433
- end
434
-
435
- it "respects custom options" do
436
- expect(app.as_json(except: :id)).not_to include("id")
437
- expect(app.as_json(only: %i[name created_at secret]))
438
- .to match(
439
- "name" => app.name,
440
- "created_at" => an_instance_of(String),
441
- )
442
- end
443
- end
444
-
445
- context "when called with authorized resource owner" do
446
- let(:owner) { FactoryBot.create(:doorkeeper_testing_user) }
447
- let(:other_owner) { FactoryBot.create(:doorkeeper_testing_user) }
448
- let(:app) { FactoryBot.create(:application, secret: "123123123", owner: owner) }
449
-
450
- before do
451
- Doorkeeper.configure do
452
- orm DOORKEEPER_ORM
453
- enable_application_owner confirmation: false
454
- end
455
- end
456
-
457
- it "includes all the attributes" do
458
- expect(app.as_json(current_resource_owner: owner))
459
- .to include(
460
- "secret" => "123123123",
461
- "redirect_uri" => app.redirect_uri,
462
- "uid" => app.uid,
463
- )
464
- end
465
-
466
- it "doesn't include unsafe attributes if current owner isn't the same as owner" do
467
- expect(app.as_json(current_resource_owner: other_owner))
468
- .not_to include("redirect_uri")
469
- end
470
- end
471
- end
472
- end