doorkeeper 3.1.0 → 4.4.3

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 (195) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.github/ISSUE_TEMPLATE.md +25 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +17 -0
  5. data/.gitignore +6 -1
  6. data/.hound.yml +2 -13
  7. data/.rubocop.yml +17 -0
  8. data/.travis.yml +26 -10
  9. data/Appraisals +18 -0
  10. data/CODE_OF_CONDUCT.md +46 -0
  11. data/CONTRIBUTING.md +2 -0
  12. data/Gemfile +5 -5
  13. data/NEWS.md +141 -2
  14. data/README.md +149 -66
  15. data/RELEASING.md +5 -12
  16. data/Rakefile +1 -1
  17. data/SECURITY.md +15 -0
  18. data/app/controllers/doorkeeper/application_controller.rb +4 -6
  19. data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
  20. data/app/controllers/doorkeeper/applications_controller.rb +18 -8
  21. data/app/controllers/doorkeeper/authorizations_controller.rb +1 -1
  22. data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
  23. data/app/controllers/doorkeeper/tokens_controller.rb +62 -15
  24. data/app/helpers/doorkeeper/dashboard_helper.rb +14 -10
  25. data/app/validators/redirect_uri_validator.rb +12 -2
  26. data/app/views/doorkeeper/applications/_delete_form.html.erb +1 -2
  27. data/app/views/doorkeeper/applications/_form.html.erb +13 -2
  28. data/app/views/doorkeeper/applications/index.html.erb +2 -0
  29. data/app/views/doorkeeper/applications/show.html.erb +4 -1
  30. data/app/views/doorkeeper/authorizations/new.html.erb +1 -1
  31. data/app/views/doorkeeper/authorized_applications/_delete_form.html.erb +1 -2
  32. data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
  33. data/app/views/layouts/doorkeeper/admin.html.erb +1 -1
  34. data/config/locales/en.yml +12 -7
  35. data/doorkeeper.gemspec +16 -11
  36. data/gemfiles/rails_4_2.gemfile +13 -0
  37. data/gemfiles/rails_5_0.gemfile +12 -0
  38. data/gemfiles/rails_5_1.gemfile +12 -0
  39. data/gemfiles/rails_5_2.gemfile +12 -0
  40. data/gemfiles/rails_master.gemfile +14 -0
  41. data/lib/doorkeeper/config.rb +119 -46
  42. data/lib/doorkeeper/engine.rb +11 -7
  43. data/lib/doorkeeper/errors.rb +18 -0
  44. data/lib/doorkeeper/grape/helpers.rb +14 -8
  45. data/lib/doorkeeper/helpers/controller.rb +8 -19
  46. data/lib/doorkeeper/models/access_grant_mixin.rb +10 -21
  47. data/lib/doorkeeper/models/access_token_mixin.rb +147 -43
  48. data/lib/doorkeeper/models/application_mixin.rb +33 -35
  49. data/lib/doorkeeper/models/concerns/accessible.rb +4 -0
  50. data/lib/doorkeeper/models/concerns/expirable.rb +15 -5
  51. data/lib/doorkeeper/models/concerns/orderable.rb +13 -0
  52. data/lib/doorkeeper/models/concerns/ownership.rb +6 -1
  53. data/lib/doorkeeper/models/concerns/revocable.rb +37 -2
  54. data/lib/doorkeeper/oauth/authorization/token.rb +22 -18
  55. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +20 -18
  56. data/lib/doorkeeper/oauth/authorization_code_request.rb +7 -5
  57. data/lib/doorkeeper/oauth/{request_concern.rb → base_request.rb} +9 -2
  58. data/lib/doorkeeper/oauth/base_response.rb +29 -0
  59. data/lib/doorkeeper/oauth/client/credentials.rb +21 -8
  60. data/lib/doorkeeper/oauth/client.rb +2 -3
  61. data/lib/doorkeeper/oauth/client_credentials/creator.rb +1 -1
  62. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  63. data/lib/doorkeeper/oauth/client_credentials/validation.rb +1 -1
  64. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -8
  65. data/lib/doorkeeper/oauth/code_response.rb +16 -16
  66. data/lib/doorkeeper/oauth/error.rb +2 -2
  67. data/lib/doorkeeper/oauth/error_response.rb +10 -10
  68. data/lib/doorkeeper/oauth/forbidden_token_response.rb +1 -1
  69. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -1
  70. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +17 -1
  71. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -4
  72. data/lib/doorkeeper/oauth/password_access_token_request.rb +8 -13
  73. data/lib/doorkeeper/oauth/pre_authorization.rb +5 -3
  74. data/lib/doorkeeper/oauth/refresh_token_request.rb +23 -14
  75. data/lib/doorkeeper/oauth/scopes.rb +18 -8
  76. data/lib/doorkeeper/oauth/token.rb +20 -21
  77. data/lib/doorkeeper/oauth/token_introspection.rb +128 -0
  78. data/lib/doorkeeper/oauth/token_request.rb +1 -2
  79. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  80. data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -0
  81. data/lib/doorkeeper/orm/active_record/access_token.rb +34 -8
  82. data/lib/doorkeeper/orm/active_record/application.rb +48 -11
  83. data/lib/doorkeeper/orm/active_record.rb +17 -22
  84. data/lib/doorkeeper/rails/helpers.rb +6 -9
  85. data/lib/doorkeeper/rails/routes/mapper.rb +4 -4
  86. data/lib/doorkeeper/rails/routes/mapping.rb +1 -1
  87. data/lib/doorkeeper/rails/routes.rb +17 -11
  88. data/lib/doorkeeper/request/authorization_code.rb +7 -1
  89. data/lib/doorkeeper/request/password.rb +2 -2
  90. data/lib/doorkeeper/request/refresh_token.rb +1 -1
  91. data/lib/doorkeeper/request.rb +7 -1
  92. data/lib/doorkeeper/server.rb +0 -8
  93. data/lib/doorkeeper/validations.rb +3 -2
  94. data/lib/doorkeeper/version.rb +34 -1
  95. data/lib/doorkeeper.rb +10 -2
  96. data/lib/generators/doorkeeper/add_client_confidentiality_generator.rb +31 -0
  97. data/lib/generators/doorkeeper/application_owner_generator.rb +11 -2
  98. data/lib/generators/doorkeeper/migration_generator.rb +13 -1
  99. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +35 -0
  100. data/lib/generators/doorkeeper/templates/add_confidential_to_application_migration.rb.erb +11 -0
  101. data/{spec/dummy/db/migrate/20130902175349_add_owner_to_application.rb → lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb} +1 -1
  102. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +11 -0
  103. data/lib/generators/doorkeeper/templates/initializer.rb +38 -6
  104. data/lib/generators/doorkeeper/templates/migration.rb.erb +69 -0
  105. data/spec/controllers/application_metal_controller.rb +10 -0
  106. data/spec/controllers/applications_controller_spec.rb +15 -4
  107. data/spec/controllers/authorizations_controller_spec.rb +74 -27
  108. data/spec/controllers/protected_resources_controller_spec.rb +70 -32
  109. data/spec/controllers/token_info_controller_spec.rb +17 -13
  110. data/spec/controllers/tokens_controller_spec.rb +198 -12
  111. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -4
  112. data/spec/dummy/app/controllers/home_controller.rb +1 -1
  113. data/spec/dummy/app/controllers/metal_controller.rb +1 -1
  114. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +3 -3
  115. data/spec/dummy/app/models/user.rb +0 -4
  116. data/spec/dummy/config/application.rb +2 -36
  117. data/spec/dummy/config/environment.rb +1 -1
  118. data/spec/dummy/config/environments/test.rb +4 -15
  119. data/spec/dummy/config/initializers/doorkeeper.rb +19 -3
  120. data/spec/dummy/config/initializers/new_framework_defaults.rb +6 -0
  121. data/spec/dummy/config/initializers/secret_token.rb +0 -1
  122. data/spec/dummy/db/migrate/20111122132257_create_users.rb +3 -1
  123. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +3 -1
  124. data/{lib/generators/doorkeeper/templates/migration.rb → spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb} +16 -4
  125. data/{lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb → spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb} +4 -2
  126. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +13 -0
  127. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_application.rb +13 -0
  128. data/spec/dummy/db/schema.rb +24 -22
  129. data/spec/factories.rb +4 -2
  130. data/spec/generators/application_owner_generator_spec.rb +24 -5
  131. data/spec/generators/migration_generator_spec.rb +24 -3
  132. data/spec/generators/previous_refresh_token_generator_spec.rb +57 -0
  133. data/spec/grape/grape_integration_spec.rb +135 -0
  134. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  135. data/spec/lib/config_spec.rb +159 -14
  136. data/spec/lib/doorkeeper_spec.rb +135 -13
  137. data/spec/lib/models/expirable_spec.rb +0 -1
  138. data/spec/lib/models/revocable_spec.rb +27 -4
  139. data/spec/lib/oauth/authorization/uri_builder_spec.rb +1 -2
  140. data/spec/lib/oauth/authorization_code_request_spec.rb +55 -12
  141. data/spec/lib/oauth/base_request_spec.rb +155 -0
  142. data/spec/lib/oauth/base_response_spec.rb +45 -0
  143. data/spec/lib/oauth/client/credentials_spec.rb +45 -2
  144. data/spec/lib/oauth/client_credentials/creator_spec.rb +1 -1
  145. data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
  146. data/spec/lib/oauth/client_credentials_request_spec.rb +1 -0
  147. data/spec/lib/oauth/code_request_spec.rb +1 -3
  148. data/spec/lib/oauth/code_response_spec.rb +34 -0
  149. data/spec/lib/oauth/error_response_spec.rb +9 -9
  150. data/spec/lib/oauth/error_spec.rb +1 -1
  151. data/spec/lib/oauth/helpers/uri_checker_spec.rb +115 -1
  152. data/spec/lib/oauth/invalid_token_response_spec.rb +36 -8
  153. data/spec/lib/oauth/password_access_token_request_spec.rb +14 -8
  154. data/spec/lib/oauth/pre_authorization_spec.rb +12 -7
  155. data/spec/lib/oauth/refresh_token_request_spec.rb +52 -9
  156. data/spec/lib/oauth/scopes_spec.rb +28 -2
  157. data/spec/lib/oauth/token_request_spec.rb +6 -8
  158. data/spec/lib/oauth/token_spec.rb +12 -5
  159. data/spec/lib/server_spec.rb +10 -3
  160. data/spec/models/doorkeeper/access_grant_spec.rb +1 -1
  161. data/spec/models/doorkeeper/access_token_spec.rb +116 -48
  162. data/spec/models/doorkeeper/application_spec.rb +145 -29
  163. data/spec/requests/applications/applications_request_spec.rb +5 -5
  164. data/spec/requests/endpoints/authorization_spec.rb +5 -6
  165. data/spec/requests/endpoints/token_spec.rb +8 -1
  166. data/spec/requests/flows/authorization_code_errors_spec.rb +11 -1
  167. data/spec/requests/flows/authorization_code_spec.rb +6 -13
  168. data/spec/requests/flows/client_credentials_spec.rb +29 -1
  169. data/spec/requests/flows/implicit_grant_errors_spec.rb +2 -2
  170. data/spec/requests/flows/password_spec.rb +118 -15
  171. data/spec/requests/flows/refresh_token_spec.rb +89 -19
  172. data/spec/requests/flows/revoke_token_spec.rb +105 -91
  173. data/spec/requests/protected_resources/metal_spec.rb +1 -1
  174. data/spec/requests/protected_resources/private_api_spec.rb +1 -1
  175. data/spec/routing/custom_controller_routes_spec.rb +4 -0
  176. data/spec/routing/default_routes_spec.rb +5 -1
  177. data/spec/spec_helper.rb +2 -0
  178. data/spec/spec_helper_integration.rb +22 -4
  179. data/spec/support/dependencies/factory_girl.rb +2 -2
  180. data/spec/support/helpers/access_token_request_helper.rb +1 -1
  181. data/spec/support/helpers/model_helper.rb +34 -7
  182. data/spec/support/helpers/request_spec_helper.rb +17 -5
  183. data/spec/support/helpers/url_helper.rb +9 -8
  184. data/spec/support/http_method_shim.rb +38 -0
  185. data/spec/support/shared/controllers_shared_context.rb +15 -10
  186. data/spec/support/shared/models_shared_examples.rb +5 -5
  187. data/spec/validators/redirect_uri_validator_spec.rb +51 -6
  188. data/spec/version/version_spec.rb +15 -0
  189. metadata +128 -46
  190. data/lib/doorkeeper/oauth/client/methods.rb +0 -18
  191. data/lib/generators/doorkeeper/application_scopes_generator.rb +0 -34
  192. data/lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb +0 -5
  193. data/spec/dummy/db/migrate/20130902165751_create_doorkeeper_tables.rb +0 -41
  194. data/spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb +0 -5
  195. data/spec/lib/oauth/client/methods_spec.rb +0 -54
@@ -2,9 +2,7 @@ require 'spec_helper_integration'
2
2
 
3
3
  describe Doorkeeper::TokensController do
4
4
  describe 'when authorization has succeeded' do
5
- let :token do
6
- double(:token, authorize: true)
7
- end
5
+ let(:token) { double(:token, authorize: true) }
8
6
 
9
7
  before do
10
8
  allow(controller).to receive(:token) { token }
@@ -38,7 +36,7 @@ describe Doorkeeper::TokensController do
38
36
  allow(I18n).to receive(:translate).
39
37
  with(
40
38
  custom_message,
41
- hash_including(scope: [:doorkeeper, :errors, :messages]),
39
+ hash_including(scope: %i[doorkeeper errors messages]),
42
40
  ).
43
41
  and_return('Authorization custom message')
44
42
 
@@ -57,19 +55,71 @@ describe Doorkeeper::TokensController do
57
55
  }
58
56
  expect(response.status).to eq 401
59
57
  expect(response.headers['WWW-Authenticate']).to match(/Bearer/)
60
- expect(JSON.load(response.body)).to eq expected_response_body
58
+ expect(JSON.parse(response.body)).to eq expected_response_body
61
59
  end
62
60
  end
63
61
 
64
- describe 'when revoke authorization has failed' do
65
- # http://tools.ietf.org/html/rfc7009#section-2.2
66
- it 'returns no error response' do
67
- token = double(:token, authorize: false)
68
- allow(controller).to receive(:token) { token }
62
+ # http://tools.ietf.org/html/rfc7009#section-2.2
63
+ describe 'revoking tokens' do
64
+ let(:client) { FactoryBot.create(:application) }
65
+ let(:access_token) { FactoryBot.create(:access_token, application: client) }
66
+
67
+ before(:each) do
68
+ allow(controller).to receive(:token) { access_token }
69
+ end
70
+
71
+ context 'when associated app is public' do
72
+ let(:client) { FactoryBot.create(:application, confidential: false) }
73
+
74
+ it 'returns 200' do
75
+ post :revoke
76
+
77
+ expect(response.status).to eq 200
78
+ end
79
+
80
+ it 'revokes the access token' do
81
+ post :revoke
82
+
83
+ expect(access_token.reload).to have_attributes(revoked?: true)
84
+ end
85
+ end
86
+
87
+ context 'when associated app is confidential' do
88
+ let(:client) { FactoryBot.create(:application, confidential: true) }
89
+ let(:oauth_client) { Doorkeeper::OAuth::Client.new(client) }
90
+
91
+ before(:each) do
92
+ allow_any_instance_of(Doorkeeper::Server).to receive(:client) { oauth_client }
93
+ end
94
+
95
+ it 'returns 200' do
96
+ post :revoke
97
+
98
+ expect(response.status).to eq 200
99
+ end
100
+
101
+ it 'revokes the access token' do
102
+ post :revoke
103
+
104
+ expect(access_token.reload).to have_attributes(revoked?: true)
105
+ end
106
+
107
+ context 'when authorization fails' do
108
+ let(:some_other_client) { FactoryBot.create(:application, confidential: true) }
109
+ let(:oauth_client) { Doorkeeper::OAuth::Client.new(some_other_client) }
110
+
111
+ it 'returns 200' do
112
+ post :revoke
69
113
 
70
- post :revoke
114
+ expect(response.status).to eq 200
115
+ end
71
116
 
72
- expect(response.status).to eq 200
117
+ it 'does not revoke the access token' do
118
+ post :revoke
119
+
120
+ expect(access_token.reload).to have_attributes(revoked?: false)
121
+ end
122
+ end
73
123
  end
74
124
  end
75
125
 
@@ -85,4 +135,140 @@ describe Doorkeeper::TokensController do
85
135
  post :create
86
136
  end
87
137
  end
138
+
139
+ describe 'when requested token introspection' do
140
+ context 'authorized using Bearer token' do
141
+ let(:client) { FactoryBot.create(:application) }
142
+ let(:access_token) { FactoryBot.create(:access_token, application: client) }
143
+
144
+ it 'responds with full token introspection' do
145
+ request.headers['Authorization'] = "Bearer #{access_token.token}"
146
+
147
+ post :introspect, token: access_token.token
148
+
149
+ should_have_json 'active', true
150
+ expect(json_response).to include('client_id', 'token_type', 'exp', 'iat')
151
+ end
152
+ end
153
+
154
+ context 'authorized using Client Authentication' do
155
+ let(:client) { FactoryBot.create(:application) }
156
+ let(:access_token) { FactoryBot.create(:access_token, application: client) }
157
+
158
+ it 'responds with full token introspection' do
159
+ request.headers['Authorization'] = basic_auth_header_for_client(client)
160
+
161
+ post :introspect, token: access_token.token
162
+
163
+ should_have_json 'active', true
164
+ expect(json_response).to include('client_id', 'token_type', 'exp', 'iat')
165
+ should_have_json 'client_id', client.uid
166
+ end
167
+ end
168
+
169
+ context 'public access token' do
170
+ let(:client) { FactoryBot.create(:application) }
171
+ let(:access_token) { FactoryBot.create(:access_token, application: nil) }
172
+
173
+ it 'responds with full token introspection' do
174
+ request.headers['Authorization'] = basic_auth_header_for_client(client)
175
+
176
+ post :introspect, token: access_token.token
177
+
178
+ should_have_json 'active', true
179
+ expect(json_response).to include('client_id', 'token_type', 'exp', 'iat')
180
+ should_have_json 'client_id', nil
181
+ end
182
+ end
183
+
184
+ context 'token was issued to a different client than is making this request' do
185
+ let(:client) { FactoryBot.create(:application) }
186
+ let(:different_client) { FactoryBot.create(:application) }
187
+ let(:access_token) { FactoryBot.create(:access_token, application: client) }
188
+
189
+ it 'responds with only active state' do
190
+ request.headers['Authorization'] = basic_auth_header_for_client(different_client)
191
+
192
+ post :introspect, token: access_token.token
193
+
194
+ expect(response).to be_successful
195
+
196
+ should_have_json 'active', false
197
+ expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
198
+ end
199
+ end
200
+
201
+ context 'using invalid credentials to authorize' do
202
+ let(:client) { double(uid: '123123', secret: '666999') }
203
+ let(:access_token) { FactoryBot.create(:access_token) }
204
+
205
+ it 'responds with invalid_client error' do
206
+ request.headers['Authorization'] = basic_auth_header_for_client(client)
207
+
208
+ post :introspect, token: access_token.token
209
+
210
+ expect(response).not_to be_successful
211
+ response_status_should_be 401
212
+
213
+ should_not_have_json 'active'
214
+ should_have_json 'error', 'invalid_client'
215
+ end
216
+ end
217
+
218
+ context 'using wrong token value' do
219
+ let(:client) { FactoryBot.create(:application) }
220
+ let(:access_token) { FactoryBot.create(:access_token, application: client) }
221
+
222
+ it 'responds with only active state' do
223
+ request.headers['Authorization'] = basic_auth_header_for_client(client)
224
+
225
+ post :introspect, token: SecureRandom.hex(16)
226
+
227
+ should_have_json 'active', false
228
+ expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
229
+ end
230
+ end
231
+
232
+ context 'when requested Access Token expired' do
233
+ let(:client) { FactoryBot.create(:application) }
234
+ let(:access_token) { FactoryBot.create(:access_token, application: client, created_at: 1.year.ago) }
235
+
236
+ it 'responds with only active state' do
237
+ request.headers['Authorization'] = basic_auth_header_for_client(client)
238
+
239
+ post :introspect, token: access_token.token
240
+
241
+ should_have_json 'active', false
242
+ expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
243
+ end
244
+ end
245
+
246
+ context 'when requested Access Token revoked' do
247
+ let(:client) { FactoryBot.create(:application) }
248
+ let(:access_token) { FactoryBot.create(:access_token, application: client, revoked_at: 1.year.ago) }
249
+
250
+ it 'responds with only active state' do
251
+ request.headers['Authorization'] = basic_auth_header_for_client(client)
252
+
253
+ post :introspect, token: access_token.token
254
+
255
+ should_have_json 'active', false
256
+ expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
257
+ end
258
+ end
259
+
260
+ context 'unauthorized (no bearer token or client credentials)' do
261
+ let(:access_token) { FactoryBot.create(:access_token) }
262
+
263
+ it 'responds with invalid_request error' do
264
+ post :introspect, token: access_token.token
265
+
266
+ expect(response).not_to be_successful
267
+ response_status_should_be 401
268
+
269
+ should_not_have_json 'active'
270
+ should_have_json 'error', 'invalid_request'
271
+ end
272
+ end
273
+ end
88
274
  end
@@ -1,12 +1,12 @@
1
1
  class FullProtectedResourcesController < ApplicationController
2
- before_filter -> { doorkeeper_authorize! :write, :admin }, only: :show
3
- before_filter :doorkeeper_authorize!, only: :index
2
+ before_action -> { doorkeeper_authorize! :write, :admin }, only: :show
3
+ before_action :doorkeeper_authorize!, only: :index
4
4
 
5
5
  def index
6
- render text: 'index'
6
+ render plain: 'index'
7
7
  end
8
8
 
9
9
  def show
10
- render text: 'show'
10
+ render plain: 'show'
11
11
  end
12
12
  end
@@ -12,6 +12,6 @@ class HomeController < ApplicationController
12
12
  end
13
13
 
14
14
  def callback
15
- render text: 'ok'
15
+ render plain: 'ok'
16
16
  end
17
17
  end
@@ -3,7 +3,7 @@ class MetalController < ActionController::Metal
3
3
  include ActionController::Head
4
4
  include Doorkeeper::Rails::Helpers
5
5
 
6
- before_filter :doorkeeper_authorize!
6
+ before_action :doorkeeper_authorize!
7
7
 
8
8
  def index
9
9
  self.response_body = { ok: true }.to_json
@@ -1,11 +1,11 @@
1
1
  class SemiProtectedResourcesController < ApplicationController
2
- before_filter :doorkeeper_authorize!, only: :index
2
+ before_action :doorkeeper_authorize!, only: :index
3
3
 
4
4
  def index
5
- render text: 'protected index'
5
+ render plain: 'protected index'
6
6
  end
7
7
 
8
8
  def show
9
- render text: 'non protected show'
9
+ render plain: 'non protected show'
10
10
  end
11
11
  end
@@ -1,8 +1,4 @@
1
1
  class User < ActiveRecord::Base
2
- if respond_to?(:attr_accessible)
3
- attr_accessible :name, :password
4
- end
5
-
6
2
  def self.authenticate!(name, password)
7
3
  User.where(name: name, password: password).first
8
4
  end
@@ -1,9 +1,8 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
- require 'action_controller/railtie'
4
- require 'sprockets/railtie'
3
+ require 'rails/all'
5
4
 
6
- Bundler.require :default
5
+ Bundler.require(*Rails.groups)
7
6
 
8
7
  require 'yaml'
9
8
 
@@ -20,38 +19,5 @@ module Dummy
20
19
  # Settings in config/environments/* take precedence over those specified here.
21
20
  # Application configuration should go into files in config/initializers
22
21
  # -- all .rb files in that directory are automatically loaded.
23
-
24
- # Only load the plugins named here, in the order given (default is alphabetical).
25
- # :all can be used as a placeholder for all plugins not explicitly named.
26
- # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
27
-
28
- # Activate observers that should always be running.
29
- # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
30
-
31
- if defined?(ActiveRecord) && Rails.version.to_i < 4
32
- config.active_record.whitelist_attributes = true
33
- end
34
-
35
- # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
36
- # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
37
- # config.time_zone = 'Central Time (US & Canada)'
38
-
39
- # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
40
- config.i18n.load_path += Dir[Rails.root.join('../../', 'config/locales', '*.{rb,yml}').to_s]
41
- # config.i18n.default_locale = :en
42
-
43
- # Configure the default encoding used in templates for Ruby 1.9.
44
- config.encoding = 'utf-8'
45
-
46
- # Configure sensitive parameters which will be filtered from the log file.
47
- config.filter_parameters += [:password]
48
-
49
- # Enable the asset pipeline
50
- config.assets.enabled = true
51
-
52
- # Version of your assets, change this if you want to expire all your assets
53
- config.assets.version = '1.0'
54
-
55
- I18n.enforce_available_locales = false
56
22
  end
57
23
  end
@@ -2,4 +2,4 @@
2
2
  require File.expand_path('../application', __FILE__)
3
3
 
4
4
  # Initialize the rails application
5
- Dummy::Application.initialize!
5
+ Rails.application.initialize!
@@ -7,21 +7,10 @@ Dummy::Application.configure do
7
7
  # and recreated between test runs. Don't rely on the data there!
8
8
  config.cache_classes = true
9
9
 
10
- # Configure static asset server for tests with Cache-Control for performance
11
- config.static_cache_control = 'public, max-age=3600'
12
-
13
- if Rails.version.to_i < 4
14
- # Log error messages when you accidentally call methods on nil
15
- config.whiny_nils = true
16
- end
17
-
18
- if Rails.version.to_i >= 4
19
- # Do not eager load code on boot. This avoids loading your whole application
20
- # just for the purpose of running a single test. If you are using a tool that
21
- # preloads Rails for running tests, you may have to set it to true.
22
- config.eager_load = false
23
- config.i18n.enforce_available_locales = true
24
- end
10
+ # Do not eager load code on boot. This avoids loading your whole application
11
+ # just for the purpose of running a single test. If you are using a tool that
12
+ # preloads Rails for running tests, you may have to set it to true.
13
+ config.eager_load = false
25
14
 
26
15
  # Show full error reports and disable caching
27
16
  config.consider_all_requests_local = true
@@ -29,11 +29,16 @@ Doorkeeper.configure do
29
29
  # Issue access tokens with refresh token (disabled by default)
30
30
  use_refresh_token
31
31
 
32
+ # Opt out of breaking api change to the native authorization code flow. Opting out sets the authorization
33
+ # code response route for native redirect uris to oauth/authorize/<code>. The default is oauth/authorize/native?code=<code>.
34
+ # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1143
35
+ # opt_out_native_route_change
36
+
32
37
  # Provide support for an owner to be assigned to each registered application (disabled by default)
33
- # Optional parameter :confirmation => true (default false) if you want to enforce ownership of
38
+ # Optional parameter confirmation: true (default false) if you want to enforce ownership of
34
39
  # a registered application
35
40
  # Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
36
- # enable_application_owner :confirmation => false
41
+ # enable_application_owner confirmation: false
37
42
 
38
43
  # Define access token scopes for your provider
39
44
  # For more information go to
@@ -82,7 +87,18 @@ Doorkeeper.configure do
82
87
  # http://tools.ietf.org/html/rfc6819#section-4.4.2
83
88
  # http://tools.ietf.org/html/rfc6819#section-4.4.3
84
89
  #
85
- # grant_flows %w(authorization_code client_credentials)
90
+ # grant_flows %w[authorization_code client_credentials]
91
+
92
+ # Hook into the strategies' request & response life-cycle in case your
93
+ # application needs advanced customization or logging:
94
+ #
95
+ # before_successful_strategy_response do |request|
96
+ # puts "BEFORE HOOK FIRED! #{request}"
97
+ # end
98
+ #
99
+ # after_successful_strategy_response do |request, response|
100
+ # puts "AFTER HOOK FIRED! #{request}, #{response}"
101
+ # end
86
102
 
87
103
  # Under some circumstances you might want to have applications auto-approved,
88
104
  # so that the user skips the authorization step.
@@ -0,0 +1,6 @@
1
+ # Require `belongs_to` associations by default. This is a new Rails 5.0
2
+ # default, so it is introduced as a configuration option to ensure that apps
3
+ # made on earlier versions of Rails are not affected when upgrading.
4
+ if Rails::VERSION::MAJOR >= 5
5
+ Rails.application.config.active_record.belongs_to_required_by_default = true
6
+ end
@@ -5,5 +5,4 @@
5
5
  # Make sure the secret is at least 30 characters and all random,
6
6
  # no regular words or you'll be exposed to dictionary attacks.
7
7
  Dummy::Application.config.secret_key_base =
8
- Dummy::Application.config.secret_token =
9
8
  'c00157b5a1bb6181792f0f4a8a080485de7bab9987e6cf159dc74c4f0573345c1bfa713b5d756e1491fc0b098567e8a619e2f8d268eda86a20a720d05d633780'
@@ -1,4 +1,6 @@
1
- class CreateUsers < ActiveRecord::Migration
1
+ # frozen_string_literal: true
2
+
3
+ class CreateUsers < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  create_table :users do |t|
4
6
  t.string :name
@@ -1,4 +1,6 @@
1
- class AddPasswordToUsers < ActiveRecord::Migration
1
+ # frozen_string_literal: true
2
+
3
+ class AddPasswordToUsers < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  add_column :users, :password, :string
4
6
  end
@@ -1,4 +1,6 @@
1
- class CreateDoorkeeperTables < ActiveRecord::Migration
1
+ # frozen_string_literal: true
2
+
3
+ class CreateDoorkeeperTables < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  create_table :oauth_applications do |t|
4
6
  t.string :name, null: false
@@ -6,14 +8,14 @@ class CreateDoorkeeperTables < ActiveRecord::Migration
6
8
  t.string :secret, null: false
7
9
  t.text :redirect_uri, null: false
8
10
  t.string :scopes, null: false, default: ''
9
- t.timestamps
11
+ t.timestamps null: false
10
12
  end
11
13
 
12
14
  add_index :oauth_applications, :uid, unique: true
13
15
 
14
16
  create_table :oauth_access_grants do |t|
15
17
  t.integer :resource_owner_id, null: false
16
- t.integer :application_id, null: false
18
+ t.references :application, null: false
17
19
  t.string :token, null: false
18
20
  t.integer :expires_in, null: false
19
21
  t.text :redirect_uri, null: false
@@ -23,10 +25,15 @@ class CreateDoorkeeperTables < ActiveRecord::Migration
23
25
  end
24
26
 
25
27
  add_index :oauth_access_grants, :token, unique: true
28
+ add_foreign_key(
29
+ :oauth_access_grants,
30
+ :oauth_applications,
31
+ column: :application_id,
32
+ )
26
33
 
27
34
  create_table :oauth_access_tokens do |t|
28
35
  t.integer :resource_owner_id
29
- t.integer :application_id
36
+ t.references :application
30
37
 
31
38
  # If you use a custom token generator you may need to change this column
32
39
  # from string to text, so that it accepts tokens larger than 255
@@ -46,5 +53,10 @@ class CreateDoorkeeperTables < ActiveRecord::Migration
46
53
  add_index :oauth_access_tokens, :token, unique: true
47
54
  add_index :oauth_access_tokens, :resource_owner_id
48
55
  add_index :oauth_access_tokens, :refresh_token, unique: true
56
+ add_foreign_key(
57
+ :oauth_access_tokens,
58
+ :oauth_applications,
59
+ column: :application_id,
60
+ )
49
61
  end
50
62
  end
@@ -1,7 +1,9 @@
1
- class AddOwnerToApplication < ActiveRecord::Migration
1
+ # frozen_string_literal: true
2
+
3
+ class AddOwnerToApplication < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  add_column :oauth_applications, :owner_id, :integer, null: true
4
6
  add_column :oauth_applications, :owner_type, :string, null: true
5
7
  add_index :oauth_applications, [:owner_id, :owner_type]
6
8
  end
7
- end
9
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddPreviousRefreshTokenToAccessTokens < ActiveRecord::Migration[4.2]
4
+ def change
5
+ add_column(
6
+ :oauth_access_tokens,
7
+ :previous_refresh_token,
8
+ :string,
9
+ default: "",
10
+ null: false
11
+ )
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddConfidentialToApplication < ActiveRecord::Migration[5.1]
4
+ def change
5
+ add_column(
6
+ :oauth_applications,
7
+ :confidential,
8
+ :boolean,
9
+ null: false,
10
+ default: true # maintaining backwards compatibility: require secrets
11
+ )
12
+ end
13
+ end
@@ -11,55 +11,57 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20141209001746) do
14
+ ActiveRecord::Schema.define(version: 20180210183654) do
15
15
 
16
- create_table "oauth_access_grants", force: true do |t|
17
- t.integer "resource_owner_id", null: false
18
- t.integer "application_id", null: false
19
- t.string "token", null: false
20
- t.integer "expires_in", null: false
21
- t.string "redirect_uri", limit: 2048, null: false
22
- t.datetime "created_at", null: false
16
+ create_table "oauth_access_grants", force: :cascade do |t|
17
+ t.integer "resource_owner_id", null: false
18
+ t.integer "application_id", null: false
19
+ t.string "token", null: false
20
+ t.integer "expires_in", null: false
21
+ t.text "redirect_uri", null: false
22
+ t.datetime "created_at", null: false
23
23
  t.datetime "revoked_at"
24
24
  t.string "scopes"
25
25
  end
26
26
 
27
27
  add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true
28
28
 
29
- create_table "oauth_access_tokens", force: true do |t|
29
+ create_table "oauth_access_tokens", force: :cascade do |t|
30
30
  t.integer "resource_owner_id"
31
31
  t.integer "application_id"
32
- t.string "token", null: false
32
+ t.string "token", null: false
33
33
  t.string "refresh_token"
34
34
  t.integer "expires_in"
35
35
  t.datetime "revoked_at"
36
- t.datetime "created_at", null: false
36
+ t.datetime "created_at", null: false
37
37
  t.string "scopes"
38
+ t.string "previous_refresh_token", default: "", null: false
38
39
  end
39
40
 
40
41
  add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true
41
42
  add_index "oauth_access_tokens", ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id"
42
43
  add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true
43
44
 
44
- create_table "oauth_applications", force: true do |t|
45
- t.string "name", null: false
46
- t.string "uid", null: false
47
- t.string "secret", null: false
48
- t.string "redirect_uri", limit: 2048, null: false
49
- t.datetime "created_at", null: false
50
- t.datetime "updated_at", null: false
45
+ create_table "oauth_applications", force: :cascade do |t|
46
+ t.string "name", null: false
47
+ t.string "uid", null: false
48
+ t.string "secret", null: false
49
+ t.text "redirect_uri", null: false
50
+ t.string "scopes", default: "", null: false
51
+ t.datetime "created_at"
52
+ t.datetime "updated_at"
51
53
  t.integer "owner_id"
52
54
  t.string "owner_type"
53
- t.string "scopes", default: "", null: false
55
+ t.boolean "confidential", default: true, null: false
54
56
  end
55
57
 
56
58
  add_index "oauth_applications", ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type"
57
59
  add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true
58
60
 
59
- create_table "users", force: true do |t|
61
+ create_table "users", force: :cascade do |t|
60
62
  t.string "name"
61
- t.datetime "created_at", null: false
62
- t.datetime "updated_at", null: false
63
+ t.datetime "created_at"
64
+ t.datetime "updated_at"
63
65
  t.string "password"
64
66
  end
65
67
 
data/spec/factories.rb CHANGED
@@ -1,4 +1,4 @@
1
- FactoryGirl.define do
1
+ FactoryBot.define do
2
2
  factory :access_grant, class: Doorkeeper::AccessGrant do
3
3
  sequence(:resource_owner_id) { |n| n }
4
4
  application
@@ -22,5 +22,7 @@ FactoryGirl.define do
22
22
  redirect_uri 'https://app.com/callback'
23
23
  end
24
24
 
25
- factory :user
25
+ # do not name this factory :user, otherwise it will conflict with factories
26
+ # from applications that use doorkeeper factories in their own tests
27
+ factory :doorkeeper_testing_user, class: :user
26
28
  end