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,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'uri'
3
+ require "uri"
4
4
 
5
5
  class RedirectUriValidator < ActiveModel::EachValidator
6
6
  def self.native_redirect_uri
@@ -9,11 +9,14 @@ class RedirectUriValidator < ActiveModel::EachValidator
9
9
 
10
10
  def validate_each(record, attribute, value)
11
11
  if value.blank?
12
+ return if Doorkeeper.configuration.allow_blank_redirect_uri?(record)
13
+
12
14
  record.errors.add(attribute, :blank)
13
15
  else
14
16
  value.split.each do |val|
15
17
  uri = ::URI.parse(val)
16
18
  next if native_redirect_uri?(uri)
19
+
17
20
  record.errors.add(attribute, :forbidden_uri) if forbidden_uri?(uri)
18
21
  record.errors.add(attribute, :fragment_present) unless uri.fragment.nil?
19
22
  record.errors.add(attribute, :relative_uri) if uri.scheme.nil? || uri.host.nil?
@@ -36,7 +39,7 @@ class RedirectUriValidator < ActiveModel::EachValidator
36
39
 
37
40
  def invalid_ssl_uri?(uri)
38
41
  forces_ssl = Doorkeeper.configuration.force_ssl_in_redirect_uri
39
- non_https = uri.try(:scheme) == 'http'
42
+ non_https = uri.try(:scheme) == "http"
40
43
 
41
44
  if forces_ssl.respond_to?(:call)
42
45
  forces_ssl.call(uri) && non_https
@@ -25,6 +25,12 @@
25
25
  <%= raw t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: content_tag(:code, class: 'bg-light') { Doorkeeper.configuration.native_redirect_uri }) %>
26
26
  </span>
27
27
  <% end %>
28
+
29
+ <% if Doorkeeper.configuration.allow_blank_redirect_uri?(application) %>
30
+ <span class="form-text text-secondary">
31
+ <%= t('doorkeeper.applications.help.blank_redirect_uri') %>
32
+ </span>
33
+ <% end %>
28
34
  </div>
29
35
  </div>
30
36
 
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require 'bundler/setup'
4
- require 'rails/all'
5
- require 'doorkeeper'
4
+ require "bundler/setup"
5
+ require "rails/all"
6
+ require "doorkeeper"
6
7
 
7
8
  # You can add fixtures and/or initialization code here to make experimenting
8
9
  # with your gem easier. You can also use a different console, if you like.
@@ -11,5 +12,5 @@ require 'doorkeeper'
11
12
  # require "pry"
12
13
  # Pry.start
13
14
 
14
- require 'irb'
15
+ require "irb"
15
16
  IRB.start(__FILE__)
@@ -32,6 +32,7 @@ en:
32
32
  help:
33
33
  confidential: 'Application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.'
34
34
  redirect_uri: 'Use one line per URI'
35
+ blank_redirect_uri: "Leave it blank if you configured your provider to use Client Credentials, Resource Owner Password Credentials or any other grant type that doesn't require redirect URI."
35
36
  native_redirect_uri: 'Use %{native_redirect_uri} if you want to add localhost URIs for development purposes'
36
37
  scopes: 'Separate scopes with spaces. Leave blank to use the default scopes.'
37
38
  edit:
@@ -1,32 +1,34 @@
1
- $LOAD_PATH.push File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
2
 
3
- require 'doorkeeper/version'
3
+ $LOAD_PATH.push File.expand_path("lib", __dir__)
4
+
5
+ require "doorkeeper/version"
4
6
 
5
7
  Gem::Specification.new do |gem|
6
- gem.name = 'doorkeeper'
8
+ gem.name = "doorkeeper"
7
9
  gem.version = Doorkeeper.gem_version
8
- gem.authors = ['Felipe Elias Philipp', 'Tute Costa', 'Jon Moss', 'Nikita Bulai']
9
- gem.email = %w(bulaj.nikita@gmail.com)
10
- gem.homepage = 'https://github.com/doorkeeper-gem/doorkeeper'
11
- gem.summary = 'OAuth 2 provider for Rails and Grape'
12
- gem.description = 'Doorkeeper is an OAuth 2 provider for Rails and Grape.'
13
- gem.license = 'MIT'
10
+ gem.authors = ["Felipe Elias Philipp", "Tute Costa", "Jon Moss", "Nikita Bulai"]
11
+ gem.email = %w[bulaj.nikita@gmail.com]
12
+ gem.homepage = "https://github.com/doorkeeper-gem/doorkeeper"
13
+ gem.summary = "OAuth 2 provider for Rails and Grape"
14
+ gem.description = "Doorkeeper is an OAuth 2 provider for Rails and Grape."
15
+ gem.license = "MIT"
14
16
 
15
17
  gem.files = `git ls-files`.split("\n")
16
18
  gem.test_files = `git ls-files -- spec/*`.split("\n")
17
- gem.require_paths = ['lib']
19
+ gem.require_paths = ["lib"]
18
20
 
19
- gem.add_dependency 'railties', '>= 4.2'
20
- gem.required_ruby_version = '>= 2.1'
21
+ gem.add_dependency "railties", ">= 5"
22
+ gem.required_ruby_version = ">= 2.4"
21
23
 
22
- gem.add_development_dependency 'appraisal'
23
- gem.add_development_dependency 'capybara'
24
- gem.add_development_dependency 'coveralls'
25
- gem.add_development_dependency 'danger', '~> 5.0'
26
- gem.add_development_dependency 'database_cleaner', '~> 1.6'
27
- gem.add_development_dependency 'factory_bot', '~> 4.8'
28
- gem.add_development_dependency 'generator_spec', '~> 0.9.3'
29
- gem.add_development_dependency 'grape'
30
- gem.add_development_dependency 'rake', '>= 11.3.0'
31
- gem.add_development_dependency 'rspec-rails'
24
+ gem.add_development_dependency "appraisal"
25
+ gem.add_development_dependency "capybara"
26
+ gem.add_development_dependency "coveralls"
27
+ gem.add_development_dependency "danger", "~> 6.0"
28
+ gem.add_development_dependency "database_cleaner", "~> 1.6"
29
+ gem.add_development_dependency "factory_bot", "~> 5.0"
30
+ gem.add_development_dependency "generator_spec", "~> 0.9.3"
31
+ gem.add_development_dependency "grape"
32
+ gem.add_development_dependency "rake", ">= 11.3.0"
33
+ gem.add_development_dependency "rspec-rails"
32
34
  end
@@ -2,12 +2,13 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 5.0.0", ">= 5.0.7.2"
5
+ gem "rails", "~> 5.0.0"
6
6
  gem "rspec-core", git: "https://github.com/rspec/rspec-core.git"
7
7
  gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
8
8
  gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
9
9
  gem "rspec-rails", branch: "4-0-dev", git: "https://github.com/rspec/rspec-rails.git"
10
10
  gem "rspec-support", git: "https://github.com/rspec/rspec-support.git"
11
+ gem "rubocop", "~> 0.66"
11
12
  gem "bcrypt", "~> 3.1", require: false
12
13
  gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
13
14
  gem "sqlite3", "~> 1.3", "< 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
@@ -2,12 +2,13 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 5.1.0", ">= 5.1.6.2"
5
+ gem "rails", "~> 5.1.0"
6
6
  gem "rspec-core", git: "https://github.com/rspec/rspec-core.git"
7
7
  gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
8
8
  gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
9
9
  gem "rspec-rails", branch: "4-0-dev", git: "https://github.com/rspec/rspec-rails.git"
10
10
  gem "rspec-support", git: "https://github.com/rspec/rspec-support.git"
11
+ gem "rubocop", "~> 0.66"
11
12
  gem "bcrypt", "~> 3.1", require: false
12
13
  gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
13
14
  gem "sqlite3", "~> 1.3", "< 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
@@ -2,12 +2,13 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 5.2.2", ">= 5.2.2.1"
5
+ gem "rails", "~> 5.2.0"
6
6
  gem "rspec-core", git: "https://github.com/rspec/rspec-core.git"
7
7
  gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
8
8
  gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
9
9
  gem "rspec-rails", branch: "4-0-dev", git: "https://github.com/rspec/rspec-rails.git"
10
10
  gem "rspec-support", git: "https://github.com/rspec/rspec-support.git"
11
+ gem "rubocop", "~> 0.66"
11
12
  gem "bcrypt", "~> 3.1", require: false
12
13
  gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
13
14
  gem "sqlite3", "~> 1.3", "< 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
@@ -8,6 +8,7 @@ gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
8
8
  gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
9
9
  gem "rspec-rails", branch: "4-0-dev", git: "https://github.com/rspec/rspec-rails.git"
10
10
  gem "rspec-support", git: "https://github.com/rspec/rspec-support.git"
11
+ gem "rubocop", "~> 0.66"
11
12
  gem "bcrypt", "~> 3.1", require: false
12
13
  gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
13
14
  gem "sqlite3", "~> 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
@@ -8,6 +8,7 @@ gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
8
8
  gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
9
9
  gem "rspec-rails", branch: "4-0-dev", git: "https://github.com/rspec/rspec-rails.git"
10
10
  gem "rspec-support", git: "https://github.com/rspec/rspec-support.git"
11
+ gem "rubocop", "~> 0.66"
11
12
  gem "bcrypt", "~> 3.1", require: false
12
13
  gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
13
14
  gem "sqlite3", "~> 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
@@ -1,82 +1,84 @@
1
- require 'doorkeeper/version'
2
- require 'doorkeeper/engine'
3
- require 'doorkeeper/config'
1
+ # frozen_string_literal: true
4
2
 
5
- require 'doorkeeper/request/strategy'
6
- require 'doorkeeper/request/authorization_code'
7
- require 'doorkeeper/request/client_credentials'
8
- require 'doorkeeper/request/code'
9
- require 'doorkeeper/request/password'
10
- require 'doorkeeper/request/refresh_token'
11
- require 'doorkeeper/request/token'
3
+ require "doorkeeper/version"
4
+ require "doorkeeper/engine"
5
+ require "doorkeeper/config"
12
6
 
13
- require 'doorkeeper/errors'
14
- require 'doorkeeper/server'
15
- require 'doorkeeper/request'
16
- require 'doorkeeper/validations'
7
+ require "doorkeeper/request/strategy"
8
+ require "doorkeeper/request/authorization_code"
9
+ require "doorkeeper/request/client_credentials"
10
+ require "doorkeeper/request/code"
11
+ require "doorkeeper/request/password"
12
+ require "doorkeeper/request/refresh_token"
13
+ require "doorkeeper/request/token"
17
14
 
18
- require 'doorkeeper/oauth/authorization/code'
19
- require 'doorkeeper/oauth/authorization/context'
20
- require 'doorkeeper/oauth/authorization/token'
21
- require 'doorkeeper/oauth/authorization/uri_builder'
22
- require 'doorkeeper/oauth/helpers/scope_checker'
23
- require 'doorkeeper/oauth/helpers/uri_checker'
24
- require 'doorkeeper/oauth/helpers/unique_token'
15
+ require "doorkeeper/errors"
16
+ require "doorkeeper/server"
17
+ require "doorkeeper/request"
18
+ require "doorkeeper/validations"
25
19
 
26
- require 'doorkeeper/oauth'
27
- require 'doorkeeper/oauth/scopes'
28
- require 'doorkeeper/oauth/error'
29
- require 'doorkeeper/oauth/base_response'
30
- require 'doorkeeper/oauth/code_response'
31
- require 'doorkeeper/oauth/token_response'
32
- require 'doorkeeper/oauth/error_response'
33
- require 'doorkeeper/oauth/pre_authorization'
34
- require 'doorkeeper/oauth/base_request'
35
- require 'doorkeeper/oauth/authorization_code_request'
36
- require 'doorkeeper/oauth/refresh_token_request'
37
- require 'doorkeeper/oauth/password_access_token_request'
20
+ require "doorkeeper/oauth/authorization/code"
21
+ require "doorkeeper/oauth/authorization/context"
22
+ require "doorkeeper/oauth/authorization/token"
23
+ require "doorkeeper/oauth/authorization/uri_builder"
24
+ require "doorkeeper/oauth/helpers/scope_checker"
25
+ require "doorkeeper/oauth/helpers/uri_checker"
26
+ require "doorkeeper/oauth/helpers/unique_token"
38
27
 
39
- require 'doorkeeper/oauth/client_credentials/validation'
40
- require 'doorkeeper/oauth/client_credentials/creator'
41
- require 'doorkeeper/oauth/client_credentials/issuer'
42
- require 'doorkeeper/oauth/client_credentials/validation'
43
- require 'doorkeeper/oauth/client/credentials'
28
+ require "doorkeeper/oauth"
29
+ require "doorkeeper/oauth/scopes"
30
+ require "doorkeeper/oauth/error"
31
+ require "doorkeeper/oauth/base_response"
32
+ require "doorkeeper/oauth/code_response"
33
+ require "doorkeeper/oauth/token_response"
34
+ require "doorkeeper/oauth/error_response"
35
+ require "doorkeeper/oauth/pre_authorization"
36
+ require "doorkeeper/oauth/base_request"
37
+ require "doorkeeper/oauth/authorization_code_request"
38
+ require "doorkeeper/oauth/refresh_token_request"
39
+ require "doorkeeper/oauth/password_access_token_request"
44
40
 
45
- require 'doorkeeper/oauth/client_credentials_request'
46
- require 'doorkeeper/oauth/code_request'
47
- require 'doorkeeper/oauth/token_request'
48
- require 'doorkeeper/oauth/client'
49
- require 'doorkeeper/oauth/token'
50
- require 'doorkeeper/oauth/token_introspection'
51
- require 'doorkeeper/oauth/invalid_token_response'
52
- require 'doorkeeper/oauth/forbidden_token_response'
41
+ require "doorkeeper/oauth/client_credentials/validation"
42
+ require "doorkeeper/oauth/client_credentials/creator"
43
+ require "doorkeeper/oauth/client_credentials/issuer"
44
+ require "doorkeeper/oauth/client_credentials/validation"
45
+ require "doorkeeper/oauth/client/credentials"
53
46
 
54
- require 'doorkeeper/secret_storing/base'
55
- require 'doorkeeper/secret_storing/plain'
56
- require 'doorkeeper/secret_storing/sha256_hash'
57
- require 'doorkeeper/secret_storing/bcrypt'
47
+ require "doorkeeper/oauth/client_credentials_request"
48
+ require "doorkeeper/oauth/code_request"
49
+ require "doorkeeper/oauth/token_request"
50
+ require "doorkeeper/oauth/client"
51
+ require "doorkeeper/oauth/token"
52
+ require "doorkeeper/oauth/token_introspection"
53
+ require "doorkeeper/oauth/invalid_token_response"
54
+ require "doorkeeper/oauth/forbidden_token_response"
58
55
 
59
- require 'doorkeeper/models/concerns/orderable'
60
- require 'doorkeeper/models/concerns/scopes'
61
- require 'doorkeeper/models/concerns/expirable'
62
- require 'doorkeeper/models/concerns/reusable'
63
- require 'doorkeeper/models/concerns/revocable'
64
- require 'doorkeeper/models/concerns/accessible'
65
- require 'doorkeeper/models/concerns/secret_storable'
56
+ require "doorkeeper/secret_storing/base"
57
+ require "doorkeeper/secret_storing/plain"
58
+ require "doorkeeper/secret_storing/sha256_hash"
59
+ require "doorkeeper/secret_storing/bcrypt"
66
60
 
67
- require 'doorkeeper/models/access_grant_mixin'
68
- require 'doorkeeper/models/access_token_mixin'
69
- require 'doorkeeper/models/application_mixin'
61
+ require "doorkeeper/models/concerns/orderable"
62
+ require "doorkeeper/models/concerns/scopes"
63
+ require "doorkeeper/models/concerns/expirable"
64
+ require "doorkeeper/models/concerns/reusable"
65
+ require "doorkeeper/models/concerns/revocable"
66
+ require "doorkeeper/models/concerns/accessible"
67
+ require "doorkeeper/models/concerns/secret_storable"
70
68
 
71
- require 'doorkeeper/helpers/controller'
69
+ require "doorkeeper/models/access_grant_mixin"
70
+ require "doorkeeper/models/access_token_mixin"
71
+ require "doorkeeper/models/application_mixin"
72
72
 
73
- require 'doorkeeper/rails/routes'
74
- require 'doorkeeper/rails/helpers'
73
+ require "doorkeeper/helpers/controller"
75
74
 
76
- require 'doorkeeper/rake'
77
- require 'doorkeeper/stale_records_cleaner'
75
+ require "doorkeeper/rails/routes"
76
+ require "doorkeeper/rails/helpers"
78
77
 
79
- require 'doorkeeper/orm/active_record'
78
+ require "doorkeeper/rake"
79
+ require "doorkeeper/stale_records_cleaner"
80
+
81
+ require "doorkeeper/orm/active_record"
80
82
 
81
83
  module Doorkeeper
82
84
  def self.authenticate(request, methods = Doorkeeper.configuration.access_token_methods)
@@ -1,9 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "doorkeeper/config/option"
4
+
1
5
  module Doorkeeper
2
6
  class MissingConfiguration < StandardError
3
7
  # Defines a MissingConfiguration error for a missing Doorkeeper
4
8
  # configuration
5
9
  def initialize
6
- super('Configuration for doorkeeper missing. Do you have doorkeeper initializer?')
10
+ super("Configuration for doorkeeper missing. Do you have doorkeeper initializer?")
7
11
  end
8
12
  end
9
13
 
@@ -12,6 +16,7 @@ module Doorkeeper
12
16
  setup_orm_adapter
13
17
  setup_orm_models
14
18
  setup_application_owner if @config.enable_application_owner?
19
+ @config
15
20
  end
16
21
 
17
22
  def self.configuration
@@ -163,7 +168,7 @@ module Doorkeeper
163
168
  # Provide a fallback secret storage implementation class for tokens
164
169
  # or use :plain to fallback to plain tokens
165
170
  def hash_token_secrets(using: nil, fallback: nil)
166
- default = '::Doorkeeper::SecretStoring::Sha256Hash'
171
+ default = "::Doorkeeper::SecretStoring::Sha256Hash"
167
172
  configure_secrets_for :token,
168
173
  using: using || default,
169
174
  fallback: fallback
@@ -178,7 +183,7 @@ module Doorkeeper
178
183
  # Provide a fallback secret storage implementation for applications
179
184
  # or use :plain to fallback to plain application secrets
180
185
  def hash_application_secrets(using: nil, fallback: nil)
181
- default = '::Doorkeeper::SecretStoring::Sha256Hash'
186
+ default = "::Doorkeeper::SecretStoring::Sha256Hash"
182
187
  configure_secrets_for :application,
183
188
  using: using || default,
184
189
  fallback: fallback
@@ -188,9 +193,7 @@ module Doorkeeper
188
193
 
189
194
  # Configure the secret storing functionality
190
195
  def configure_secrets_for(type, using:, fallback:)
191
- unless %i[application token].include?(type)
192
- raise ArgumentError, "Invalid type #{type}"
193
- end
196
+ raise ArgumentError, "Invalid type #{type}" if %i[application token].exclude?(type)
194
197
 
195
198
  @config.instance_variable_set(:"@#{type}_secret_strategy",
196
199
  using.constantize)
@@ -198,7 +201,7 @@ module Doorkeeper
198
201
  if fallback.nil?
199
202
  return
200
203
  elsif fallback.to_sym == :plain
201
- fallback = '::Doorkeeper::SecretStoring::Plain'
204
+ fallback = "::Doorkeeper::SecretStoring::Plain"
202
205
  end
203
206
 
204
207
  @config.instance_variable_set(:"@#{type}_secret_fallback_strategy",
@@ -206,71 +209,13 @@ module Doorkeeper
206
209
  end
207
210
  end
208
211
 
209
- module Option
210
- # Defines configuration option
211
- #
212
- # When you call option, it defines two methods. One method will take place
213
- # in the +Config+ class and the other method will take place in the
214
- # +Builder+ class.
215
- #
216
- # The +name+ parameter will set both builder method and config attribute.
217
- # If the +:as+ option is defined, the builder method will be the specified
218
- # option while the config attribute will be the +name+ parameter.
219
- #
220
- # If you want to introduce another level of config DSL you can
221
- # define +builder_class+ parameter.
222
- # Builder should take a block as the initializer parameter and respond to function +build+
223
- # that returns the value of the config attribute.
224
- #
225
- # ==== Options
226
- #
227
- # * [:+as+] Set the builder method that goes inside +configure+ block
228
- # * [+:default+] The default value in case no option was set
229
- #
230
- # ==== Examples
231
- #
232
- # option :name
233
- # option :name, as: :set_name
234
- # option :name, default: 'My Name'
235
- # option :scopes builder_class: ScopesBuilder
236
- #
237
- def option(name, options = {})
238
- attribute = options[:as] || name
239
- attribute_builder = options[:builder_class]
240
-
241
- Builder.instance_eval do
242
- remove_method name if method_defined?(name)
243
- define_method name do |*args, &block|
244
- # TODO: is builder_class option being used?
245
- value = if attribute_builder
246
- attribute_builder.new(&block).build
247
- else
248
- block || args.first
249
- end
250
-
251
- @config.instance_variable_set(:"@#{attribute}", value)
252
- end
253
- end
254
-
255
- define_method attribute do |*_args|
256
- if instance_variable_defined?(:"@#{attribute}")
257
- instance_variable_get(:"@#{attribute}")
258
- else
259
- options[:default]
260
- end
261
- end
262
-
263
- public attribute
264
- end
265
- end
266
-
267
212
  extend Option
268
213
 
269
214
  option :resource_owner_authenticator,
270
215
  as: :authenticate_resource_owner,
271
216
  default: (lambda do |_routes|
272
217
  ::Rails.logger.warn(
273
- I18n.t('doorkeeper.errors.messages.resource_owner_authenticator_not_configured')
218
+ I18n.t("doorkeeper.errors.messages.resource_owner_authenticator_not_configured")
274
219
  )
275
220
 
276
221
  nil
@@ -280,7 +225,7 @@ module Doorkeeper
280
225
  as: :authenticate_admin,
281
226
  default: (lambda do |_routes|
282
227
  ::Rails.logger.warn(
283
- I18n.t('doorkeeper.errors.messages.admin_authenticator_not_configured')
228
+ I18n.t("doorkeeper.errors.messages.admin_authenticator_not_configured")
284
229
  )
285
230
 
286
231
  head :forbidden
@@ -289,7 +234,7 @@ module Doorkeeper
289
234
  option :resource_owner_from_credentials,
290
235
  default: (lambda do |_routes|
291
236
  ::Rails.logger.warn(
292
- I18n.t('doorkeeper.errors.messages.credential_flow_not_configured')
237
+ I18n.t("doorkeeper.errors.messages.credential_flow_not_configured")
293
238
  )
294
239
 
295
240
  nil
@@ -309,7 +254,7 @@ module Doorkeeper
309
254
  option :custom_access_token_expires_in, default: ->(_context) { nil }
310
255
  option :authorization_code_expires_in, default: 600
311
256
  option :orm, default: :active_record
312
- option :native_redirect_uri, default: 'urn:ietf:wg:oauth:2.0:oob'
257
+ option :native_redirect_uri, default: "urn:ietf:wg:oauth:2.0:oob"
313
258
  option :active_record_options, default: {}
314
259
  option :grant_flows, default: %w[authorization_code client_credentials]
315
260
  option :handle_auth_errors, default: :render
@@ -325,7 +270,7 @@ module Doorkeeper
325
270
  #
326
271
  # @param realm [String] ("Doorkeeper") Authentication realm
327
272
  #
328
- option :realm, default: 'Doorkeeper'
273
+ option :realm, default: "Doorkeeper"
329
274
 
330
275
  # Forces the usage of the HTTPS protocol in non-native redirect uris
331
276
  # (enabled by default in non-development environments). OAuth2
@@ -349,8 +294,7 @@ module Doorkeeper
349
294
  # the name of the access token generator class
350
295
  #
351
296
  option :access_token_generator,
352
- default: 'Doorkeeper::OAuth::Helpers::UniqueToken'
353
-
297
+ default: "Doorkeeper::OAuth::Helpers::UniqueToken"
354
298
 
355
299
  # Default access token generator is a SecureRandom class from Ruby stdlib.
356
300
  # This option defines which method will be used to generate a unique token value.
@@ -358,7 +302,7 @@ module Doorkeeper
358
302
  # @param access_token_generator [String]
359
303
  # the name of the access token generator class
360
304
  #
361
- option :default_generator_method, default: :urlsafe_base64
305
+ option :default_generator_method, default: :urlsafe_base64
362
306
 
363
307
  # The controller Doorkeeper::ApplicationController inherits from.
364
308
  # Defaults to ActionController::Base.
@@ -366,11 +310,22 @@ module Doorkeeper
366
310
  #
367
311
  # @param base_controller [String] the name of the base controller
368
312
  option :base_controller,
369
- default: 'ActionController::Base'
313
+ default: "ActionController::Base"
314
+
315
+ # Allows to set blank redirect URIs for Applications in case
316
+ # server configured to use URI-less grant flows.
317
+ #
318
+ option :allow_blank_redirect_uri,
319
+ default: (lambda do |grant_flows, _application|
320
+ grant_flows.exclude?("authorization_code") &&
321
+ grant_flows.exclude?("implicit")
322
+ end)
370
323
 
371
324
  attr_reader :api_only,
372
325
  :enforce_content_type,
373
- :reuse_access_token
326
+ :reuse_access_token,
327
+ :token_secret_fallback_strategy,
328
+ :application_secret_fallback_strategy
374
329
 
375
330
  # Return the valid subset of this configuration
376
331
  def validate
@@ -419,18 +374,10 @@ module Doorkeeper
419
374
  @token_secret_strategy ||= ::Doorkeeper::SecretStoring::Plain
420
375
  end
421
376
 
422
- def token_secret_fallback_strategy
423
- @token_secret_fallback_strategy
424
- end
425
-
426
377
  def application_secret_strategy
427
378
  @application_secret_strategy ||= ::Doorkeeper::SecretStoring::Plain
428
379
  end
429
380
 
430
- def application_secret_fallback_strategy
431
- @application_secret_fallback_strategy
432
- end
433
-
434
381
  def default_scopes
435
382
  @default_scopes ||= OAuth::Scopes.new
436
383
  end
@@ -452,7 +399,11 @@ module Doorkeeper
452
399
  end
453
400
 
454
401
  def access_token_methods
455
- @access_token_methods ||= %i[from_bearer_authorization from_access_token_param from_bearer_param]
402
+ @access_token_methods ||= %i[
403
+ from_bearer_authorization
404
+ from_access_token_param
405
+ from_bearer_param
406
+ ]
456
407
  end
457
408
 
458
409
  def authorization_response_types
@@ -463,6 +414,18 @@ module Doorkeeper
463
414
  @token_grant_types ||= calculate_token_grant_types.freeze
464
415
  end
465
416
 
417
+ def allow_blank_redirect_uri?(application = nil)
418
+ if allow_blank_redirect_uri.respond_to?(:call)
419
+ allow_blank_redirect_uri.call(grant_flows, application)
420
+ else
421
+ allow_blank_redirect_uri
422
+ end
423
+ end
424
+
425
+ def option_defined?(name)
426
+ instance_variable_defined?("@#{name}")
427
+ end
428
+
466
429
  private
467
430
 
468
431
  # Helper to read boolearized configuration option
@@ -476,8 +439,8 @@ module Doorkeeper
476
439
  #
477
440
  def calculate_authorization_response_types
478
441
  types = []
479
- types << 'code' if grant_flows.include? 'authorization_code'
480
- types << 'token' if grant_flows.include? 'implicit'
442
+ types << "code" if grant_flows.include? "authorization_code"
443
+ types << "token" if grant_flows.include? "implicit"
481
444
  types
482
445
  end
483
446
 
@@ -485,8 +448,8 @@ module Doorkeeper
485
448
  # request endpoint, and return them in array.
486
449
  #
487
450
  def calculate_token_grant_types
488
- types = grant_flows - ['implicit']
489
- types << 'refresh_token' if refresh_token_enabled?
451
+ types = grant_flows - ["implicit"]
452
+ types << "refresh_token" if refresh_token_enabled?
490
453
  types
491
454
  end
492
455
 
@@ -518,8 +481,8 @@ module Doorkeeper
518
481
  (token_reuse_limit > 0 && token_reuse_limit <= 100)
519
482
 
520
483
  ::Rails.logger.warn(
521
- 'You have configured an invalid value for token_reuse_limit option. ' \
522
- 'It will be set to default 100'
484
+ "You have configured an invalid value for token_reuse_limit option. " \
485
+ "It will be set to default 100"
523
486
  )
524
487
  @token_reuse_limit = 100
525
488
  end