doorkeeper 4.4.0 → 5.6.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (284) hide show
  1. checksums.yaml +5 -5
  2. data/{NEWS.md → CHANGELOG.md} +471 -16
  3. data/README.md +108 -403
  4. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  5. data/app/controllers/doorkeeper/application_controller.rb +8 -5
  6. data/app/controllers/doorkeeper/application_metal_controller.rb +7 -11
  7. data/app/controllers/doorkeeper/applications_controller.rb +62 -27
  8. data/app/controllers/doorkeeper/authorizations_controller.rb +112 -18
  9. data/app/controllers/doorkeeper/authorized_applications_controller.rb +22 -3
  10. data/app/controllers/doorkeeper/token_info_controller.rb +16 -4
  11. data/app/controllers/doorkeeper/tokens_controller.rb +104 -35
  12. data/app/helpers/doorkeeper/dashboard_helper.rb +9 -7
  13. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  14. data/app/views/doorkeeper/applications/_form.html.erb +27 -26
  15. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  16. data/app/views/doorkeeper/applications/index.html.erb +17 -7
  17. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  18. data/app/views/doorkeeper/applications/show.html.erb +38 -17
  19. data/app/views/doorkeeper/authorizations/error.html.erb +4 -2
  20. data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
  21. data/app/views/doorkeeper/authorizations/new.html.erb +16 -10
  22. data/app/views/layouts/doorkeeper/admin.html.erb +16 -14
  23. data/config/locales/en.yml +28 -5
  24. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  25. data/lib/doorkeeper/config/option.rb +82 -0
  26. data/lib/doorkeeper/config/validations.rb +53 -0
  27. data/lib/doorkeeper/config.rb +477 -142
  28. data/lib/doorkeeper/engine.rb +17 -4
  29. data/lib/doorkeeper/errors.rb +25 -16
  30. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  31. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  32. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  33. data/lib/doorkeeper/grant_flow.rb +45 -0
  34. data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
  35. data/lib/doorkeeper/grape/helpers.rb +13 -7
  36. data/lib/doorkeeper/helpers/controller.rb +43 -10
  37. data/lib/doorkeeper/models/access_grant_mixin.rb +97 -3
  38. data/lib/doorkeeper/models/access_token_mixin.rb +273 -67
  39. data/lib/doorkeeper/models/application_mixin.rb +50 -5
  40. data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
  41. data/lib/doorkeeper/models/concerns/expirable.rb +7 -3
  42. data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
  43. data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
  44. data/lib/doorkeeper/models/concerns/ownership.rb +4 -7
  45. data/lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb +30 -0
  46. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  47. data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
  48. data/lib/doorkeeper/models/concerns/revocable.rb +3 -27
  49. data/lib/doorkeeper/models/concerns/scopes.rb +12 -2
  50. data/lib/doorkeeper/models/concerns/secret_storable.rb +106 -0
  51. data/lib/doorkeeper/oauth/authorization/code.rb +54 -12
  52. data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
  53. data/lib/doorkeeper/oauth/authorization/token.rb +64 -24
  54. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +7 -5
  55. data/lib/doorkeeper/oauth/authorization_code_request.rb +69 -11
  56. data/lib/doorkeeper/oauth/base_request.rb +36 -24
  57. data/lib/doorkeeper/oauth/base_response.rb +2 -0
  58. data/lib/doorkeeper/oauth/client/credentials.rb +5 -5
  59. data/lib/doorkeeper/oauth/client.rb +10 -11
  60. data/lib/doorkeeper/oauth/client_credentials/creator.rb +44 -4
  61. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +16 -9
  62. data/lib/doorkeeper/oauth/client_credentials/validator.rb +55 -0
  63. data/lib/doorkeeper/oauth/client_credentials_request.rb +10 -11
  64. data/lib/doorkeeper/oauth/code_request.rb +8 -12
  65. data/lib/doorkeeper/oauth/code_response.rb +27 -15
  66. data/lib/doorkeeper/oauth/error.rb +3 -1
  67. data/lib/doorkeeper/oauth/error_response.rb +34 -14
  68. data/lib/doorkeeper/oauth/forbidden_token_response.rb +11 -3
  69. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +23 -18
  70. data/lib/doorkeeper/oauth/helpers/unique_token.rb +20 -3
  71. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +42 -6
  72. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  73. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  74. data/lib/doorkeeper/oauth/invalid_token_response.rb +29 -4
  75. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  76. data/lib/doorkeeper/oauth/password_access_token_request.rb +43 -10
  77. data/lib/doorkeeper/oauth/pre_authorization.rb +136 -26
  78. data/lib/doorkeeper/oauth/refresh_token_request.rb +67 -31
  79. data/lib/doorkeeper/oauth/scopes.rb +8 -4
  80. data/lib/doorkeeper/oauth/token.rb +12 -8
  81. data/lib/doorkeeper/oauth/token_introspection.rb +99 -25
  82. data/lib/doorkeeper/oauth/token_request.rb +8 -20
  83. data/lib/doorkeeper/oauth/token_response.rb +13 -10
  84. data/lib/doorkeeper/oauth.rb +13 -0
  85. data/lib/doorkeeper/orm/active_record/access_grant.rb +5 -30
  86. data/lib/doorkeeper/orm/active_record/access_token.rb +5 -43
  87. data/lib/doorkeeper/orm/active_record/application.rb +6 -57
  88. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +63 -0
  89. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +77 -0
  90. data/lib/doorkeeper/orm/active_record/mixins/application.rb +210 -0
  91. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
  92. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +36 -0
  93. data/lib/doorkeeper/orm/active_record.rb +31 -20
  94. data/lib/doorkeeper/rails/helpers.rb +10 -8
  95. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  96. data/lib/doorkeeper/rails/routes/mapper.rb +4 -2
  97. data/lib/doorkeeper/rails/routes/mapping.rb +9 -7
  98. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  99. data/lib/doorkeeper/rails/routes.rb +45 -25
  100. data/lib/doorkeeper/rake/db.rake +40 -0
  101. data/lib/doorkeeper/rake/setup.rake +6 -0
  102. data/lib/doorkeeper/rake.rb +14 -0
  103. data/lib/doorkeeper/request/authorization_code.rb +6 -4
  104. data/lib/doorkeeper/request/client_credentials.rb +3 -3
  105. data/lib/doorkeeper/request/code.rb +1 -1
  106. data/lib/doorkeeper/request/password.rb +4 -3
  107. data/lib/doorkeeper/request/refresh_token.rb +6 -5
  108. data/lib/doorkeeper/request/strategy.rb +4 -2
  109. data/lib/doorkeeper/request/token.rb +1 -1
  110. data/lib/doorkeeper/request.rb +61 -34
  111. data/lib/doorkeeper/secret_storing/base.rb +64 -0
  112. data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
  113. data/lib/doorkeeper/secret_storing/plain.rb +33 -0
  114. data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
  115. data/lib/doorkeeper/server.rb +9 -11
  116. data/lib/doorkeeper/stale_records_cleaner.rb +24 -0
  117. data/lib/doorkeeper/validations.rb +2 -0
  118. data/lib/doorkeeper/version.rb +7 -29
  119. data/lib/doorkeeper.rb +180 -65
  120. data/lib/generators/doorkeeper/application_owner_generator.rb +24 -18
  121. data/lib/generators/doorkeeper/confidential_applications_generator.rb +33 -0
  122. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  123. data/lib/generators/doorkeeper/install_generator.rb +19 -9
  124. data/lib/generators/doorkeeper/migration_generator.rb +23 -18
  125. data/lib/generators/doorkeeper/pkce_generator.rb +33 -0
  126. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +28 -22
  127. data/{spec/dummy/db/migrate/20180210183654_add_confidential_to_application.rb → lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb} +2 -2
  128. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
  129. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  130. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +8 -0
  131. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  132. data/lib/generators/doorkeeper/templates/initializer.rb +402 -32
  133. data/lib/generators/doorkeeper/templates/migration.rb.erb +47 -18
  134. data/lib/generators/doorkeeper/views_generator.rb +8 -4
  135. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  136. metadata +97 -309
  137. data/.coveralls.yml +0 -1
  138. data/.github/ISSUE_TEMPLATE.md +0 -25
  139. data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  140. data/.gitignore +0 -19
  141. data/.hound.yml +0 -2
  142. data/.rspec +0 -1
  143. data/.rubocop.yml +0 -17
  144. data/.travis.yml +0 -38
  145. data/Appraisals +0 -18
  146. data/CODE_OF_CONDUCT.md +0 -46
  147. data/CONTRIBUTING.md +0 -47
  148. data/Gemfile +0 -10
  149. data/RELEASING.md +0 -10
  150. data/Rakefile +0 -20
  151. data/SECURITY.md +0 -15
  152. data/app/validators/redirect_uri_validator.rb +0 -44
  153. data/doorkeeper.gemspec +0 -32
  154. data/gemfiles/rails_4_2.gemfile +0 -13
  155. data/gemfiles/rails_5_0.gemfile +0 -12
  156. data/gemfiles/rails_5_1.gemfile +0 -12
  157. data/gemfiles/rails_5_2.gemfile +0 -12
  158. data/gemfiles/rails_master.gemfile +0 -14
  159. data/lib/doorkeeper/oauth/client_credentials/validation.rb +0 -45
  160. data/lib/generators/doorkeeper/add_client_confidentiality_generator.rb +0 -31
  161. data/lib/generators/doorkeeper/templates/add_confidential_to_application_migration.rb.erb +0 -11
  162. data/spec/controllers/application_metal_controller.rb +0 -10
  163. data/spec/controllers/applications_controller_spec.rb +0 -69
  164. data/spec/controllers/authorizations_controller_spec.rb +0 -218
  165. data/spec/controllers/protected_resources_controller_spec.rb +0 -309
  166. data/spec/controllers/token_info_controller_spec.rb +0 -56
  167. data/spec/controllers/tokens_controller_spec.rb +0 -274
  168. data/spec/dummy/Rakefile +0 -7
  169. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  170. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -7
  171. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -12
  172. data/spec/dummy/app/controllers/home_controller.rb +0 -17
  173. data/spec/dummy/app/controllers/metal_controller.rb +0 -11
  174. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -11
  175. data/spec/dummy/app/helpers/application_helper.rb +0 -5
  176. data/spec/dummy/app/models/user.rb +0 -5
  177. data/spec/dummy/app/views/home/index.html.erb +0 -0
  178. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  179. data/spec/dummy/config/application.rb +0 -23
  180. data/spec/dummy/config/boot.rb +0 -9
  181. data/spec/dummy/config/database.yml +0 -15
  182. data/spec/dummy/config/environment.rb +0 -5
  183. data/spec/dummy/config/environments/development.rb +0 -29
  184. data/spec/dummy/config/environments/production.rb +0 -62
  185. data/spec/dummy/config/environments/test.rb +0 -44
  186. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  187. data/spec/dummy/config/initializers/doorkeeper.rb +0 -107
  188. data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -6
  189. data/spec/dummy/config/initializers/secret_token.rb +0 -8
  190. data/spec/dummy/config/initializers/session_store.rb +0 -8
  191. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  192. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  193. data/spec/dummy/config/routes.rb +0 -52
  194. data/spec/dummy/config.ru +0 -4
  195. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  196. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  197. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -62
  198. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  199. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  200. data/spec/dummy/db/schema.rb +0 -68
  201. data/spec/dummy/public/404.html +0 -26
  202. data/spec/dummy/public/422.html +0 -26
  203. data/spec/dummy/public/500.html +0 -26
  204. data/spec/dummy/public/favicon.ico +0 -0
  205. data/spec/dummy/script/rails +0 -6
  206. data/spec/factories.rb +0 -28
  207. data/spec/generators/application_owner_generator_spec.rb +0 -41
  208. data/spec/generators/install_generator_spec.rb +0 -31
  209. data/spec/generators/migration_generator_spec.rb +0 -41
  210. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -57
  211. data/spec/generators/templates/routes.rb +0 -3
  212. data/spec/generators/views_generator_spec.rb +0 -27
  213. data/spec/grape/grape_integration_spec.rb +0 -135
  214. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -24
  215. data/spec/lib/config_spec.rb +0 -437
  216. data/spec/lib/doorkeeper_spec.rb +0 -150
  217. data/spec/lib/models/expirable_spec.rb +0 -50
  218. data/spec/lib/models/revocable_spec.rb +0 -59
  219. data/spec/lib/models/scopes_spec.rb +0 -43
  220. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -41
  221. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -108
  222. data/spec/lib/oauth/base_request_spec.rb +0 -155
  223. data/spec/lib/oauth/base_response_spec.rb +0 -45
  224. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  225. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -44
  226. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -86
  227. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -54
  228. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  229. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -105
  230. data/spec/lib/oauth/client_spec.rb +0 -39
  231. data/spec/lib/oauth/code_request_spec.rb +0 -43
  232. data/spec/lib/oauth/code_response_spec.rb +0 -34
  233. data/spec/lib/oauth/error_response_spec.rb +0 -61
  234. data/spec/lib/oauth/error_spec.rb +0 -23
  235. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -23
  236. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -64
  237. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -20
  238. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -213
  239. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -56
  240. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -96
  241. data/spec/lib/oauth/pre_authorization_spec.rb +0 -155
  242. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -166
  243. data/spec/lib/oauth/scopes_spec.rb +0 -149
  244. data/spec/lib/oauth/token_request_spec.rb +0 -96
  245. data/spec/lib/oauth/token_response_spec.rb +0 -85
  246. data/spec/lib/oauth/token_spec.rb +0 -116
  247. data/spec/lib/request/strategy_spec.rb +0 -53
  248. data/spec/lib/server_spec.rb +0 -59
  249. data/spec/models/doorkeeper/access_grant_spec.rb +0 -36
  250. data/spec/models/doorkeeper/access_token_spec.rb +0 -418
  251. data/spec/models/doorkeeper/application_spec.rb +0 -286
  252. data/spec/requests/applications/applications_request_spec.rb +0 -94
  253. data/spec/requests/applications/authorized_applications_spec.rb +0 -30
  254. data/spec/requests/endpoints/authorization_spec.rb +0 -71
  255. data/spec/requests/endpoints/token_spec.rb +0 -71
  256. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -76
  257. data/spec/requests/flows/authorization_code_spec.rb +0 -149
  258. data/spec/requests/flows/client_credentials_spec.rb +0 -86
  259. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -32
  260. data/spec/requests/flows/implicit_grant_spec.rb +0 -61
  261. data/spec/requests/flows/password_spec.rb +0 -197
  262. data/spec/requests/flows/refresh_token_spec.rb +0 -174
  263. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  264. data/spec/requests/flows/skip_authorization_spec.rb +0 -59
  265. data/spec/requests/protected_resources/metal_spec.rb +0 -14
  266. data/spec/requests/protected_resources/private_api_spec.rb +0 -81
  267. data/spec/routing/custom_controller_routes_spec.rb +0 -75
  268. data/spec/routing/default_routes_spec.rb +0 -39
  269. data/spec/routing/scoped_routes_spec.rb +0 -31
  270. data/spec/spec_helper.rb +0 -4
  271. data/spec/spec_helper_integration.rb +0 -74
  272. data/spec/support/dependencies/factory_girl.rb +0 -2
  273. data/spec/support/helpers/access_token_request_helper.rb +0 -11
  274. data/spec/support/helpers/authorization_request_helper.rb +0 -41
  275. data/spec/support/helpers/config_helper.rb +0 -9
  276. data/spec/support/helpers/model_helper.rb +0 -72
  277. data/spec/support/helpers/request_spec_helper.rb +0 -88
  278. data/spec/support/helpers/url_helper.rb +0 -56
  279. data/spec/support/http_method_shim.rb +0 -38
  280. data/spec/support/orm/active_record.rb +0 -3
  281. data/spec/support/shared/controllers_shared_context.rb +0 -65
  282. data/spec/support/shared/models_shared_examples.rb +0 -52
  283. data/spec/validators/redirect_uri_validator_spec.rb +0 -123
  284. data/spec/version/version_spec.rb +0 -15
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Orm
5
+ module ActiveRecord
6
+ # Helper class to clear stale and non-active tokens and grants.
7
+ # Used by Doorkeeper Rake tasks.
8
+ #
9
+ class StaleRecordsCleaner
10
+ def initialize(base_scope)
11
+ @base_scope = base_scope
12
+ end
13
+
14
+ # Clears revoked records
15
+ def clean_revoked
16
+ table = @base_scope.arel_table
17
+
18
+ @base_scope
19
+ .where.not(revoked_at: nil)
20
+ .where(table[:revoked_at].lt(Time.current))
21
+ .in_batches(&:delete_all)
22
+ end
23
+
24
+ # Clears expired records
25
+ def clean_expired(ttl)
26
+ table = @base_scope.arel_table
27
+
28
+ @base_scope
29
+ .where.not(expires_in: nil)
30
+ .where(table[:created_at].lt(Time.current - ttl))
31
+ .in_batches(&:delete_all)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,33 +1,44 @@
1
- require 'active_support/lazy_load_hooks'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
+ autoload :AccessGrant, "doorkeeper/orm/active_record/access_grant"
5
+ autoload :AccessToken, "doorkeeper/orm/active_record/access_token"
6
+ autoload :Application, "doorkeeper/orm/active_record/application"
7
+ autoload :RedirectUriValidator, "doorkeeper/orm/active_record/redirect_uri_validator"
8
+
9
+ module Models
10
+ autoload :Ownership, "doorkeeper/models/concerns/ownership"
11
+ end
12
+
13
+ # ActiveRecord ORM for Doorkeeper entity models.
14
+ # Consists of three main OAuth entities:
15
+ # * Access Token
16
+ # * Access Grant
17
+ # * Application (client)
18
+ #
19
+ # Do a lazy loading of all the required and configured stuff.
20
+ #
4
21
  module Orm
5
22
  module ActiveRecord
6
- def self.initialize_models!
7
- lazy_load do
8
- require 'doorkeeper/orm/active_record/access_grant'
9
- require 'doorkeeper/orm/active_record/access_token'
10
- require 'doorkeeper/orm/active_record/application'
23
+ autoload :StaleRecordsCleaner, "doorkeeper/orm/active_record/stale_records_cleaner"
11
24
 
12
- if Doorkeeper.configuration.active_record_options[:establish_connection]
13
- [Doorkeeper::AccessGrant, Doorkeeper::AccessToken, Doorkeeper::Application].each do |model|
14
- options = Doorkeeper.configuration.active_record_options[:establish_connection]
15
- model.establish_connection(options)
16
- end
17
- end
18
- end
25
+ module Mixins
26
+ autoload :AccessGrant, "doorkeeper/orm/active_record/mixins/access_grant"
27
+ autoload :AccessToken, "doorkeeper/orm/active_record/mixins/access_token"
28
+ autoload :Application, "doorkeeper/orm/active_record/mixins/application"
19
29
  end
20
30
 
21
- def self.initialize_application_owner!
22
- lazy_load do
23
- require 'doorkeeper/models/concerns/ownership'
31
+ def self.run_hooks
32
+ initialize_configured_associations
33
+ end
24
34
 
25
- Doorkeeper::Application.send :include, Doorkeeper::Models::Ownership
35
+ def self.initialize_configured_associations
36
+ if Doorkeeper.config.enable_application_owner?
37
+ Doorkeeper.config.application_model.include ::Doorkeeper::Models::Ownership
26
38
  end
27
- end
28
39
 
29
- def self.lazy_load(&block)
30
- ActiveSupport.on_load(:active_record, {}, &block)
40
+ Doorkeeper.config.access_grant_model.include ::Doorkeeper::Models::PolymorphicResourceOwner::ForAccessGrant
41
+ Doorkeeper.config.access_token_model.include ::Doorkeeper::Models::PolymorphicResourceOwner::ForAccessToken
31
42
  end
32
43
  end
33
44
  end
@@ -1,12 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
4
  module Rails
3
5
  module Helpers
4
6
  def doorkeeper_authorize!(*scopes)
5
- @_doorkeeper_scopes = scopes.presence || Doorkeeper.configuration.default_scopes
7
+ @_doorkeeper_scopes = scopes.presence || Doorkeeper.config.default_scopes
6
8
 
7
- unless valid_doorkeeper_token?
8
- doorkeeper_render_error
9
- end
9
+ doorkeeper_render_error unless valid_doorkeeper_token?
10
10
  end
11
11
 
12
12
  def doorkeeper_unauthorized_render_options(**); end
@@ -14,13 +14,15 @@ module Doorkeeper
14
14
  def doorkeeper_forbidden_render_options(**); end
15
15
 
16
16
  def valid_doorkeeper_token?
17
- doorkeeper_token && doorkeeper_token.acceptable?(@_doorkeeper_scopes)
17
+ doorkeeper_token&.acceptable?(@_doorkeeper_scopes)
18
18
  end
19
19
 
20
20
  private
21
21
 
22
22
  def doorkeeper_render_error
23
23
  error = doorkeeper_error
24
+ error.raise_exception! if Doorkeeper.config.raise_on_errors?
25
+
24
26
  headers.merge!(error.headers.reject { |k| k == "Content-Type" })
25
27
  doorkeeper_render_error_with(error)
26
28
  end
@@ -28,7 +30,7 @@ module Doorkeeper
28
30
  def doorkeeper_render_error_with(error)
29
31
  options = doorkeeper_render_options(error) || {}
30
32
  status = doorkeeper_status_for_error(
31
- error, options.delete(:respond_not_found_when_forbidden)
33
+ error, options.delete(:respond_not_found_when_forbidden),
32
34
  )
33
35
  if options.blank?
34
36
  head status
@@ -68,9 +70,9 @@ module Doorkeeper
68
70
  end
69
71
 
70
72
  def doorkeeper_token
71
- @_doorkeeper_token ||= OAuth::Token.authenticate(
73
+ @doorkeeper_token ||= OAuth::Token.authenticate(
72
74
  request,
73
- *Doorkeeper.configuration.access_token_methods
75
+ *Doorkeeper.config.access_token_methods,
74
76
  )
75
77
  end
76
78
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rails
5
+ # Abstract router module that implements base behavior
6
+ # for generating and mapping Rails routes.
7
+ #
8
+ # Could be reused in Doorkeeper extensions.
9
+ #
10
+ module AbstractRouter
11
+ extend ActiveSupport::Concern
12
+
13
+ attr_reader :routes
14
+
15
+ def initialize(routes, mapper = Mapper.new, &block)
16
+ @routes = routes
17
+ @mapping = mapper.map(&block)
18
+ end
19
+
20
+ def generate_routes!(**_options)
21
+ raise NotImplementedError, "must be redefined for #{self.class.name}!"
22
+ end
23
+
24
+ private
25
+
26
+ def map_route(name, method)
27
+ return if @mapping.skipped?(name)
28
+
29
+ send(method, @mapping[name])
30
+
31
+ mapping[name] = @mapping[name]
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
4
  module Rails
3
5
  class Routes # :nodoc:
4
6
  class Mapper
5
- def initialize
6
- @mapping = Mapping.new
7
+ def initialize(mapping = Mapping.new)
8
+ @mapping = mapping
7
9
  end
8
10
 
9
11
  def map(&block)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
4
  module Rails
3
5
  class Routes # :nodoc:
@@ -6,17 +8,17 @@ module Doorkeeper
6
8
 
7
9
  def initialize
8
10
  @controllers = {
9
- authorizations: 'doorkeeper/authorizations',
10
- applications: 'doorkeeper/applications',
11
- authorized_applications: 'doorkeeper/authorized_applications',
12
- tokens: 'doorkeeper/tokens',
13
- token_info: 'doorkeeper/token_info'
11
+ authorizations: "doorkeeper/authorizations",
12
+ applications: "doorkeeper/applications",
13
+ authorized_applications: "doorkeeper/authorized_applications",
14
+ tokens: "doorkeeper/tokens",
15
+ token_info: "doorkeeper/token_info",
14
16
  }
15
17
 
16
18
  @as = {
17
19
  authorizations: :authorization,
18
20
  tokens: :token,
19
- token_info: :token_info
21
+ token_info: :token_info,
20
22
  }
21
23
 
22
24
  @skips = []
@@ -25,7 +27,7 @@ module Doorkeeper
25
27
  def [](routes)
26
28
  {
27
29
  controllers: @controllers[routes],
28
- as: @as[routes]
30
+ as: @as[routes],
29
31
  }
30
32
  end
31
33
 
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rails
5
+ class Routes
6
+ # Thread-safe registry of any Doorkeeper additional routes.
7
+ # Used to allow implementing of Doorkeeper extensions that must
8
+ # use their own routes.
9
+ #
10
+ module Registry
11
+ ROUTES_ACCESS_LOCK = Mutex.new
12
+ ROUTES_DEFINITION_LOCK = Mutex.new
13
+
14
+ InvalidRouterClass = Class.new(StandardError)
15
+
16
+ # Collection of additional registered routes for Doorkeeper.
17
+ #
18
+ # @return [Array<Object>] set of registered routes
19
+ #
20
+ def registered_routes
21
+ ROUTES_DEFINITION_LOCK.synchronize do
22
+ @registered_routes ||= Set.new
23
+ end
24
+ end
25
+
26
+ # Registers additional routes in the Doorkeeper registry
27
+ #
28
+ # @param [Object] routes
29
+ # routes class
30
+ #
31
+ def register_routes(routes)
32
+ if !routes.is_a?(Module) || !(routes < AbstractRouter)
33
+ raise InvalidRouterClass, "routes class must include Doorkeeper::Rails::AbstractRouter"
34
+ end
35
+
36
+ ROUTES_ACCESS_LOCK.synchronize do
37
+ registered_routes << routes
38
+ end
39
+ end
40
+
41
+ alias register register_routes
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,5 +1,9 @@
1
- require 'doorkeeper/rails/routes/mapping'
2
- require 'doorkeeper/rails/routes/mapper'
1
+ # frozen_string_literal: true
2
+
3
+ require "doorkeeper/rails/routes/mapping"
4
+ require "doorkeeper/rails/routes/mapper"
5
+ require "doorkeeper/rails/routes/abstract_router"
6
+ require "doorkeeper/rails/routes/registry"
3
7
 
4
8
  module Doorkeeper
5
9
  module Rails
@@ -10,23 +14,29 @@ module Doorkeeper
10
14
  end
11
15
  end
12
16
 
13
- def self.install!
14
- ActionDispatch::Routing::Mapper.send :include, Doorkeeper::Rails::Routes::Helper
17
+ include AbstractRouter
18
+ extend Registry
19
+
20
+ mattr_reader :mapping do
21
+ {}
15
22
  end
16
23
 
17
- attr_reader :routes
24
+ def self.install!
25
+ ActionDispatch::Routing::Mapper.include Doorkeeper::Rails::Routes::Helper
26
+
27
+ registered_routes.each(&:install!)
28
+ end
18
29
 
19
- def initialize(routes, &block)
20
- @routes = routes
21
- @mapping = Mapper.new.map(&block)
30
+ def initialize(routes, mapper = Mapper.new, &block)
31
+ super
22
32
  end
23
33
 
24
34
  def generate_routes!(options)
25
- routes.scope options[:scope] || 'oauth', as: 'oauth' do
35
+ routes.scope options[:scope] || "oauth", as: "oauth" do
26
36
  map_route(:authorizations, :authorization_routes)
27
37
  map_route(:tokens, :token_routes)
28
38
  map_route(:tokens, :revoke_routes)
29
- map_route(:tokens, :introspect_routes)
39
+ map_route(:tokens, :introspect_routes) if introspection_routes?
30
40
  map_route(:applications, :application_routes)
31
41
  map_route(:authorized_applications, :authorized_applications_routes)
32
42
  map_route(:token_info, :token_info_routes)
@@ -35,19 +45,15 @@ module Doorkeeper
35
45
 
36
46
  private
37
47
 
38
- def map_route(name, method)
39
- send(method, @mapping[name]) unless @mapping.skipped?(name)
40
- end
41
-
42
48
  def authorization_routes(mapping)
43
49
  routes.resource(
44
50
  :authorization,
45
- path: 'authorize',
51
+ path: "authorize",
46
52
  only: %i[create destroy],
47
53
  as: mapping[:as],
48
- controller: mapping[:controllers]
54
+ controller: mapping[:controllers],
49
55
  ) do
50
- routes.get '/native', action: :show, on: :member
56
+ routes.get native_authorization_code_route, action: :show, on: :member
51
57
  routes.get '/', action: :new, on: :member
52
58
  end
53
59
  end
@@ -55,35 +61,49 @@ module Doorkeeper
55
61
  def token_routes(mapping)
56
62
  routes.resource(
57
63
  :token,
58
- path: 'token',
64
+ path: "token",
59
65
  only: [:create], as: mapping[:as],
60
- controller: mapping[:controllers]
66
+ controller: mapping[:controllers],
61
67
  )
62
68
  end
63
69
 
64
70
  def revoke_routes(mapping)
65
- routes.post 'revoke', controller: mapping[:controllers], action: :revoke
71
+ routes.post "revoke", controller: mapping[:controllers], action: :revoke
66
72
  end
67
73
 
68
74
  def introspect_routes(mapping)
69
- routes.post 'introspect', controller: mapping[:controllers], action: :introspect
75
+ routes.post "introspect", controller: mapping[:controllers], action: :introspect
70
76
  end
71
77
 
72
78
  def token_info_routes(mapping)
73
79
  routes.resource(
74
80
  :token_info,
75
- path: 'token/info',
81
+ path: "token/info",
76
82
  only: [:show], as: mapping[:as],
77
- controller: mapping[:controllers]
83
+ controller: mapping[:controllers],
78
84
  )
79
85
  end
80
86
 
81
87
  def application_routes(mapping)
82
- routes.resources :doorkeeper_applications, controller: mapping[:controllers], as: :applications, path: 'applications'
88
+ routes.resources :doorkeeper_applications,
89
+ controller: mapping[:controllers],
90
+ as: :applications,
91
+ path: "applications"
83
92
  end
84
93
 
85
94
  def authorized_applications_routes(mapping)
86
- routes.resources :authorized_applications, only: %i[index destroy], controller: mapping[:controllers]
95
+ routes.resources :authorized_applications,
96
+ only: %i[index destroy],
97
+ controller: mapping[:controllers]
98
+ end
99
+
100
+ def native_authorization_code_route
101
+ Doorkeeper.configuration.native_authorization_code_route
102
+ end
103
+
104
+ def introspection_routes?
105
+ Doorkeeper.configured? &&
106
+ !Doorkeeper.config.allow_token_introspection.is_a?(FalseClass)
87
107
  end
88
108
  end
89
109
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :doorkeeper do
4
+ namespace :db do
5
+ desc "Removes stale data from doorkeeper related database tables"
6
+ task cleanup: [
7
+ "doorkeeper:db:cleanup:revoked_tokens",
8
+ "doorkeeper:db:cleanup:expired_tokens",
9
+ "doorkeeper:db:cleanup:revoked_grants",
10
+ "doorkeeper:db:cleanup:expired_grants",
11
+ ]
12
+
13
+ namespace :cleanup do
14
+ desc "Removes stale access tokens"
15
+ task revoked_tokens: "doorkeeper:setup" do
16
+ cleaner = Doorkeeper::StaleRecordsCleaner.new(Doorkeeper.config.access_token_model)
17
+ cleaner.clean_revoked
18
+ end
19
+
20
+ desc "Removes expired (TTL passed) access tokens"
21
+ task expired_tokens: "doorkeeper:setup" do
22
+ expirable_tokens = Doorkeeper.config.access_token_model.where(refresh_token: nil)
23
+ cleaner = Doorkeeper::StaleRecordsCleaner.new(expirable_tokens)
24
+ cleaner.clean_expired(Doorkeeper.config.access_token_expires_in)
25
+ end
26
+
27
+ desc "Removes stale access grants"
28
+ task revoked_grants: "doorkeeper:setup" do
29
+ cleaner = Doorkeeper::StaleRecordsCleaner.new(Doorkeeper.config.access_grant_model)
30
+ cleaner.clean_revoked
31
+ end
32
+
33
+ desc "Removes expired (TTL passed) access grants"
34
+ task expired_grants: "doorkeeper:setup" do
35
+ cleaner = Doorkeeper::StaleRecordsCleaner.new(Doorkeeper.config.access_grant_model)
36
+ cleaner.clean_expired(Doorkeeper.config.authorization_code_expires_in)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :doorkeeper do
4
+ task setup: :environment do
5
+ end
6
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rake
5
+ class << self
6
+ def load_tasks
7
+ glob = File.join(File.absolute_path(__dir__), "rake", "*.rake")
8
+ Dir[glob].each do |rake_file|
9
+ load rake_file
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,4 +1,4 @@
1
- require 'doorkeeper/request/strategy'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
4
  module Request
@@ -7,17 +7,19 @@ module Doorkeeper
7
7
 
8
8
  def request
9
9
  @request ||= OAuth::AuthorizationCodeRequest.new(
10
- Doorkeeper.configuration,
10
+ Doorkeeper.config,
11
11
  grant,
12
12
  client,
13
- parameters
13
+ parameters,
14
14
  )
15
15
  end
16
16
 
17
17
  private
18
18
 
19
19
  def grant
20
- AccessGrant.by_token(parameters[:code])
20
+ raise Errors::MissingRequiredParameter, :code if parameters[:code].blank?
21
+
22
+ Doorkeeper.config.access_grant_model.by_token(parameters[:code])
21
23
  end
22
24
  end
23
25
  end
@@ -1,4 +1,4 @@
1
- require 'doorkeeper/request/strategy'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
4
  module Request
@@ -7,9 +7,9 @@ module Doorkeeper
7
7
 
8
8
  def request
9
9
  @request ||= OAuth::ClientCredentialsRequest.new(
10
- Doorkeeper.configuration,
10
+ Doorkeeper.config,
11
11
  client,
12
- parameters
12
+ parameters,
13
13
  )
14
14
  end
15
15
  end
@@ -1,4 +1,4 @@
1
- require 'doorkeeper/request/strategy'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
4
  module Request
@@ -1,4 +1,4 @@
1
- require 'doorkeeper/request/strategy'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
4
  module Request
@@ -7,10 +7,11 @@ module Doorkeeper
7
7
 
8
8
  def request
9
9
  @request ||= OAuth::PasswordAccessTokenRequest.new(
10
- Doorkeeper.configuration,
10
+ Doorkeeper.config,
11
11
  client,
12
+ credentials,
12
13
  resource_owner,
13
- parameters
14
+ parameters,
14
15
  )
15
16
  end
16
17
  end
@@ -1,4 +1,4 @@
1
- require 'doorkeeper/request/strategy'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
4
  module Request
@@ -6,14 +6,15 @@ module Doorkeeper
6
6
  delegate :credentials, :parameters, to: :server
7
7
 
8
8
  def refresh_token
9
- AccessToken.by_refresh_token(parameters[:refresh_token])
9
+ Doorkeeper.config.access_token_model.by_refresh_token(parameters[:refresh_token])
10
10
  end
11
11
 
12
12
  def request
13
13
  @request ||= OAuth::RefreshTokenRequest.new(
14
- Doorkeeper.configuration,
15
- refresh_token, credentials,
16
- parameters
14
+ Doorkeeper.config,
15
+ refresh_token,
16
+ credentials,
17
+ parameters,
17
18
  )
18
19
  end
19
20
  end
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
4
  module Request
3
5
  class Strategy
4
- attr_accessor :server
6
+ attr_reader :server
5
7
 
6
8
  delegate :authorize, to: :request
7
9
 
8
10
  def initialize(server)
9
- self.server = server
11
+ @server = server
10
12
  end
11
13
 
12
14
  def request
@@ -1,4 +1,4 @@
1
- require 'doorkeeper/request/strategy'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
4
  module Request