doorkeeper 3.1.0 → 5.6.2

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 (270) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1079 -0
  3. data/README.md +114 -326
  4. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  5. data/app/controllers/doorkeeper/application_controller.rb +7 -6
  6. data/app/controllers/doorkeeper/application_metal_controller.rb +9 -12
  7. data/app/controllers/doorkeeper/applications_controller.rb +66 -21
  8. data/app/controllers/doorkeeper/authorizations_controller.rb +100 -18
  9. data/app/controllers/doorkeeper/authorized_applications_controller.rb +23 -4
  10. data/app/controllers/doorkeeper/token_info_controller.rb +16 -4
  11. data/app/controllers/doorkeeper/tokens_controller.rb +138 -22
  12. data/app/helpers/doorkeeper/dashboard_helper.rb +15 -9
  13. data/app/views/doorkeeper/applications/_delete_form.html.erb +4 -3
  14. data/app/views/doorkeeper/applications/_form.html.erb +33 -21
  15. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  16. data/app/views/doorkeeper/applications/index.html.erb +18 -6
  17. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  18. data/app/views/doorkeeper/applications/show.html.erb +40 -16
  19. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  20. data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
  21. data/app/views/doorkeeper/authorizations/new.html.erb +17 -11
  22. data/app/views/doorkeeper/authorized_applications/_delete_form.html.erb +1 -2
  23. data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
  24. data/app/views/layouts/doorkeeper/admin.html.erb +16 -14
  25. data/config/locales/en.yml +37 -9
  26. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  27. data/lib/doorkeeper/config/option.rb +82 -0
  28. data/lib/doorkeeper/config/validations.rb +53 -0
  29. data/lib/doorkeeper/config.rb +602 -142
  30. data/lib/doorkeeper/engine.rb +22 -7
  31. data/lib/doorkeeper/errors.rb +37 -10
  32. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  33. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  34. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  35. data/lib/doorkeeper/grant_flow.rb +45 -0
  36. data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
  37. data/lib/doorkeeper/grape/helpers.rb +24 -12
  38. data/lib/doorkeeper/helpers/controller.rb +49 -27
  39. data/lib/doorkeeper/models/access_grant_mixin.rb +99 -16
  40. data/lib/doorkeeper/models/access_token_mixin.rb +386 -77
  41. data/lib/doorkeeper/models/application_mixin.rb +73 -30
  42. data/lib/doorkeeper/models/concerns/accessible.rb +6 -0
  43. data/lib/doorkeeper/models/concerns/expirable.rb +20 -6
  44. data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
  45. data/lib/doorkeeper/models/concerns/orderable.rb +15 -0
  46. data/lib/doorkeeper/models/concerns/ownership.rb +4 -2
  47. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  48. data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
  49. data/lib/doorkeeper/models/concerns/revocable.rb +13 -2
  50. data/lib/doorkeeper/models/concerns/scopes.rb +12 -2
  51. data/lib/doorkeeper/models/concerns/secret_storable.rb +106 -0
  52. data/lib/doorkeeper/oauth/authorization/code.rb +48 -12
  53. data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
  54. data/lib/doorkeeper/oauth/authorization/token.rb +72 -28
  55. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +22 -18
  56. data/lib/doorkeeper/oauth/authorization_code_request.rb +64 -14
  57. data/lib/doorkeeper/oauth/base_request.rb +66 -0
  58. data/lib/doorkeeper/oauth/base_response.rb +31 -0
  59. data/lib/doorkeeper/oauth/client/credentials.rb +23 -10
  60. data/lib/doorkeeper/oauth/client.rb +10 -12
  61. data/lib/doorkeeper/oauth/client_credentials/creator.rb +48 -4
  62. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +17 -9
  63. data/lib/doorkeeper/oauth/client_credentials/validator.rb +55 -0
  64. data/lib/doorkeeper/oauth/client_credentials_request.rb +14 -15
  65. data/lib/doorkeeper/oauth/code_request.rb +8 -12
  66. data/lib/doorkeeper/oauth/code_response.rb +31 -19
  67. data/lib/doorkeeper/oauth/error.rb +5 -3
  68. data/lib/doorkeeper/oauth/error_response.rb +41 -20
  69. data/lib/doorkeeper/oauth/forbidden_token_response.rb +11 -3
  70. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +24 -19
  71. data/lib/doorkeeper/oauth/helpers/unique_token.rb +20 -3
  72. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +55 -4
  73. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  74. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  75. data/lib/doorkeeper/oauth/invalid_token_response.rb +31 -5
  76. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  77. data/lib/doorkeeper/oauth/password_access_token_request.rb +46 -18
  78. data/lib/doorkeeper/oauth/pre_authorization.rb +135 -26
  79. data/lib/doorkeeper/oauth/refresh_token_request.rb +67 -30
  80. data/lib/doorkeeper/oauth/scopes.rb +26 -12
  81. data/lib/doorkeeper/oauth/token.rb +28 -25
  82. data/lib/doorkeeper/oauth/token_introspection.rb +202 -0
  83. data/lib/doorkeeper/oauth/token_request.rb +8 -21
  84. data/lib/doorkeeper/oauth/token_response.rb +14 -10
  85. data/lib/doorkeeper/oauth.rb +13 -0
  86. data/lib/doorkeeper/orm/active_record/access_grant.rb +6 -4
  87. data/lib/doorkeeper/orm/active_record/access_token.rb +5 -17
  88. data/lib/doorkeeper/orm/active_record/application.rb +6 -20
  89. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +69 -0
  90. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +81 -0
  91. data/lib/doorkeeper/orm/active_record/mixins/application.rb +214 -0
  92. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
  93. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +33 -0
  94. data/lib/doorkeeper/orm/active_record.rb +36 -26
  95. data/lib/doorkeeper/rails/helpers.rb +14 -15
  96. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  97. data/lib/doorkeeper/rails/routes/mapper.rb +4 -2
  98. data/lib/doorkeeper/rails/routes/mapping.rb +10 -8
  99. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  100. data/lib/doorkeeper/rails/routes.rb +45 -28
  101. data/lib/doorkeeper/rake/db.rake +40 -0
  102. data/lib/doorkeeper/rake/setup.rake +6 -0
  103. data/lib/doorkeeper/rake.rb +14 -0
  104. data/lib/doorkeeper/request/authorization_code.rb +12 -4
  105. data/lib/doorkeeper/request/client_credentials.rb +3 -3
  106. data/lib/doorkeeper/request/code.rb +1 -1
  107. data/lib/doorkeeper/request/password.rb +5 -4
  108. data/lib/doorkeeper/request/refresh_token.rb +6 -5
  109. data/lib/doorkeeper/request/strategy.rb +4 -2
  110. data/lib/doorkeeper/request/token.rb +1 -1
  111. data/lib/doorkeeper/request.rb +62 -29
  112. data/lib/doorkeeper/secret_storing/base.rb +64 -0
  113. data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
  114. data/lib/doorkeeper/secret_storing/plain.rb +33 -0
  115. data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
  116. data/lib/doorkeeper/server.rb +9 -19
  117. data/lib/doorkeeper/stale_records_cleaner.rb +24 -0
  118. data/lib/doorkeeper/validations.rb +5 -2
  119. data/lib/doorkeeper/version.rb +12 -1
  120. data/lib/doorkeeper.rb +112 -56
  121. data/lib/generators/doorkeeper/application_owner_generator.rb +28 -13
  122. data/lib/generators/doorkeeper/confidential_applications_generator.rb +33 -0
  123. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  124. data/lib/generators/doorkeeper/install_generator.rb +19 -9
  125. data/lib/generators/doorkeeper/migration_generator.rb +27 -10
  126. data/lib/generators/doorkeeper/pkce_generator.rb +33 -0
  127. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +41 -0
  128. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  129. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +9 -0
  130. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +13 -0
  131. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +8 -0
  132. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  133. data/lib/generators/doorkeeper/templates/initializer.rb +417 -32
  134. data/lib/generators/doorkeeper/templates/migration.rb.erb +88 -0
  135. data/lib/generators/doorkeeper/views_generator.rb +8 -4
  136. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  137. metadata +163 -280
  138. data/.gitignore +0 -14
  139. data/.hound.yml +0 -13
  140. data/.rspec +0 -1
  141. data/.travis.yml +0 -22
  142. data/CONTRIBUTING.md +0 -45
  143. data/Gemfile +0 -10
  144. data/NEWS.md +0 -525
  145. data/RELEASING.md +0 -17
  146. data/Rakefile +0 -20
  147. data/app/validators/redirect_uri_validator.rb +0 -34
  148. data/doorkeeper.gemspec +0 -27
  149. data/lib/doorkeeper/oauth/client/methods.rb +0 -18
  150. data/lib/doorkeeper/oauth/client_credentials/validation.rb +0 -45
  151. data/lib/doorkeeper/oauth/request_concern.rb +0 -48
  152. data/lib/generators/doorkeeper/application_scopes_generator.rb +0 -34
  153. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +0 -7
  154. data/lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb +0 -5
  155. data/lib/generators/doorkeeper/templates/migration.rb +0 -50
  156. data/spec/controllers/applications_controller_spec.rb +0 -58
  157. data/spec/controllers/authorizations_controller_spec.rb +0 -203
  158. data/spec/controllers/protected_resources_controller_spec.rb +0 -271
  159. data/spec/controllers/token_info_controller_spec.rb +0 -52
  160. data/spec/controllers/tokens_controller_spec.rb +0 -88
  161. data/spec/dummy/Rakefile +0 -7
  162. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  163. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -7
  164. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -12
  165. data/spec/dummy/app/controllers/home_controller.rb +0 -17
  166. data/spec/dummy/app/controllers/metal_controller.rb +0 -11
  167. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -11
  168. data/spec/dummy/app/helpers/application_helper.rb +0 -5
  169. data/spec/dummy/app/models/user.rb +0 -9
  170. data/spec/dummy/app/views/home/index.html.erb +0 -0
  171. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  172. data/spec/dummy/config/application.rb +0 -57
  173. data/spec/dummy/config/boot.rb +0 -9
  174. data/spec/dummy/config/database.yml +0 -15
  175. data/spec/dummy/config/environment.rb +0 -5
  176. data/spec/dummy/config/environments/development.rb +0 -29
  177. data/spec/dummy/config/environments/production.rb +0 -62
  178. data/spec/dummy/config/environments/test.rb +0 -55
  179. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  180. data/spec/dummy/config/initializers/doorkeeper.rb +0 -96
  181. data/spec/dummy/config/initializers/secret_token.rb +0 -9
  182. data/spec/dummy/config/initializers/session_store.rb +0 -8
  183. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  184. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  185. data/spec/dummy/config/routes.rb +0 -52
  186. data/spec/dummy/config.ru +0 -4
  187. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -9
  188. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -5
  189. data/spec/dummy/db/migrate/20130902165751_create_doorkeeper_tables.rb +0 -41
  190. data/spec/dummy/db/migrate/20130902175349_add_owner_to_application.rb +0 -7
  191. data/spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb +0 -5
  192. data/spec/dummy/db/schema.rb +0 -66
  193. data/spec/dummy/public/404.html +0 -26
  194. data/spec/dummy/public/422.html +0 -26
  195. data/spec/dummy/public/500.html +0 -26
  196. data/spec/dummy/public/favicon.ico +0 -0
  197. data/spec/dummy/script/rails +0 -6
  198. data/spec/factories.rb +0 -26
  199. data/spec/generators/application_owner_generator_spec.rb +0 -22
  200. data/spec/generators/install_generator_spec.rb +0 -31
  201. data/spec/generators/migration_generator_spec.rb +0 -20
  202. data/spec/generators/templates/routes.rb +0 -3
  203. data/spec/generators/views_generator_spec.rb +0 -27
  204. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -24
  205. data/spec/lib/config_spec.rb +0 -317
  206. data/spec/lib/doorkeeper_spec.rb +0 -28
  207. data/spec/lib/models/expirable_spec.rb +0 -51
  208. data/spec/lib/models/revocable_spec.rb +0 -36
  209. data/spec/lib/models/scopes_spec.rb +0 -43
  210. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -42
  211. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -80
  212. data/spec/lib/oauth/client/credentials_spec.rb +0 -47
  213. data/spec/lib/oauth/client/methods_spec.rb +0 -54
  214. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -44
  215. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -86
  216. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -54
  217. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  218. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -104
  219. data/spec/lib/oauth/client_spec.rb +0 -39
  220. data/spec/lib/oauth/code_request_spec.rb +0 -45
  221. data/spec/lib/oauth/error_response_spec.rb +0 -61
  222. data/spec/lib/oauth/error_spec.rb +0 -23
  223. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -23
  224. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -64
  225. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -20
  226. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -104
  227. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -28
  228. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -90
  229. data/spec/lib/oauth/pre_authorization_spec.rb +0 -155
  230. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -123
  231. data/spec/lib/oauth/scopes_spec.rb +0 -123
  232. data/spec/lib/oauth/token_request_spec.rb +0 -98
  233. data/spec/lib/oauth/token_response_spec.rb +0 -85
  234. data/spec/lib/oauth/token_spec.rb +0 -109
  235. data/spec/lib/request/strategy_spec.rb +0 -53
  236. data/spec/lib/server_spec.rb +0 -52
  237. data/spec/models/doorkeeper/access_grant_spec.rb +0 -36
  238. data/spec/models/doorkeeper/access_token_spec.rb +0 -350
  239. data/spec/models/doorkeeper/application_spec.rb +0 -187
  240. data/spec/requests/applications/applications_request_spec.rb +0 -94
  241. data/spec/requests/applications/authorized_applications_spec.rb +0 -30
  242. data/spec/requests/endpoints/authorization_spec.rb +0 -72
  243. data/spec/requests/endpoints/token_spec.rb +0 -64
  244. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -66
  245. data/spec/requests/flows/authorization_code_spec.rb +0 -156
  246. data/spec/requests/flows/client_credentials_spec.rb +0 -58
  247. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -32
  248. data/spec/requests/flows/implicit_grant_spec.rb +0 -61
  249. data/spec/requests/flows/password_spec.rb +0 -94
  250. data/spec/requests/flows/refresh_token_spec.rb +0 -104
  251. data/spec/requests/flows/revoke_token_spec.rb +0 -143
  252. data/spec/requests/flows/skip_authorization_spec.rb +0 -59
  253. data/spec/requests/protected_resources/metal_spec.rb +0 -14
  254. data/spec/requests/protected_resources/private_api_spec.rb +0 -81
  255. data/spec/routing/custom_controller_routes_spec.rb +0 -71
  256. data/spec/routing/default_routes_spec.rb +0 -35
  257. data/spec/routing/scoped_routes_spec.rb +0 -31
  258. data/spec/spec_helper.rb +0 -2
  259. data/spec/spec_helper_integration.rb +0 -56
  260. data/spec/support/dependencies/factory_girl.rb +0 -2
  261. data/spec/support/helpers/access_token_request_helper.rb +0 -11
  262. data/spec/support/helpers/authorization_request_helper.rb +0 -41
  263. data/spec/support/helpers/config_helper.rb +0 -9
  264. data/spec/support/helpers/model_helper.rb +0 -45
  265. data/spec/support/helpers/request_spec_helper.rb +0 -76
  266. data/spec/support/helpers/url_helper.rb +0 -55
  267. data/spec/support/orm/active_record.rb +0 -3
  268. data/spec/support/shared/controllers_shared_context.rb +0 -60
  269. data/spec/support/shared/models_shared_examples.rb +0 -52
  270. data/spec/validators/redirect_uri_validator_spec.rb +0 -78
@@ -1,32 +1,42 @@
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
6
- class Routes
10
+ class Routes # :nodoc:
7
11
  module Helper
8
- # TODO: options hash is not being used
9
12
  def use_doorkeeper(options = {}, &block)
10
13
  Doorkeeper::Rails::Routes.new(self, &block).generate_routes!(options)
11
14
  end
12
15
  end
13
16
 
14
- def self.install!
15
- ActionDispatch::Routing::Mapper.send :include, Doorkeeper::Rails::Routes::Helper
17
+ include AbstractRouter
18
+ extend Registry
19
+
20
+ mattr_reader :mapping do
21
+ {}
16
22
  end
17
23
 
18
- attr_accessor :routes
24
+ def self.install!
25
+ ActionDispatch::Routing::Mapper.include Doorkeeper::Rails::Routes::Helper
19
26
 
20
- def initialize(routes, &block)
21
- @routes, @block = routes, block
27
+ registered_routes.each(&:install!)
28
+ end
29
+
30
+ def initialize(routes, mapper = Mapper.new, &block)
31
+ super
22
32
  end
23
33
 
24
34
  def generate_routes!(options)
25
- @mapping = Mapper.new.map(&@block)
26
- routes.scope options[:scope] || 'oauth', as: 'oauth' do
35
+ routes.scope options[:scope] || "oauth", as: "oauth" do
27
36
  map_route(:authorizations, :authorization_routes)
28
37
  map_route(:tokens, :token_routes)
29
38
  map_route(:tokens, :revoke_routes)
39
+ map_route(:tokens, :introspect_routes) unless Doorkeeper.config.allow_token_introspection.is_a?(FalseClass)
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,21 +45,15 @@ module Doorkeeper
35
45
 
36
46
  private
37
47
 
38
- def map_route(name, method)
39
- unless @mapping.skipped?(name)
40
- send method, @mapping[name]
41
- end
42
- end
43
-
44
48
  def authorization_routes(mapping)
45
49
  routes.resource(
46
50
  :authorization,
47
- path: 'authorize',
48
- only: [:create, :destroy],
51
+ path: "authorize",
52
+ only: %i[create destroy],
49
53
  as: mapping[:as],
50
- controller: mapping[:controllers]
54
+ controller: mapping[:controllers],
51
55
  ) do
52
- routes.get '/:code', action: :show, on: :member
56
+ routes.get native_authorization_code_route, action: :show, on: :member
53
57
  routes.get '/', action: :new, on: :member
54
58
  end
55
59
  end
@@ -57,31 +61,44 @@ module Doorkeeper
57
61
  def token_routes(mapping)
58
62
  routes.resource(
59
63
  :token,
60
- path: 'token',
64
+ path: "token",
61
65
  only: [:create], as: mapping[:as],
62
- controller: mapping[:controllers]
66
+ controller: mapping[:controllers],
63
67
  )
64
68
  end
65
69
 
66
70
  def revoke_routes(mapping)
67
- routes.post 'revoke', controller: mapping[:controllers], action: :revoke
71
+ routes.post "revoke", controller: mapping[:controllers], action: :revoke
72
+ end
73
+
74
+ def introspect_routes(mapping)
75
+ routes.post "introspect", controller: mapping[:controllers], action: :introspect
68
76
  end
69
77
 
70
78
  def token_info_routes(mapping)
71
79
  routes.resource(
72
80
  :token_info,
73
- path: 'token/info',
81
+ path: "token/info",
74
82
  only: [:show], as: mapping[:as],
75
- controller: mapping[:controllers]
83
+ controller: mapping[:controllers],
76
84
  )
77
85
  end
78
86
 
79
87
  def application_routes(mapping)
80
- 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"
81
92
  end
82
93
 
83
94
  def authorized_applications_routes(mapping)
84
- routes.resources :authorized_applications, only: [: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
85
102
  end
86
103
  end
87
104
  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,18 +1,26 @@
1
- require 'doorkeeper/request/strategy'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
4
  module Request
5
5
  class AuthorizationCode < Strategy
6
- delegate :grant, :client, :parameters, to: :server
6
+ delegate :client, :parameters, to: :server
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
+
17
+ private
18
+
19
+ def grant
20
+ raise Errors::MissingRequiredParameter, :code if parameters[:code].blank?
21
+
22
+ Doorkeeper.config.access_grant_model.by_token(parameters[:code])
23
+ end
16
24
  end
17
25
  end
18
26
  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,16 +1,17 @@
1
- require 'doorkeeper/request/strategy'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
4
  module Request
5
5
  class Password < Strategy
6
- delegate :credentials, :resource_owner, :parameters, to: :server
6
+ delegate :credentials, :resource_owner, :parameters, :client, to: :server
7
7
 
8
8
  def request
9
9
  @request ||= OAuth::PasswordAccessTokenRequest.new(
10
- Doorkeeper.configuration,
10
+ Doorkeeper.config,
11
+ client,
11
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
- server.current_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
@@ -1,40 +1,73 @@
1
- require 'doorkeeper/request/authorization_code'
2
- require 'doorkeeper/request/client_credentials'
3
- require 'doorkeeper/request/code'
4
- require 'doorkeeper/request/password'
5
- require 'doorkeeper/request/refresh_token'
6
- require 'doorkeeper/request/token'
1
+ # frozen_string_literal: true
7
2
 
8
3
  module Doorkeeper
9
4
  module Request
10
- module_function
5
+ class << self
6
+ def authorization_strategy(response_type)
7
+ grant_flow = authorization_flows.detect do |flow|
8
+ flow.matches_response_type?(response_type)
9
+ end
11
10
 
12
- def authorization_strategy(response_type)
13
- get_strategy response_type, authorization_response_types
14
- rescue NameError
15
- raise Errors::InvalidAuthorizationStrategy
16
- end
11
+ if grant_flow
12
+ grant_flow.response_type_strategy
13
+ else
14
+ # [NOTE]: this will be removed in a newer versions of Doorkeeper.
15
+ # For retro-compatibility only
16
+ build_fallback_strategy_class(response_type)
17
+ end
18
+ end
17
19
 
18
- def token_strategy(grant_type)
19
- get_strategy grant_type, token_grant_types
20
- rescue NameError
21
- raise Errors::InvalidTokenStrategy
22
- end
20
+ def token_strategy(grant_type)
21
+ raise Errors::MissingRequiredParameter, :grant_type if grant_type.blank?
23
22
 
24
- def get_strategy(grant_or_request_type, available)
25
- fail Errors::MissingRequestStrategy unless grant_or_request_type.present?
26
- fail NameError unless available.include?(grant_or_request_type.to_s)
27
- "Doorkeeper::Request::#{grant_or_request_type.to_s.camelize}".constantize
28
- end
23
+ grant_flow = token_flows.detect do |flow|
24
+ flow.matches_grant_type?(grant_type)
25
+ end
29
26
 
30
- def authorization_response_types
31
- Doorkeeper.configuration.authorization_response_types
32
- end
33
- private_class_method :authorization_response_types
27
+ if grant_flow
28
+ grant_flow.grant_type_strategy
29
+ else
30
+ # [NOTE]: this will be removed in a newer versions of Doorkeeper.
31
+ # For retro-compatibility only
32
+ raise Errors::InvalidTokenStrategy unless available.include?(grant_type.to_s)
33
+
34
+ strategy_class = build_fallback_strategy_class(grant_type)
35
+ raise Errors::InvalidTokenStrategy unless strategy_class
36
+
37
+ strategy_class
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def authorization_flows
44
+ Doorkeeper.configuration.authorization_response_flows
45
+ end
46
+
47
+ def token_flows
48
+ Doorkeeper.configuration.token_grant_flows
49
+ end
50
+
51
+ # [NOTE]: this will be removed in a newer versions of Doorkeeper.
52
+ # For retro-compatibility only
53
+ def available
54
+ Doorkeeper.config.deprecated_token_grant_types_resolver
55
+ end
56
+
57
+ def build_fallback_strategy_class(grant_or_request_type)
58
+ strategy_class_name = grant_or_request_type.to_s.tr(" ", "_").camelize
59
+ fallback_strategy = "Doorkeeper::Request::#{strategy_class_name}".constantize
60
+
61
+ ::Kernel.warn <<~WARNING
62
+ [DOORKEEPER] #{fallback_strategy} found using fallback, it must be
63
+ registered using `Doorkeeper::GrantFlow.register(grant_flow_name, **options)`.
64
+ This functionality will be removed in a newer versions of Doorkeeper.
65
+ WARNING
34
66
 
35
- def token_grant_types
36
- Doorkeeper.configuration.token_grant_types
67
+ fallback_strategy
68
+ rescue NameError
69
+ raise Errors::InvalidTokenStrategy
70
+ end
37
71
  end
38
- private_class_method :token_grant_types
39
72
  end
40
73
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module SecretStoring
5
+ ##
6
+ # Base class for secret storing, including common helpers
7
+ class Base
8
+ ##
9
+ # Return the value to be stored by the database
10
+ # used for looking up a database value.
11
+ # @param plain_secret The plain secret input / generated
12
+ def self.transform_secret(_plain_secret)
13
+ raise NotImplementedError
14
+ end
15
+
16
+ ##
17
+ # Transform and store the given secret attribute => value
18
+ # pair used for safely storing the attribute
19
+ # @param resource The model instance being modified
20
+ # @param attribute The secret attribute
21
+ # @param plain_secret The plain secret input / generated
22
+ def self.store_secret(resource, attribute, plain_secret)
23
+ transformed_value = transform_secret(plain_secret)
24
+ resource.public_send(:"#{attribute}=", transformed_value)
25
+
26
+ transformed_value
27
+ end
28
+
29
+ ##
30
+ # Return the restored value from the database
31
+ # @param resource The resource instance to act on
32
+ # @param attribute The secret attribute to restore
33
+ # as retrieved from the database.
34
+ def self.restore_secret(_resource, _attribute)
35
+ raise NotImplementedError
36
+ end
37
+
38
+ ##
39
+ # Determines whether this strategy supports restoring
40
+ # secrets from the database. This allows detecting users
41
+ # trying to use a non-restorable strategy with +reuse_access_tokens+.
42
+ def self.allows_restoring_secrets?
43
+ false
44
+ end
45
+
46
+ ##
47
+ # Determines what secrets this strategy is applicable for
48
+ def self.validate_for(model)
49
+ valid = %i[token application]
50
+ return true if valid.include?(model.to_sym)
51
+
52
+ raise ArgumentError, "'#{name}' can not be used for #{model}."
53
+ end
54
+
55
+ ##
56
+ # Securely compare the given +input+ value with a +stored+ value
57
+ # processed by +transform_secret+.
58
+ def self.secret_matches?(input, stored)
59
+ transformed_input = transform_secret(input)
60
+ ActiveSupport::SecurityUtils.secure_compare transformed_input, stored
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module SecretStoring
5
+ ##
6
+ # Plain text secret storing, which is the default
7
+ # but also provides fallback lookup if
8
+ # other secret storing mechanisms are enabled.
9
+ class BCrypt < Base
10
+ ##
11
+ # Return the value to be stored by the database
12
+ # @param plain_secret The plain secret input / generated
13
+ def self.transform_secret(plain_secret)
14
+ ::BCrypt::Password.create(plain_secret.to_s)
15
+ end
16
+
17
+ ##
18
+ # Securely compare the given +input+ value with a +stored+ value
19
+ # processed by +transform_secret+.
20
+ def self.secret_matches?(input, stored)
21
+ ::BCrypt::Password.new(stored.to_s) == input.to_s
22
+ rescue ::BCrypt::Errors::InvalidHash
23
+ false
24
+ end
25
+
26
+ ##
27
+ # Determines whether this strategy supports restoring
28
+ # secrets from the database. This allows detecting users
29
+ # trying to use a non-restorable strategy with +reuse_access_tokens+.
30
+ def self.allows_restoring_secrets?
31
+ false
32
+ end
33
+
34
+ ##
35
+ # Determines what secrets this strategy is applicable for
36
+ def self.validate_for(model)
37
+ unless model.to_sym == :application
38
+ raise ArgumentError,
39
+ "'#{name}' can only be used for storing application secrets."
40
+ end
41
+
42
+ unless bcrypt_present?
43
+ raise ArgumentError,
44
+ "'#{name}' requires the 'bcrypt' gem being loaded."
45
+ end
46
+
47
+ true
48
+ end
49
+
50
+ ##
51
+ # Test if we can require the BCrypt gem
52
+ def self.bcrypt_present?
53
+ require "bcrypt"
54
+ true
55
+ rescue LoadError
56
+ false
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module SecretStoring
5
+ ##
6
+ # Plain text secret storing, which is the default
7
+ # but also provides fallback lookup if
8
+ # other secret storing mechanisms are enabled.
9
+ class Plain < Base
10
+ ##
11
+ # Return the value to be stored by the database
12
+ # @param plain_secret The plain secret input / generated
13
+ def self.transform_secret(plain_secret)
14
+ plain_secret
15
+ end
16
+
17
+ ##
18
+ # Return the restored value from the database
19
+ # @param resource The resource instance to act on
20
+ # @param attribute The secret attribute to restore
21
+ # as retrieved from the database.
22
+ def self.restore_secret(resource, attribute)
23
+ resource.public_send(attribute)
24
+ end
25
+
26
+ ##
27
+ # Plain values obviously allow restoring
28
+ def self.allows_restoring_secrets?
29
+ true
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module SecretStoring
5
+ ##
6
+ # Plain text secret storing, which is the default
7
+ # but also provides fallback lookup if
8
+ # other secret storing mechanisms are enabled.
9
+ class Sha256Hash < Base
10
+ ##
11
+ # Return the value to be stored by the database
12
+ # @param plain_secret The plain secret input / generated
13
+ def self.transform_secret(plain_secret)
14
+ ::Digest::SHA256.hexdigest plain_secret
15
+ end
16
+
17
+ ##
18
+ # Determines whether this strategy supports restoring
19
+ # secrets from the database. This allows detecting users
20
+ # trying to use a non-restorable strategy with +reuse_access_tokens+.
21
+ def self.allows_restoring_secrets?
22
+ false
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,19 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
4
  class Server
3
- attr_accessor :context
5
+ attr_reader :context
4
6
 
5
- def initialize(context = nil)
7
+ def initialize(context)
6
8
  @context = context
7
9
  end
8
10
 
9
11
  def authorization_request(strategy)
10
- klass = Request.authorization_strategy strategy
11
- klass.new self
12
+ klass = Request.authorization_strategy(strategy)
13
+ klass.new(self)
12
14
  end
13
15
 
14
16
  def token_request(strategy)
15
- klass = Request.token_strategy strategy
16
- klass.new self
17
+ klass = Request.token_strategy(strategy)
18
+ klass.new(self)
17
19
  end
18
20
 
19
21
  # TODO: context should be the request
@@ -25,29 +27,17 @@ module Doorkeeper
25
27
  @client ||= OAuth::Client.authenticate(credentials)
26
28
  end
27
29
 
28
- def client_via_uid
29
- @client_via_uid ||= OAuth::Client.find(parameters[:client_id])
30
- end
31
-
32
30
  def current_resource_owner
33
31
  context.send :current_resource_owner
34
32
  end
35
33
 
36
- def current_refresh_token
37
- AccessToken.by_refresh_token(parameters[:refresh_token])
38
- end
39
-
40
- def grant
41
- AccessGrant.by_token(parameters[:code])
42
- end
43
-
44
34
  # TODO: Use configuration and evaluate proper context on block
45
35
  def resource_owner
46
36
  context.send :resource_owner_from_credentials
47
37
  end
48
38
 
49
39
  def credentials
50
- methods = Doorkeeper.configuration.client_credentials_methods
40
+ methods = Doorkeeper.config.client_credentials_methods
51
41
  @credentials ||= OAuth::Client::Credentials.from_request(context.request, *methods)
52
42
  end
53
43
  end