doorkeeper-mongodb 5.3.0 → 5.5.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 (192) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/Rakefile +18 -4
  4. data/lib/doorkeeper/orm/mongoid9/access_grant.rb +26 -0
  5. data/lib/doorkeeper/orm/mongoid9/access_token.rb +38 -0
  6. data/lib/doorkeeper/orm/mongoid9/application.rb +43 -0
  7. data/lib/doorkeeper/orm/mongoid9/stale_records_cleaner.rb +11 -0
  8. data/lib/doorkeeper/orm/mongoid9.rb +50 -0
  9. data/lib/doorkeeper-mongodb/mixins/mongoid/access_grant_mixin.rb +6 -2
  10. data/lib/doorkeeper-mongodb/mixins/mongoid/access_token_mixin.rb +46 -6
  11. data/lib/doorkeeper-mongodb/mixins/mongoid/application_mixin.rb +2 -2
  12. data/lib/doorkeeper-mongodb/version.rb +1 -1
  13. data/lib/doorkeeper-mongodb.rb +1 -0
  14. data/spec/dummy/app/assets/config/manifest.js +0 -0
  15. data/spec/dummy/app/controllers/application_controller.rb +0 -0
  16. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -0
  17. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -0
  18. data/spec/dummy/app/controllers/home_controller.rb +0 -0
  19. data/spec/dummy/app/controllers/metal_controller.rb +0 -0
  20. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -0
  21. data/spec/dummy/app/helpers/application_helper.rb +0 -0
  22. data/spec/dummy/app/views/home/index.html.erb +0 -0
  23. data/spec/dummy/app/views/layouts/application.html.erb +0 -0
  24. data/spec/dummy/config/application.rb +0 -0
  25. data/spec/dummy/config/boot.rb +0 -0
  26. data/spec/dummy/config/database.yml +0 -0
  27. data/spec/dummy/config/environment.rb +0 -0
  28. data/spec/dummy/config/environments/development.rb +0 -0
  29. data/spec/dummy/config/environments/production.rb +0 -0
  30. data/spec/dummy/config/environments/test.rb +0 -0
  31. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -0
  32. data/spec/dummy/config/initializers/doorkeeper.rb +7 -2
  33. data/spec/dummy/config/initializers/secret_token.rb +0 -0
  34. data/spec/dummy/config/initializers/session_store.rb +0 -0
  35. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -0
  36. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -0
  37. data/spec/dummy/config/mongoid8.yml +19 -0
  38. data/spec/dummy/config/mongoid9.yml +19 -0
  39. data/spec/dummy/config/routes.rb +0 -0
  40. data/spec/dummy/config.ru +1 -1
  41. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -0
  42. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -0
  43. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -0
  44. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -0
  45. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -0
  46. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -0
  47. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -0
  48. data/spec/dummy/db/migrate/20230205064514_add_custom_attributes.rb +8 -0
  49. data/spec/dummy/db/schema.rb +3 -1
  50. data/spec/dummy/log/test.log +39440 -0
  51. data/spec/dummy/public/404.html +0 -0
  52. data/spec/dummy/public/422.html +0 -0
  53. data/spec/dummy/public/500.html +0 -0
  54. data/spec/dummy/public/favicon.ico +0 -0
  55. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/2L/2LdlR-88TqZc8vSU7Z58xiNpCGRZj0CIlOxSN4Vx2i4.cache +1 -0
  56. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{Pn/PnXU_mkG2fLZFm9BwiZ03BZdBTjKuInP-cRXjHS7yJo.cache → 2r/2r0L9eNOmETsg4Tm1IgBdw3J4ahcko41NpILRXu19_A.cache} +0 -0
  57. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/5y/5ywocFQgpSY36nyF_xDKPExhDRo-eqeiqfDvQee1K9k.cache +2 -0
  58. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{Qs/QsVgO6vM5Yn9oeYTYlrqtyVnK6sdVDWDa083N7zpfHw.cache → 8r/8rW0CpDDUJZ7xvg86t6jZ6WmyvaVZ0uTPEPRjghFIKo.cache} +0 -0
  59. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{PA/PAH_jI20wRw12tngeJ-V619c30avNLDu5U9Z-9Pc5SQ.cache → Cs/CsfBL8Dls9-jhjFsNYt4DZxu5LWChDMB-xXKjsEFSsU.cache} +0 -0
  60. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{8D/8DJG7JfPvShfLLyeSom6NZ_TcQc6QH27tJ7prEWZPfI.cache → Cv/Cv9WXE_0OqtPUZBXfTWaE8uKx9oFIzqO18ZkwVaBLSg.cache} +0 -0
  61. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Mf/MfB2-0nbsmC548XBSLftafi6BZ9nAquBA-6eu7mAmdE.cache +2 -0
  62. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/N2/N2cUP-Um_nQ5ZTCQr_H0bKIjOSIyV7Ry5sT6-DB9e4A.cache +1 -0
  63. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{FJ/FJlQpfMtpRbrM5P8A7d2FAelFKwo6GrVs2xks8z5GKU.cache → Ot/OtNAnT3d-csAKBtJ8UBLOSwUDyfmOdCWpS08RaSCGsQ.cache} +0 -0
  64. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/P3/P33RwiTMGEu2wZySBEUmf5U7hnfBhdL49wzdUWXYNRs.cache +1 -0
  65. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/RZ/RZAL9gIt4aD731Ikf7UZZNPSZXzhPqtDskLB7nQcWH4.cache +1 -0
  66. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/SQ/SQVJeYO2bM0qgQiOaeVBjYo3SWQZmvixa3tXUjsmuUs.cache +0 -0
  67. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{Ma/MaK3K1AoZZ4xM5fOOifhROd73hfZJpP4yGbkGdoYtEk.cache → V2/V2JApVhUSYhvWnNVIbpe58U4xheVkpi0gCStqjDN6-A.cache} +0 -0
  68. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{Lk/LklIq5hrBAPESXVUpFMwQ9L-1qTj90sPVi6U19_Xi-Q.cache → VA/VADOUaZFukufOb44ts4KoyQZumPcVJET0bi9RvC7c-o.cache} +1 -1
  69. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Vz/VzdPLfWn16XbpHNJdkDMamAf3QutM29cvvPkDNyy5nE.cache +1 -0
  70. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/W9/W9QfraySVwoRt-SgGOIS0e-iP8R1qP_URwXZw1l6M5E.cache +0 -0
  71. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Wy/Wyiw07ngOzgV6RPis_Lo2hhSRkwo2YSqKTEDAF0crhA.cache +0 -0
  72. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Z6/Z6rAtdVt3OXS26vLVCtdO3vmMlttI3ajdpbC2FHk7iQ.cache +0 -0
  73. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/b6/b6QRH6ZdCc0e6bUWu4qni_kZmptaMgWciO8Jl9q6_p8.cache +0 -0
  74. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{Pm/PmheG0PGFqDws1qgFOxOyIL-gpMof3Ar9eSRKVLYuik.cache → fP/fPihom3hnc1rQQxpviTvZPRJB_IghWYWP3dDcsGrcLk.cache} +0 -0
  75. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gD/gDU38plXvosMgFK47_PBI9xGVsmsE2tShWEZzxiek3k.cache +1 -0
  76. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/gR/gRqL5_jaFW7eA3d2frJmOzw_vFLuvfhwMhotAlsO8J4.cache +2 -0
  77. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/jC/jCTZ1jAldKBn4OTANBBmCKzxLrDgok1ur4meoTqlDNg.cache +0 -0
  78. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{yN/yNOFGOsnHmxXNMkuEAWuL1u3jlmdvrdeoTx6DDJ1in8.cache → jc/jcB8w1gBT7JP10DW4OOvvYpW1ZFeMyedngmMy3QbRLQ.cache} +0 -0
  79. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/jg/jgxXkkkXf1NPOPrpNdEJzhDt-2xHGzd_-mLkIHWrOr4.cache +2 -0
  80. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/nx/nxzZnvk5YyBhTUloQSZZ5zRuaqlsLiHy_AbOzQ3d788.cache +0 -0
  81. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/wr/wrlf8nUW2yftpcIA97qImyECR8f8o3OiOdHLdfkmw8c.cache +1 -0
  82. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/{qT/qTQIQsmS0Wbbg2JxNn9rxdI5qVOTg5SfyQdaTvr9vLo.cache → xd/xdD4KJ55W3jy5PIrwT0UnDp1toKpUfgrjJBgB4WaPIc.cache} +0 -0
  83. data/spec/support/doorkeeper_rspec.rb +0 -0
  84. data/spec/support/orm/mongoid.rb +18 -2
  85. data/spec/support/orm/mongoid8.rb +6 -0
  86. data/spec/support/orm/mongoid9.rb +6 -0
  87. data/spec/support/render_with_matcher.rb +26 -0
  88. metadata +126 -241
  89. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  90. data/spec/controllers/applications_controller_spec.rb +0 -270
  91. data/spec/controllers/authorizations_controller_spec.rb +0 -744
  92. data/spec/controllers/protected_resources_controller_spec.rb +0 -361
  93. data/spec/controllers/token_info_controller_spec.rb +0 -50
  94. data/spec/controllers/tokens_controller_spec.rb +0 -542
  95. data/spec/doorkeeper/redirect_uri_validator_spec.rb +0 -183
  96. data/spec/doorkeeper/server_spec.rb +0 -50
  97. data/spec/doorkeeper/stale_records_cleaner_spec.rb +0 -103
  98. data/spec/doorkeeper/version_spec.rb +0 -17
  99. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/-o/-ofn45zIfO5vx4VD6m6NXesLf6da5usA-Sbw2SVju3o.cache +0 -2
  100. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/0_/0_ouGcG_o_1zmVmBe-tdQYk594LBwVa1bumjrKtdfEw.cache +0 -0
  101. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/2X/2XMMcHbyTSRqh1GkV0xzyIETNtt-zgN6iniziShaKmQ.cache +0 -2
  102. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/4Q/4QQw-pMQ98JIj3xdcFhGBQdysdGPY9rWffRqWMmyjew.cache +0 -1
  103. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/7H/7HjRsym0tTpXFCVhWt6kteMs_-CozKVbr9s5syHm8es.cache +0 -1
  104. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/8B/8BxJyv22HPFHu1se_l2J8qW1N9NzZ16UOWOy1YMSgs4.cache +0 -1
  105. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/9x/9xjtGv-yKjj62x9uFwBZg8pTSh9ERPAgANwNo9uwIaA.cache +0 -1
  106. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Bt/BtXO7f0PZ8DNt3TMLYM-zY7LkbWa_KgyB0v1V98M1CQ.cache +0 -1
  107. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/E0/E02f1Q2tutWumMulGCFNfqQNjvEP_hMAK_5E83eWepI.cache +0 -0
  108. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/EZ/EZGpd6pUEJZxO6uT2yIS4Fpn5KX7VDgC9VB3AaemF5Q.cache +0 -2
  109. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/L8/L8mOWakJlWKr6MU85rj0V7yGFfNyIR6vE6YXtqArPGw.cache +0 -1
  110. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/MB/MBWRxa9S470ee8suxVKp0jYgv6K6FQOqKGV0kPGQNMs.cache +0 -1
  111. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Ph/Ph7RtH_NvG2I8XpTa8mA8SBQXZDzBPVIh4CH6g7OXJ0.cache +0 -2
  112. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/So/So59ksdx2dw-_A3-zFZ6Palr7fROjm7_0JDZb04temw.cache +0 -0
  113. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/Wt/WtXL_iDofLeTH_v0Yf3PM421r9b1V0g-VBvMPeu9KA0.cache +0 -0
  114. data/spec/dummy/tmp/cache/assets/sprockets/v4.0.0/dX/dX6FDdUIy8yBCOoaoXcjf71rX9N_bpiXGJ4Urt32NTk.cache +0 -0
  115. data/spec/factories.rb +0 -30
  116. data/spec/grape/grape_integration_spec.rb +0 -137
  117. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  118. data/spec/lib/config_spec.rb +0 -824
  119. data/spec/lib/doorkeeper_spec.rb +0 -27
  120. data/spec/lib/models/expirable_spec.rb +0 -61
  121. data/spec/lib/models/reusable_spec.rb +0 -40
  122. data/spec/lib/models/revocable_spec.rb +0 -55
  123. data/spec/lib/models/scopes_spec.rb +0 -61
  124. data/spec/lib/models/secret_storable_spec.rb +0 -136
  125. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -35
  126. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -180
  127. data/spec/lib/oauth/base_request_spec.rb +0 -210
  128. data/spec/lib/oauth/base_response_spec.rb +0 -45
  129. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  130. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -135
  131. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -110
  132. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -92
  133. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  134. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -105
  135. data/spec/lib/oauth/client_spec.rb +0 -38
  136. data/spec/lib/oauth/code_request_spec.rb +0 -46
  137. data/spec/lib/oauth/code_response_spec.rb +0 -36
  138. data/spec/lib/oauth/error_response_spec.rb +0 -65
  139. data/spec/lib/oauth/error_spec.rb +0 -21
  140. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
  141. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
  142. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  143. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  144. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
  145. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
  146. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -202
  147. data/spec/lib/oauth/pre_authorization_spec.rb +0 -230
  148. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -166
  149. data/spec/lib/oauth/scopes_spec.rb +0 -146
  150. data/spec/lib/oauth/token_request_spec.rb +0 -164
  151. data/spec/lib/oauth/token_response_spec.rb +0 -84
  152. data/spec/lib/oauth/token_spec.rb +0 -156
  153. data/spec/lib/option_spec.rb +0 -51
  154. data/spec/lib/request/strategy_spec.rb +0 -51
  155. data/spec/lib/secret_storing/base_spec.rb +0 -61
  156. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -50
  157. data/spec/lib/secret_storing/plain_spec.rb +0 -45
  158. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -49
  159. data/spec/models/doorkeeper/access_grant_spec.rb +0 -173
  160. data/spec/models/doorkeeper/access_token_spec.rb +0 -644
  161. data/spec/models/doorkeeper/application_spec.rb +0 -499
  162. data/spec/requests/applications/applications_request_spec.rb +0 -257
  163. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  164. data/spec/requests/endpoints/authorization_spec.rb +0 -91
  165. data/spec/requests/endpoints/token_spec.rb +0 -85
  166. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -86
  167. data/spec/requests/flows/authorization_code_spec.rb +0 -559
  168. data/spec/requests/flows/client_credentials_spec.rb +0 -219
  169. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  170. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  171. data/spec/requests/flows/password_spec.rb +0 -356
  172. data/spec/requests/flows/refresh_token_spec.rb +0 -255
  173. data/spec/requests/flows/revoke_token_spec.rb +0 -196
  174. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  175. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  176. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  177. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  178. data/spec/routing/default_routes_spec.rb +0 -41
  179. data/spec/routing/scoped_routes_spec.rb +0 -47
  180. data/spec/spec_helper.rb +0 -54
  181. data/spec/spec_helper_integration.rb +0 -4
  182. data/spec/support/dependencies/factory_bot.rb +0 -4
  183. data/spec/support/helpers/access_token_request_helper.rb +0 -14
  184. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  185. data/spec/support/helpers/config_helper.rb +0 -11
  186. data/spec/support/helpers/model_helper.rb +0 -78
  187. data/spec/support/helpers/request_spec_helper.rb +0 -98
  188. data/spec/support/helpers/url_helper.rb +0 -62
  189. data/spec/support/orm/active_record.rb +0 -5
  190. data/spec/support/shared/controllers_shared_context.rb +0 -100
  191. data/spec/support/shared/hashing_shared_context.rb +0 -40
  192. data/spec/support/shared/models_shared_examples.rb +0 -56
@@ -1,499 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
- require "bcrypt"
5
-
6
- RSpec.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 "when 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 "when application owner is not required" do
95
- before 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 "when 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
- describe "redirect URI" do
122
- context "when grant flows allow blank redirect URI" do
123
- before do
124
- Doorkeeper.configure do
125
- orm DOORKEEPER_ORM
126
- grant_flows %w[password client_credentials]
127
- end
128
- end
129
-
130
- it "is valid without redirect_uri" do
131
- new_application.save
132
- new_application.redirect_uri = nil
133
- expect(new_application).to be_valid
134
- end
135
- end
136
-
137
- context "when grant flows require redirect URI" do
138
- before do
139
- Doorkeeper.configure do
140
- orm DOORKEEPER_ORM
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
- orm DOORKEEPER_ORM
156
- grant_flows %w[password client_credentials]
157
- allow_blank_redirect_uri false
158
- end
159
- end
160
-
161
- it "is invalid without redirect_uri" do
162
- new_application.save
163
- new_application.redirect_uri = nil
164
- expect(new_application).not_to be_valid
165
- end
166
- end
167
- end
168
-
169
- context "with hashing enabled" do
170
- include_context "with application hashing enabled"
171
- let(:app) { FactoryBot.create :application }
172
- let(:default_strategy) { Doorkeeper::SecretStoring::Sha256Hash }
173
-
174
- it "uses SHA256 to avoid additional dependencies" do
175
- # Ensure token was generated
176
- app.validate
177
- expect(app.secret).to eq(default_strategy.transform_secret(app.plaintext_secret))
178
- end
179
-
180
- context "when bcrypt strategy is configured" do
181
- # In this text context, we have bcrypt loaded so `bcrypt_present?`
182
- # will always be true
183
- before do
184
- Doorkeeper.configure do
185
- orm DOORKEEPER_ORM
186
- hash_application_secrets using: "Doorkeeper::SecretStoring::BCrypt"
187
- end
188
- end
189
-
190
- it "holds a volatile plaintext and BCrypt secret" do
191
- expect(app.secret_strategy).to eq Doorkeeper::SecretStoring::BCrypt
192
- expect(app.plaintext_secret).to be_a(String)
193
- expect(app.secret).not_to eq(app.plaintext_secret)
194
- expect { ::BCrypt::Password.create(app.secret) }.not_to raise_error
195
- end
196
- end
197
-
198
- it "does not fallback to plain lookup by default" do
199
- lookup = described_class.by_uid_and_secret(app.uid, app.secret)
200
- expect(lookup).to eq(nil)
201
-
202
- lookup = described_class.by_uid_and_secret(app.uid, app.plaintext_secret)
203
- expect(lookup).to eq(app)
204
- end
205
-
206
- context "with fallback enabled" do
207
- include_context "with token hashing and fallback lookup enabled"
208
-
209
- it "provides plain and hashed lookup" do
210
- lookup = described_class.by_uid_and_secret(app.uid, app.secret)
211
- expect(lookup).to eq(app)
212
-
213
- lookup = described_class.by_uid_and_secret(app.uid, app.plaintext_secret)
214
- expect(lookup).to eq(app)
215
- end
216
- end
217
-
218
- it "does not provide access to secret after loading" do
219
- lookup = described_class.by_uid_and_secret(app.uid, app.plaintext_secret)
220
- expect(lookup.plaintext_secret).to be_nil
221
- end
222
- end
223
-
224
- describe "destroy related models on cascade" do
225
- before do
226
- new_application.save
227
- end
228
-
229
- let(:resource_owner) { FactoryBot.create(:resource_owner) }
230
-
231
- it "destroys its access grants" do
232
- FactoryBot.create(
233
- :access_grant,
234
- application: new_application,
235
- resource_owner_id: resource_owner.id,
236
- resource_owner_type: resource_owner.class.name,
237
- )
238
-
239
- expect { new_application.destroy }.to change { Doorkeeper::AccessGrant.count }.by(-1)
240
- end
241
-
242
- it "destroys its access tokens" do
243
- FactoryBot.create(:access_token, application: new_application)
244
- FactoryBot.create(:access_token, application: new_application, revoked_at: Time.now.utc)
245
- expect do
246
- new_application.destroy
247
- end.to change { Doorkeeper::AccessToken.count }.by(-2)
248
- end
249
- end
250
-
251
- describe "#ordered_by" do
252
- let(:applications) { FactoryBot.create_list(:application, 5) }
253
-
254
- context "when a direction is not specified" do
255
- it "calls order with a default order of asc" do
256
- names = applications.map(&:name).sort
257
- expect(described_class.ordered_by(:name).map(&:name)).to eq(names)
258
- end
259
- end
260
-
261
- context "when a direction is specified" do
262
- it "calls order with specified direction" do
263
- names = applications.map(&:name).sort.reverse
264
- expect(described_class.ordered_by(:name, :desc).map(&:name)).to eq(names)
265
- end
266
- end
267
- end
268
-
269
- describe "#redirect_uri=" do
270
- context "when array of valid redirect_uris" do
271
- it "joins by newline" do
272
- new_application.redirect_uri = ["http://localhost/callback1", "http://localhost/callback2"]
273
- expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
274
- end
275
- end
276
-
277
- context "when string of valid redirect_uris" do
278
- it "stores as-is" do
279
- new_application.redirect_uri = "http://localhost/callback1\nhttp://localhost/callback2"
280
- expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
281
- end
282
- end
283
- end
284
-
285
- describe "#renew_secret" do
286
- let(:app) { FactoryBot.create :application }
287
-
288
- it "generates a new secret" do
289
- old_secret = app.secret
290
- app.renew_secret
291
- expect(old_secret).not_to eq(app.secret)
292
- end
293
- end
294
-
295
- describe "#authorized_for" do
296
- let(:resource_owner) { FactoryBot.create(:resource_owner) }
297
- let(:other_resource_owner) { FactoryBot.create(:resource_owner) }
298
-
299
- it "is empty if the application is not authorized for anyone" do
300
- expect(described_class.authorized_for(resource_owner)).to be_empty
301
- end
302
-
303
- it "returns only application for a specific resource owner" do
304
- FactoryBot.create(
305
- :access_token,
306
- resource_owner_id: other_resource_owner.id,
307
- resource_owner_type: other_resource_owner.class.name,
308
- )
309
- token = FactoryBot.create(
310
- :access_token,
311
- resource_owner_id: resource_owner.id,
312
- resource_owner_type: resource_owner.class.name,
313
- )
314
- expect(described_class.authorized_for(resource_owner)).to eq([token.application])
315
- end
316
-
317
- it "excludes revoked tokens" do
318
- FactoryBot.create(
319
- :access_token,
320
- resource_owner_id: resource_owner.id,
321
- resource_owner_type: resource_owner.class.name,
322
- revoked_at: 2.days.ago,
323
- )
324
- expect(described_class.authorized_for(resource_owner)).to be_empty
325
- end
326
-
327
- it "returns all applications that have been authorized" do
328
- token1 = FactoryBot.create(
329
- :access_token,
330
- resource_owner_id: resource_owner.id,
331
- resource_owner_type: resource_owner.class.name,
332
- )
333
- token2 = FactoryBot.create(
334
- :access_token,
335
- resource_owner_id: resource_owner.id,
336
- resource_owner_type: resource_owner.class.name,
337
- )
338
- expect(described_class.authorized_for(resource_owner))
339
- .to eq([token1.application, token2.application])
340
- end
341
-
342
- it "returns only one application even if it has been authorized twice" do
343
- application = FactoryBot.create(:application)
344
- FactoryBot.create(
345
- :access_token,
346
- resource_owner_id: resource_owner.id,
347
- resource_owner_type: resource_owner.class.name,
348
- application: application,
349
- )
350
- FactoryBot.create(
351
- :access_token,
352
- resource_owner_id: resource_owner.id,
353
- resource_owner_type: resource_owner.class.name,
354
- application: application,
355
- )
356
- expect(described_class.authorized_for(resource_owner)).to eq([application])
357
- end
358
- end
359
-
360
- describe "#revoke_tokens_and_grants_for" do
361
- it "revokes all access tokens and access grants" do
362
- application_id = 42
363
- resource_owner = double
364
- expect(Doorkeeper::AccessToken)
365
- .to receive(:revoke_all_for).with(application_id, resource_owner)
366
- expect(Doorkeeper::AccessGrant)
367
- .to receive(:revoke_all_for).with(application_id, resource_owner)
368
-
369
- described_class.revoke_tokens_and_grants_for(application_id, resource_owner)
370
- end
371
- end
372
-
373
- describe "#by_uid_and_secret" do
374
- context "when application is private/confidential" do
375
- it "finds the application via uid/secret" do
376
- app = FactoryBot.create :application
377
- authenticated = described_class.by_uid_and_secret(app.uid, app.secret)
378
- expect(authenticated).to eq(app)
379
- end
380
-
381
- context "when secret is wrong" do
382
- it "does not find the application" do
383
- app = FactoryBot.create :application
384
- authenticated = described_class.by_uid_and_secret(app.uid, "bad")
385
- expect(authenticated).to eq(nil)
386
- end
387
- end
388
- end
389
-
390
- context "when application is public/non-confidential" do
391
- context "when secret is blank" do
392
- it "finds the application" do
393
- app = FactoryBot.create :application, confidential: false
394
- authenticated = described_class.by_uid_and_secret(app.uid, nil)
395
- expect(authenticated).to eq(app)
396
- end
397
- end
398
-
399
- context "when secret is wrong" do
400
- it "does not find the application" do
401
- app = FactoryBot.create :application, confidential: false
402
- authenticated = described_class.by_uid_and_secret(app.uid, "bad")
403
- expect(authenticated).to eq(nil)
404
- end
405
- end
406
- end
407
- end
408
-
409
- describe "#confidential?" do
410
- subject { FactoryBot.create(:application, confidential: confidential).confidential? }
411
-
412
- context "when application is private/confidential" do
413
- let(:confidential) { true }
414
-
415
- it { expect(subject).to eq(true) }
416
- end
417
-
418
- context "when application is public/non-confidential" do
419
- let(:confidential) { false }
420
-
421
- it { expect(subject).to eq(false) }
422
- end
423
- end
424
-
425
- describe "#as_json" do
426
- let(:app) { FactoryBot.create :application, secret: "123123123" }
427
-
428
- before do
429
- allow(Doorkeeper.configuration)
430
- .to receive(:application_secret_strategy).and_return(Doorkeeper::SecretStoring::Plain)
431
- end
432
-
433
- # AR specific feature
434
- if DOORKEEPER_ORM == :active_record
435
- it "correctly works with #to_json" do
436
- ActiveRecord::Base.include_root_in_json = true
437
- expect(app.to_json(include_root_in_json: true)).to match(/application.+?:\{/)
438
- ActiveRecord::Base.include_root_in_json = false
439
- end
440
- end
441
-
442
- context "when called without authorized resource owner" do
443
- it "includes minimal set of attributes" do
444
- expect(app.as_json).to match(
445
- "id" => app.id,
446
- "name" => app.name,
447
- "created_at" => anything,
448
- )
449
- end
450
-
451
- it "includes application UID if it's public" do
452
- app = FactoryBot.create :application, secret: "123123123", confidential: false
453
-
454
- expect(app.as_json).to match(
455
- "id" => app.id,
456
- "name" => app.name,
457
- "created_at" => anything,
458
- "uid" => app.uid,
459
- )
460
- end
461
-
462
- it "respects custom options" do
463
- expect(app.as_json(except: :id)).not_to include("id")
464
- expect(app.as_json(only: %i[name created_at secret]))
465
- .to match(
466
- "name" => app.name,
467
- "created_at" => anything,
468
- )
469
- end
470
- end
471
-
472
- context "when called with authorized resource owner" do
473
- let(:owner) { FactoryBot.create(:doorkeeper_testing_user) }
474
- let(:other_owner) { FactoryBot.create(:doorkeeper_testing_user) }
475
- let(:app) { FactoryBot.create(:application, secret: "123123123", owner: owner) }
476
-
477
- before do
478
- Doorkeeper.configure do
479
- orm DOORKEEPER_ORM
480
- enable_application_owner confirmation: false
481
- end
482
- end
483
-
484
- it "includes all the attributes" do
485
- expect(app.as_json(current_resource_owner: owner))
486
- .to include(
487
- "secret" => "123123123",
488
- "redirect_uri" => app.redirect_uri,
489
- "uid" => app.uid,
490
- )
491
- end
492
-
493
- it "doesn't include unsafe attributes if current owner isn't the same as owner" do
494
- expect(app.as_json(current_resource_owner: other_owner))
495
- .not_to include("redirect_uri")
496
- end
497
- end
498
- end
499
- end