doorkeeper 4.2.6 → 5.5.4

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 (274) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1049 -0
  3. data/README.md +110 -353
  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 -16
  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 +115 -38
  12. data/app/helpers/doorkeeper/dashboard_helper.rb +10 -6
  13. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  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 +6 -0
  22. data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
  23. data/app/views/layouts/doorkeeper/admin.html.erb +16 -14
  24. data/config/locales/en.yml +34 -7
  25. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  26. data/lib/doorkeeper/config/option.rb +82 -0
  27. data/lib/doorkeeper/config/validations.rb +53 -0
  28. data/lib/doorkeeper/config.rb +514 -167
  29. data/lib/doorkeeper/engine.rb +11 -5
  30. data/lib/doorkeeper/errors.rb +25 -16
  31. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  32. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  33. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  34. data/lib/doorkeeper/grant_flow.rb +45 -0
  35. data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
  36. data/lib/doorkeeper/grape/helpers.rb +23 -12
  37. data/lib/doorkeeper/helpers/controller.rb +51 -14
  38. data/lib/doorkeeper/models/access_grant_mixin.rb +94 -27
  39. data/lib/doorkeeper/models/access_token_mixin.rb +284 -96
  40. data/lib/doorkeeper/models/application_mixin.rb +58 -27
  41. data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
  42. data/lib/doorkeeper/models/concerns/expirable.rb +12 -6
  43. data/lib/doorkeeper/models/concerns/orderable.rb +15 -0
  44. data/lib/doorkeeper/models/concerns/ownership.rb +4 -7
  45. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  46. data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
  47. data/lib/doorkeeper/models/concerns/revocable.rb +3 -27
  48. data/lib/doorkeeper/models/concerns/scopes.rb +12 -2
  49. data/lib/doorkeeper/models/concerns/secret_storable.rb +106 -0
  50. data/lib/doorkeeper/oauth/authorization/code.rb +48 -12
  51. data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
  52. data/lib/doorkeeper/oauth/authorization/token.rb +66 -28
  53. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +7 -5
  54. data/lib/doorkeeper/oauth/authorization_code_request.rb +63 -10
  55. data/lib/doorkeeper/oauth/base_request.rb +35 -19
  56. data/lib/doorkeeper/oauth/base_response.rb +2 -0
  57. data/lib/doorkeeper/oauth/client/credentials.rb +9 -7
  58. data/lib/doorkeeper/oauth/client.rb +10 -11
  59. data/lib/doorkeeper/oauth/client_credentials/creator.rb +47 -4
  60. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +16 -9
  61. data/lib/doorkeeper/oauth/client_credentials/validator.rb +56 -0
  62. data/lib/doorkeeper/oauth/client_credentials_request.rb +10 -11
  63. data/lib/doorkeeper/oauth/code_request.rb +8 -12
  64. data/lib/doorkeeper/oauth/code_response.rb +27 -15
  65. data/lib/doorkeeper/oauth/error.rb +5 -3
  66. data/lib/doorkeeper/oauth/error_response.rb +35 -15
  67. data/lib/doorkeeper/oauth/forbidden_token_response.rb +11 -3
  68. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +23 -18
  69. data/lib/doorkeeper/oauth/helpers/unique_token.rb +20 -3
  70. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +53 -3
  71. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  72. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  73. data/lib/doorkeeper/oauth/invalid_token_response.rb +29 -5
  74. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  75. data/lib/doorkeeper/oauth/password_access_token_request.rb +44 -10
  76. data/lib/doorkeeper/oauth/pre_authorization.rb +135 -26
  77. data/lib/doorkeeper/oauth/refresh_token_request.rb +60 -31
  78. data/lib/doorkeeper/oauth/scopes.rb +26 -12
  79. data/lib/doorkeeper/oauth/token.rb +13 -9
  80. data/lib/doorkeeper/oauth/token_introspection.rb +202 -0
  81. data/lib/doorkeeper/oauth/token_request.rb +8 -20
  82. data/lib/doorkeeper/oauth/token_response.rb +14 -10
  83. data/lib/doorkeeper/oauth.rb +13 -0
  84. data/lib/doorkeeper/orm/active_record/access_grant.rb +6 -4
  85. data/lib/doorkeeper/orm/active_record/access_token.rb +5 -42
  86. data/lib/doorkeeper/orm/active_record/application.rb +6 -20
  87. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +69 -0
  88. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +60 -0
  89. data/lib/doorkeeper/orm/active_record/mixins/application.rb +199 -0
  90. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
  91. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +33 -0
  92. data/lib/doorkeeper/orm/active_record.rb +37 -8
  93. data/lib/doorkeeper/rails/helpers.rb +14 -13
  94. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  95. data/lib/doorkeeper/rails/routes/mapper.rb +4 -2
  96. data/lib/doorkeeper/rails/routes/mapping.rb +9 -7
  97. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  98. data/lib/doorkeeper/rails/routes.rb +41 -28
  99. data/lib/doorkeeper/rake/db.rake +40 -0
  100. data/lib/doorkeeper/rake/setup.rake +11 -0
  101. data/lib/doorkeeper/rake.rb +14 -0
  102. data/lib/doorkeeper/request/authorization_code.rb +6 -4
  103. data/lib/doorkeeper/request/client_credentials.rb +3 -3
  104. data/lib/doorkeeper/request/code.rb +1 -1
  105. data/lib/doorkeeper/request/password.rb +5 -14
  106. data/lib/doorkeeper/request/refresh_token.rb +6 -5
  107. data/lib/doorkeeper/request/strategy.rb +4 -2
  108. data/lib/doorkeeper/request/token.rb +1 -1
  109. data/lib/doorkeeper/request.rb +62 -29
  110. data/lib/doorkeeper/secret_storing/base.rb +64 -0
  111. data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
  112. data/lib/doorkeeper/secret_storing/plain.rb +33 -0
  113. data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
  114. data/lib/doorkeeper/server.rb +9 -11
  115. data/lib/doorkeeper/stale_records_cleaner.rb +24 -0
  116. data/lib/doorkeeper/validations.rb +5 -2
  117. data/lib/doorkeeper/version.rb +12 -1
  118. data/lib/doorkeeper.rb +111 -62
  119. data/lib/generators/doorkeeper/application_owner_generator.rb +28 -13
  120. data/lib/generators/doorkeeper/confidential_applications_generator.rb +33 -0
  121. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  122. data/lib/generators/doorkeeper/install_generator.rb +19 -9
  123. data/lib/generators/doorkeeper/migration_generator.rb +27 -10
  124. data/lib/generators/doorkeeper/pkce_generator.rb +33 -0
  125. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +31 -19
  126. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  127. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +9 -0
  128. data/{spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb → lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb} +3 -1
  129. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +8 -0
  130. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  131. data/lib/generators/doorkeeper/templates/initializer.rb +412 -33
  132. data/lib/generators/doorkeeper/templates/migration.rb.erb +88 -0
  133. data/lib/generators/doorkeeper/views_generator.rb +8 -4
  134. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  135. metadata +114 -276
  136. data/.coveralls.yml +0 -1
  137. data/.gitignore +0 -19
  138. data/.hound.yml +0 -13
  139. data/.rspec +0 -1
  140. data/.travis.yml +0 -26
  141. data/Appraisals +0 -14
  142. data/CONTRIBUTING.md +0 -47
  143. data/Gemfile +0 -10
  144. data/NEWS.md +0 -606
  145. data/RELEASING.md +0 -10
  146. data/Rakefile +0 -20
  147. data/app/validators/redirect_uri_validator.rb +0 -34
  148. data/doorkeeper.gemspec +0 -29
  149. data/gemfiles/rails_4_2.gemfile +0 -11
  150. data/gemfiles/rails_5_0.gemfile +0 -12
  151. data/gemfiles/rails_5_1.gemfile +0 -13
  152. data/lib/doorkeeper/oauth/client_credentials/validation.rb +0 -45
  153. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +0 -7
  154. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb +0 -11
  155. data/lib/generators/doorkeeper/templates/migration.rb +0 -68
  156. data/spec/controllers/application_metal_controller.rb +0 -10
  157. data/spec/controllers/applications_controller_spec.rb +0 -58
  158. data/spec/controllers/authorizations_controller_spec.rb +0 -218
  159. data/spec/controllers/protected_resources_controller_spec.rb +0 -300
  160. data/spec/controllers/token_info_controller_spec.rb +0 -52
  161. data/spec/controllers/tokens_controller_spec.rb +0 -88
  162. data/spec/dummy/Rakefile +0 -7
  163. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  164. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -7
  165. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -12
  166. data/spec/dummy/app/controllers/home_controller.rb +0 -17
  167. data/spec/dummy/app/controllers/metal_controller.rb +0 -11
  168. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -11
  169. data/spec/dummy/app/helpers/application_helper.rb +0 -5
  170. data/spec/dummy/app/models/user.rb +0 -5
  171. data/spec/dummy/app/views/home/index.html.erb +0 -0
  172. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  173. data/spec/dummy/config/application.rb +0 -23
  174. data/spec/dummy/config/boot.rb +0 -9
  175. data/spec/dummy/config/database.yml +0 -15
  176. data/spec/dummy/config/environment.rb +0 -5
  177. data/spec/dummy/config/environments/development.rb +0 -29
  178. data/spec/dummy/config/environments/production.rb +0 -62
  179. data/spec/dummy/config/environments/test.rb +0 -44
  180. data/spec/dummy/config/initializers/active_record_belongs_to_required_by_default.rb +0 -6
  181. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  182. data/spec/dummy/config/initializers/doorkeeper.rb +0 -96
  183. data/spec/dummy/config/initializers/secret_token.rb +0 -9
  184. data/spec/dummy/config/initializers/session_store.rb +0 -8
  185. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  186. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  187. data/spec/dummy/config/routes.rb +0 -52
  188. data/spec/dummy/config.ru +0 -4
  189. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -9
  190. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -5
  191. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -60
  192. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -7
  193. data/spec/dummy/db/schema.rb +0 -67
  194. data/spec/dummy/public/404.html +0 -26
  195. data/spec/dummy/public/422.html +0 -26
  196. data/spec/dummy/public/500.html +0 -26
  197. data/spec/dummy/public/favicon.ico +0 -0
  198. data/spec/dummy/script/rails +0 -6
  199. data/spec/factories.rb +0 -28
  200. data/spec/generators/application_owner_generator_spec.rb +0 -22
  201. data/spec/generators/install_generator_spec.rb +0 -31
  202. data/spec/generators/migration_generator_spec.rb +0 -20
  203. data/spec/generators/templates/routes.rb +0 -3
  204. data/spec/generators/views_generator_spec.rb +0 -27
  205. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -24
  206. data/spec/lib/config_spec.rb +0 -334
  207. data/spec/lib/doorkeeper_spec.rb +0 -150
  208. data/spec/lib/models/expirable_spec.rb +0 -50
  209. data/spec/lib/models/revocable_spec.rb +0 -59
  210. data/spec/lib/models/scopes_spec.rb +0 -43
  211. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -41
  212. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -80
  213. data/spec/lib/oauth/base_request_spec.rb +0 -160
  214. data/spec/lib/oauth/base_response_spec.rb +0 -45
  215. data/spec/lib/oauth/client/credentials_spec.rb +0 -88
  216. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -44
  217. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -86
  218. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -54
  219. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  220. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -104
  221. data/spec/lib/oauth/client_spec.rb +0 -39
  222. data/spec/lib/oauth/code_request_spec.rb +0 -45
  223. data/spec/lib/oauth/code_response_spec.rb +0 -34
  224. data/spec/lib/oauth/error_response_spec.rb +0 -61
  225. data/spec/lib/oauth/error_spec.rb +0 -23
  226. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -23
  227. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -64
  228. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -20
  229. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -104
  230. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -56
  231. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -90
  232. data/spec/lib/oauth/pre_authorization_spec.rb +0 -155
  233. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -154
  234. data/spec/lib/oauth/scopes_spec.rb +0 -122
  235. data/spec/lib/oauth/token_request_spec.rb +0 -98
  236. data/spec/lib/oauth/token_response_spec.rb +0 -85
  237. data/spec/lib/oauth/token_spec.rb +0 -116
  238. data/spec/lib/request/strategy_spec.rb +0 -53
  239. data/spec/lib/server_spec.rb +0 -49
  240. data/spec/models/doorkeeper/access_grant_spec.rb +0 -36
  241. data/spec/models/doorkeeper/access_token_spec.rb +0 -394
  242. data/spec/models/doorkeeper/application_spec.rb +0 -179
  243. data/spec/requests/applications/applications_request_spec.rb +0 -94
  244. data/spec/requests/applications/authorized_applications_spec.rb +0 -30
  245. data/spec/requests/endpoints/authorization_spec.rb +0 -71
  246. data/spec/requests/endpoints/token_spec.rb +0 -64
  247. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -76
  248. data/spec/requests/flows/authorization_code_spec.rb +0 -148
  249. data/spec/requests/flows/client_credentials_spec.rb +0 -58
  250. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -32
  251. data/spec/requests/flows/implicit_grant_spec.rb +0 -61
  252. data/spec/requests/flows/password_spec.rb +0 -115
  253. data/spec/requests/flows/refresh_token_spec.rb +0 -174
  254. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  255. data/spec/requests/flows/skip_authorization_spec.rb +0 -59
  256. data/spec/requests/protected_resources/metal_spec.rb +0 -14
  257. data/spec/requests/protected_resources/private_api_spec.rb +0 -81
  258. data/spec/routing/custom_controller_routes_spec.rb +0 -71
  259. data/spec/routing/default_routes_spec.rb +0 -35
  260. data/spec/routing/scoped_routes_spec.rb +0 -31
  261. data/spec/spec_helper.rb +0 -4
  262. data/spec/spec_helper_integration.rb +0 -63
  263. data/spec/support/dependencies/factory_girl.rb +0 -2
  264. data/spec/support/helpers/access_token_request_helper.rb +0 -11
  265. data/spec/support/helpers/authorization_request_helper.rb +0 -41
  266. data/spec/support/helpers/config_helper.rb +0 -9
  267. data/spec/support/helpers/model_helper.rb +0 -67
  268. data/spec/support/helpers/request_spec_helper.rb +0 -84
  269. data/spec/support/helpers/url_helper.rb +0 -55
  270. data/spec/support/http_method_shim.rb +0 -38
  271. data/spec/support/orm/active_record.rb +0 -3
  272. data/spec/support/shared/controllers_shared_context.rb +0 -69
  273. data/spec/support/shared/models_shared_examples.rb +0 -52
  274. data/spec/validators/redirect_uri_validator_spec.rb +0 -78
@@ -1,86 +1,334 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Doorkeeper.configure do
2
- # Change the ORM that doorkeeper will use (needs plugins)
4
+ # Change the ORM that doorkeeper will use (requires ORM extensions installed).
5
+ # Check the list of supported ORMs here: https://github.com/doorkeeper-gem/doorkeeper#orms
3
6
  orm :active_record
4
7
 
5
8
  # This block will be called to check whether the resource owner is authenticated or not.
6
9
  resource_owner_authenticator do
7
- fail "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}"
10
+ raise "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}"
8
11
  # Put your resource owner authentication logic here.
9
12
  # Example implementation:
10
- # User.find_by_id(session[:user_id]) || redirect_to(new_user_session_url)
13
+ # User.find_by(id: session[:user_id]) || redirect_to(new_user_session_url)
11
14
  end
12
15
 
13
- # If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
16
+ # If you didn't skip applications controller from Doorkeeper routes in your application routes.rb
17
+ # file then you need to declare this block in order to restrict access to the web interface for
18
+ # adding oauth authorized applications. In other case it will return 403 Forbidden response
19
+ # every time somebody will try to access the admin web interface.
20
+ #
14
21
  # admin_authenticator do
15
22
  # # Put your admin authentication logic here.
16
23
  # # Example implementation:
17
- # Admin.find_by_id(session[:admin_id]) || redirect_to(new_admin_session_url)
24
+ #
25
+ # if current_user
26
+ # head :forbidden unless current_user.admin?
27
+ # else
28
+ # redirect_to sign_in_url
29
+ # end
18
30
  # end
19
31
 
20
- # Authorization Code expiration time (default 10 minutes).
32
+ # You can use your own model classes if you need to extend (or even override) default
33
+ # Doorkeeper models such as `Application`, `AccessToken` and `AccessGrant.
34
+ #
35
+ # Be default Doorkeeper ActiveRecord ORM uses it's own classes:
36
+ #
37
+ # access_token_class "Doorkeeper::AccessToken"
38
+ # access_grant_class "Doorkeeper::AccessGrant"
39
+ # application_class "Doorkeeper::Application"
40
+ #
41
+ # Don't forget to include Doorkeeper ORM mixins into your custom models:
42
+ #
43
+ # * ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken - for access token
44
+ # * ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessGrant - for access grant
45
+ # * ::Doorkeeper::Orm::ActiveRecord::Mixins::Application - for application (OAuth2 clients)
46
+ #
47
+ # For example:
48
+ #
49
+ # access_token_class "MyAccessToken"
50
+ #
51
+ # class MyAccessToken < ApplicationRecord
52
+ # include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken
53
+ #
54
+ # self.table_name = "hey_i_wanna_my_name"
55
+ #
56
+ # def destroy_me!
57
+ # destroy
58
+ # end
59
+ # end
60
+
61
+ # Enables polymorphic Resource Owner association for Access Tokens and Access Grants.
62
+ # By default this option is disabled.
63
+ #
64
+ # Make sure you properly setup you database and have all the required columns (run
65
+ # `bundle exec rails generate doorkeeper:enable_polymorphic_resource_owner` and execute Rails
66
+ # migrations).
67
+ #
68
+ # If this option enabled, Doorkeeper will store not only Resource Owner primary key
69
+ # value, but also it's type (class name). See "Polymorphic Associations" section of
70
+ # Rails guides: https://guides.rubyonrails.org/association_basics.html#polymorphic-associations
71
+ #
72
+ # [NOTE] If you apply this option on already existing project don't forget to manually
73
+ # update `resource_owner_type` column in the database and fix migration template as it will
74
+ # set NOT NULL constraint for Access Grants table.
75
+ #
76
+ # use_polymorphic_resource_owner
77
+
78
+ # If you are planning to use Doorkeeper in Rails 5 API-only application, then you might
79
+ # want to use API mode that will skip all the views management and change the way how
80
+ # Doorkeeper responds to a requests.
81
+ #
82
+ # api_only
83
+
84
+ # Enforce token request content type to application/x-www-form-urlencoded.
85
+ # It is not enabled by default to not break prior versions of the gem.
86
+ #
87
+ # enforce_content_type
88
+
89
+ # Authorization Code expiration time (default: 10 minutes).
90
+ #
21
91
  # authorization_code_expires_in 10.minutes
22
92
 
23
- # Access token expiration time (default 2 hours).
24
- # If you want to disable expiration, set this to nil.
93
+ # Access token expiration time (default: 2 hours).
94
+ # If you want to disable expiration, set this to `nil`.
95
+ #
25
96
  # access_token_expires_in 2.hours
26
97
 
27
- # Assign a custom TTL for implicit grants.
28
- # custom_access_token_expires_in do |oauth_client|
29
- # oauth_client.application.additional_settings.implicit_oauth_expiration
98
+ # Assign custom TTL for access tokens. Will be used instead of access_token_expires_in
99
+ # option if defined. In case the block returns `nil` value Doorkeeper fallbacks to
100
+ # +access_token_expires_in+ configuration option value. If you really need to issue a
101
+ # non-expiring access token (which is not recommended) then you need to return
102
+ # Float::INFINITY from this block.
103
+ #
104
+ # `context` has the following properties available:
105
+ #
106
+ # * `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
107
+ # * `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
108
+ # * `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes)
109
+ # * `resource_owner` - authorized resource owner instance (if present)
110
+ #
111
+ # custom_access_token_expires_in do |context|
112
+ # context.client.additional_settings.implicit_oauth_expiration
30
113
  # end
31
114
 
32
115
  # Use a custom class for generating the access token.
33
- # https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
116
+ # See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-access-token-generator
117
+ #
34
118
  # access_token_generator '::Doorkeeper::JWT'
35
119
 
36
- # The controller Doorkeeper::ApplicationController inherits from.
37
- # Defaults to ActionController::Base.
38
- # https://github.com/doorkeeper-gem/doorkeeper#custom-base-controller
120
+ # The controller +Doorkeeper::ApplicationController+ inherits from.
121
+ # Defaults to +ActionController::Base+ unless +api_only+ is set, which changes the default to
122
+ # +ActionController::API+. The return value of this option must be a stringified class name.
123
+ # See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-controllers
124
+ #
39
125
  # base_controller 'ApplicationController'
40
126
 
41
- # Reuse access token for the same resource owner within an application (disabled by default)
127
+ # Reuse access token for the same resource owner within an application (disabled by default).
128
+ #
129
+ # This option protects your application from creating new tokens before old valid one becomes
130
+ # expired so your database doesn't bloat. Keep in mind that when this option is `on` Doorkeeper
131
+ # doesn't updates existing token expiration time, it will create a new token instead.
42
132
  # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
133
+ #
134
+ # You can not enable this option together with +hash_token_secrets+.
135
+ #
43
136
  # reuse_access_token
44
137
 
45
- # Issue access tokens with refresh token (disabled by default)
138
+ # In case you enabled `reuse_access_token` option Doorkeeper will try to find matching
139
+ # token using `matching_token_for` Access Token API that searches for valid records
140
+ # in batches in order not to pollute the memory with all the database records. By default
141
+ # Doorkeeper uses batch size of 10 000 records. You can increase or decrease this value
142
+ # depending on your needs and server capabilities.
143
+ #
144
+ # token_lookup_batch_size 10_000
145
+
146
+ # Set a limit for token_reuse if using reuse_access_token option
147
+ #
148
+ # This option limits token_reusability to some extent.
149
+ # If not set then access_token will be reused unless it expires.
150
+ # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
151
+ #
152
+ # This option should be a percentage(i.e. (0,100])
153
+ #
154
+ # token_reuse_limit 100
155
+
156
+ # Only allow one valid access token obtained via client credentials
157
+ # per client. If a new access token is obtained before the old one
158
+ # expired, the old one gets revoked (disabled by default)
159
+ #
160
+ # When enabling this option, make sure that you do not expect multiple processes
161
+ # using the same credentials at the same time (e.g. web servers spanning
162
+ # multiple machines and/or processes).
163
+ #
164
+ # revoke_previous_client_credentials_token
165
+
166
+ # Hash access and refresh tokens before persisting them.
167
+ # This will disable the possibility to use +reuse_access_token+
168
+ # since plain values can no longer be retrieved.
169
+ #
170
+ # Note: If you are already a user of doorkeeper and have existing tokens
171
+ # in your installation, they will be invalid without adding 'fallback: :plain'.
172
+ #
173
+ # hash_token_secrets
174
+ # By default, token secrets will be hashed using the
175
+ # +Doorkeeper::Hashing::SHA256+ strategy.
176
+ #
177
+ # If you wish to use another hashing implementation, you can override
178
+ # this strategy as follows:
179
+ #
180
+ # hash_token_secrets using: '::Doorkeeper::Hashing::MyCustomHashImpl'
181
+ #
182
+ # Keep in mind that changing the hashing function will invalidate all existing
183
+ # secrets, if there are any.
184
+
185
+ # Hash application secrets before persisting them.
186
+ #
187
+ # hash_application_secrets
188
+ #
189
+ # By default, applications will be hashed
190
+ # with the +Doorkeeper::SecretStoring::SHA256+ strategy.
191
+ #
192
+ # If you wish to use bcrypt for application secret hashing, uncomment
193
+ # this line instead:
194
+ #
195
+ # hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt'
196
+
197
+ # When the above option is enabled, and a hashed token or secret is not found,
198
+ # you can allow to fall back to another strategy. For users upgrading
199
+ # doorkeeper and wishing to enable hashing, you will probably want to enable
200
+ # the fallback to plain tokens.
201
+ #
202
+ # This will ensure that old access tokens and secrets
203
+ # will remain valid even if the hashing above is enabled.
204
+ #
205
+ # This can be done by adding 'fallback: plain', e.g. :
206
+ #
207
+ # hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt', fallback: :plain
208
+
209
+ # Issue access tokens with refresh token (disabled by default), you may also
210
+ # pass a block which accepts `context` to customize when to give a refresh
211
+ # token or not. Similar to +custom_access_token_expires_in+, `context` has
212
+ # the following properties:
213
+ #
214
+ # `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
215
+ # `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
216
+ # `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes)
217
+ #
46
218
  # use_refresh_token
47
219
 
48
220
  # Provide support for an owner to be assigned to each registered application (disabled by default)
49
- # Optional parameter confirmation: true (default false) if you want to enforce ownership of
221
+ # Optional parameter confirmation: true (default: false) if you want to enforce ownership of
50
222
  # a registered application
51
- # Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
223
+ # NOTE: you must also run the rails g doorkeeper:application_owner generator
224
+ # to provide the necessary support
225
+ #
52
226
  # enable_application_owner confirmation: false
53
227
 
54
228
  # Define access token scopes for your provider
55
229
  # For more information go to
56
- # https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
230
+ # https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes
231
+ #
57
232
  # default_scopes :public
58
233
  # optional_scopes :write, :update
59
234
 
235
+ # Allows to restrict only certain scopes for grant_type.
236
+ # By default, all the scopes will be available for all the grant types.
237
+ #
238
+ # Keys to this hash should be the name of grant_type and
239
+ # values should be the array of scopes for that grant type.
240
+ # Note: scopes should be from configured_scopes (i.e. default or optional)
241
+ #
242
+ # scopes_by_grant_type password: [:write], client_credentials: [:update]
243
+
244
+ # Forbids creating/updating applications with arbitrary scopes that are
245
+ # not in configuration, i.e. +default_scopes+ or +optional_scopes+.
246
+ # (disabled by default)
247
+ #
248
+ # enforce_configured_scopes
249
+
60
250
  # Change the way client credentials are retrieved from the request object.
61
251
  # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
62
252
  # falls back to the `:client_id` and `:client_secret` params from the `params` object.
63
- # Check out the wiki for more information on customization
253
+ # Check out https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated
254
+ # for more information on customization
255
+ #
64
256
  # client_credentials :from_basic, :from_params
65
257
 
66
258
  # Change the way access token is authenticated from the request object.
67
259
  # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
68
260
  # falls back to the `:access_token` or `:bearer_token` params from the `params` object.
69
- # Check out the wiki for more information on customization
70
- # access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param
71
-
72
- # Change the native redirect uri for client apps
73
- # When clients register with the following redirect uri, they won't be redirected to any server and the authorization code will be displayed within the provider
74
- # The value can be any string. Use nil to disable this feature. When disabled, clients must provide a valid URL
75
- # (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi)
261
+ # Check out https://github.com/doorkeeper-gem/doorkeeper/wiki/Changing-how-clients-are-authenticated
262
+ # for more information on customization
76
263
  #
77
- # native_redirect_uri 'urn:ietf:wg:oauth:2.0:oob'
264
+ # access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param
78
265
 
79
266
  # Forces the usage of the HTTPS protocol in non-native redirect uris (enabled
80
267
  # by default in non-development environments). OAuth2 delegates security in
81
268
  # communication to the HTTPS protocol so it is wise to keep this enabled.
82
269
  #
270
+ # Callable objects such as proc, lambda, block or any object that responds to
271
+ # #call can be used in order to allow conditional checks (to allow non-SSL
272
+ # redirects to localhost for example).
273
+ #
83
274
  # force_ssl_in_redirect_uri !Rails.env.development?
275
+ #
276
+ # force_ssl_in_redirect_uri { |uri| uri.host != 'localhost' }
277
+
278
+ # Specify what redirect URI's you want to block during Application creation.
279
+ # Any redirect URI is allowed by default.
280
+ #
281
+ # You can use this option in order to forbid URI's with 'javascript' scheme
282
+ # for example.
283
+ #
284
+ # forbid_redirect_uri { |uri| uri.scheme.to_s.downcase == 'javascript' }
285
+
286
+ # Allows to set blank redirect URIs for Applications in case Doorkeeper configured
287
+ # to use URI-less OAuth grant flows like Client Credentials or Resource Owner
288
+ # Password Credentials. The option is on by default and checks configured grant
289
+ # types, but you **need** to manually drop `NOT NULL` constraint from `redirect_uri`
290
+ # column for `oauth_applications` database table.
291
+ #
292
+ # You can completely disable this feature with:
293
+ #
294
+ # allow_blank_redirect_uri false
295
+ #
296
+ # Or you can define your custom check:
297
+ #
298
+ # allow_blank_redirect_uri do |grant_flows, client|
299
+ # client.superapp?
300
+ # end
301
+
302
+ # Specify how authorization errors should be handled.
303
+ # By default, doorkeeper renders json errors when access token
304
+ # is invalid, expired, revoked or has invalid scopes.
305
+ #
306
+ # If you want to render error response yourself (i.e. rescue exceptions),
307
+ # set +handle_auth_errors+ to `:raise` and rescue Doorkeeper::Errors::InvalidToken
308
+ # or following specific errors:
309
+ #
310
+ # Doorkeeper::Errors::TokenForbidden, Doorkeeper::Errors::TokenExpired,
311
+ # Doorkeeper::Errors::TokenRevoked, Doorkeeper::Errors::TokenUnknown
312
+ #
313
+ # handle_auth_errors :raise
314
+
315
+ # Customize token introspection response.
316
+ # Allows to add your own fields to default one that are required by the OAuth spec
317
+ # for the introspection response. It could be `sub`, `aud` and so on.
318
+ # This configuration option can be a proc, lambda or any Ruby object responds
319
+ # to `.call` method and result of it's invocation must be a Hash.
320
+ #
321
+ # custom_introspection_response do |token, context|
322
+ # {
323
+ # "sub": "Z5O3upPC88QrAjx00dis",
324
+ # "aud": "https://protected.example.net/resource",
325
+ # "username": User.find(token.resource_owner_id).username
326
+ # }
327
+ # end
328
+ #
329
+ # or
330
+ #
331
+ # custom_introspection_response CustomIntrospectionResponder
84
332
 
85
333
  # Specify what grant flows are enabled in array of Strings. The valid
86
334
  # strings and the flows they enable are:
@@ -95,18 +343,149 @@ Doorkeeper.configure do
95
343
  #
96
344
  # implicit and password grant flows have risks that you should understand
97
345
  # before enabling:
98
- # http://tools.ietf.org/html/rfc6819#section-4.4.2
99
- # http://tools.ietf.org/html/rfc6819#section-4.4.3
346
+ # https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.2
347
+ # https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.3
100
348
  #
101
- # grant_flows %w(authorization_code client_credentials)
349
+ # grant_flows %w[authorization_code client_credentials]
350
+
351
+ # Allows to customize OAuth grant flows that +each+ application support.
352
+ # You can configure a custom block (or use a class respond to `#call`) that must
353
+ # return `true` in case Application instance supports requested OAuth grant flow
354
+ # during the authorization request to the server. This configuration +doesn't+
355
+ # set flows per application, it only allows to check if application supports
356
+ # specific grant flow.
357
+ #
358
+ # For example you can add an additional database column to `oauth_applications` table,
359
+ # say `t.array :grant_flows, default: []`, and store allowed grant flows that can
360
+ # be used with this application there. Then when authorization requested Doorkeeper
361
+ # will call this block to check if specific Application (passed with client_id and/or
362
+ # client_secret) is allowed to perform the request for the specific grant type
363
+ # (authorization, password, client_credentials, etc).
364
+ #
365
+ # Example of the block:
366
+ #
367
+ # ->(flow, client) { client.grant_flows.include?(flow) }
368
+ #
369
+ # In case this option invocation result is `false`, Doorkeeper server returns
370
+ # :unauthorized_client error and stops the request.
371
+ #
372
+ # @param allow_grant_flow_for_client [Proc] Block or any object respond to #call
373
+ # @return [Boolean] `true` if allow or `false` if forbid the request
374
+ #
375
+ # allow_grant_flow_for_client do |grant_flow, client|
376
+ # # `grant_flows` is an Array column with grant
377
+ # # flows that application supports
378
+ #
379
+ # client.grant_flows.include?(grant_flow)
380
+ # end
381
+
382
+ # If you need arbitrary Resource Owner-Client authorization you can enable this option
383
+ # and implement the check your need. Config option must respond to #call and return
384
+ # true in case resource owner authorized for the specific application or false in other
385
+ # cases.
386
+ #
387
+ # Be default all Resource Owners are authorized to any Client (application).
388
+ #
389
+ # authorize_resource_owner_for_client do |client, resource_owner|
390
+ # resource_owner.admin? || client.owners_allowlist.include?(resource_owner)
391
+ # end
392
+
393
+ # Hook into the strategies' request & response life-cycle in case your
394
+ # application needs advanced customization or logging:
395
+ #
396
+ # before_successful_strategy_response do |request|
397
+ # puts "BEFORE HOOK FIRED! #{request}"
398
+ # end
399
+ #
400
+ # after_successful_strategy_response do |request, response|
401
+ # puts "AFTER HOOK FIRED! #{request}, #{response}"
402
+ # end
403
+
404
+ # Hook into Authorization flow in order to implement Single Sign Out
405
+ # or add any other functionality. Inside the block you have an access
406
+ # to `controller` (authorizations controller instance) and `context`
407
+ # (Doorkeeper::OAuth::Hooks::Context instance) which provides pre auth
408
+ # or auth objects with issued token based on hook type (before or after).
409
+ #
410
+ # before_successful_authorization do |controller, context|
411
+ # Rails.logger.info(controller.request.params.inspect)
412
+ #
413
+ # Rails.logger.info(context.pre_auth.inspect)
414
+ # end
415
+ #
416
+ # after_successful_authorization do |controller, context|
417
+ # controller.session[:logout_urls] <<
418
+ # Doorkeeper::Application
419
+ # .find_by(controller.request.params.slice(:redirect_uri))
420
+ # .logout_uri
421
+ #
422
+ # Rails.logger.info(context.auth.inspect)
423
+ # Rails.logger.info(context.issued_token)
424
+ # end
102
425
 
103
426
  # Under some circumstances you might want to have applications auto-approved,
104
427
  # so that the user skips the authorization step.
105
428
  # For example if dealing with a trusted application.
429
+ #
106
430
  # skip_authorization do |resource_owner, client|
107
431
  # client.superapp? or resource_owner.admin?
108
432
  # end
109
433
 
110
- # WWW-Authenticate Realm (default "Doorkeeper").
434
+ # Configure custom constraints for the Token Introspection request.
435
+ # By default this configuration option allows to introspect a token by another
436
+ # token of the same application, OR to introspect the token that belongs to
437
+ # authorized client (from authenticated client) OR when token doesn't
438
+ # belong to any client (public token). Otherwise requester has no access to the
439
+ # introspection and it will return response as stated in the RFC.
440
+ #
441
+ # Block arguments:
442
+ #
443
+ # @param token [Doorkeeper::AccessToken]
444
+ # token to be introspected
445
+ #
446
+ # @param authorized_client [Doorkeeper::Application]
447
+ # authorized client (if request is authorized using Basic auth with
448
+ # Client Credentials for example)
449
+ #
450
+ # @param authorized_token [Doorkeeper::AccessToken]
451
+ # Bearer token used to authorize the request
452
+ #
453
+ # In case the block returns `nil` or `false` introspection responses with 401 status code
454
+ # when using authorized token to introspect, or you'll get 200 with { "active": false } body
455
+ # when using authorized client to introspect as stated in the
456
+ # RFC 7662 section 2.2. Introspection Response.
457
+ #
458
+ # Using with caution:
459
+ # Keep in mind that these three parameters pass to block can be nil as following case:
460
+ # `authorized_client` is nil if and only if `authorized_token` is present, and vice versa.
461
+ # `token` will be nil if and only if `authorized_token` is present.
462
+ # So remember to use `&` or check if it is present before calling method on
463
+ # them to make sure you doesn't get NoMethodError exception.
464
+ #
465
+ # You can define your custom check:
466
+ #
467
+ # allow_token_introspection do |token, authorized_client, authorized_token|
468
+ # if authorized_token
469
+ # # customize: require `introspection` scope
470
+ # authorized_token.application == token&.application ||
471
+ # authorized_token.scopes.include?("introspection")
472
+ # elsif token.application
473
+ # # `protected_resource` is a new database boolean column, for example
474
+ # authorized_client == token.application || authorized_client.protected_resource?
475
+ # else
476
+ # # public token (when token.application is nil, token doesn't belong to any application)
477
+ # true
478
+ # end
479
+ # end
480
+ #
481
+ # Or you can completely disable any token introspection:
482
+ #
483
+ # allow_token_introspection false
484
+ #
485
+ # If you need to block the request at all, then configure your routes.rb or web-server
486
+ # like nginx to forbid the request.
487
+
488
+ # WWW-Authenticate Realm (default: "Doorkeeper").
489
+ #
111
490
  # realm "Doorkeeper"
112
491
  end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
4
+ def change
5
+ create_table :oauth_applications do |t|
6
+ t.string :name, null: false
7
+ t.string :uid, null: false
8
+ t.string :secret, null: false
9
+
10
+ # Remove `null: false` if you are planning to use grant flows
11
+ # that doesn't require redirect URI to be used during authorization
12
+ # like Client Credentials flow or Resource Owner Password.
13
+ t.text :redirect_uri, null: false
14
+ t.string :scopes, null: false, default: ''
15
+ t.boolean :confidential, null: false, default: true
16
+ t.timestamps null: false
17
+ end
18
+
19
+ add_index :oauth_applications, :uid, unique: true
20
+
21
+ create_table :oauth_access_grants do |t|
22
+ t.references :resource_owner, null: false
23
+ t.references :application, null: false
24
+ t.string :token, null: false
25
+ t.integer :expires_in, null: false
26
+ t.text :redirect_uri, null: false
27
+ t.datetime :created_at, null: false
28
+ t.datetime :revoked_at
29
+ t.string :scopes, null: false, default: ''
30
+ end
31
+
32
+ add_index :oauth_access_grants, :token, unique: true
33
+ add_foreign_key(
34
+ :oauth_access_grants,
35
+ :oauth_applications,
36
+ column: :application_id
37
+ )
38
+
39
+ create_table :oauth_access_tokens do |t|
40
+ t.references :resource_owner, index: true
41
+
42
+ # Remove `null: false` if you are planning to use Password
43
+ # Credentials Grant flow that doesn't require an application.
44
+ t.references :application, null: false
45
+
46
+ # If you use a custom token generator you may need to change this column
47
+ # from string to text, so that it accepts tokens larger than 255
48
+ # characters. More info on custom token generators in:
49
+ # https://github.com/doorkeeper-gem/doorkeeper/tree/v3.0.0.rc1#custom-access-token-generator
50
+ #
51
+ # t.text :token, null: false
52
+ t.string :token, null: false
53
+
54
+ t.string :refresh_token
55
+ t.integer :expires_in
56
+ t.datetime :revoked_at
57
+ t.datetime :created_at, null: false
58
+ t.string :scopes
59
+
60
+ # The authorization server MAY issue a new refresh token, in which case
61
+ # *the client MUST discard the old refresh token* and replace it with the
62
+ # new refresh token. The authorization server MAY revoke the old
63
+ # refresh token after issuing a new refresh token to the client.
64
+ # @see https://datatracker.ietf.org/doc/html/rfc6749#section-6
65
+ #
66
+ # Doorkeeper implementation: if there is a `previous_refresh_token` column,
67
+ # refresh tokens will be revoked after a related access token is used.
68
+ # If there is no `previous_refresh_token` column, previous tokens are
69
+ # revoked as soon as a new access token is created.
70
+ #
71
+ # Comment out this line if you want refresh tokens to be instantly
72
+ # revoked after use.
73
+ t.string :previous_refresh_token, null: false, default: ""
74
+ end
75
+
76
+ add_index :oauth_access_tokens, :token, unique: true
77
+ add_index :oauth_access_tokens, :refresh_token, unique: true
78
+ add_foreign_key(
79
+ :oauth_access_tokens,
80
+ :oauth_applications,
81
+ column: :application_id
82
+ )
83
+
84
+ # Uncomment below to ensure a valid reference to the resource owner's table
85
+ # add_foreign_key :oauth_access_grants, <model>, column: :resource_owner_id
86
+ # add_foreign_key :oauth_access_tokens, <model>, column: :resource_owner_id
87
+ end
88
+ end
@@ -1,13 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Doorkeeper
2
4
  module Generators
5
+ # Generates doorkeeper views for Rails application
6
+ #
3
7
  class ViewsGenerator < ::Rails::Generators::Base
4
- source_root File.expand_path('../../../../app/views', __FILE__)
8
+ source_root File.expand_path("../../../app/views", __dir__)
5
9
 
6
- desc 'Copies default Doorkeeper views and layouts to your application.'
10
+ desc "Copies default Doorkeeper views and layouts to your application."
7
11
 
8
12
  def manifest
9
- directory 'doorkeeper', 'app/views/doorkeeper'
10
- directory 'layouts/doorkeeper', 'app/views/layouts/doorkeeper'
13
+ directory "doorkeeper", "app/views/doorkeeper"
14
+ directory "layouts/doorkeeper", "app/views/layouts/doorkeeper"
11
15
  end
12
16
  end
13
17
  end