doorkeeper 4.2.5 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +25 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +17 -0
  4. data/.gitignore +2 -1
  5. data/.gitlab-ci.yml +16 -0
  6. data/.hound.yml +2 -13
  7. data/.rubocop.yml +17 -0
  8. data/.travis.yml +19 -4
  9. data/Appraisals +8 -4
  10. data/CODE_OF_CONDUCT.md +46 -0
  11. data/Gemfile +1 -1
  12. data/NEWS.md +115 -0
  13. data/README.md +175 -39
  14. data/RELEASING.md +5 -12
  15. data/Rakefile +6 -0
  16. data/SECURITY.md +15 -0
  17. data/UPGRADE.md +2 -0
  18. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  19. data/app/controllers/doorkeeper/application_controller.rb +2 -5
  20. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -0
  21. data/app/controllers/doorkeeper/applications_controller.rb +47 -13
  22. data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
  23. data/app/controllers/doorkeeper/authorized_applications_controller.rb +19 -2
  24. data/app/controllers/doorkeeper/tokens_controller.rb +24 -17
  25. data/app/helpers/doorkeeper/dashboard_helper.rb +8 -6
  26. data/app/validators/redirect_uri_validator.rb +13 -2
  27. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  28. data/app/views/doorkeeper/applications/_form.html.erb +31 -19
  29. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  30. data/app/views/doorkeeper/applications/index.html.erb +18 -6
  31. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  32. data/app/views/doorkeeper/applications/show.html.erb +8 -5
  33. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  34. data/app/views/doorkeeper/authorizations/new.html.erb +5 -1
  35. data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
  36. data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
  37. data/config/locales/en.yml +19 -6
  38. data/doorkeeper.gemspec +20 -20
  39. data/gemfiles/rails_4_2.gemfile +6 -4
  40. data/gemfiles/rails_5_0.gemfile +4 -4
  41. data/gemfiles/rails_5_1.gemfile +6 -7
  42. data/gemfiles/rails_5_2.gemfile +12 -0
  43. data/gemfiles/rails_master.gemfile +17 -0
  44. data/lib/doorkeeper/config.rb +123 -71
  45. data/lib/doorkeeper/engine.rb +7 -3
  46. data/lib/doorkeeper/errors.rb +20 -5
  47. data/lib/doorkeeper/grape/helpers.rb +14 -9
  48. data/lib/doorkeeper/helpers/controller.rb +16 -22
  49. data/lib/doorkeeper/models/access_grant_mixin.rb +67 -23
  50. data/lib/doorkeeper/models/access_token_mixin.rb +54 -55
  51. data/lib/doorkeeper/models/application_mixin.rb +16 -30
  52. data/lib/doorkeeper/models/concerns/expirable.rb +7 -5
  53. data/lib/doorkeeper/models/concerns/orderable.rb +13 -0
  54. data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
  55. data/lib/doorkeeper/oauth/authorization/code.rb +31 -8
  56. data/lib/doorkeeper/oauth/authorization/context.rb +15 -0
  57. data/lib/doorkeeper/oauth/authorization/token.rb +46 -20
  58. data/lib/doorkeeper/oauth/authorization_code_request.rb +33 -3
  59. data/lib/doorkeeper/oauth/base_request.rb +23 -7
  60. data/lib/doorkeeper/oauth/client/credentials.rb +6 -4
  61. data/lib/doorkeeper/oauth/client.rb +2 -4
  62. data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -1
  63. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +6 -3
  64. data/lib/doorkeeper/oauth/client_credentials/validation.rb +4 -6
  65. data/lib/doorkeeper/oauth/client_credentials_request.rb +0 -4
  66. data/lib/doorkeeper/oauth/error.rb +2 -2
  67. data/lib/doorkeeper/oauth/error_response.rb +11 -4
  68. data/lib/doorkeeper/oauth/forbidden_token_response.rb +1 -1
  69. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +0 -8
  70. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +15 -0
  71. data/lib/doorkeeper/oauth/invalid_token_response.rb +3 -4
  72. data/lib/doorkeeper/oauth/password_access_token_request.rb +8 -4
  73. data/lib/doorkeeper/oauth/pre_authorization.rb +45 -13
  74. data/lib/doorkeeper/oauth/refresh_token_request.rb +7 -1
  75. data/lib/doorkeeper/oauth/scopes.rb +19 -9
  76. data/lib/doorkeeper/oauth/token.rb +6 -3
  77. data/lib/doorkeeper/oauth/token_introspection.rb +128 -0
  78. data/lib/doorkeeper/oauth/token_response.rb +4 -2
  79. data/lib/doorkeeper/oauth.rb +13 -0
  80. data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -0
  81. data/lib/doorkeeper/orm/active_record/access_token.rb +21 -20
  82. data/lib/doorkeeper/orm/active_record/application.rb +45 -0
  83. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
  84. data/lib/doorkeeper/orm/active_record.rb +21 -8
  85. data/lib/doorkeeper/rails/helpers.rb +7 -10
  86. data/lib/doorkeeper/rails/routes.rb +21 -7
  87. data/lib/doorkeeper/rake/db.rake +40 -0
  88. data/lib/doorkeeper/rake/setup.rake +6 -0
  89. data/lib/doorkeeper/rake.rb +14 -0
  90. data/lib/doorkeeper/request/authorization_code.rb +0 -2
  91. data/lib/doorkeeper/request/client_credentials.rb +0 -2
  92. data/lib/doorkeeper/request/code.rb +0 -2
  93. data/lib/doorkeeper/request/password.rb +1 -13
  94. data/lib/doorkeeper/request/refresh_token.rb +0 -2
  95. data/lib/doorkeeper/request/token.rb +0 -2
  96. data/lib/doorkeeper/request.rb +29 -30
  97. data/lib/doorkeeper/validations.rb +3 -2
  98. data/lib/doorkeeper/version.rb +14 -1
  99. data/lib/doorkeeper.rb +21 -17
  100. data/lib/generators/doorkeeper/application_owner_generator.rb +26 -12
  101. data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
  102. data/lib/generators/doorkeeper/install_generator.rb +17 -9
  103. data/lib/generators/doorkeeper/migration_generator.rb +26 -9
  104. data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
  105. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +31 -20
  106. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  107. data/lib/generators/doorkeeper/templates/{add_owner_to_application_migration.rb → add_owner_to_application_migration.rb.erb} +1 -1
  108. data/lib/generators/doorkeeper/templates/{add_previous_refresh_token_to_access_tokens.rb → add_previous_refresh_token_to_access_tokens.rb.erb} +1 -1
  109. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
  110. data/lib/generators/doorkeeper/templates/initializer.rb +104 -12
  111. data/lib/generators/doorkeeper/templates/{migration.rb → migration.rb.erb} +2 -1
  112. data/lib/generators/doorkeeper/views_generator.rb +3 -1
  113. data/spec/controllers/application_metal_controller_spec.rb +50 -0
  114. data/spec/controllers/applications_controller_spec.rb +141 -17
  115. data/spec/controllers/authorizations_controller_spec.rb +304 -27
  116. data/spec/controllers/protected_resources_controller_spec.rb +44 -35
  117. data/spec/controllers/token_info_controller_spec.rb +17 -21
  118. data/spec/controllers/tokens_controller_spec.rb +201 -17
  119. data/spec/dummy/app/assets/config/manifest.js +2 -0
  120. data/spec/dummy/config/environments/test.rb +4 -5
  121. data/spec/dummy/config/initializers/doorkeeper.rb +23 -2
  122. data/spec/dummy/config/initializers/{active_record_belongs_to_required_by_default.rb → new_framework_defaults.rb} +5 -1
  123. data/spec/dummy/config/initializers/secret_token.rb +0 -1
  124. data/spec/dummy/config/routes.rb +3 -42
  125. data/spec/dummy/db/migrate/20111122132257_create_users.rb +3 -1
  126. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +3 -1
  127. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -1
  128. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +3 -1
  129. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +3 -1
  130. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
  131. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +13 -0
  132. data/spec/dummy/db/schema.rb +38 -37
  133. data/spec/factories.rb +1 -1
  134. data/spec/generators/application_owner_generator_spec.rb +25 -6
  135. data/spec/generators/confidential_applications_generator_spec.rb +45 -0
  136. data/spec/generators/install_generator_spec.rb +1 -1
  137. data/spec/generators/migration_generator_spec.rb +25 -4
  138. data/spec/generators/pkce_generator_spec.rb +43 -0
  139. data/spec/generators/previous_refresh_token_generator_spec.rb +57 -0
  140. data/spec/generators/views_generator_spec.rb +1 -1
  141. data/spec/grape/grape_integration_spec.rb +135 -0
  142. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +2 -2
  143. data/spec/lib/config_spec.rb +199 -22
  144. data/spec/lib/doorkeeper_spec.rb +1 -126
  145. data/spec/lib/models/expirable_spec.rb +0 -4
  146. data/spec/lib/models/revocable_spec.rb +2 -4
  147. data/spec/lib/models/scopes_spec.rb +0 -4
  148. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
  149. data/spec/lib/oauth/authorization_code_request_spec.rb +63 -13
  150. data/spec/lib/oauth/base_request_spec.rb +43 -10
  151. data/spec/lib/oauth/base_response_spec.rb +1 -1
  152. data/spec/lib/oauth/client/credentials_spec.rb +5 -5
  153. data/spec/lib/oauth/client_credentials/creator_spec.rb +6 -2
  154. data/spec/lib/oauth/client_credentials/issuer_spec.rb +26 -7
  155. data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -3
  156. data/spec/lib/oauth/client_credentials_integration_spec.rb +2 -2
  157. data/spec/lib/oauth/client_credentials_request_spec.rb +4 -5
  158. data/spec/lib/oauth/client_spec.rb +0 -3
  159. data/spec/lib/oauth/code_request_spec.rb +5 -5
  160. data/spec/lib/oauth/error_response_spec.rb +0 -3
  161. data/spec/lib/oauth/error_spec.rb +1 -3
  162. data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
  163. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -3
  164. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
  165. data/spec/lib/oauth/helpers/uri_checker_spec.rb +115 -3
  166. data/spec/lib/oauth/invalid_token_response_spec.rb +2 -5
  167. data/spec/lib/oauth/password_access_token_request_spec.rb +46 -5
  168. data/spec/lib/oauth/pre_authorization_spec.rb +40 -6
  169. data/spec/lib/oauth/refresh_token_request_spec.rb +30 -14
  170. data/spec/lib/oauth/scopes_spec.rb +28 -4
  171. data/spec/lib/oauth/token_request_spec.rb +10 -13
  172. data/spec/lib/oauth/token_response_spec.rb +0 -1
  173. data/spec/lib/oauth/token_spec.rb +37 -14
  174. data/spec/lib/orm/active_record/stale_records_cleaner_spec.rb +79 -0
  175. data/spec/lib/request/strategy_spec.rb +0 -1
  176. data/spec/lib/server_spec.rb +10 -0
  177. data/spec/models/doorkeeper/access_grant_spec.rb +45 -2
  178. data/spec/models/doorkeeper/access_token_spec.rb +132 -64
  179. data/spec/models/doorkeeper/application_spec.rb +114 -23
  180. data/spec/requests/applications/applications_request_spec.rb +139 -6
  181. data/spec/requests/applications/authorized_applications_spec.rb +1 -1
  182. data/spec/requests/endpoints/authorization_spec.rb +1 -1
  183. data/spec/requests/endpoints/token_spec.rb +15 -6
  184. data/spec/requests/flows/authorization_code_errors_spec.rb +12 -2
  185. data/spec/requests/flows/authorization_code_spec.rb +199 -2
  186. data/spec/requests/flows/client_credentials_spec.rb +73 -5
  187. data/spec/requests/flows/implicit_grant_errors_spec.rb +3 -3
  188. data/spec/requests/flows/implicit_grant_spec.rb +38 -11
  189. data/spec/requests/flows/password_spec.rb +160 -24
  190. data/spec/requests/flows/refresh_token_spec.rb +6 -6
  191. data/spec/requests/flows/revoke_token_spec.rb +26 -26
  192. data/spec/requests/flows/skip_authorization_spec.rb +16 -11
  193. data/spec/requests/protected_resources/metal_spec.rb +2 -2
  194. data/spec/requests/protected_resources/private_api_spec.rb +2 -2
  195. data/spec/routing/custom_controller_routes_spec.rb +63 -7
  196. data/spec/routing/default_routes_spec.rb +6 -2
  197. data/spec/routing/scoped_routes_spec.rb +16 -2
  198. data/spec/spec_helper.rb +54 -3
  199. data/spec/spec_helper_integration.rb +2 -64
  200. data/spec/support/dependencies/factory_bot.rb +2 -0
  201. data/spec/support/doorkeeper_rspec.rb +19 -0
  202. data/spec/support/helpers/access_token_request_helper.rb +1 -1
  203. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  204. data/spec/support/helpers/model_helper.rb +9 -4
  205. data/spec/support/helpers/request_spec_helper.rb +18 -6
  206. data/spec/support/helpers/url_helper.rb +15 -10
  207. data/spec/support/http_method_shim.rb +12 -16
  208. data/spec/support/shared/controllers_shared_context.rb +2 -6
  209. data/spec/support/shared/models_shared_examples.rb +4 -4
  210. data/spec/validators/redirect_uri_validator_spec.rb +58 -7
  211. data/spec/version/version_spec.rb +15 -0
  212. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  213. metadata +75 -33
  214. data/spec/controllers/application_metal_controller.rb +0 -10
  215. data/spec/support/dependencies/factory_girl.rb +0 -2
data/README.md CHANGED
@@ -1,24 +1,38 @@
1
- # Doorkeeper - awesome oauth provider for your Rails app.
1
+ # Doorkeeper awesome OAuth 2 provider for your Rails / Grape app.
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/doorkeeper.svg)](https://rubygems.org/gems/doorkeeper)
3
4
  [![Build Status](https://travis-ci.org/doorkeeper-gem/doorkeeper.svg?branch=master)](https://travis-ci.org/doorkeeper-gem/doorkeeper)
4
- [![Dependency Status](https://gemnasium.com/doorkeeper-gem/doorkeeper.svg?travis)](https://gemnasium.com/doorkeeper-gem/doorkeeper)
5
5
  [![Code Climate](https://codeclimate.com/github/doorkeeper-gem/doorkeeper.svg)](https://codeclimate.com/github/doorkeeper-gem/doorkeeper)
6
- [![Gem Version](https://badge.fury.io/rb/doorkeeper.svg)](https://rubygems.org/gems/doorkeeper)
6
+ [![Coverage Status](https://coveralls.io/repos/github/doorkeeper-gem/doorkeeper/badge.svg?branch=master)](https://coveralls.io/github/doorkeeper-gem/doorkeeper?branch=master)
7
7
  [![Security](https://hakiri.io/github/doorkeeper-gem/doorkeeper/master.svg)](https://hakiri.io/github/doorkeeper-gem/doorkeeper/master)
8
+ [![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
8
9
 
9
- Doorkeeper is a gem that makes it easy to introduce OAuth 2 provider
10
- functionality to your Rails or Grape application.
10
+ Doorkeeper is a gem (Rails engine) that makes it easy to introduce OAuth 2 provider
11
+ functionality to your Ruby on Rails or Grape application.
11
12
 
12
- [PR 567]: https://github.com/doorkeeper-gem/doorkeeper/pull/567
13
+ Supported features:
13
14
 
15
+ - [The OAuth 2.0 Authorization Framework](https://tools.ietf.org/html/rfc6749)
16
+ - [Authorization Code Flow](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.1)
17
+ - [Access Token Scopes](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.3)
18
+ - [Refresh token](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-1.5)
19
+ - [Implicit grant](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.2)
20
+ - [Resource Owner Password Credentials](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.3)
21
+ - [Client Credentials](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.4)
22
+ - [Proof Key for Code Exchange](https://tools.ietf.org/html/rfc7636)
23
+ - [OAuth 2.0 Token Revocation](http://tools.ietf.org/html/rfc7009)
24
+ - [OAuth 2.0 Token Introspection](https://tools.ietf.org/html/rfc7662)
14
25
 
15
26
  ## Documentation valid for `master` branch
16
27
 
17
28
  Please check the documentation for the version of doorkeeper you are using in:
18
29
  https://github.com/doorkeeper-gem/doorkeeper/releases
19
30
 
20
- - See the [wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki)
31
+ - See the [Wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki)
32
+ - See [upgrade guides](https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions)
21
33
  - For general questions, please post in [Stack Overflow](http://stackoverflow.com/questions/tagged/doorkeeper)
34
+ - See [SECURITY.md](SECURITY.md) for this project's security disclose
35
+ policy
22
36
 
23
37
  ## Table of Contents
24
38
 
@@ -27,19 +41,26 @@ https://github.com/doorkeeper-gem/doorkeeper/releases
27
41
 
28
42
  - [Installation](#installation)
29
43
  - [Configuration](#configuration)
30
- - [Active Record](#active-record)
31
- - [Other ORMs](#other-orms)
44
+ - [ORM](#orm)
45
+ - [Active Record](#active-record)
46
+ - [MongoDB](#mongodb)
47
+ - [Sequel](#sequel)
48
+ - [Couchbase](#couchbase)
49
+ - [API mode](#api-mode)
32
50
  - [Routes](#routes)
33
51
  - [Authenticating](#authenticating)
34
52
  - [Internationalization (I18n)](#internationalization-i18n)
53
+ - [Rake Tasks](#rake-tasks)
35
54
  - [Protecting resources with OAuth (a.k.a your API endpoint)](#protecting-resources-with-oauth-aka-your-api-endpoint)
36
- - [Protect your API with OAuth when using Grape](#protect-your-api-with-oauth-when-using-grape)
55
+ - [Ruby on Rails controllers](#ruby-on-rails-controllers)
56
+ - [Grape endpoints](#grape-endpoints)
37
57
  - [Route Constraints and other integrations](#route-constraints-and-other-integrations)
38
58
  - [Access Token Scopes](#access-token-scopes)
39
59
  - [Custom Access Token Generator](#custom-access-token-generator)
40
60
  - [Authenticated resource owner](#authenticated-resource-owner)
41
61
  - [Applications list](#applications-list)
42
62
  - [Other customizations](#other-customizations)
63
+ - [Testing](#testing)
43
64
  - [Upgrading](#upgrading)
44
65
  - [Development](#development)
45
66
  - [Contributing](#contributing)
@@ -69,10 +90,12 @@ This will install the doorkeeper initializer into `config/initializers/doorkeepe
69
90
 
70
91
  ## Configuration
71
92
 
72
- ### Active Record
93
+ ### ORM
73
94
 
74
- By default doorkeeper is configured to use active record, so to start you have
75
- to generate the migration tables:
95
+ #### Active Record
96
+
97
+ By default doorkeeper is configured to use Active Record, so to start you have
98
+ to generate the migration tables (supports Rails >= 5 migrations versioning):
76
99
 
77
100
  rails generate doorkeeper:migration
78
101
 
@@ -84,25 +107,81 @@ for each table that includes a `resource_owner_id` column:
84
107
  add_foreign_key :table_name, :users, column: :resource_owner_id
85
108
  ```
86
109
 
110
+ If you want to enable [PKCE flow] for mobile apps, you need to generate another
111
+ migration:
112
+
113
+ [PKCE flow]: https://tools.ietf.org/html/rfc7636
114
+
115
+ ```sh
116
+ rails generate doorkeeper:pkce
117
+ ```
118
+
87
119
  Then run migrations:
88
120
 
89
121
  ```sh
90
122
  rake db:migrate
91
123
  ```
92
124
 
93
- ### Other ORMs
125
+ Ensure to use non-confidential apps for pkce. PKCE is created, because
126
+ you cannot trust its apps' secret. So whatever app needs pkce: it means, it cannot
127
+ be a confidential app by design.
128
+
129
+
130
+ Remember to add associations to your model so the related records are deleted.
131
+ If you don't do this an `ActiveRecord::InvalidForeignKey`-error will be raised
132
+ when you try to destroy a model with related access grants or access tokens.
133
+
134
+ ```ruby
135
+ class User < ApplicationRecord
136
+ has_many :access_grants, class_name: "Doorkeeper::AccessGrant",
137
+ foreign_key: :resource_owner_id,
138
+ dependent: :delete_all # or :destroy if you need callbacks
139
+
140
+ has_many :access_tokens, class_name: "Doorkeeper::AccessToken",
141
+ foreign_key: :resource_owner_id,
142
+ dependent: :delete_all # or :destroy if you need callbacks
143
+ end
144
+ ```
145
+
146
+ #### MongoDB
94
147
 
95
148
  See [doorkeeper-mongodb project] for Mongoid and MongoMapper support. Follow along
96
149
  the implementation in that repository to extend doorkeeper with other ORMs.
97
150
 
98
151
  [doorkeeper-mongodb project]: https://github.com/doorkeeper-gem/doorkeeper-mongodb
99
152
 
153
+ #### Sequel
154
+
100
155
  If you are using [Sequel gem] then you can add [doorkeeper-sequel extension] to your project.
101
156
  Follow configuration instructions for setting up the necessary Doorkeeper ORM.
102
157
 
103
158
  [Sequel gem]: https://github.com/jeremyevans/sequel/
104
159
  [doorkeeper-sequel extension]: https://github.com/nbulaj/doorkeeper-sequel
105
160
 
161
+ #### Couchbase
162
+
163
+ Use [doorkeeper-couchbase] extension if you are using Couchbase database.
164
+
165
+ [doorkeeper-couchbase]: https://github.com/acaprojects/doorkeeper-couchbase
166
+
167
+ ### API mode
168
+
169
+ By default Doorkeeper uses full Rails stack to provide all the OAuth 2 functionality
170
+ with additional features like administration area for managing applications. By the
171
+ way, starting from Doorkeeper 5 you can use API mode for your [API only Rails 5 applications](http://edgeguides.rubyonrails.org/api_app.html).
172
+ All you need is just to configure the gem to work in desired mode:
173
+
174
+ ``` ruby
175
+ Doorkeeper.configure do
176
+ # ...
177
+
178
+ api_only
179
+ end
180
+ ```
181
+
182
+ Keep in mind, that in this mode you will not be able to access `Applications` or
183
+ `Authorized Applications` controllers because they will be skipped. CSRF protections (which are otherwise enabled) will be skipped, and all the redirects will be returned as JSON response with corresponding locations.
184
+
106
185
  ### Routes
107
186
 
108
187
  The installation script will also automatically add the Doorkeeper routes into
@@ -117,12 +196,13 @@ end
117
196
 
118
197
  This will mount following routes:
119
198
 
120
- GET /oauth/authorize/:code
199
+ GET /oauth/authorize/native?code
121
200
  GET /oauth/authorize
122
201
  POST /oauth/authorize
123
202
  DELETE /oauth/authorize
124
203
  POST /oauth/token
125
204
  POST /oauth/revoke
205
+ POST /oauth/introspect
126
206
  resources /oauth/applications
127
207
  GET /oauth/authorized_applications
128
208
  DELETE /oauth/authorized_applications/:id
@@ -139,7 +219,7 @@ and authentication block in `config/initializers/doorkeeper.rb`:
139
219
  ``` ruby
140
220
  Doorkeeper.configure do
141
221
  resource_owner_authenticator do
142
- User.find_by_id(session[:current_user_id]) || redirect_to(login_url)
222
+ User.find_by(id: session[:current_user_id]) || redirect_to(login_url)
143
223
  end
144
224
  end
145
225
  ```
@@ -152,20 +232,52 @@ the methods defined over there.
152
232
  You may want to check other ways of authentication
153
233
  [here](https://github.com/doorkeeper-gem/doorkeeper/wiki/Authenticating-using-Clearance-or-DIY).
154
234
 
155
-
156
235
  ### Internationalization (I18n)
157
236
 
158
- See language files in [the I18n repository](https://github.com/doorkeeper-gem/doorkeeper-i18n).
237
+ Doorkeeper support multiple languages. See language files in
238
+ [the I18n repository](https://github.com/doorkeeper-gem/doorkeeper-i18n).
239
+
240
+ ### Rake Tasks
241
+
242
+ If you are using `rake`, you can load rake tasks provided by this gem, by adding
243
+ the following line to your `Rakefile`:
244
+
245
+ ```ruby
246
+ Doorkeeper::Rake.load_tasks
247
+ ```
248
+
249
+ #### Cleaning up
159
250
 
251
+ By default Doorkeeper is retaining expired and revoked access tokens and grants.
252
+ This allows to keep an audit log of those records, but it also leads to the
253
+ corresponding tables to grow large over the lifetime of your application.
254
+
255
+ If you are concerned about those tables growing too large,
256
+ you can regularly run the following rake task to remove stale entries
257
+ from the database:
258
+
259
+ ```rake
260
+ rake doorkeeper:db:cleanup
261
+ ```
262
+
263
+ Note that this will remove tokens that are expired according to the configured TTL
264
+ in `Doorkeeper.configuration.access_token_expires_in`. The specific `expires_in`
265
+ value of each access token **is not considered**. The same is true for access
266
+ grants.
160
267
 
161
268
  ## Protecting resources with OAuth (a.k.a your API endpoint)
162
269
 
163
- To protect your API with OAuth, you just need to setup `before_action`s
164
- specifying the actions you want to protect. For example:
270
+ ### Ruby on Rails controllers
271
+
272
+ To protect your controllers (usual one or `ActionController::API`) with OAuth,
273
+ you just need to setup `before_action`s specifying the actions you want to
274
+ protect. For example:
165
275
 
166
276
  ``` ruby
167
277
  class Api::V1::ProductsController < Api::V1::ApiController
168
- before_action :doorkeeper_authorize! # Require access token for all actions
278
+ before_action :doorkeeper_authorize! # Requires access token for all actions
279
+
280
+ # before_action -> { doorkeeper_authorize! :read, :write }
169
281
 
170
282
  # your actions
171
283
  end
@@ -174,16 +286,17 @@ end
174
286
  You can pass any option `before_action` accepts, such as `if`, `only`,
175
287
  `except`, and others.
176
288
 
177
- ### Protect your API with OAuth when using Grape
289
+ ### Grape endpoints
178
290
 
179
- As of [PR 567] doorkeeper has helpers for Grape >= 0.10. One of them is
180
- `doorkeeper_authorize!` and can be used in a similar way as an example above.
181
- Note that you have to use `require 'doorkeeper/grape/helpers'` and
182
- `helpers Doorkeeper::Grape::Helpers`.
291
+ Starting from version 2.2 Doorkeeper provides helpers for the
292
+ [Grape framework] >= 0.10. One of them is `doorkeeper_authorize!` that
293
+ can be used in a similar way as an example above to protect your API
294
+ with OAuth. Note that you have to use `require 'doorkeeper/grape/helpers'`
295
+ and `helpers Doorkeeper::Grape::Helpers` in your Grape API class.
183
296
 
184
297
  For more information about integration with Grape see the [Wiki].
185
298
 
186
- [PR 567]: https://github.com/doorkeeper-gem/doorkeeper/pull/567
299
+ [Grape framework]: https://github.com/ruby-grape/grape
187
300
  [Wiki]: https://github.com/doorkeeper-gem/doorkeeper/wiki/Grape-Integration
188
301
 
189
302
  ``` ruby
@@ -198,8 +311,8 @@ module API
198
311
  doorkeeper_authorize!
199
312
  end
200
313
 
201
- route_setting :scopes, ['user:email']
202
- get :emails do
314
+ # route_setting :scopes, ['user:email'] - for old versions of Grape
315
+ get :emails, scopes: [:user, :write] do
203
316
  [{'email' => current_user.email}]
204
317
  end
205
318
 
@@ -209,7 +322,6 @@ module API
209
322
  end
210
323
  ```
211
324
 
212
-
213
325
  ### Route Constraints and other integrations
214
326
 
215
327
  You can leverage the `Doorkeeper.authenticate` facade to easily extract a
@@ -224,7 +336,6 @@ module Constraint
224
336
  token = Doorkeeper.authenticate(request)
225
337
  token && token.accessible?
226
338
  end
227
-
228
339
  end
229
340
  end
230
341
  ```
@@ -296,8 +407,10 @@ JWT token support is available with
296
407
 
297
408
  ### Custom Base Controller
298
409
 
299
- By default Doorkeeper's main controller `Doorkeeper::ApplicationController` inherits from `ActionController::Base`.
300
- You may want to use your own controller to inherit from, to keep Doorkeeper controllers in the same context than the rest your app:
410
+ By default Doorkeeper's main controller `Doorkeeper::ApplicationController`
411
+ inherits from `ActionController::Base`. You may want to use your own
412
+ controller to inherit from, to keep Doorkeeper controllers in the same
413
+ context than the rest your app:
301
414
 
302
415
  ```ruby
303
416
  Doorkeeper.configure do
@@ -342,7 +455,7 @@ To protect the endpoint you should uncomment these lines:
342
455
  # config/initializers/doorkeeper.rb
343
456
  Doorkeeper.configure do
344
457
  admin_authenticator do |routes|
345
- Admin.find_by_id(session[:admin_id]) || redirect_to(routes.new_admin_session_url)
458
+ Admin.find_by(id: session[:admin_id]) || redirect_to(routes.new_admin_session_url)
346
459
  end
347
460
  end
348
461
  ```
@@ -353,10 +466,36 @@ customize the controller used by the list or skip the controller all together.
353
466
  For more information see the page
354
467
  [in the wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-routes).
355
468
 
469
+ By default, everybody can create application with any scopes. However,
470
+ you can enforce users to create applications only with configured scopes
471
+ (`default_scopes` and `optional_scopes` from the Doorkeeper initializer):
472
+
473
+ ```ruby
474
+ # config/initializers/doorkeeper.rb
475
+ Doorkeeper.configure do
476
+ # ...
477
+
478
+ default_scopes :read, :write
479
+ optional_scopes :create, :update
480
+
481
+ enforce_configured_scopes
482
+ end
483
+ ```
484
+
356
485
  ## Other customizations
357
486
 
358
487
  - [Associate users to OAuth applications (ownership)](https://github.com/doorkeeper-gem/doorkeeper/wiki/Associate-users-to-OAuth-applications-%28ownership%29)
359
488
  - [CORS - Cross Origin Resource Sharing](https://github.com/doorkeeper-gem/doorkeeper/wiki/%5BCORS%5D-Cross-Origin-Resource-Sharing)
489
+ - see more on [Wiki page](https://github.com/doorkeeper-gem/doorkeeper/wiki)
490
+
491
+ ## Testing
492
+
493
+ You can use Doorkeeper models in your application test suite. Note that starting from
494
+ Doorkeeper 4.3.0 it uses [ActiveSupport lazy loading hooks](http://api.rubyonrails.org/classes/ActiveSupport/LazyLoadHooks.html)
495
+ to load models. There are [known issue](https://github.com/doorkeeper-gem/doorkeeper/issues/1043)
496
+ with the `factory_bot_rails` gem (it executes factories building before `ActiveRecord::Base`
497
+ is initialized using hooks in gem railtie, so you can catch a `uninitialized constant` error).
498
+ It is recommended to use pure `factory_bot` gem to solve this problem.
360
499
 
361
500
  ## Upgrading
362
501
 
@@ -373,7 +512,7 @@ To run the local engine server:
373
512
 
374
513
  ```
375
514
  bundle install
376
- bundle exec rails server
515
+ bundle exec rake doorkeeper:server
377
516
  ````
378
517
 
379
518
  By default, it uses the latest Rails version with ActiveRecord. To run the
@@ -383,8 +522,6 @@ tests with a specific ORM and Rails version:
383
522
  rails=4.2.0 orm=active_record bundle exec rake
384
523
  ```
385
524
 
386
- Or you might prefer to run `script/run_all` to integrate against all ORMs.
387
-
388
525
  ## Contributing
389
526
 
390
527
  Want to contribute and don't know where to start? Check out [features we're
@@ -400,7 +537,7 @@ page](https://github.com/doorkeeper-gem/doorkeeper/wiki/Contributing).
400
537
 
401
538
  ### Wiki
402
539
 
403
- You can find everything about doorkeeper in our [wiki
540
+ You can find everything about Doorkeeper in our [wiki
404
541
  here](https://github.com/doorkeeper-gem/doorkeeper/wiki).
405
542
 
406
543
  ### Screencast
@@ -422,7 +559,6 @@ here](https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-wi
422
559
  Thanks to all our [awesome
423
560
  contributors](https://github.com/doorkeeper-gem/doorkeeper/graphs/contributors)!
424
561
 
425
-
426
562
  ### IETF Standards
427
563
 
428
564
  * [The OAuth 2.0 Authorization Framework](http://tools.ietf.org/html/rfc6749)
data/RELEASING.md CHANGED
@@ -1,17 +1,10 @@
1
1
  # Releasing doorkeeper
2
2
 
3
+ How to release doorkeeper in five easy steps!
4
+
3
5
  1. Update `lib/doorkeeper/version.rb` file accordingly.
4
6
  2. Update `NEWS.md` to reflect the changes since last release.
5
- 3. Commit changes. There shouldn’t be code changes, and thus CI doesn’t need to
6
- run, you can then add “[ci skip]” to the commit message.
7
- 4. Tag the release: `git tag vVERSION -m "Release vVERSION"`
8
- 5. Push changes: `git push && git push --tags`
9
- 6. Build and publish the gem:
10
-
11
- ```bash
12
- gem build doorkeeper.gemspec
13
- gem push doorkeeper-*.gem
14
- ```
15
-
16
- 7. Announce the new release, making sure to say “thank you” to the contributors
7
+ 3. Commit changes: `git commit -am 'Bump to vVERSION'`
8
+ 4. Run `rake release`
9
+ 5. Announce the new release, making sure to say “thank you” to the contributors
17
10
  who helped shape this version!
data/Rakefile CHANGED
@@ -15,6 +15,12 @@ namespace :doorkeeper do
15
15
  cd 'spec/dummy'
16
16
  system 'bundle exec rails g doorkeeper:install --force'
17
17
  end
18
+
19
+ desc 'Runs local test server'
20
+ task :server do
21
+ cd 'spec/dummy'
22
+ system 'bundle exec rails server'
23
+ end
18
24
  end
19
25
 
20
26
  Bundler::GemHelper.install_tasks
data/SECURITY.md ADDED
@@ -0,0 +1,15 @@
1
+ # Reporting security issues in Doorkeeper
2
+
3
+ Hello! Thank you for wanting to disclose a possible security
4
+ vulnerability within the Doorkeeper gem! Please follow our disclosure
5
+ policy as outlined below:
6
+
7
+ 1. Do NOT open up a GitHub issue with your report. Security reports
8
+ should be kept private until a possible fix is determined.
9
+ 2. Send an email to Nikita Bulai at bulaj.nikita AT gmail.com or one of
10
+ the others Doorkeeper maintainers listed in gemspec. You should receive
11
+ a prompt response.
12
+ 3. Be patient. Since Doorkeeper is in a stable maintenance phase, we want to
13
+ do as little as possible to rock the boat of the project.
14
+
15
+ Thank you very much for adhering for these policies!
data/UPGRADE.md ADDED
@@ -0,0 +1,2 @@
1
+ See [Upgrade Guides](https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions)
2
+ in the project Wiki.
@@ -5,6 +5,6 @@
5
5
  *= require_tree .
6
6
  */
7
7
 
8
- td {
9
- vertical-align: middle !important;
8
+ .doorkeeper-admin .form-group > .field_with_errors {
9
+ width: 16.66667%;
10
10
  }
@@ -4,12 +4,9 @@ module Doorkeeper
4
4
 
5
5
  include Helpers::Controller
6
6
 
7
- if ::Rails.version.to_i < 4
8
- protect_from_forgery
9
- else
7
+ unless Doorkeeper.configuration.api_only
10
8
  protect_from_forgery with: :exception
9
+ helper 'doorkeeper/dashboard'
11
10
  end
12
-
13
- helper 'doorkeeper/dashboard'
14
11
  end
15
12
  end
@@ -5,6 +5,7 @@ module Doorkeeper
5
5
  AbstractController::Rendering,
6
6
  ActionController::Rendering,
7
7
  ActionController::Renderers::All,
8
+ AbstractController::Callbacks,
8
9
  Helpers::Controller
9
10
  ].freeze
10
11
 
@@ -12,6 +13,9 @@ module Doorkeeper
12
13
  include mod
13
14
  end
14
15
 
16
+ before_action :enforce_content_type,
17
+ if: -> { Doorkeeper.configuration.enforce_content_type }
18
+
15
19
  ActiveSupport.run_load_hooks(:doorkeeper_metal_controller, self)
16
20
  end
17
21
  end
@@ -1,12 +1,24 @@
1
1
  module Doorkeeper
2
2
  class ApplicationsController < Doorkeeper::ApplicationController
3
- layout 'doorkeeper/admin'
3
+ layout 'doorkeeper/admin' unless Doorkeeper.configuration.api_only
4
4
 
5
5
  before_action :authenticate_admin!
6
- before_action :set_application, only: [:show, :edit, :update, :destroy]
6
+ before_action :set_application, only: %i[show edit update destroy]
7
7
 
8
8
  def index
9
- @applications = Application.all
9
+ @applications = Application.ordered_by(:created_at)
10
+
11
+ respond_to do |format|
12
+ format.html
13
+ format.json { head :no_content }
14
+ end
15
+ end
16
+
17
+ def show
18
+ respond_to do |format|
19
+ format.html
20
+ format.json { render json: @application }
21
+ end
10
22
  end
11
23
 
12
24
  def new
@@ -15,26 +27,47 @@ module Doorkeeper
15
27
 
16
28
  def create
17
29
  @application = Application.new(application_params)
30
+
18
31
  if @application.save
19
- flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create])
20
- redirect_to oauth_application_url(@application)
32
+ flash[:notice] = I18n.t(:notice, scope: %i[doorkeeper flash applications create])
33
+
34
+ respond_to do |format|
35
+ format.html { redirect_to oauth_application_url(@application) }
36
+ format.json { render json: @application }
37
+ end
21
38
  else
22
- render :new
39
+ respond_to do |format|
40
+ format.html { render :new }
41
+ format.json { render json: { errors: @application.errors.full_messages }, status: :unprocessable_entity }
42
+ end
23
43
  end
24
44
  end
25
45
 
46
+ def edit; end
47
+
26
48
  def update
27
- if @application.update_attributes(application_params)
28
- flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :update])
29
- redirect_to oauth_application_url(@application)
49
+ if @application.update(application_params)
50
+ flash[:notice] = I18n.t(:notice, scope: %i[doorkeeper flash applications update])
51
+
52
+ respond_to do |format|
53
+ format.html { redirect_to oauth_application_url(@application) }
54
+ format.json { render json: @application }
55
+ end
30
56
  else
31
- render :edit
57
+ respond_to do |format|
58
+ format.html { render :edit }
59
+ format.json { render json: { errors: @application.errors.full_messages }, status: :unprocessable_entity }
60
+ end
32
61
  end
33
62
  end
34
63
 
35
64
  def destroy
36
- flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :destroy]) if @application.destroy
37
- redirect_to oauth_applications_url
65
+ flash[:notice] = I18n.t(:notice, scope: %i[doorkeeper flash applications destroy]) if @application.destroy
66
+
67
+ respond_to do |format|
68
+ format.html { redirect_to oauth_applications_url }
69
+ format.json { head :no_content }
70
+ end
38
71
  end
39
72
 
40
73
  private
@@ -44,7 +77,8 @@ module Doorkeeper
44
77
  end
45
78
 
46
79
  def application_params
47
- params.require(:doorkeeper_application).permit(:name, :redirect_uri, :scopes)
80
+ params.require(:doorkeeper_application).
81
+ permit(:name, :redirect_uri, :scopes, :confidential)
48
82
  end
49
83
  end
50
84
  end