doorkeeper 5.1.0.rc2 → 5.1.0

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