doorkeeper 5.1.0 → 5.5.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of doorkeeper might be problematic. Click here for more details.

Files changed (265) hide show
  1. checksums.yaml +4 -4
  2. data/{NEWS.md → CHANGELOG.md} +242 -25
  3. data/README.md +21 -11
  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 +8 -7
  7. data/app/controllers/doorkeeper/authorizations_controller.rb +56 -19
  8. data/app/controllers/doorkeeper/authorized_applications_controller.rb +6 -6
  9. data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
  10. data/app/controllers/doorkeeper/tokens_controller.rb +93 -25
  11. data/app/views/doorkeeper/applications/_form.html.erb +1 -7
  12. data/app/views/doorkeeper/applications/show.html.erb +35 -14
  13. data/app/views/doorkeeper/authorizations/form_post.html.erb +11 -0
  14. data/config/locales/en.yml +13 -3
  15. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  16. data/lib/doorkeeper/config/option.rb +20 -2
  17. data/lib/doorkeeper/config/validations.rb +53 -0
  18. data/lib/doorkeeper/config.rb +295 -121
  19. data/lib/doorkeeper/engine.rb +1 -1
  20. data/lib/doorkeeper/errors.rb +13 -18
  21. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  22. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  23. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  24. data/lib/doorkeeper/grant_flow.rb +45 -0
  25. data/lib/doorkeeper/grape/helpers.rb +7 -3
  26. data/lib/doorkeeper/helpers/controller.rb +36 -11
  27. data/lib/doorkeeper/models/access_grant_mixin.rb +22 -18
  28. data/lib/doorkeeper/models/access_token_mixin.rb +194 -51
  29. data/lib/doorkeeper/models/application_mixin.rb +8 -7
  30. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  31. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  32. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  33. data/lib/doorkeeper/models/concerns/revocable.rb +1 -28
  34. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  35. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  36. data/lib/doorkeeper/oauth/authorization/code.rb +25 -14
  37. data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
  38. data/lib/doorkeeper/oauth/authorization/token.rb +24 -19
  39. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  40. data/lib/doorkeeper/oauth/authorization_code_request.rb +40 -21
  41. data/lib/doorkeeper/oauth/base_request.rb +21 -23
  42. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  43. data/lib/doorkeeper/oauth/client.rb +8 -9
  44. data/lib/doorkeeper/oauth/client_credentials/creator.rb +45 -5
  45. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +10 -8
  46. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +13 -3
  47. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  48. data/lib/doorkeeper/oauth/code_request.rb +6 -12
  49. data/lib/doorkeeper/oauth/code_response.rb +24 -14
  50. data/lib/doorkeeper/oauth/error.rb +1 -1
  51. data/lib/doorkeeper/oauth/error_response.rb +10 -11
  52. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +8 -12
  53. data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
  54. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +19 -5
  55. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  56. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  57. data/lib/doorkeeper/oauth/invalid_token_response.rb +7 -4
  58. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  59. data/lib/doorkeeper/oauth/password_access_token_request.rb +34 -11
  60. data/lib/doorkeeper/oauth/pre_authorization.rb +111 -42
  61. data/lib/doorkeeper/oauth/refresh_token_request.rb +45 -33
  62. data/lib/doorkeeper/oauth/token.rb +6 -7
  63. data/lib/doorkeeper/oauth/token_introspection.rb +24 -18
  64. data/lib/doorkeeper/oauth/token_request.rb +6 -20
  65. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  66. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  67. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  68. data/lib/doorkeeper/orm/active_record/application.rb +5 -83
  69. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +68 -0
  70. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +59 -0
  71. data/lib/doorkeeper/orm/active_record/mixins/application.rb +198 -0
  72. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
  73. data/lib/doorkeeper/orm/active_record.rb +20 -6
  74. data/lib/doorkeeper/rails/helpers.rb +4 -4
  75. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  76. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  77. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  78. data/lib/doorkeeper/rails/routes.rb +17 -25
  79. data/lib/doorkeeper/rake/db.rake +6 -6
  80. data/lib/doorkeeper/rake/setup.rake +5 -0
  81. data/lib/doorkeeper/request/authorization_code.rb +5 -3
  82. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  83. data/lib/doorkeeper/request/password.rb +3 -2
  84. data/lib/doorkeeper/request/refresh_token.rb +5 -4
  85. data/lib/doorkeeper/request/strategy.rb +2 -2
  86. data/lib/doorkeeper/request.rb +49 -17
  87. data/lib/doorkeeper/server.rb +7 -11
  88. data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
  89. data/lib/doorkeeper/version.rb +2 -6
  90. data/lib/doorkeeper.rb +114 -79
  91. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  92. data/lib/generators/doorkeeper/confidential_applications_generator.rb +2 -2
  93. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  94. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  95. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  96. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +7 -7
  97. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
  98. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  99. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  100. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  101. data/lib/generators/doorkeeper/templates/initializer.rb +205 -43
  102. data/lib/generators/doorkeeper/templates/migration.rb.erb +18 -6
  103. metadata +45 -312
  104. data/.coveralls.yml +0 -1
  105. data/.github/ISSUE_TEMPLATE.md +0 -25
  106. data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  107. data/.gitignore +0 -20
  108. data/.gitlab-ci.yml +0 -16
  109. data/.hound.yml +0 -3
  110. data/.rspec +0 -1
  111. data/.rubocop.yml +0 -50
  112. data/.travis.yml +0 -35
  113. data/Appraisals +0 -40
  114. data/CODE_OF_CONDUCT.md +0 -46
  115. data/CONTRIBUTING.md +0 -47
  116. data/Dangerfile +0 -67
  117. data/Gemfile +0 -24
  118. data/RELEASING.md +0 -10
  119. data/Rakefile +0 -28
  120. data/SECURITY.md +0 -15
  121. data/UPGRADE.md +0 -2
  122. data/app/validators/redirect_uri_validator.rb +0 -50
  123. data/bin/console +0 -16
  124. data/doorkeeper.gemspec +0 -34
  125. data/gemfiles/rails_5_0.gemfile +0 -17
  126. data/gemfiles/rails_5_1.gemfile +0 -17
  127. data/gemfiles/rails_5_2.gemfile +0 -17
  128. data/gemfiles/rails_6_0.gemfile +0 -17
  129. data/gemfiles/rails_master.gemfile +0 -17
  130. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  131. data/spec/controllers/applications_controller_spec.rb +0 -180
  132. data/spec/controllers/authorizations_controller_spec.rb +0 -527
  133. data/spec/controllers/protected_resources_controller_spec.rb +0 -353
  134. data/spec/controllers/token_info_controller_spec.rb +0 -50
  135. data/spec/controllers/tokens_controller_spec.rb +0 -330
  136. data/spec/dummy/Rakefile +0 -9
  137. data/spec/dummy/app/assets/config/manifest.js +0 -2
  138. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  139. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  140. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  141. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  142. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  143. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  144. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  145. data/spec/dummy/app/models/user.rb +0 -7
  146. data/spec/dummy/app/views/home/index.html.erb +0 -0
  147. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  148. data/spec/dummy/config/application.rb +0 -47
  149. data/spec/dummy/config/boot.rb +0 -7
  150. data/spec/dummy/config/database.yml +0 -15
  151. data/spec/dummy/config/environment.rb +0 -5
  152. data/spec/dummy/config/environments/development.rb +0 -31
  153. data/spec/dummy/config/environments/production.rb +0 -64
  154. data/spec/dummy/config/environments/test.rb +0 -45
  155. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  156. data/spec/dummy/config/initializers/doorkeeper.rb +0 -121
  157. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  158. data/spec/dummy/config/initializers/session_store.rb +0 -10
  159. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  160. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  161. data/spec/dummy/config/routes.rb +0 -13
  162. data/spec/dummy/config.ru +0 -6
  163. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  164. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  165. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  166. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  167. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  168. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  169. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  170. data/spec/dummy/db/schema.rb +0 -68
  171. data/spec/dummy/public/404.html +0 -26
  172. data/spec/dummy/public/422.html +0 -26
  173. data/spec/dummy/public/500.html +0 -26
  174. data/spec/dummy/public/favicon.ico +0 -0
  175. data/spec/dummy/script/rails +0 -9
  176. data/spec/factories.rb +0 -30
  177. data/spec/generators/application_owner_generator_spec.rb +0 -28
  178. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  179. data/spec/generators/install_generator_spec.rb +0 -36
  180. data/spec/generators/migration_generator_spec.rb +0 -28
  181. data/spec/generators/pkce_generator_spec.rb +0 -28
  182. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  183. data/spec/generators/templates/routes.rb +0 -4
  184. data/spec/generators/views_generator_spec.rb +0 -29
  185. data/spec/grape/grape_integration_spec.rb +0 -137
  186. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  187. data/spec/lib/config_spec.rb +0 -697
  188. data/spec/lib/doorkeeper_spec.rb +0 -27
  189. data/spec/lib/models/expirable_spec.rb +0 -61
  190. data/spec/lib/models/reusable_spec.rb +0 -40
  191. data/spec/lib/models/revocable_spec.rb +0 -59
  192. data/spec/lib/models/scopes_spec.rb +0 -53
  193. data/spec/lib/models/secret_storable_spec.rb +0 -135
  194. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  195. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -156
  196. data/spec/lib/oauth/base_request_spec.rb +0 -205
  197. data/spec/lib/oauth/base_response_spec.rb +0 -47
  198. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  199. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -94
  200. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  201. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  202. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -29
  203. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -109
  204. data/spec/lib/oauth/client_spec.rb +0 -38
  205. data/spec/lib/oauth/code_request_spec.rb +0 -47
  206. data/spec/lib/oauth/code_response_spec.rb +0 -36
  207. data/spec/lib/oauth/error_response_spec.rb +0 -66
  208. data/spec/lib/oauth/error_spec.rb +0 -23
  209. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -22
  210. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -98
  211. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  212. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -247
  213. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -55
  214. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -192
  215. data/spec/lib/oauth/pre_authorization_spec.rb +0 -215
  216. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
  217. data/spec/lib/oauth/scopes_spec.rb +0 -148
  218. data/spec/lib/oauth/token_request_spec.rb +0 -150
  219. data/spec/lib/oauth/token_response_spec.rb +0 -86
  220. data/spec/lib/oauth/token_spec.rb +0 -158
  221. data/spec/lib/request/strategy_spec.rb +0 -54
  222. data/spec/lib/secret_storing/base_spec.rb +0 -60
  223. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  224. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  225. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  226. data/spec/lib/server_spec.rb +0 -61
  227. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  228. data/spec/models/doorkeeper/access_grant_spec.rb +0 -144
  229. data/spec/models/doorkeeper/access_token_spec.rb +0 -591
  230. data/spec/models/doorkeeper/application_spec.rb +0 -367
  231. data/spec/requests/applications/applications_request_spec.rb +0 -259
  232. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  233. data/spec/requests/endpoints/authorization_spec.rb +0 -73
  234. data/spec/requests/endpoints/token_spec.rb +0 -75
  235. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -78
  236. data/spec/requests/flows/authorization_code_spec.rb +0 -447
  237. data/spec/requests/flows/client_credentials_spec.rb +0 -128
  238. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -34
  239. data/spec/requests/flows/implicit_grant_spec.rb +0 -90
  240. data/spec/requests/flows/password_spec.rb +0 -259
  241. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  242. data/spec/requests/flows/revoke_token_spec.rb +0 -143
  243. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  244. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  245. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  246. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  247. data/spec/routing/default_routes_spec.rb +0 -41
  248. data/spec/routing/scoped_routes_spec.rb +0 -47
  249. data/spec/spec_helper.rb +0 -57
  250. data/spec/spec_helper_integration.rb +0 -4
  251. data/spec/support/dependencies/factory_bot.rb +0 -4
  252. data/spec/support/doorkeeper_rspec.rb +0 -22
  253. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  254. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  255. data/spec/support/helpers/config_helper.rb +0 -11
  256. data/spec/support/helpers/model_helper.rb +0 -78
  257. data/spec/support/helpers/request_spec_helper.rb +0 -98
  258. data/spec/support/helpers/url_helper.rb +0 -62
  259. data/spec/support/http_method_shim.rb +0 -29
  260. data/spec/support/orm/active_record.rb +0 -5
  261. data/spec/support/shared/controllers_shared_context.rb +0 -123
  262. data/spec/support/shared/hashing_shared_context.rb +0 -36
  263. data/spec/support/shared/models_shared_examples.rb +0 -54
  264. data/spec/validators/redirect_uri_validator_spec.rb +0 -158
  265. data/spec/version/version_spec.rb +0 -17
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- feature "Authorization endpoint" do
6
- background do
7
- config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
8
- client_exists(name: "MyApp")
9
- end
10
-
11
- scenario "requires resource owner to be authenticated" do
12
- visit authorization_endpoint_url(client: @client)
13
- i_should_see "Sign in"
14
- i_should_be_on "/"
15
- end
16
-
17
- context "with authenticated resource owner" do
18
- background do
19
- create_resource_owner
20
- sign_in
21
- end
22
-
23
- scenario "displays the authorization form" do
24
- visit authorization_endpoint_url(client: @client)
25
- i_should_see "Authorize MyApp to use your account?"
26
- end
27
-
28
- scenario "displays all requested scopes" do
29
- default_scopes_exist :public
30
- optional_scopes_exist :write
31
- visit authorization_endpoint_url(client: @client, scope: "public write")
32
- i_should_see "Access your public data"
33
- i_should_see "Update your data"
34
- end
35
- end
36
-
37
- context "with a invalid request" do
38
- background do
39
- create_resource_owner
40
- sign_in
41
- end
42
-
43
- scenario "displays the related error" do
44
- visit authorization_endpoint_url(client: @client, response_type: "")
45
- i_should_not_see "Authorize"
46
- i_should_see_translated_error_message :unsupported_response_type
47
- end
48
-
49
- scenario "displays unsupported_response_type error when using a disabled response type" do
50
- config_is_set(:grant_flows, ["implicit"])
51
- visit authorization_endpoint_url(client: @client, response_type: "code")
52
- i_should_not_see "Authorize"
53
- i_should_see_translated_error_message :unsupported_response_type
54
- end
55
- end
56
-
57
- context "forgery protection enabled" do
58
- background do
59
- create_resource_owner
60
- sign_in
61
- end
62
-
63
- scenario "raises exception on forged requests" do
64
- allowing_forgery_protection do
65
- expect do
66
- page.driver.post authorization_endpoint_url(client_id: @client.uid,
67
- redirect_uri: @client.redirect_uri,
68
- response_type: "code")
69
- end.to raise_error(ActionController::InvalidAuthenticityToken)
70
- end
71
- end
72
- end
73
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- describe "Token endpoint" do
6
- before do
7
- client_exists
8
- authorization_code_exists application: @client, scopes: "public"
9
- end
10
-
11
- it "respond with correct headers" do
12
- post token_endpoint_url(code: @authorization.token, client: @client)
13
- should_have_header "Pragma", "no-cache"
14
-
15
- # Rails 5.2 changed headers
16
- if ::Rails::VERSION::MAJOR >= 5 && ::Rails::VERSION::MINOR >= 2 || ::Rails::VERSION::MAJOR >= 6
17
- should_have_header "Cache-Control", "private, no-store"
18
- else
19
- should_have_header "Cache-Control", "no-store"
20
- end
21
-
22
- should_have_header "Content-Type", "application/json; charset=utf-8"
23
- end
24
-
25
- it "accepts client credentials with basic auth header" do
26
- post token_endpoint_url,
27
- params: {
28
- code: @authorization.token,
29
- redirect_uri: @client.redirect_uri,
30
- },
31
- headers: { "HTTP_AUTHORIZATION" => basic_auth_header_for_client(@client) }
32
-
33
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
34
- end
35
-
36
- it "returns null for expires_in when a permanent token is set" do
37
- config_is_set(:access_token_expires_in, nil)
38
- post token_endpoint_url(code: @authorization.token, client: @client)
39
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
40
- should_not_have_json "expires_in"
41
- end
42
-
43
- it "returns unsupported_grant_type for invalid grant_type param" do
44
- post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "nothing")
45
-
46
- should_not_have_json "access_token"
47
- should_have_json "error", "unsupported_grant_type"
48
- should_have_json "error_description", translated_error_message("unsupported_grant_type")
49
- end
50
-
51
- it "returns unsupported_grant_type for disabled grant flows" do
52
- config_is_set(:grant_flows, ["implicit"])
53
- post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "authorization_code")
54
-
55
- should_not_have_json "access_token"
56
- should_have_json "error", "unsupported_grant_type"
57
- should_have_json "error_description", translated_error_message("unsupported_grant_type")
58
- end
59
-
60
- it "returns unsupported_grant_type when refresh_token is not in use" do
61
- post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "refresh_token")
62
-
63
- should_not_have_json "access_token"
64
- should_have_json "error", "unsupported_grant_type"
65
- should_have_json "error_description", translated_error_message("unsupported_grant_type")
66
- end
67
-
68
- it "returns invalid_request if grant_type is missing" do
69
- post token_endpoint_url(code: @authorization.token, client: @client, grant_type: "")
70
-
71
- should_not_have_json "access_token"
72
- should_have_json "error", "invalid_request"
73
- should_have_json "error_description", translated_error_message("invalid_request")
74
- end
75
- end
@@ -1,78 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- feature "Authorization Code Flow Errors" do
6
- let(:client_params) { {} }
7
- background do
8
- config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
9
- client_exists client_params
10
- create_resource_owner
11
- sign_in
12
- end
13
-
14
- after do
15
- access_grant_should_not_exist
16
- end
17
-
18
- context "with a client trying to xss resource owner" do
19
- let(:client_name) { "<div id='xss'>XSS</div>" }
20
- let(:client_params) { { name: client_name } }
21
- scenario "resource owner visit authorization endpoint" do
22
- visit authorization_endpoint_url(client: @client)
23
- expect(page).not_to have_css("#xss")
24
- end
25
- end
26
-
27
- context "when access was denied" do
28
- scenario "redirects with error" do
29
- visit authorization_endpoint_url(client: @client)
30
- click_on "Deny"
31
-
32
- i_should_be_on_client_callback @client
33
- url_should_not_have_param "code"
34
- url_should_have_param "error", "access_denied"
35
- url_should_have_param "error_description", translated_error_message(:access_denied)
36
- end
37
-
38
- scenario "redirects with state parameter" do
39
- visit authorization_endpoint_url(client: @client, state: "return-this")
40
- click_on "Deny"
41
-
42
- i_should_be_on_client_callback @client
43
- url_should_not_have_param "code"
44
- url_should_have_param "state", "return-this"
45
- end
46
- end
47
- end
48
-
49
- describe "Authorization Code Flow Errors", "after authorization" do
50
- before do
51
- client_exists
52
- authorization_code_exists application: @client
53
- end
54
-
55
- it "returns :invalid_grant error when posting an already revoked grant code" do
56
- # First successful request
57
- post token_endpoint_url(code: @authorization.token, client: @client)
58
-
59
- # Second attempt with same token
60
- expect do
61
- post token_endpoint_url(code: @authorization.token, client: @client)
62
- end.to_not(change { Doorkeeper::AccessToken.count })
63
-
64
- should_not_have_json "access_token"
65
- should_have_json "error", "invalid_grant"
66
- should_have_json "error_description", translated_error_message("invalid_grant")
67
- end
68
-
69
- it "returns :invalid_grant error for invalid grant code" do
70
- post token_endpoint_url(code: "invalid", client: @client)
71
-
72
- access_token_should_not_exist
73
-
74
- should_not_have_json "access_token"
75
- should_have_json "error", "invalid_grant"
76
- should_have_json "error_description", translated_error_message("invalid_grant")
77
- end
78
- end
@@ -1,447 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "spec_helper"
4
-
5
- feature "Authorization Code Flow" do
6
- background do
7
- config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
8
- client_exists
9
- create_resource_owner
10
- sign_in
11
- end
12
-
13
- scenario "resource owner authorizes the client" do
14
- visit authorization_endpoint_url(client: @client)
15
- click_on "Authorize"
16
-
17
- access_grant_should_exist_for(@client, @resource_owner)
18
-
19
- i_should_be_on_client_callback(@client)
20
-
21
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
22
- url_should_not_have_param("state")
23
- url_should_not_have_param("error")
24
- end
25
-
26
- context "with grant hashing enabled" do
27
- background do
28
- config_is_set(:token_secret_strategy, ::Doorkeeper::SecretStoring::Sha256Hash)
29
- end
30
-
31
- scenario "Authorization Code Flow with hashing" do
32
- @client.redirect_uri = Doorkeeper.configuration.native_redirect_uri
33
- @client.save!
34
- visit authorization_endpoint_url(client: @client)
35
- click_on "Authorize"
36
-
37
- access_grant_should_exist_for(@client, @resource_owner)
38
-
39
- code = current_params["code"]
40
- expect(code).not_to be_nil
41
-
42
- hashed_code = Doorkeeper::AccessGrant.secret_strategy.transform_secret code
43
- expect(hashed_code).to eq Doorkeeper::AccessGrant.first.token
44
-
45
- expect(code).not_to eq(hashed_code)
46
-
47
- i_should_see "Authorization code:"
48
- i_should_see code
49
- i_should_not_see hashed_code
50
- end
51
- end
52
-
53
- scenario "resource owner authorizes using test url" do
54
- @client.redirect_uri = Doorkeeper.configuration.native_redirect_uri
55
- @client.save!
56
- visit authorization_endpoint_url(client: @client)
57
- click_on "Authorize"
58
-
59
- access_grant_should_exist_for(@client, @resource_owner)
60
-
61
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
62
- i_should_see "Authorization code:"
63
- i_should_see Doorkeeper::AccessGrant.first.token
64
- end
65
-
66
- scenario "resource owner authorizes the client with state parameter set" do
67
- visit authorization_endpoint_url(client: @client, state: "return-me")
68
- click_on "Authorize"
69
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
70
- url_should_have_param("state", "return-me")
71
- url_should_not_have_param("code_challenge_method")
72
- end
73
-
74
- scenario "resource owner requests an access token with authorization code" do
75
- visit authorization_endpoint_url(client: @client)
76
- click_on "Authorize"
77
-
78
- authorization_code = Doorkeeper::AccessGrant.first.token
79
- create_access_token authorization_code, @client
80
-
81
- access_token_should_exist_for(@client, @resource_owner)
82
-
83
- should_not_have_json "error"
84
-
85
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
86
- should_have_json "token_type", "Bearer"
87
- should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
88
- end
89
-
90
- scenario "resource owner requests an access token with authorization code but without secret" do
91
- visit authorization_endpoint_url(client: @client)
92
- click_on "Authorize"
93
-
94
- authorization_code = Doorkeeper::AccessGrant.first.token
95
- page.driver.post token_endpoint_url(code: authorization_code, client_id: @client.uid,
96
- redirect_uri: @client.redirect_uri)
97
-
98
- expect(Doorkeeper::AccessToken.count).to be_zero
99
-
100
- should_have_json "error", "invalid_client"
101
- end
102
-
103
- scenario "resource owner requests an access token with authorization code but without client id" do
104
- visit authorization_endpoint_url(client: @client)
105
- click_on "Authorize"
106
-
107
- authorization_code = Doorkeeper::AccessGrant.first.token
108
- page.driver.post token_endpoint_url(code: authorization_code, client_secret: @client.secret,
109
- redirect_uri: @client.redirect_uri)
110
-
111
- expect(Doorkeeper::AccessToken.count).to be_zero
112
-
113
- should_have_json "error", "invalid_client"
114
- end
115
-
116
- scenario "silently authorizes if matching token exists" do
117
- default_scopes_exist :public, :write
118
-
119
- access_token_exists application: @client,
120
- expires_in: -100, # even expired token
121
- resource_owner_id: @resource_owner.id,
122
- scopes: "public write"
123
-
124
- visit authorization_endpoint_url(client: @client, scope: "public write")
125
-
126
- response_status_should_be 200
127
- i_should_not_see "Authorize"
128
- end
129
-
130
- context "with PKCE" do
131
- context "plain" do
132
- let(:code_challenge) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
133
- let(:code_verifier) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
134
-
135
- scenario "resource owner authorizes the client with code_challenge parameter set" do
136
- visit authorization_endpoint_url(
137
- client: @client,
138
- code_challenge: code_challenge,
139
- code_challenge_method: "plain"
140
- )
141
- click_on "Authorize"
142
-
143
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
144
- url_should_not_have_param("code_challenge_method")
145
- url_should_not_have_param("code_challenge")
146
- end
147
-
148
- scenario "mobile app requests an access token with authorization code but not pkce token" do
149
- visit authorization_endpoint_url(client: @client)
150
- click_on "Authorize"
151
-
152
- authorization_code = current_params["code"]
153
- create_access_token authorization_code, @client, code_verifier
154
-
155
- should_have_json "error", "invalid_grant"
156
- end
157
-
158
- scenario "mobile app requests an access token with authorization code and plain code challenge method" do
159
- visit authorization_endpoint_url(
160
- client: @client,
161
- code_challenge: code_challenge,
162
- code_challenge_method: "plain"
163
- )
164
- click_on "Authorize"
165
-
166
- authorization_code = current_params["code"]
167
- create_access_token authorization_code, @client, code_verifier
168
-
169
- access_token_should_exist_for(@client, @resource_owner)
170
-
171
- should_not_have_json "error"
172
-
173
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
174
- should_have_json "token_type", "Bearer"
175
- should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
176
- end
177
-
178
- scenario "mobile app requests an access token with authorization code and code_challenge" do
179
- visit authorization_endpoint_url(client: @client,
180
- code_challenge: code_verifier,
181
- code_challenge_method: "plain")
182
- click_on "Authorize"
183
-
184
- authorization_code = current_params["code"]
185
- create_access_token authorization_code, @client, code_verifier: nil
186
-
187
- should_not_have_json "access_token"
188
- should_have_json "error", "invalid_grant"
189
- end
190
- end
191
-
192
- context "s256" do
193
- let(:code_challenge) { "Oz733NtQ0rJP8b04fgZMJMwprn6Iw8sMCT_9bR1q4tA" }
194
- let(:code_verifier) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
195
-
196
- scenario "resource owner authorizes the client with code_challenge parameter set" do
197
- visit authorization_endpoint_url(
198
- client: @client,
199
- code_challenge: code_challenge,
200
- code_challenge_method: "S256"
201
- )
202
- click_on "Authorize"
203
-
204
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
205
- url_should_not_have_param("code_challenge_method")
206
- url_should_not_have_param("code_challenge")
207
- end
208
-
209
- scenario "mobile app requests an access token with authorization code and S256 code challenge method" do
210
- visit authorization_endpoint_url(
211
- client: @client,
212
- code_challenge: code_challenge,
213
- code_challenge_method: "S256"
214
- )
215
- click_on "Authorize"
216
-
217
- authorization_code = current_params["code"]
218
- create_access_token authorization_code, @client, code_verifier
219
-
220
- access_token_should_exist_for(@client, @resource_owner)
221
-
222
- should_not_have_json "error"
223
-
224
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
225
- should_have_json "token_type", "Bearer"
226
- should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
227
- end
228
-
229
- scenario "mobile app requests an access token with authorization code and without code_verifier" do
230
- visit authorization_endpoint_url(
231
- client: @client,
232
- code_challenge: code_challenge,
233
- code_challenge_method: "S256"
234
- )
235
- click_on "Authorize"
236
- authorization_code = current_params["code"]
237
- create_access_token authorization_code, @client
238
- should_have_json "error", "invalid_request"
239
- should_not_have_json "access_token"
240
- end
241
-
242
- scenario "mobile app requests an access token with authorization code and without secret" do
243
- visit authorization_endpoint_url(
244
- client: @client,
245
- code_challenge: code_challenge,
246
- code_challenge_method: "S256"
247
- )
248
- click_on "Authorize"
249
-
250
- authorization_code = current_params["code"]
251
- page.driver.post token_endpoint_url(code: authorization_code, client_id: @client.uid,
252
- redirect_uri: @client.redirect_uri, code_verifier: code_verifier)
253
- should_have_json "error", "invalid_client"
254
- should_not_have_json "access_token"
255
- end
256
-
257
- scenario "mobile app requests an access token with authorization code and without secret but is marked as not confidential" do
258
- @client.update_attribute :confidential, false
259
- visit authorization_endpoint_url(client: @client, code_challenge: code_challenge, code_challenge_method: "S256")
260
- click_on "Authorize"
261
-
262
- authorization_code = current_params["code"]
263
- page.driver.post token_endpoint_url(
264
- code: authorization_code,
265
- client_id: @client.uid,
266
- redirect_uri: @client.redirect_uri,
267
- code_verifier: code_verifier
268
- )
269
- should_not_have_json "error"
270
-
271
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
272
- should_have_json "token_type", "Bearer"
273
- should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
274
- end
275
-
276
- scenario "mobile app requests an access token with authorization code but no code verifier" do
277
- visit authorization_endpoint_url(
278
- client: @client,
279
- code_challenge: code_challenge,
280
- code_challenge_method: "S256"
281
- )
282
- click_on "Authorize"
283
-
284
- authorization_code = current_params["code"]
285
- create_access_token authorization_code, @client
286
-
287
- should_not_have_json "access_token"
288
- should_have_json "error", "invalid_request"
289
- end
290
-
291
- scenario "mobile app requests an access token with authorization code with wrong verifier" do
292
- visit authorization_endpoint_url(
293
- client: @client,
294
- code_challenge: code_challenge,
295
- code_challenge_method: "S256"
296
- )
297
- click_on "Authorize"
298
-
299
- authorization_code = current_params["code"]
300
- create_access_token authorization_code, @client, "incorrect-code-verifier"
301
-
302
- should_not_have_json "access_token"
303
- should_have_json "error", "invalid_grant"
304
- end
305
-
306
- scenario "code_challenge_mehthod in token request is totally ignored" do
307
- visit authorization_endpoint_url(
308
- client: @client,
309
- code_challenge: code_challenge,
310
- code_challenge_method: "S256"
311
- )
312
- click_on "Authorize"
313
-
314
- authorization_code = current_params["code"]
315
- page.driver.post token_endpoint_url(
316
- code: authorization_code,
317
- client: @client,
318
- code_verifier: code_challenge,
319
- code_challenge_method: "plain"
320
- )
321
-
322
- should_not_have_json "access_token"
323
- should_have_json "error", "invalid_grant"
324
- end
325
-
326
- scenario "expects to set code_challenge_method explicitely without fallback" do
327
- visit authorization_endpoint_url(client: @client, code_challenge: code_challenge)
328
- expect(page).to have_content("The code challenge method must be plain or S256.")
329
- end
330
- end
331
- end
332
-
333
- context "when application scopes are present and no scope is passed" do
334
- background do
335
- @client.update(scopes: "public write read")
336
- end
337
-
338
- scenario "access grant has no scope" do
339
- default_scopes_exist :admin
340
- visit authorization_endpoint_url(client: @client)
341
- click_on "Authorize"
342
- access_grant_should_exist_for(@client, @resource_owner)
343
- grant = Doorkeeper::AccessGrant.first
344
- expect(grant.scopes).to be_empty
345
- end
346
-
347
- scenario "access grant have scopes which are common in application scopees and default scopes" do
348
- default_scopes_exist :public, :write
349
- visit authorization_endpoint_url(client: @client)
350
- click_on "Authorize"
351
- access_grant_should_exist_for(@client, @resource_owner)
352
- access_grant_should_have_scopes :public, :write
353
- end
354
- end
355
-
356
- context "with scopes" do
357
- background do
358
- default_scopes_exist :public
359
- optional_scopes_exist :write
360
- end
361
-
362
- scenario "resource owner authorizes the client with default scopes" do
363
- visit authorization_endpoint_url(client: @client)
364
- click_on "Authorize"
365
- access_grant_should_exist_for(@client, @resource_owner)
366
- access_grant_should_have_scopes :public
367
- end
368
-
369
- scenario "resource owner authorizes the client with required scopes" do
370
- visit authorization_endpoint_url(client: @client, scope: "public write")
371
- click_on "Authorize"
372
- access_grant_should_have_scopes :public, :write
373
- end
374
-
375
- scenario "resource owner authorizes the client with required scopes (without defaults)" do
376
- visit authorization_endpoint_url(client: @client, scope: "write")
377
- click_on "Authorize"
378
- access_grant_should_have_scopes :write
379
- end
380
-
381
- scenario "new access token matches required scopes" do
382
- visit authorization_endpoint_url(client: @client, scope: "public write")
383
- click_on "Authorize"
384
-
385
- authorization_code = Doorkeeper::AccessGrant.first.token
386
- create_access_token authorization_code, @client
387
-
388
- access_token_should_exist_for(@client, @resource_owner)
389
- access_token_should_have_scopes :public, :write
390
- end
391
-
392
- scenario "returns new token if scopes have changed" do
393
- client_is_authorized(@client, @resource_owner, scopes: "public write")
394
- visit authorization_endpoint_url(client: @client, scope: "public")
395
- click_on "Authorize"
396
-
397
- authorization_code = Doorkeeper::AccessGrant.first.token
398
- create_access_token authorization_code, @client
399
-
400
- expect(Doorkeeper::AccessToken.count).to be(2)
401
-
402
- should_have_json "access_token", Doorkeeper::AccessToken.last.token
403
- end
404
-
405
- scenario "resource owner authorizes the client with extra scopes" do
406
- client_is_authorized(@client, @resource_owner, scopes: "public")
407
- visit authorization_endpoint_url(client: @client, scope: "public write")
408
- click_on "Authorize"
409
-
410
- authorization_code = Doorkeeper::AccessGrant.first.token
411
- create_access_token authorization_code, @client
412
-
413
- expect(Doorkeeper::AccessToken.count).to be(2)
414
-
415
- should_have_json "access_token", Doorkeeper::AccessToken.last.token
416
- access_token_should_have_scopes :public, :write
417
- end
418
- end
419
- end
420
-
421
- describe "Authorization Code Flow" do
422
- before do
423
- Doorkeeper.configure do
424
- orm DOORKEEPER_ORM
425
- use_refresh_token
426
- end
427
-
428
- client_exists
429
- end
430
-
431
- context "issuing a refresh token" do
432
- before do
433
- authorization_code_exists application: @client
434
- end
435
-
436
- it "second of simultaneous client requests get an error for revoked acccess token" do
437
- authorization_code = Doorkeeper::AccessGrant.first.token
438
- allow_any_instance_of(Doorkeeper::AccessGrant)
439
- .to receive(:revoked?).and_return(false, true)
440
-
441
- post token_endpoint_url(code: authorization_code, client: @client)
442
-
443
- should_not_have_json "access_token"
444
- should_have_json "error", "invalid_grant"
445
- end
446
- end
447
- end