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,559 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- feature "Authorization Code Flow" do
6
- background do
7
- default_scopes_exist :default
8
- config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
9
- client_exists
10
- create_resource_owner
11
- sign_in
12
- end
13
-
14
- scenario "resource owner authorizes the client" do
15
- visit authorization_endpoint_url(client: @client)
16
- click_on "Authorize"
17
-
18
- access_grant_should_exist_for(@client, @resource_owner)
19
-
20
- i_should_be_on_client_callback(@client)
21
-
22
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
23
- url_should_not_have_param("state")
24
- url_should_not_have_param("error")
25
- end
26
-
27
- context "when configured to check application supported grant flow" do
28
- before do
29
- config_is_set(:allow_grant_flow_for_client, ->(_grant_flow, client) { client.name == "admin" })
30
- end
31
-
32
- scenario "forbids the request when doesn't satisfy condition" do
33
- @client.update(name: "sample app")
34
-
35
- visit authorization_endpoint_url(client: @client)
36
-
37
- i_should_see_translated_error_message("unauthorized_client")
38
- end
39
-
40
- scenario "allows the request when satisfies condition" do
41
- @client.update(name: "admin")
42
-
43
- visit authorization_endpoint_url(client: @client)
44
- i_should_not_see_translated_error_message("unauthorized_client")
45
- click_on "Authorize"
46
-
47
- authorization_code = Doorkeeper::AccessGrant.first.token
48
- create_access_token authorization_code, @client
49
-
50
- access_token_should_exist_for(@client, @resource_owner)
51
-
52
- expect(json_response).to match(
53
- "access_token" => Doorkeeper::AccessToken.first.token,
54
- "token_type" => "Bearer",
55
- "expires_in" => 7200,
56
- "scope" => "default",
57
- "created_at" => an_instance_of(Integer),
58
- )
59
- end
60
- end
61
-
62
- context "with grant hashing enabled" do
63
- background do
64
- config_is_set(:token_secret_strategy, ::Doorkeeper::SecretStoring::Sha256Hash)
65
- end
66
-
67
- def authorize(redirect_url)
68
- @client.redirect_uri = redirect_url
69
- @client.save!
70
- visit authorization_endpoint_url(client: @client)
71
- click_on "Authorize"
72
-
73
- access_grant_should_exist_for(@client, @resource_owner)
74
-
75
- code = current_params["code"]
76
- expect(code).not_to be_nil
77
-
78
- hashed_code = Doorkeeper::AccessGrant.secret_strategy.transform_secret code
79
- expect(hashed_code).to eq Doorkeeper::AccessGrant.first.token
80
-
81
- [code, hashed_code]
82
- end
83
-
84
- scenario "using redirect_url urn:ietf:wg:oauth:2.0:oob" do
85
- code, hashed_code = authorize("urn:ietf:wg:oauth:2.0:oob")
86
- expect(code).not_to eq(hashed_code)
87
- i_should_see "Authorization code:"
88
- i_should_see code
89
- i_should_not_see hashed_code
90
- end
91
-
92
- scenario "using redirect_url urn:ietf:wg:oauth:2.0:oob:auto" do
93
- code, hashed_code = authorize("urn:ietf:wg:oauth:2.0:oob:auto")
94
- expect(code).not_to eq(hashed_code)
95
- i_should_see "Authorization code:"
96
- i_should_see code
97
- i_should_not_see hashed_code
98
- end
99
- end
100
-
101
- scenario "resource owner authorizes using oob url" do
102
- @client.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
103
- @client.save!
104
- visit authorization_endpoint_url(client: @client)
105
- click_on "Authorize"
106
-
107
- access_grant_should_exist_for(@client, @resource_owner)
108
-
109
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
110
- i_should_see "Authorization code:"
111
- i_should_see Doorkeeper::AccessGrant.first.token
112
- end
113
-
114
- scenario "resource owner authorizes the client with state parameter set" do
115
- visit authorization_endpoint_url(client: @client, state: "return-me")
116
- click_on "Authorize"
117
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
118
- url_should_have_param("state", "return-me")
119
- url_should_not_have_param("code_challenge_method")
120
- end
121
-
122
- scenario "resource owner requests an access token without authorization code" do
123
- create_access_token "", @client
124
-
125
- access_token_should_not_exist
126
-
127
- expect(Doorkeeper::AccessToken.count).to be_zero
128
-
129
- expect(json_response).to match(
130
- "error" => "invalid_request",
131
- "error_description" => translated_invalid_request_error_message(:missing_param, :code),
132
- )
133
- end
134
-
135
- scenario "resource owner requests an access token with authorization code" do
136
- visit authorization_endpoint_url(client: @client)
137
- click_on "Authorize"
138
-
139
- authorization_code = Doorkeeper::AccessGrant.first.token
140
- create_access_token authorization_code, @client
141
-
142
- access_token_should_exist_for(@client, @resource_owner)
143
-
144
- expect(json_response).to match(
145
- "access_token" => Doorkeeper::AccessToken.first.token,
146
- "token_type" => "Bearer",
147
- "expires_in" => 7200,
148
- "scope" => "default",
149
- "created_at" => an_instance_of(Integer),
150
- )
151
- end
152
-
153
- scenario "resource owner requests an access token with authorization code but without secret" do
154
- visit authorization_endpoint_url(client: @client)
155
- click_on "Authorize"
156
-
157
- authorization_code = Doorkeeper::AccessGrant.first.token
158
- page.driver.post token_endpoint_url(
159
- code: authorization_code, client_id: @client.uid,
160
- redirect_uri: @client.redirect_uri,
161
- )
162
-
163
- expect(Doorkeeper::AccessToken.count).to be_zero
164
-
165
- expect(json_response).to match(
166
- "error" => "invalid_client",
167
- "error_description" => translated_error_message(:invalid_client),
168
- )
169
- end
170
-
171
- scenario "resource owner requests an access token with authorization code but without client id" do
172
- visit authorization_endpoint_url(client: @client)
173
- click_on "Authorize"
174
-
175
- authorization_code = Doorkeeper::AccessGrant.first.token
176
- page.driver.post token_endpoint_url(
177
- code: authorization_code, client_secret: @client.secret,
178
- redirect_uri: @client.redirect_uri,
179
- )
180
-
181
- expect(Doorkeeper::AccessToken.count).to be_zero
182
-
183
- expect(json_response).to match(
184
- "error" => "invalid_client",
185
- "error_description" => translated_error_message(:invalid_client),
186
- )
187
- end
188
-
189
- scenario "silently authorizes if matching token exists" do
190
- default_scopes_exist :public, :write
191
-
192
- access_token_exists application: @client,
193
- expires_in: -100, # even expired token
194
- resource_owner_id: @resource_owner.id,
195
- resource_owner_type: @resource_owner.class.name,
196
- scopes: "public write"
197
-
198
- visit authorization_endpoint_url(client: @client, scope: "public write")
199
-
200
- response_status_should_be 200
201
- i_should_not_see "Authorize"
202
- end
203
-
204
- context "with PKCE" do
205
- context "when plain" do
206
- let(:code_challenge) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
207
- let(:code_verifier) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
208
-
209
- scenario "resource owner authorizes the client with code_challenge parameter set" do
210
- visit authorization_endpoint_url(
211
- client: @client,
212
- code_challenge: code_challenge,
213
- code_challenge_method: "plain",
214
- )
215
- click_on "Authorize"
216
-
217
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
218
- url_should_not_have_param("code_challenge_method")
219
- url_should_not_have_param("code_challenge")
220
- end
221
-
222
- scenario "mobile app requests an access token with authorization code but not pkce token" do
223
- visit authorization_endpoint_url(client: @client)
224
- click_on "Authorize"
225
-
226
- authorization_code = current_params["code"]
227
- create_access_token authorization_code, @client, code_verifier
228
-
229
- expect(json_response).to match(
230
- "error" => "invalid_grant",
231
- "error_description" => translated_error_message(:invalid_grant),
232
- )
233
- end
234
-
235
- scenario "mobile app requests an access token with authorization code and plain code challenge method" do
236
- visit authorization_endpoint_url(
237
- client: @client,
238
- code_challenge: code_challenge,
239
- code_challenge_method: "plain",
240
- )
241
- click_on "Authorize"
242
-
243
- authorization_code = current_params["code"]
244
- create_access_token authorization_code, @client, code_verifier
245
-
246
- access_token_should_exist_for(@client, @resource_owner)
247
-
248
- expect(json_response).to match(
249
- "access_token" => Doorkeeper::AccessToken.first.token,
250
- "token_type" => "Bearer",
251
- "expires_in" => 7200,
252
- "scope" => "default",
253
- "created_at" => an_instance_of(Integer),
254
- )
255
- end
256
-
257
- scenario "mobile app requests an access token with authorization code but without code_verifier" do
258
- visit authorization_endpoint_url(
259
- client: @client,
260
- code_challenge: code_challenge,
261
- code_challenge_method: "plain",
262
- )
263
- click_on "Authorize"
264
-
265
- authorization_code = current_params["code"]
266
- create_access_token authorization_code, @client, nil
267
-
268
- expect(json_response).to match(
269
- "error" => "invalid_request",
270
- "error_description" => translated_invalid_request_error_message(:missing_param, :code_verifier),
271
- )
272
- end
273
-
274
- scenario "mobile app requests an access token with authorization code with wrong code_verifier" do
275
- visit authorization_endpoint_url(
276
- client: @client,
277
- code_challenge: code_challenge,
278
- code_challenge_method: "plain",
279
- )
280
- click_on "Authorize"
281
-
282
- authorization_code = current_params["code"]
283
- create_access_token authorization_code, @client, "wrong_code_verifier"
284
-
285
- expect(json_response).not_to include("access_token")
286
- expect(json_response).to match(
287
- "error" => "invalid_grant",
288
- "error_description" => translated_error_message(:invalid_grant),
289
- )
290
- end
291
- end
292
-
293
- context "when S256" do
294
- let(:code_challenge) { "Oz733NtQ0rJP8b04fgZMJMwprn6Iw8sMCT_9bR1q4tA" }
295
- let(:code_verifier) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
296
-
297
- scenario "resource owner authorizes the client with code_challenge parameter set" do
298
- visit authorization_endpoint_url(
299
- client: @client,
300
- code_challenge: code_challenge,
301
- code_challenge_method: "S256",
302
- )
303
- click_on "Authorize"
304
-
305
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
306
- url_should_not_have_param("code_challenge_method")
307
- url_should_not_have_param("code_challenge")
308
- end
309
-
310
- scenario "mobile app requests an access token with authorization code and S256 code challenge method" do
311
- visit authorization_endpoint_url(
312
- client: @client,
313
- code_challenge: code_challenge,
314
- code_challenge_method: "S256",
315
- )
316
- click_on "Authorize"
317
-
318
- authorization_code = current_params["code"]
319
- create_access_token authorization_code, @client, code_verifier
320
-
321
- access_token_should_exist_for(@client, @resource_owner)
322
-
323
- expect(json_response).to match(
324
- "access_token" => Doorkeeper::AccessToken.first.token,
325
- "token_type" => "Bearer",
326
- "expires_in" => 7200,
327
- "scope" => "default",
328
- "created_at" => an_instance_of(Integer),
329
- )
330
- end
331
-
332
- scenario "mobile app requests an access token with authorization code and without secret" do
333
- visit authorization_endpoint_url(
334
- client: @client,
335
- code_challenge: code_challenge,
336
- code_challenge_method: "S256",
337
- )
338
- click_on "Authorize"
339
-
340
- authorization_code = current_params["code"]
341
- page.driver.post token_endpoint_url(
342
- code: authorization_code,
343
- client_id: @client.uid,
344
- redirect_uri: @client.redirect_uri,
345
- code_verifier: code_verifier,
346
- )
347
-
348
- expect(json_response).to match(
349
- "error" => "invalid_client",
350
- "error_description" => translated_error_message(:invalid_client),
351
- )
352
- end
353
-
354
- scenario "mobile app requests an access token with authorization code and without secret but is marked as not confidential" do
355
- @client.update_attribute :confidential, false
356
- visit authorization_endpoint_url(client: @client, code_challenge: code_challenge, code_challenge_method: "S256")
357
- click_on "Authorize"
358
-
359
- authorization_code = current_params["code"]
360
- page.driver.post token_endpoint_url(
361
- code: authorization_code,
362
- client_id: @client.uid,
363
- redirect_uri: @client.redirect_uri,
364
- code_verifier: code_verifier,
365
- )
366
-
367
- expect(json_response).to match(
368
- "access_token" => Doorkeeper::AccessToken.first.token,
369
- "token_type" => "Bearer",
370
- "expires_in" => 7200,
371
- "scope" => "default",
372
- "created_at" => an_instance_of(Integer),
373
- )
374
- end
375
-
376
- scenario "mobile app requests an access token with authorization code but no code verifier" do
377
- visit authorization_endpoint_url(
378
- client: @client,
379
- code_challenge: code_challenge,
380
- code_challenge_method: "S256",
381
- )
382
- click_on "Authorize"
383
-
384
- authorization_code = current_params["code"]
385
- create_access_token authorization_code, @client
386
-
387
- expect(json_response).not_to include("access_token")
388
- expect(json_response).to match(
389
- "error" => "invalid_request",
390
- "error_description" => translated_invalid_request_error_message(:missing_param, :code_verifier),
391
- )
392
- end
393
-
394
- scenario "mobile app requests an access token with authorization code with wrong verifier" do
395
- visit authorization_endpoint_url(
396
- client: @client,
397
- code_challenge: code_challenge,
398
- code_challenge_method: "S256",
399
- )
400
- click_on "Authorize"
401
-
402
- authorization_code = current_params["code"]
403
- create_access_token authorization_code, @client, "incorrect-code-verifier"
404
-
405
- expect(json_response).to match(
406
- "error" => "invalid_grant",
407
- "error_description" => translated_error_message(:invalid_grant),
408
- )
409
- end
410
-
411
- scenario "code_challenge_methhod in token request is totally ignored" do
412
- visit authorization_endpoint_url(
413
- client: @client,
414
- code_challenge: code_challenge,
415
- code_challenge_method: "S256",
416
- )
417
- click_on "Authorize"
418
-
419
- authorization_code = current_params["code"]
420
- page.driver.post token_endpoint_url(
421
- code: authorization_code,
422
- client: @client,
423
- code_verifier: code_challenge,
424
- code_challenge_method: "plain",
425
- )
426
-
427
- expect(json_response).to match(
428
- "error" => "invalid_grant",
429
- "error_description" => translated_error_message(:invalid_grant),
430
- )
431
- end
432
-
433
- scenario "expects to set code_challenge_method explicitely without fallback" do
434
- visit authorization_endpoint_url(client: @client, code_challenge: code_challenge)
435
- expect(page).to have_content("The code challenge method must be plain or S256.")
436
- end
437
- end
438
- end
439
-
440
- context "when application scopes are present and no scope is passed" do
441
- background do
442
- @client.update(scopes: "public write read default")
443
- end
444
-
445
- scenario "scope is invalid because default scope is different from application scope" do
446
- default_scopes_exist :admin
447
- visit authorization_endpoint_url(client: @client)
448
- response_status_should_be 200
449
- i_should_not_see "Authorize"
450
- i_should_see_translated_error_message :invalid_scope
451
- end
452
-
453
- scenario "access grant have scopes which are common in application scopees and default scopes" do
454
- default_scopes_exist :public, :write
455
- visit authorization_endpoint_url(client: @client)
456
- click_on "Authorize"
457
- access_grant_should_exist_for(@client, @resource_owner)
458
- access_grant_should_have_scopes :public, :write
459
- end
460
- end
461
-
462
- context "with scopes" do
463
- background do
464
- default_scopes_exist :public
465
- optional_scopes_exist :write
466
- end
467
-
468
- scenario "resource owner authorizes the client with default scopes" do
469
- visit authorization_endpoint_url(client: @client)
470
- click_on "Authorize"
471
- access_grant_should_exist_for(@client, @resource_owner)
472
- access_grant_should_have_scopes :public
473
- end
474
-
475
- scenario "resource owner authorizes the client with required scopes" do
476
- visit authorization_endpoint_url(client: @client, scope: "public write")
477
- click_on "Authorize"
478
- access_grant_should_have_scopes :public, :write
479
- end
480
-
481
- scenario "resource owner authorizes the client with required scopes (without defaults)" do
482
- visit authorization_endpoint_url(client: @client, scope: "write")
483
- click_on "Authorize"
484
- access_grant_should_have_scopes :write
485
- end
486
-
487
- scenario "new access token matches required scopes" do
488
- visit authorization_endpoint_url(client: @client, scope: "public write")
489
- click_on "Authorize"
490
-
491
- authorization_code = Doorkeeper::AccessGrant.first.token
492
- create_access_token authorization_code, @client
493
-
494
- access_token_should_exist_for(@client, @resource_owner)
495
- access_token_should_have_scopes :public, :write
496
- end
497
-
498
- scenario "returns new token if scopes have changed" do
499
- client_is_authorized(@client, @resource_owner, scopes: "public write")
500
- visit authorization_endpoint_url(client: @client, scope: "public")
501
- click_on "Authorize"
502
-
503
- authorization_code = Doorkeeper::AccessGrant.first.token
504
- create_access_token authorization_code, @client
505
-
506
- expect(Doorkeeper::AccessToken.count).to be(2)
507
-
508
- expect(json_response).to include("access_token" => Doorkeeper::AccessToken.last.token)
509
- end
510
-
511
- scenario "resource owner authorizes the client with extra scopes" do
512
- client_is_authorized(@client, @resource_owner, scopes: "public")
513
- visit authorization_endpoint_url(client: @client, scope: "public write")
514
- click_on "Authorize"
515
-
516
- authorization_code = Doorkeeper::AccessGrant.first.token
517
- create_access_token authorization_code, @client
518
-
519
- expect(Doorkeeper::AccessToken.count).to be(2)
520
-
521
- expect(json_response).to include("access_token" => Doorkeeper::AccessToken.last.token)
522
- access_token_should_have_scopes :public, :write
523
- end
524
- end
525
-
526
- context "when two requests sent" do
527
- before do
528
- Doorkeeper.configure do
529
- orm DOORKEEPER_ORM
530
- use_refresh_token
531
- end
532
-
533
- client_exists
534
- end
535
-
536
- describe "issuing a refresh token" do
537
- let(:resource_owner) { FactoryBot.create(:resource_owner) }
538
-
539
- before do
540
- authorization_code_exists application: @client,
541
- resource_owner_id: resource_owner.id,
542
- resource_owner_type: resource_owner.class.name
543
- end
544
-
545
- it "second of simultaneous client requests get an error for revoked access token" do
546
- authorization_code = Doorkeeper::AccessGrant.first.token
547
- allow_any_instance_of(Doorkeeper::AccessGrant)
548
- .to receive(:revoked?).and_return(false, true)
549
-
550
- page.driver.post token_endpoint_url(code: authorization_code, client: @client)
551
-
552
- expect(json_response).to match(
553
- "error" => "invalid_grant",
554
- "error_description" => translated_error_message(:invalid_grant),
555
- )
556
- end
557
- end
558
- end
559
- end