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,11 +1,13 @@
1
- require 'coveralls'
1
+ # frozen_string_literal: true
2
2
 
3
- Coveralls.wear!('rails') do
4
- add_filter('/spec/')
5
- add_filter('/lib/generators/doorkeeper/templates/')
3
+ require "coveralls"
4
+
5
+ Coveralls.wear!("rails") do
6
+ add_filter("/spec/")
7
+ add_filter("/lib/generators/doorkeeper/templates/")
6
8
  end
7
9
 
8
- ENV['RAILS_ENV'] ||= 'test'
10
+ ENV["RAILS_ENV"] ||= "test"
9
11
 
10
12
  $LOAD_PATH.unshift File.dirname(__FILE__)
11
13
 
@@ -13,15 +15,15 @@ require "#{File.dirname(__FILE__)}/support/doorkeeper_rspec.rb"
13
15
 
14
16
  DOORKEEPER_ORM = Doorkeeper::RSpec.detect_orm
15
17
 
16
- require 'dummy/config/environment'
17
- require 'rspec/rails'
18
- require 'capybara/rspec'
19
- require 'database_cleaner'
20
- require 'generator_spec/test_case'
18
+ require "dummy/config/environment"
19
+ require "rspec/rails"
20
+ require "capybara/rspec"
21
+ require "database_cleaner"
22
+ require "generator_spec/test_case"
21
23
 
22
24
  # Load JRuby SQLite3 if in that platform
23
25
  if defined? JRUBY_VERSION
24
- require 'jdbc/sqlite3'
26
+ require "jdbc/sqlite3"
25
27
  Jdbc::SQLite3.load_driver
26
28
  end
27
29
 
@@ -29,7 +31,6 @@ Doorkeeper::RSpec.print_configuration_info
29
31
 
30
32
  # Remove after dropping support of Rails 4.2
31
33
  require "#{File.dirname(__FILE__)}/support/http_method_shim"
32
- require "#{File.dirname(__FILE__)}/support/ruby_2_6_rails_4_2_patch"
33
34
 
34
35
  require "support/orm/#{DOORKEEPER_ORM}"
35
36
 
@@ -52,5 +53,5 @@ RSpec.configure do |config|
52
53
  DatabaseCleaner.clean
53
54
  end
54
55
 
55
- config.order = 'random'
56
+ config.order = "random"
56
57
  end
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # For compatibility only
2
- require 'spec_helper'
4
+ require "spec_helper"
@@ -1,2 +1,4 @@
1
- require 'factory_bot'
1
+ # frozen_string_literal: true
2
+
3
+ require "factory_bot"
2
4
  FactoryBot.find_definitions
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
4
  class RSpec
3
5
  # Print's useful information about env: Ruby / Rails versions,
@@ -13,7 +15,7 @@ module Doorkeeper
13
15
 
14
16
  # Tries to find ORM from the Gemfile used to run test suite
15
17
  def self.detect_orm
16
- orm = (ENV['BUNDLE_GEMFILE'] || '').match(/Gemfile\.(.+)\.rb/)
18
+ orm = (ENV["BUNDLE_GEMFILE"] || "").match(/Gemfile\.(.+)\.rb/)
17
19
  (orm && orm[1] || :active_record).to_sym
18
20
  end
19
21
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AccessTokenRequestHelper
2
4
  def client_is_authorized(client, resource_owner, access_token_attributes = {})
3
5
  attributes = {
4
6
  application: client,
5
- resource_owner_id: resource_owner.id
7
+ resource_owner_id: resource_owner.id,
6
8
  }.merge(access_token_attributes)
7
9
  FactoryBot.create(:access_token, attributes)
8
10
  end
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AuthorizationRequestHelper
2
4
  def resource_owner_is_authenticated(resource_owner = nil)
3
- resource_owner ||= User.create!(name: 'Joe', password: 'sekret')
5
+ resource_owner ||= User.create!(name: "Joe", password: "sekret")
4
6
  Doorkeeper.configuration.instance_variable_set(:@authenticate_resource_owner, proc { resource_owner })
5
7
  end
6
8
 
7
9
  def resource_owner_is_not_authenticated
8
- Doorkeeper.configuration.instance_variable_set(:@authenticate_resource_owner, proc { redirect_to('/sign_in') })
10
+ Doorkeeper.configuration.instance_variable_set(:@authenticate_resource_owner, proc { redirect_to("/sign_in") })
9
11
  end
10
12
 
11
13
  def default_scopes_exist(*scopes)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ConfigHelper
2
4
  def config_is_set(setting, value = nil, &block)
3
5
  setting_ivar = "@#{setting}"
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ModelHelper
2
4
  def client_exists(client_attributes = {})
3
5
  @client = FactoryBot.create(:application, client_attributes)
4
6
  end
5
7
 
6
8
  def create_resource_owner
7
- @resource_owner = User.create!(name: 'Joe', password: 'sekret')
9
+ @resource_owner = User.create!(name: "Joe", password: "sekret")
8
10
  end
9
11
 
10
12
  def authorization_code_exists(options = {})
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RequestSpecHelper
2
4
  def i_am_logged_in
3
5
  allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) {})
@@ -48,7 +50,7 @@ module RequestSpecHelper
48
50
  end
49
51
 
50
52
  def with_access_token_header(token)
51
- with_header 'Authorization', "Bearer #{token}"
53
+ with_header "Authorization", "Bearer #{token}"
52
54
  end
53
55
 
54
56
  def with_header(header, value)
@@ -72,8 +74,8 @@ module RequestSpecHelper
72
74
  end
73
75
 
74
76
  def sign_in
75
- visit '/'
76
- click_on 'Sign in'
77
+ visit "/"
78
+ click_on "Sign in"
77
79
  end
78
80
 
79
81
  def create_access_token(authorization_code, client, code_verifier = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module UrlHelper
2
4
  def token_endpoint_url(options = {})
3
5
  parameters = {
@@ -5,9 +7,9 @@ module UrlHelper
5
7
  client_id: options[:client_id] || options[:client].try(:uid),
6
8
  client_secret: options[:client_secret] || options[:client].try(:secret),
7
9
  redirect_uri: options[:redirect_uri] || options[:client].try(:redirect_uri),
8
- grant_type: options[:grant_type] || 'authorization_code',
10
+ grant_type: options[:grant_type] || "authorization_code",
9
11
  code_verifier: options[:code_verifier],
10
- code_challenge_method: options[:code_challenge_method]
12
+ code_challenge_method: options[:code_challenge_method],
11
13
  }.reject { |_, v| v.blank? }
12
14
  "/oauth/token?#{build_query(parameters)}"
13
15
  end
@@ -20,7 +22,7 @@ module UrlHelper
20
22
  username: options[:resource_owner_username] || options[:resource_owner].try(:name),
21
23
  password: options[:resource_owner_password] || options[:resource_owner].try(:password),
22
24
  scope: options[:scope],
23
- grant_type: 'password'
25
+ grant_type: "password",
24
26
  }
25
27
  "/oauth/token?#{build_query(parameters)}"
26
28
  end
@@ -29,11 +31,11 @@ module UrlHelper
29
31
  parameters = {
30
32
  client_id: options[:client_id] || options[:client].try(:uid),
31
33
  redirect_uri: options[:redirect_uri] || options[:client].try(:redirect_uri),
32
- response_type: options[:response_type] || 'code',
34
+ response_type: options[:response_type] || "code",
33
35
  scope: options[:scope],
34
36
  state: options[:state],
35
37
  code_challenge: options[:code_challenge],
36
- code_challenge_method: options[:code_challenge_method]
38
+ code_challenge_method: options[:code_challenge_method],
37
39
  }.reject { |_, v| v.blank? }
38
40
  "/oauth/authorize?#{build_query(parameters)}"
39
41
  end
@@ -43,13 +45,13 @@ module UrlHelper
43
45
  refresh_token: options[:refresh_token],
44
46
  client_id: options[:client_id] || options[:client].try(:uid),
45
47
  client_secret: options[:client_secret] || options[:client].try(:secret),
46
- grant_type: options[:grant_type] || 'refresh_token'
48
+ grant_type: options[:grant_type] || "refresh_token",
47
49
  }
48
50
  "/oauth/token?#{build_query(parameters)}"
49
51
  end
50
52
 
51
53
  def revocation_token_endpoint_url
52
- '/oauth/revoke'
54
+ "/oauth/revoke"
53
55
  end
54
56
 
55
57
  def build_query(hash)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Rails 5 deprecates calling HTTP action methods with positional arguments
2
4
  # in favor of keyword arguments. However, the keyword argument form is only
3
5
  # supported in Rails 5+. Since we support back to 4, we need some sort of shim
@@ -17,18 +19,11 @@ module RoutingHTTPMethodShim
17
19
  end
18
20
 
19
21
  module ControllerHTTPMethodShim
20
- def process(action, http_method = 'GET', **args)
22
+ def process(action, http_method = "GET", **args)
21
23
  if (as = args.delete(:as))
22
- @request.headers['Content-Type'] = Mime[as].to_s
24
+ @request.headers["Content-Type"] = Mime[as].to_s
23
25
  end
24
26
 
25
27
  super(action, http_method, args[:params], args[:session], args[:flash])
26
28
  end
27
29
  end
28
-
29
- if ::Rails::VERSION::MAJOR < 5
30
- RSpec.configure do |config|
31
- config.include ControllerHTTPMethodShim, type: :controller
32
- config.include RoutingHTTPMethodShim, type: :request
33
- end
34
- end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # load schema to in memory sqlite
2
4
  ActiveRecord::Migration.verbose = false
3
- load Rails.root + 'db/schema.rb'
5
+ load Rails.root + "db/schema.rb"
@@ -1,5 +1,7 @@
1
- shared_context 'valid token', token: :valid do
2
- let(:token_string) { '1A2B3C4D' }
1
+ # frozen_string_literal: true
2
+
3
+ shared_context "valid token", token: :valid do
4
+ let(:token_string) { "1A2B3C4D" }
3
5
 
4
6
  let :token do
5
7
  double(Doorkeeper::AccessToken,
@@ -14,8 +16,8 @@ shared_context 'valid token', token: :valid do
14
16
  end
15
17
  end
16
18
 
17
- shared_context 'invalid token', token: :invalid do
18
- let(:token_string) { '1A2B3C4D' }
19
+ shared_context "invalid token", token: :invalid do
20
+ let(:token_string) { "1A2B3C4D" }
19
21
 
20
22
  let :token do
21
23
  double(Doorkeeper::AccessToken,
@@ -31,22 +33,22 @@ shared_context 'invalid token', token: :invalid do
31
33
  end
32
34
  end
33
35
 
34
- shared_context 'authenticated resource owner' do
36
+ shared_context "authenticated resource owner" do
35
37
  before do
36
38
  user = double(:resource, id: 1)
37
39
  allow(Doorkeeper.configuration).to receive(:authenticate_resource_owner) { proc { user } }
38
40
  end
39
41
  end
40
42
 
41
- shared_context 'not authenticated resource owner' do
43
+ shared_context "not authenticated resource owner" do
42
44
  before do
43
- allow(Doorkeeper.configuration).to receive(:authenticate_resource_owner) { proc { redirect_to '/' } }
45
+ allow(Doorkeeper.configuration).to receive(:authenticate_resource_owner) { proc { redirect_to "/" } }
44
46
  end
45
47
  end
46
48
 
47
- shared_context 'valid authorization request' do
49
+ shared_context "valid authorization request" do
48
50
  let :authorization do
49
- double(:authorization, valid?: true, authorize: true, success_redirect_uri: 'http://something.com/cb?code=token')
51
+ double(:authorization, valid?: true, authorize: true, success_redirect_uri: "http://something.com/cb?code=token")
50
52
  end
51
53
 
52
54
  before do
@@ -54,7 +56,7 @@ shared_context 'valid authorization request' do
54
56
  end
55
57
  end
56
58
 
57
- shared_context 'invalid authorization request' do
59
+ shared_context "invalid authorization request" do
58
60
  let :authorization do
59
61
  double(:authorization, valid?: false, authorize: false, redirect_on_error?: false)
60
62
  end
@@ -64,9 +66,9 @@ shared_context 'invalid authorization request' do
64
66
  end
65
67
  end
66
68
 
67
- shared_context 'expired token', token: :expired do
69
+ shared_context "expired token", token: :expired do
68
70
  let :token_string do
69
- '1A2B3C4DEXP'
71
+ "1A2B3C4DEXP"
70
72
  end
71
73
 
72
74
  let :token do
@@ -83,9 +85,9 @@ shared_context 'expired token', token: :expired do
83
85
  end
84
86
  end
85
87
 
86
- shared_context 'revoked token', token: :revoked do
88
+ shared_context "revoked token", token: :revoked do
87
89
  let :token_string do
88
- '1A2B3C4DREV'
90
+ "1A2B3C4DREV"
89
91
  end
90
92
 
91
93
  let :token do
@@ -102,9 +104,9 @@ shared_context 'revoked token', token: :revoked do
102
104
  end
103
105
  end
104
106
 
105
- shared_context 'forbidden token', token: :forbidden do
107
+ shared_context "forbidden token", token: :forbidden do
106
108
  let :token_string do
107
- '1A2B3C4DFORB'
109
+ "1A2B3C4DFORB"
108
110
  end
109
111
 
110
112
  let :token do
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- shared_context 'with token hashing enabled' do
3
+ shared_context "with token hashing enabled" do
4
4
  let(:hashed_or_plain_token_func) do
5
5
  Doorkeeper::SecretStoring::Sha256Hash.method(:transform_secret)
6
6
  end
@@ -12,7 +12,7 @@ shared_context 'with token hashing enabled' do
12
12
  end
13
13
  end
14
14
 
15
- shared_context 'with token hashing and fallback lookup enabled' do
15
+ shared_context "with token hashing and fallback lookup enabled" do
16
16
  let(:hashed_or_plain_token_func) do
17
17
  Doorkeeper::SecretStoring::Sha256Hash.method(:transform_secret)
18
18
  end
@@ -24,7 +24,7 @@ shared_context 'with token hashing and fallback lookup enabled' do
24
24
  end
25
25
  end
26
26
 
27
- shared_context 'with application hashing enabled' do
27
+ shared_context "with application hashing enabled" do
28
28
  let(:hashed_or_plain_token_func) do
29
29
  Doorkeeper::SecretStoring::Sha256Hash.method(:transform_secret)
30
30
  end
@@ -1,46 +1,48 @@
1
- shared_examples 'an accessible token' do
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples "an accessible token" do
2
4
  describe :accessible? do
3
- it 'is accessible if token is not expired' do
5
+ it "is accessible if token is not expired" do
4
6
  allow(subject).to receive(:expired?).and_return(false)
5
7
  should be_accessible
6
8
  end
7
9
 
8
- it 'is not accessible if token is expired' do
10
+ it "is not accessible if token is expired" do
9
11
  allow(subject).to receive(:expired?).and_return(true)
10
12
  should_not be_accessible
11
13
  end
12
14
  end
13
15
  end
14
16
 
15
- shared_examples 'a revocable token' do
17
+ shared_examples "a revocable token" do
16
18
  describe :accessible? do
17
19
  before { subject.save! }
18
20
 
19
- it 'is accessible if token is not revoked' do
21
+ it "is accessible if token is not revoked" do
20
22
  expect(subject).to be_accessible
21
23
  end
22
24
 
23
- it 'is not accessible if token is revoked' do
25
+ it "is not accessible if token is revoked" do
24
26
  subject.revoke
25
27
  expect(subject).not_to be_accessible
26
28
  end
27
29
  end
28
30
  end
29
31
 
30
- shared_examples 'a unique token' do
32
+ shared_examples "a unique token" do
31
33
  describe :token do
32
- it 'is generated before validation' do
34
+ it "is generated before validation" do
33
35
  expect { subject.valid? }.to change { subject.token }.from(nil)
34
36
  end
35
37
 
36
- it 'is not valid if token exists' do
38
+ it "is not valid if token exists" do
37
39
  token1 = FactoryBot.create factory_name
38
40
  token2 = FactoryBot.create factory_name
39
41
  token2.token = token1.token
40
42
  expect(token2).not_to be_valid
41
43
  end
42
44
 
43
- it 'expects database to throw an error when tokens are the same' do
45
+ it "expects database to throw an error when tokens are the same" do
44
46
  token1 = FactoryBot.create factory_name
45
47
  token2 = FactoryBot.create factory_name
46
48
  token2.token = token1.token
@@ -1,12 +1,14 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  describe RedirectUriValidator do
4
6
  subject do
5
7
  FactoryBot.create(:application)
6
8
  end
7
9
 
8
- it 'is valid when the uri is a uri' do
9
- subject.redirect_uri = 'https://example.com/callback'
10
+ it "is valid when the uri is a uri" do
11
+ subject.redirect_uri = "https://example.com/callback"
10
12
  expect(subject).to be_valid
11
13
  end
12
14
 
@@ -15,115 +17,142 @@ describe RedirectUriValidator do
15
17
  # the system browser.
16
18
  #
17
19
  # @see https://www.oauth.com/oauth2-servers/redirect-uris/redirect-uris-native-apps/
18
- it 'is valid when the uri is custom native URI' do
19
- subject.redirect_uri = 'myapp://callback'
20
+ it "is valid when the uri is custom native URI" do
21
+ subject.redirect_uri = "myapp://callback"
20
22
  expect(subject).to be_valid
21
23
  end
22
24
 
23
- it 'is valid when the uri has a query parameter' do
24
- subject.redirect_uri = 'https://example.com/abcd?xyz=123'
25
+ it "is valid when the uri has a query parameter" do
26
+ subject.redirect_uri = "https://example.com/abcd?xyz=123"
25
27
  expect(subject).to be_valid
26
28
  end
27
29
 
28
- it 'accepts native redirect uri' do
29
- subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
30
+ it "accepts native redirect uri" do
31
+ subject.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
30
32
  expect(subject).to be_valid
31
33
  end
32
34
 
33
- it 'rejects if test uri is disabled' do
35
+ it "rejects if test uri is disabled" do
34
36
  allow(RedirectUriValidator).to receive(:native_redirect_uri).and_return(nil)
35
- subject.redirect_uri = 'urn:some:test'
37
+ subject.redirect_uri = "urn:some:test"
36
38
  expect(subject).not_to be_valid
37
39
  end
38
40
 
39
- it 'is invalid when the uri is not a uri' do
40
- subject.redirect_uri = ']'
41
+ it "is invalid when the uri is not a uri" do
42
+ subject.redirect_uri = "]"
41
43
  expect(subject).not_to be_valid
42
- expect(subject.errors[:redirect_uri].first).to eq('must be a valid URI.')
44
+ expect(subject.errors[:redirect_uri].first).to eq("must be a valid URI.")
43
45
  end
44
46
 
45
- it 'is invalid when the uri is relative' do
46
- subject.redirect_uri = '/abcd'
47
+ it "is invalid when the uri is relative" do
48
+ subject.redirect_uri = "/abcd"
47
49
  expect(subject).not_to be_valid
48
- expect(subject.errors[:redirect_uri].first).to eq('must be an absolute URI.')
50
+ expect(subject.errors[:redirect_uri].first).to eq("must be an absolute URI.")
49
51
  end
50
52
 
51
- it 'is invalid when the uri has a fragment' do
52
- subject.redirect_uri = 'https://example.com/abcd#xyz'
53
+ it "is invalid when the uri has a fragment" do
54
+ subject.redirect_uri = "https://example.com/abcd#xyz"
53
55
  expect(subject).not_to be_valid
54
- expect(subject.errors[:redirect_uri].first).to eq('cannot contain a fragment.')
56
+ expect(subject.errors[:redirect_uri].first).to eq("cannot contain a fragment.")
55
57
  end
56
58
 
57
- context 'force secured uri' do
58
- it 'accepts an valid uri' do
59
- subject.redirect_uri = 'https://example.com/callback'
59
+ context "force secured uri" do
60
+ it "accepts an valid uri" do
61
+ subject.redirect_uri = "https://example.com/callback"
60
62
  expect(subject).to be_valid
61
63
  end
62
64
 
63
- it 'accepts native redirect uri' do
64
- subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
65
+ it "accepts native redirect uri" do
66
+ subject.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
65
67
  expect(subject).to be_valid
66
68
  end
67
69
 
68
- it 'accepts app redirect uri' do
69
- subject.redirect_uri = 'some-awesome-app://oauth/callback'
70
+ it "accepts app redirect uri" do
71
+ subject.redirect_uri = "some-awesome-app://oauth/callback"
70
72
  expect(subject).to be_valid
71
73
  end
72
74
 
73
- it 'accepts a non secured protocol when disabled' do
74
- subject.redirect_uri = 'http://example.com/callback'
75
+ it "accepts a non secured protocol when disabled" do
76
+ subject.redirect_uri = "http://example.com/callback"
75
77
  allow(Doorkeeper.configuration).to receive(
76
78
  :force_ssl_in_redirect_uri
77
79
  ).and_return(false)
78
80
  expect(subject).to be_valid
79
81
  end
80
82
 
81
- it 'accepts a non secured protocol when conditional option defined' do
83
+ it "accepts a non secured protocol when conditional option defined" do
82
84
  Doorkeeper.configure do
83
85
  orm DOORKEEPER_ORM
84
- force_ssl_in_redirect_uri { |uri| uri.host != 'localhost' }
86
+ force_ssl_in_redirect_uri { |uri| uri.host != "localhost" }
85
87
  end
86
88
 
87
- application = FactoryBot.build(:application, redirect_uri: 'http://localhost/callback')
89
+ application = FactoryBot.build(:application, redirect_uri: "http://localhost/callback")
88
90
  expect(application).to be_valid
89
91
 
90
- application = FactoryBot.build(:application, redirect_uri: 'https://test.com/callback')
92
+ application = FactoryBot.build(:application, redirect_uri: "https://test.com/callback")
91
93
  expect(application).to be_valid
92
94
 
93
- application = FactoryBot.build(:application, redirect_uri: 'http://localhost2/callback')
95
+ application = FactoryBot.build(:application, redirect_uri: "http://localhost2/callback")
94
96
  expect(application).not_to be_valid
95
97
 
96
- application = FactoryBot.build(:application, redirect_uri: 'https://test.com/callback')
98
+ application = FactoryBot.build(:application, redirect_uri: "https://test.com/callback")
97
99
  expect(application).to be_valid
98
100
  end
99
101
 
100
- it 'forbids redirect uri if required' do
101
- subject.redirect_uri = 'javascript://document.cookie'
102
+ it "forbids redirect uri if required" do
103
+ subject.redirect_uri = "javascript://document.cookie"
102
104
 
103
105
  Doorkeeper.configure do
104
106
  orm DOORKEEPER_ORM
105
- forbid_redirect_uri { |uri| uri.scheme == 'javascript' }
107
+ forbid_redirect_uri { |uri| uri.scheme == "javascript" }
106
108
  end
107
109
 
108
110
  expect(subject).to be_invalid
109
- expect(subject.errors[:redirect_uri].first).to eq('is forbidden by the server.')
111
+ expect(subject.errors[:redirect_uri].first).to eq("is forbidden by the server.")
110
112
 
111
- subject.redirect_uri = 'https://localhost/callback'
113
+ subject.redirect_uri = "https://localhost/callback"
112
114
  expect(subject).to be_valid
113
115
  end
114
116
 
115
- it 'invalidates the uri when the uri does not use a secure protocol' do
116
- subject.redirect_uri = 'http://example.com/callback'
117
+ it "invalidates the uri when the uri does not use a secure protocol" do
118
+ subject.redirect_uri = "http://example.com/callback"
117
119
  expect(subject).not_to be_valid
118
120
  error = subject.errors[:redirect_uri].first
119
- expect(error).to eq('must be an HTTPS/SSL URI.')
121
+ expect(error).to eq("must be an HTTPS/SSL URI.")
120
122
  end
121
123
  end
122
124
 
123
- context 'multiple redirect uri' do
124
- it 'invalidates the second uri when the first uri is native uri' do
125
+ context "multiple redirect uri" do
126
+ it "invalidates the second uri when the first uri is native uri" do
125
127
  subject.redirect_uri = "urn:ietf:wg:oauth:2.0:oob\nexample.com/callback"
126
128
  expect(subject).to be_invalid
127
129
  end
128
130
  end
131
+
132
+ context "blank redirect URI" do
133
+ it "forbids blank redirect uri by default" do
134
+ subject.redirect_uri = ""
135
+
136
+ expect(subject).to be_invalid
137
+ expect(subject.errors[:redirect_uri]).not_to be_blank
138
+ end
139
+
140
+ it "forbids blank redirect uri by custom condition" do
141
+ Doorkeeper.configure do
142
+ orm DOORKEEPER_ORM
143
+ allow_blank_redirect_uri do |_grant_flows, application|
144
+ application.name == "admin app"
145
+ end
146
+ end
147
+
148
+ subject.name = "test app"
149
+ subject.redirect_uri = ""
150
+
151
+ expect(subject).to be_invalid
152
+ expect(subject.errors[:redirect_uri]).not_to be_blank
153
+
154
+ subject.name = "admin app"
155
+ expect(subject).to be_valid
156
+ end
157
+ end
129
158
  end