doorkeeper 4.2.0 → 5.5.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 (271) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1038 -0
  3. data/README.md +110 -348
  4. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  5. data/app/controllers/doorkeeper/application_controller.rb +6 -7
  6. data/app/controllers/doorkeeper/application_metal_controller.rb +7 -11
  7. data/app/controllers/doorkeeper/applications_controller.rb +65 -20
  8. data/app/controllers/doorkeeper/authorizations_controller.rb +97 -17
  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 +112 -35
  12. data/app/helpers/doorkeeper/dashboard_helper.rb +10 -6
  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 +7 -1
  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 +33 -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 +545 -143
  30. data/lib/doorkeeper/engine.rb +11 -5
  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 +100 -21
  40. data/lib/doorkeeper/models/access_token_mixin.rb +379 -75
  41. data/lib/doorkeeper/models/application_mixin.rb +72 -25
  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/orderable.rb +15 -0
  45. data/lib/doorkeeper/models/concerns/ownership.rb +4 -7
  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 +12 -18
  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 +48 -12
  52. data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
  53. data/lib/doorkeeper/oauth/authorization/token.rb +66 -28
  54. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +22 -18
  55. data/lib/doorkeeper/oauth/authorization_code_request.rb +64 -14
  56. data/lib/doorkeeper/oauth/base_request.rb +66 -0
  57. data/lib/doorkeeper/oauth/base_response.rb +31 -0
  58. data/lib/doorkeeper/oauth/client/credentials.rb +23 -10
  59. data/lib/doorkeeper/oauth/client.rb +10 -12
  60. data/lib/doorkeeper/oauth/client_credentials/creator.rb +47 -4
  61. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +16 -9
  62. data/lib/doorkeeper/oauth/client_credentials/validator.rb +56 -0
  63. data/lib/doorkeeper/oauth/client_credentials_request.rb +11 -15
  64. data/lib/doorkeeper/oauth/code_request.rb +8 -12
  65. data/lib/doorkeeper/oauth/code_response.rb +28 -15
  66. data/lib/doorkeeper/oauth/error.rb +5 -3
  67. data/lib/doorkeeper/oauth/error_response.rb +41 -20
  68. data/lib/doorkeeper/oauth/forbidden_token_response.rb +10 -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 +53 -3
  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 +31 -5
  75. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  76. data/lib/doorkeeper/oauth/password_access_token_request.rb +45 -13
  77. data/lib/doorkeeper/oauth/pre_authorization.rb +135 -26
  78. data/lib/doorkeeper/oauth/refresh_token_request.rb +61 -36
  79. data/lib/doorkeeper/oauth/scopes.rb +26 -12
  80. data/lib/doorkeeper/oauth/token.rb +25 -23
  81. data/lib/doorkeeper/oauth/token_introspection.rb +202 -0
  82. data/lib/doorkeeper/oauth/token_request.rb +8 -21
  83. data/lib/doorkeeper/oauth/token_response.rb +14 -10
  84. data/lib/doorkeeper/oauth.rb +13 -0
  85. data/lib/doorkeeper/orm/active_record/access_grant.rb +6 -4
  86. data/lib/doorkeeper/orm/active_record/access_token.rb +5 -25
  87. data/lib/doorkeeper/orm/active_record/application.rb +6 -15
  88. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +68 -0
  89. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +59 -0
  90. data/lib/doorkeeper/orm/active_record/mixins/application.rb +198 -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 +33 -0
  93. data/lib/doorkeeper/orm/active_record.rb +37 -8
  94. data/lib/doorkeeper/rails/helpers.rb +14 -15
  95. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  96. data/lib/doorkeeper/rails/routes/mapper.rb +3 -1
  97. data/lib/doorkeeper/rails/routes/mapping.rb +10 -8
  98. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  99. data/lib/doorkeeper/rails/routes.rb +42 -30
  100. data/lib/doorkeeper/rake/db.rake +40 -0
  101. data/lib/doorkeeper/rake/setup.rake +11 -0
  102. data/lib/doorkeeper/rake.rb +14 -0
  103. data/lib/doorkeeper/request/authorization_code.rb +12 -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 +5 -14
  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 +62 -29
  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 -19
  116. data/lib/doorkeeper/stale_records_cleaner.rb +24 -0
  117. data/lib/doorkeeper/validations.rb +5 -2
  118. data/lib/doorkeeper/version.rb +12 -1
  119. data/lib/doorkeeper.rb +111 -56
  120. data/lib/generators/doorkeeper/application_owner_generator.rb +28 -13
  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 +27 -10
  125. data/lib/generators/doorkeeper/pkce_generator.rb +33 -0
  126. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +31 -19
  127. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  128. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +9 -0
  129. data/lib/generators/doorkeeper/templates/{add_previous_refresh_token_to_access_tokens.rb → add_previous_refresh_token_to_access_tokens.rb.erb} +3 -1
  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 +410 -31
  133. data/lib/generators/doorkeeper/templates/migration.rb.erb +88 -0
  134. data/lib/generators/doorkeeper/views_generator.rb +8 -4
  135. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  136. metadata +132 -286
  137. data/.gitignore +0 -14
  138. data/.hound.yml +0 -13
  139. data/.rspec +0 -1
  140. data/.travis.yml +0 -20
  141. data/CONTRIBUTING.md +0 -47
  142. data/Gemfile +0 -14
  143. data/NEWS.md +0 -593
  144. data/RELEASING.md +0 -17
  145. data/Rakefile +0 -20
  146. data/app/validators/redirect_uri_validator.rb +0 -34
  147. data/doorkeeper.gemspec +0 -28
  148. data/lib/doorkeeper/oauth/client/methods.rb +0 -18
  149. data/lib/doorkeeper/oauth/client_credentials/validation.rb +0 -45
  150. data/lib/doorkeeper/oauth/request_concern.rb +0 -48
  151. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +0 -7
  152. data/lib/generators/doorkeeper/templates/migration.rb +0 -68
  153. data/spec/controllers/application_metal_controller.rb +0 -10
  154. data/spec/controllers/applications_controller_spec.rb +0 -58
  155. data/spec/controllers/authorizations_controller_spec.rb +0 -189
  156. data/spec/controllers/protected_resources_controller_spec.rb +0 -300
  157. data/spec/controllers/token_info_controller_spec.rb +0 -52
  158. data/spec/controllers/tokens_controller_spec.rb +0 -88
  159. data/spec/dummy/Rakefile +0 -7
  160. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  161. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -7
  162. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -12
  163. data/spec/dummy/app/controllers/home_controller.rb +0 -17
  164. data/spec/dummy/app/controllers/metal_controller.rb +0 -11
  165. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -11
  166. data/spec/dummy/app/helpers/application_helper.rb +0 -5
  167. data/spec/dummy/app/models/user.rb +0 -5
  168. data/spec/dummy/app/views/home/index.html.erb +0 -0
  169. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  170. data/spec/dummy/config/application.rb +0 -23
  171. data/spec/dummy/config/boot.rb +0 -9
  172. data/spec/dummy/config/database.yml +0 -15
  173. data/spec/dummy/config/environment.rb +0 -5
  174. data/spec/dummy/config/environments/development.rb +0 -29
  175. data/spec/dummy/config/environments/production.rb +0 -62
  176. data/spec/dummy/config/environments/test.rb +0 -44
  177. data/spec/dummy/config/initializers/active_record_belongs_to_required_by_default.rb +0 -6
  178. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  179. data/spec/dummy/config/initializers/doorkeeper.rb +0 -96
  180. data/spec/dummy/config/initializers/secret_token.rb +0 -9
  181. data/spec/dummy/config/initializers/session_store.rb +0 -8
  182. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  183. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  184. data/spec/dummy/config/routes.rb +0 -52
  185. data/spec/dummy/config.ru +0 -4
  186. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -9
  187. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -5
  188. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -60
  189. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -7
  190. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -11
  191. data/spec/dummy/db/schema.rb +0 -67
  192. data/spec/dummy/public/404.html +0 -26
  193. data/spec/dummy/public/422.html +0 -26
  194. data/spec/dummy/public/500.html +0 -26
  195. data/spec/dummy/public/favicon.ico +0 -0
  196. data/spec/dummy/script/rails +0 -6
  197. data/spec/factories.rb +0 -28
  198. data/spec/generators/application_owner_generator_spec.rb +0 -22
  199. data/spec/generators/install_generator_spec.rb +0 -31
  200. data/spec/generators/migration_generator_spec.rb +0 -20
  201. data/spec/generators/templates/routes.rb +0 -3
  202. data/spec/generators/views_generator_spec.rb +0 -27
  203. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -24
  204. data/spec/lib/config_spec.rb +0 -334
  205. data/spec/lib/doorkeeper_spec.rb +0 -28
  206. data/spec/lib/models/expirable_spec.rb +0 -51
  207. data/spec/lib/models/revocable_spec.rb +0 -59
  208. data/spec/lib/models/scopes_spec.rb +0 -43
  209. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -42
  210. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -80
  211. data/spec/lib/oauth/client/credentials_spec.rb +0 -47
  212. data/spec/lib/oauth/client/methods_spec.rb +0 -54
  213. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -44
  214. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -86
  215. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -54
  216. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  217. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -104
  218. data/spec/lib/oauth/client_spec.rb +0 -39
  219. data/spec/lib/oauth/code_request_spec.rb +0 -45
  220. data/spec/lib/oauth/code_response_spec.rb +0 -34
  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 -154
  231. data/spec/lib/oauth/scopes_spec.rb +0 -122
  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 -116
  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 -394
  239. data/spec/models/doorkeeper/application_spec.rb +0 -179
  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 -115
  250. data/spec/requests/flows/refresh_token_spec.rb +0 -174
  251. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  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 -59
  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 -67
  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/http_method_shim.rb +0 -24
  268. data/spec/support/orm/active_record.rb +0 -3
  269. data/spec/support/shared/controllers_shared_context.rb +0 -69
  270. data/spec/support/shared/models_shared_examples.rb +0 -52
  271. data/spec/validators/redirect_uri_validator_spec.rb +0 -78
@@ -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,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :doorkeeper do
4
+ task setup: :environment do
5
+ # Dirty hack to manually initialize AR because of lazy auto-loading,
6
+ # in other case we'll see NameError: uninitialized constant Doorkeeper::AccessToken
7
+ if Doorkeeper.config.orm == :active_record && defined?(::ActiveRecord::Base)
8
+ Object.const_get("::ActiveRecord::Base")
9
+ end
10
+ end
11
+ 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,28 +1,19 @@
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
11
  client,
12
+ credentials,
12
13
  resource_owner,
13
- parameters
14
+ parameters,
14
15
  )
15
16
  end
16
-
17
- private
18
-
19
- def client
20
- if credentials
21
- server.client
22
- elsif parameters[:client_id]
23
- server.client_via_uid
24
- end
25
- end
26
17
  end
27
18
  end
28
19
  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
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ class StaleRecordsCleaner
5
+ CLEANER_CLASS = "StaleRecordsCleaner"
6
+
7
+ def self.for(base_scope)
8
+ orm_adapter = "doorkeeper/orm/#{configured_orm}".classify
9
+
10
+ orm_cleaner = "#{orm_adapter}::#{CLEANER_CLASS}".constantize
11
+ orm_cleaner.new(base_scope)
12
+ rescue NameError
13
+ raise Doorkeeper::Errors::NoOrmCleaner, "'#{configured_orm}' ORM has no cleaner!"
14
+ end
15
+
16
+ def self.new(base_scope)
17
+ self.for(base_scope)
18
+ end
19
+
20
+ def self.configured_orm
21
+ Doorkeeper.config.orm
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
4
  module Validations
3
5
  extend ActiveSupport::Concern
@@ -6,9 +8,10 @@ module Doorkeeper
6
8
 
7
9
  def validate
8
10
  @error = nil
11
+
9
12
  self.class.validations.each do |validation|
13
+ @error = validation[:options][:error] unless send("validate_#{validation[:attribute]}")
10
14
  break if @error
11
- @error = validation.last unless send("validate_#{validation.first}")
12
15
  end
13
16
  end
14
17
 
@@ -19,7 +22,7 @@ module Doorkeeper
19
22
 
20
23
  module ClassMethods
21
24
  def validate(attribute, options = {})
22
- validations << [attribute, options[:error]]
25
+ validations << { attribute: attribute, options: options }
23
26
  end
24
27
 
25
28
  def validations
@@ -1,3 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
- VERSION = "4.2.0".freeze
4
+ module VERSION
5
+ # Semantic versioning
6
+ MAJOR = 5
7
+ MINOR = 5
8
+ TINY = 2
9
+ PRE = nil
10
+
11
+ # Full version number
12
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
13
+ end
3
14
  end