doorkeeper 5.4.0.rc1 → 5.4.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 (189) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -1
  3. data/app/controllers/doorkeeper/applications_controller.rb +3 -3
  4. data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
  5. data/app/views/doorkeeper/applications/_form.html.erb +1 -1
  6. data/lib/doorkeeper/config/abstract_builder.rb +1 -1
  7. data/lib/doorkeeper/config.rb +24 -18
  8. data/lib/doorkeeper/engine.rb +1 -1
  9. data/lib/doorkeeper/helpers/controller.rb +4 -4
  10. data/lib/doorkeeper/models/access_grant_mixin.rb +11 -5
  11. data/lib/doorkeeper/models/access_token_mixin.rb +9 -5
  12. data/lib/doorkeeper/models/application_mixin.rb +5 -4
  13. data/lib/doorkeeper/oauth/authorization/code.rb +1 -1
  14. data/lib/doorkeeper/oauth/authorization/token.rb +1 -1
  15. data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -2
  16. data/lib/doorkeeper/oauth/client_credentials/validator.rb +3 -1
  17. data/lib/doorkeeper/oauth/code_request.rb +2 -2
  18. data/lib/doorkeeper/oauth/password_access_token_request.rb +1 -1
  19. data/lib/doorkeeper/oauth/pre_authorization.rb +5 -4
  20. data/lib/doorkeeper/oauth/token.rb +4 -5
  21. data/lib/doorkeeper/oauth/token_introspection.rb +1 -5
  22. data/lib/doorkeeper/oauth/token_request.rb +1 -1
  23. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +1 -1
  24. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +1 -1
  25. data/lib/doorkeeper/orm/active_record/mixins/application.rb +64 -9
  26. data/lib/doorkeeper/orm/active_record.rb +10 -2
  27. data/lib/doorkeeper/request/refresh_token.rb +2 -1
  28. data/lib/doorkeeper/server.rb +1 -1
  29. data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
  30. data/lib/doorkeeper/version.rb +1 -1
  31. data/lib/doorkeeper.rb +1 -1
  32. data/lib/generators/doorkeeper/templates/migration.rb.erb +12 -5
  33. metadata +7 -301
  34. data/Appraisals +0 -26
  35. data/CODE_OF_CONDUCT.md +0 -46
  36. data/CONTRIBUTING.md +0 -49
  37. data/Dangerfile +0 -67
  38. data/Dockerfile +0 -29
  39. data/Gemfile +0 -25
  40. data/NEWS.md +0 -1
  41. data/RELEASING.md +0 -11
  42. data/Rakefile +0 -28
  43. data/SECURITY.md +0 -15
  44. data/UPGRADE.md +0 -2
  45. data/bin/console +0 -30
  46. data/doorkeeper.gemspec +0 -42
  47. data/gemfiles/rails_5_0.gemfile +0 -19
  48. data/gemfiles/rails_5_1.gemfile +0 -19
  49. data/gemfiles/rails_5_2.gemfile +0 -19
  50. data/gemfiles/rails_6_0.gemfile +0 -19
  51. data/gemfiles/rails_master.gemfile +0 -19
  52. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  53. data/spec/controllers/applications_controller_spec.rb +0 -274
  54. data/spec/controllers/authorizations_controller_spec.rb +0 -743
  55. data/spec/controllers/protected_resources_controller_spec.rb +0 -361
  56. data/spec/controllers/token_info_controller_spec.rb +0 -50
  57. data/spec/controllers/tokens_controller_spec.rb +0 -499
  58. data/spec/dummy/Rakefile +0 -9
  59. data/spec/dummy/app/assets/config/manifest.js +0 -2
  60. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  61. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  62. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  63. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  64. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  65. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  66. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  67. data/spec/dummy/app/models/user.rb +0 -11
  68. data/spec/dummy/app/views/home/index.html.erb +0 -0
  69. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  70. data/spec/dummy/config/application.rb +0 -51
  71. data/spec/dummy/config/boot.rb +0 -7
  72. data/spec/dummy/config/database.yml +0 -15
  73. data/spec/dummy/config/environment.rb +0 -5
  74. data/spec/dummy/config/environments/development.rb +0 -31
  75. data/spec/dummy/config/environments/production.rb +0 -64
  76. data/spec/dummy/config/environments/test.rb +0 -45
  77. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  78. data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
  79. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  80. data/spec/dummy/config/initializers/session_store.rb +0 -10
  81. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  82. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  83. data/spec/dummy/config/routes.rb +0 -13
  84. data/spec/dummy/config.ru +0 -6
  85. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  86. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  87. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  88. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  89. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  90. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  91. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  92. data/spec/dummy/db/schema.rb +0 -70
  93. data/spec/dummy/public/404.html +0 -26
  94. data/spec/dummy/public/422.html +0 -26
  95. data/spec/dummy/public/500.html +0 -26
  96. data/spec/dummy/public/favicon.ico +0 -0
  97. data/spec/dummy/script/rails +0 -9
  98. data/spec/factories.rb +0 -30
  99. data/spec/generators/application_owner_generator_spec.rb +0 -28
  100. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  101. data/spec/generators/enable_polymorphic_resource_owner_generator_spec.rb +0 -47
  102. data/spec/generators/install_generator_spec.rb +0 -36
  103. data/spec/generators/migration_generator_spec.rb +0 -28
  104. data/spec/generators/pkce_generator_spec.rb +0 -28
  105. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  106. data/spec/generators/templates/routes.rb +0 -4
  107. data/spec/generators/views_generator_spec.rb +0 -29
  108. data/spec/grape/grape_integration_spec.rb +0 -137
  109. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  110. data/spec/lib/config_spec.rb +0 -813
  111. data/spec/lib/doorkeeper_spec.rb +0 -27
  112. data/spec/lib/models/expirable_spec.rb +0 -61
  113. data/spec/lib/models/reusable_spec.rb +0 -40
  114. data/spec/lib/models/revocable_spec.rb +0 -58
  115. data/spec/lib/models/scopes_spec.rb +0 -61
  116. data/spec/lib/models/secret_storable_spec.rb +0 -135
  117. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  118. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -180
  119. data/spec/lib/oauth/base_request_spec.rb +0 -210
  120. data/spec/lib/oauth/base_response_spec.rb +0 -45
  121. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  122. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -135
  123. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -110
  124. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -57
  125. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  126. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -108
  127. data/spec/lib/oauth/client_spec.rb +0 -38
  128. data/spec/lib/oauth/code_request_spec.rb +0 -46
  129. data/spec/lib/oauth/code_response_spec.rb +0 -36
  130. data/spec/lib/oauth/error_response_spec.rb +0 -64
  131. data/spec/lib/oauth/error_spec.rb +0 -21
  132. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
  133. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
  134. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  135. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  136. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
  137. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
  138. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -201
  139. data/spec/lib/oauth/pre_authorization_spec.rb +0 -218
  140. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -166
  141. data/spec/lib/oauth/scopes_spec.rb +0 -146
  142. data/spec/lib/oauth/token_request_spec.rb +0 -164
  143. data/spec/lib/oauth/token_response_spec.rb +0 -84
  144. data/spec/lib/oauth/token_spec.rb +0 -156
  145. data/spec/lib/option_spec.rb +0 -51
  146. data/spec/lib/request/strategy_spec.rb +0 -54
  147. data/spec/lib/secret_storing/base_spec.rb +0 -60
  148. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  149. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  150. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  151. data/spec/lib/server_spec.rb +0 -49
  152. data/spec/lib/stale_records_cleaner_spec.rb +0 -102
  153. data/spec/models/doorkeeper/access_grant_spec.rb +0 -175
  154. data/spec/models/doorkeeper/access_token_spec.rb +0 -650
  155. data/spec/models/doorkeeper/application_spec.rb +0 -442
  156. data/spec/requests/applications/applications_request_spec.rb +0 -259
  157. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  158. data/spec/requests/endpoints/authorization_spec.rb +0 -91
  159. data/spec/requests/endpoints/token_spec.rb +0 -79
  160. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -82
  161. data/spec/requests/flows/authorization_code_spec.rb +0 -530
  162. data/spec/requests/flows/client_credentials_spec.rb +0 -207
  163. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  164. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  165. data/spec/requests/flows/password_spec.rb +0 -316
  166. data/spec/requests/flows/refresh_token_spec.rb +0 -241
  167. data/spec/requests/flows/revoke_token_spec.rb +0 -196
  168. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  169. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  170. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  171. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  172. data/spec/routing/default_routes_spec.rb +0 -41
  173. data/spec/routing/scoped_routes_spec.rb +0 -47
  174. data/spec/spec_helper.rb +0 -54
  175. data/spec/spec_helper_integration.rb +0 -4
  176. data/spec/support/dependencies/factory_bot.rb +0 -4
  177. data/spec/support/doorkeeper_rspec.rb +0 -22
  178. data/spec/support/helpers/access_token_request_helper.rb +0 -14
  179. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  180. data/spec/support/helpers/config_helper.rb +0 -11
  181. data/spec/support/helpers/model_helper.rb +0 -78
  182. data/spec/support/helpers/request_spec_helper.rb +0 -110
  183. data/spec/support/helpers/url_helper.rb +0 -62
  184. data/spec/support/orm/active_record.rb +0 -5
  185. data/spec/support/shared/controllers_shared_context.rb +0 -133
  186. data/spec/support/shared/hashing_shared_context.rb +0 -36
  187. data/spec/support/shared/models_shared_examples.rb +0 -56
  188. data/spec/validators/redirect_uri_validator_spec.rb +0 -183
  189. data/spec/version/version_spec.rb +0 -17
@@ -1,530 +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
- should_not_have_json "error"
53
-
54
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
55
- should_have_json "token_type", "Bearer"
56
- should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
57
- end
58
- end
59
-
60
- context "with grant hashing enabled" do
61
- background do
62
- config_is_set(:token_secret_strategy, ::Doorkeeper::SecretStoring::Sha256Hash)
63
- end
64
-
65
- def authorize(redirect_url)
66
- @client.redirect_uri = redirect_url
67
- @client.save!
68
- visit authorization_endpoint_url(client: @client)
69
- click_on "Authorize"
70
-
71
- access_grant_should_exist_for(@client, @resource_owner)
72
-
73
- code = current_params["code"]
74
- expect(code).not_to be_nil
75
-
76
- hashed_code = Doorkeeper::AccessGrant.secret_strategy.transform_secret code
77
- expect(hashed_code).to eq Doorkeeper::AccessGrant.first.token
78
-
79
- [code, hashed_code]
80
- end
81
-
82
- scenario "using redirect_url urn:ietf:wg:oauth:2.0:oob" do
83
- code, hashed_code = authorize("urn:ietf:wg:oauth:2.0:oob")
84
- expect(code).not_to eq(hashed_code)
85
- i_should_see "Authorization code:"
86
- i_should_see code
87
- i_should_not_see hashed_code
88
- end
89
-
90
- scenario "using redirect_url urn:ietf:wg:oauth:2.0:oob:auto" do
91
- code, hashed_code = authorize("urn:ietf:wg:oauth:2.0:oob:auto")
92
- expect(code).not_to eq(hashed_code)
93
- i_should_see "Authorization code:"
94
- i_should_see code
95
- i_should_not_see hashed_code
96
- end
97
- end
98
-
99
- scenario "resource owner authorizes using oob url" do
100
- @client.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
101
- @client.save!
102
- visit authorization_endpoint_url(client: @client)
103
- click_on "Authorize"
104
-
105
- access_grant_should_exist_for(@client, @resource_owner)
106
-
107
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
108
- i_should_see "Authorization code:"
109
- i_should_see Doorkeeper::AccessGrant.first.token
110
- end
111
-
112
- scenario "resource owner authorizes the client with state parameter set" do
113
- visit authorization_endpoint_url(client: @client, state: "return-me")
114
- click_on "Authorize"
115
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
116
- url_should_have_param("state", "return-me")
117
- url_should_not_have_param("code_challenge_method")
118
- end
119
-
120
- scenario "resource owner requests an access token without authorization code" do
121
- create_access_token "", @client
122
-
123
- access_token_should_not_exist
124
-
125
- expect(Doorkeeper::AccessToken.count).to be_zero
126
-
127
- should_have_json "error", "invalid_request"
128
- should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :code)
129
- end
130
-
131
- scenario "resource owner requests an access token with authorization code" do
132
- visit authorization_endpoint_url(client: @client)
133
- click_on "Authorize"
134
-
135
- authorization_code = Doorkeeper::AccessGrant.first.token
136
- create_access_token authorization_code, @client
137
-
138
- access_token_should_exist_for(@client, @resource_owner)
139
-
140
- should_not_have_json "error"
141
-
142
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
143
- should_have_json "token_type", "Bearer"
144
- should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
145
- end
146
-
147
- scenario "resource owner requests an access token with authorization code but without secret" do
148
- visit authorization_endpoint_url(client: @client)
149
- click_on "Authorize"
150
-
151
- authorization_code = Doorkeeper::AccessGrant.first.token
152
- page.driver.post token_endpoint_url(
153
- code: authorization_code, client_id: @client.uid,
154
- redirect_uri: @client.redirect_uri,
155
- )
156
-
157
- expect(Doorkeeper::AccessToken.count).to be_zero
158
-
159
- should_have_json "error", "invalid_client"
160
- should_have_json "error_description", translated_error_message(:invalid_client)
161
- end
162
-
163
- scenario "resource owner requests an access token with authorization code but without client id" do
164
- visit authorization_endpoint_url(client: @client)
165
- click_on "Authorize"
166
-
167
- authorization_code = Doorkeeper::AccessGrant.first.token
168
- page.driver.post token_endpoint_url(
169
- code: authorization_code, client_secret: @client.secret,
170
- redirect_uri: @client.redirect_uri,
171
- )
172
-
173
- expect(Doorkeeper::AccessToken.count).to be_zero
174
-
175
- should_have_json "error", "invalid_client"
176
- should_have_json "error_description", translated_error_message(:invalid_client)
177
- end
178
-
179
- scenario "silently authorizes if matching token exists" do
180
- default_scopes_exist :public, :write
181
-
182
- access_token_exists application: @client,
183
- expires_in: -100, # even expired token
184
- resource_owner_id: @resource_owner.id,
185
- resource_owner_type: @resource_owner.class.name,
186
- scopes: "public write"
187
-
188
- visit authorization_endpoint_url(client: @client, scope: "public write")
189
-
190
- response_status_should_be 200
191
- i_should_not_see "Authorize"
192
- end
193
-
194
- context "with PKCE" do
195
- context "plain" do
196
- let(:code_challenge) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
197
- let(:code_verifier) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
198
-
199
- scenario "resource owner authorizes the client with code_challenge parameter set" do
200
- visit authorization_endpoint_url(
201
- client: @client,
202
- code_challenge: code_challenge,
203
- code_challenge_method: "plain",
204
- )
205
- click_on "Authorize"
206
-
207
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
208
- url_should_not_have_param("code_challenge_method")
209
- url_should_not_have_param("code_challenge")
210
- end
211
-
212
- scenario "mobile app requests an access token with authorization code but not pkce token" do
213
- visit authorization_endpoint_url(client: @client)
214
- click_on "Authorize"
215
-
216
- authorization_code = current_params["code"]
217
- create_access_token authorization_code, @client, code_verifier
218
-
219
- should_have_json "error", "invalid_grant"
220
- should_have_json "error_description", translated_error_message(:invalid_grant)
221
- end
222
-
223
- scenario "mobile app requests an access token with authorization code and plain code challenge method" do
224
- visit authorization_endpoint_url(
225
- client: @client,
226
- code_challenge: code_challenge,
227
- code_challenge_method: "plain",
228
- )
229
- click_on "Authorize"
230
-
231
- authorization_code = current_params["code"]
232
- create_access_token authorization_code, @client, code_verifier
233
-
234
- access_token_should_exist_for(@client, @resource_owner)
235
-
236
- should_not_have_json "error"
237
-
238
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
239
- should_have_json "token_type", "Bearer"
240
- should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
241
- end
242
-
243
- scenario "mobile app requests an access token with authorization code but without code_verifier" do
244
- visit authorization_endpoint_url(
245
- client: @client,
246
- code_challenge: code_challenge,
247
- code_challenge_method: "plain",
248
- )
249
- click_on "Authorize"
250
-
251
- authorization_code = current_params["code"]
252
- create_access_token authorization_code, @client, nil
253
-
254
- should_not_have_json "access_token"
255
- should_have_json "error", "invalid_request"
256
- should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :code_verifier)
257
- end
258
-
259
- scenario "mobile app requests an access token with authorization code with wrong code_verifier" do
260
- visit authorization_endpoint_url(
261
- client: @client,
262
- code_challenge: code_challenge,
263
- code_challenge_method: "plain",
264
- )
265
- click_on "Authorize"
266
-
267
- authorization_code = current_params["code"]
268
- create_access_token authorization_code, @client, "wrong_code_verifier"
269
-
270
- should_not_have_json "access_token"
271
- should_have_json "error", "invalid_grant"
272
- should_have_json "error_description", translated_error_message(:invalid_grant)
273
- end
274
- end
275
-
276
- context "s256" do
277
- let(:code_challenge) { "Oz733NtQ0rJP8b04fgZMJMwprn6Iw8sMCT_9bR1q4tA" }
278
- let(:code_verifier) { "a45a9fea-0676-477e-95b1-a40f72ac3cfb" }
279
-
280
- scenario "resource owner authorizes the client with code_challenge parameter set" do
281
- visit authorization_endpoint_url(
282
- client: @client,
283
- code_challenge: code_challenge,
284
- code_challenge_method: "S256",
285
- )
286
- click_on "Authorize"
287
-
288
- url_should_have_param("code", Doorkeeper::AccessGrant.first.token)
289
- url_should_not_have_param("code_challenge_method")
290
- url_should_not_have_param("code_challenge")
291
- end
292
-
293
- scenario "mobile app requests an access token with authorization code and S256 code challenge method" do
294
- visit authorization_endpoint_url(
295
- client: @client,
296
- code_challenge: code_challenge,
297
- code_challenge_method: "S256",
298
- )
299
- click_on "Authorize"
300
-
301
- authorization_code = current_params["code"]
302
- create_access_token authorization_code, @client, code_verifier
303
-
304
- access_token_should_exist_for(@client, @resource_owner)
305
-
306
- should_not_have_json "error"
307
-
308
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
309
- should_have_json "token_type", "Bearer"
310
- should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
311
- end
312
-
313
- scenario "mobile app requests an access token with authorization code and without secret" do
314
- visit authorization_endpoint_url(
315
- client: @client,
316
- code_challenge: code_challenge,
317
- code_challenge_method: "S256",
318
- )
319
- click_on "Authorize"
320
-
321
- authorization_code = current_params["code"]
322
- page.driver.post token_endpoint_url(
323
- code: authorization_code,
324
- client_id: @client.uid,
325
- redirect_uri: @client.redirect_uri,
326
- code_verifier: code_verifier,
327
- )
328
- should_not_have_json "access_token"
329
- should_have_json "error", "invalid_client"
330
- should_have_json "error_description", translated_error_message(:invalid_client)
331
- end
332
-
333
- scenario "mobile app requests an access token with authorization code and without secret but is marked as not confidential" do
334
- @client.update_attribute :confidential, false
335
- visit authorization_endpoint_url(client: @client, code_challenge: code_challenge, code_challenge_method: "S256")
336
- click_on "Authorize"
337
-
338
- authorization_code = current_params["code"]
339
- page.driver.post token_endpoint_url(
340
- code: authorization_code,
341
- client_id: @client.uid,
342
- redirect_uri: @client.redirect_uri,
343
- code_verifier: code_verifier,
344
- )
345
- should_not_have_json "error"
346
-
347
- should_have_json "access_token", Doorkeeper::AccessToken.first.token
348
- should_have_json "token_type", "Bearer"
349
- should_have_json_within "expires_in", Doorkeeper::AccessToken.first.expires_in, 1
350
- end
351
-
352
- scenario "mobile app requests an access token with authorization code but no code verifier" do
353
- visit authorization_endpoint_url(
354
- client: @client,
355
- code_challenge: code_challenge,
356
- code_challenge_method: "S256",
357
- )
358
- click_on "Authorize"
359
-
360
- authorization_code = current_params["code"]
361
- create_access_token authorization_code, @client
362
-
363
- should_not_have_json "access_token"
364
- should_have_json "error", "invalid_request"
365
- should_have_json "error_description", translated_invalid_request_error_message(:missing_param, :code_verifier)
366
- end
367
-
368
- scenario "mobile app requests an access token with authorization code with wrong verifier" do
369
- visit authorization_endpoint_url(
370
- client: @client,
371
- code_challenge: code_challenge,
372
- code_challenge_method: "S256",
373
- )
374
- click_on "Authorize"
375
-
376
- authorization_code = current_params["code"]
377
- create_access_token authorization_code, @client, "incorrect-code-verifier"
378
-
379
- should_not_have_json "access_token"
380
- should_have_json "error", "invalid_grant"
381
- should_have_json "error_description", translated_error_message(:invalid_grant)
382
- end
383
-
384
- scenario "code_challenge_mehthod in token request is totally ignored" do
385
- visit authorization_endpoint_url(
386
- client: @client,
387
- code_challenge: code_challenge,
388
- code_challenge_method: "S256",
389
- )
390
- click_on "Authorize"
391
-
392
- authorization_code = current_params["code"]
393
- page.driver.post token_endpoint_url(
394
- code: authorization_code,
395
- client: @client,
396
- code_verifier: code_challenge,
397
- code_challenge_method: "plain",
398
- )
399
-
400
- should_not_have_json "access_token"
401
- should_have_json "error", "invalid_grant"
402
- should_have_json "error_description", translated_error_message(:invalid_grant)
403
- end
404
-
405
- scenario "expects to set code_challenge_method explicitely without fallback" do
406
- visit authorization_endpoint_url(client: @client, code_challenge: code_challenge)
407
- expect(page).to have_content("The code challenge method must be plain or S256.")
408
- end
409
- end
410
- end
411
-
412
- context "when application scopes are present and no scope is passed" do
413
- background do
414
- @client.update(scopes: "public write read default")
415
- end
416
-
417
- scenario "scope is invalid because default scope is different from application scope" do
418
- default_scopes_exist :admin
419
- visit authorization_endpoint_url(client: @client)
420
- response_status_should_be 200
421
- i_should_not_see "Authorize"
422
- i_should_see_translated_error_message :invalid_scope
423
- end
424
-
425
- scenario "access grant have scopes which are common in application scopees and default scopes" do
426
- default_scopes_exist :public, :write
427
- visit authorization_endpoint_url(client: @client)
428
- click_on "Authorize"
429
- access_grant_should_exist_for(@client, @resource_owner)
430
- access_grant_should_have_scopes :public, :write
431
- end
432
- end
433
-
434
- context "with scopes" do
435
- background do
436
- default_scopes_exist :public
437
- optional_scopes_exist :write
438
- end
439
-
440
- scenario "resource owner authorizes the client with default scopes" do
441
- visit authorization_endpoint_url(client: @client)
442
- click_on "Authorize"
443
- access_grant_should_exist_for(@client, @resource_owner)
444
- access_grant_should_have_scopes :public
445
- end
446
-
447
- scenario "resource owner authorizes the client with required scopes" do
448
- visit authorization_endpoint_url(client: @client, scope: "public write")
449
- click_on "Authorize"
450
- access_grant_should_have_scopes :public, :write
451
- end
452
-
453
- scenario "resource owner authorizes the client with required scopes (without defaults)" do
454
- visit authorization_endpoint_url(client: @client, scope: "write")
455
- click_on "Authorize"
456
- access_grant_should_have_scopes :write
457
- end
458
-
459
- scenario "new access token matches required scopes" do
460
- visit authorization_endpoint_url(client: @client, scope: "public write")
461
- click_on "Authorize"
462
-
463
- authorization_code = Doorkeeper::AccessGrant.first.token
464
- create_access_token authorization_code, @client
465
-
466
- access_token_should_exist_for(@client, @resource_owner)
467
- access_token_should_have_scopes :public, :write
468
- end
469
-
470
- scenario "returns new token if scopes have changed" do
471
- client_is_authorized(@client, @resource_owner, scopes: "public write")
472
- visit authorization_endpoint_url(client: @client, scope: "public")
473
- click_on "Authorize"
474
-
475
- authorization_code = Doorkeeper::AccessGrant.first.token
476
- create_access_token authorization_code, @client
477
-
478
- expect(Doorkeeper::AccessToken.count).to be(2)
479
-
480
- should_have_json "access_token", Doorkeeper::AccessToken.last.token
481
- end
482
-
483
- scenario "resource owner authorizes the client with extra scopes" do
484
- client_is_authorized(@client, @resource_owner, scopes: "public")
485
- visit authorization_endpoint_url(client: @client, scope: "public write")
486
- click_on "Authorize"
487
-
488
- authorization_code = Doorkeeper::AccessGrant.first.token
489
- create_access_token authorization_code, @client
490
-
491
- expect(Doorkeeper::AccessToken.count).to be(2)
492
-
493
- should_have_json "access_token", Doorkeeper::AccessToken.last.token
494
- access_token_should_have_scopes :public, :write
495
- end
496
- end
497
- end
498
-
499
- describe "Authorization Code Flow" do
500
- before do
501
- Doorkeeper.configure do
502
- orm DOORKEEPER_ORM
503
- use_refresh_token
504
- end
505
-
506
- client_exists
507
- end
508
-
509
- context "issuing a refresh token" do
510
- let(:resource_owner) { FactoryBot.create(:resource_owner) }
511
-
512
- before do
513
- authorization_code_exists application: @client,
514
- resource_owner_id: resource_owner.id,
515
- resource_owner_type: resource_owner.class.name
516
- end
517
-
518
- it "second of simultaneous client requests get an error for revoked acccess token" do
519
- authorization_code = Doorkeeper::AccessGrant.first.token
520
- allow_any_instance_of(Doorkeeper::AccessGrant)
521
- .to receive(:revoked?).and_return(false, true)
522
-
523
- post token_endpoint_url(code: authorization_code, client: @client)
524
-
525
- should_not_have_json "access_token"
526
- should_have_json "error", "invalid_grant"
527
- should_have_json "error_description", translated_error_message(:invalid_grant)
528
- end
529
- end
530
- end