doorkeeper 4.3.2 → 5.0.0.rc1

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 (176) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +4 -0
  4. data/.travis.yml +2 -0
  5. data/Appraisals +2 -2
  6. data/Gemfile +1 -1
  7. data/NEWS.md +36 -0
  8. data/README.md +85 -3
  9. data/Rakefile +6 -0
  10. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  11. data/app/controllers/doorkeeper/application_controller.rb +4 -3
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -0
  13. data/app/controllers/doorkeeper/applications_controller.rb +43 -22
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +15 -1
  16. data/app/controllers/doorkeeper/tokens_controller.rb +2 -6
  17. data/app/helpers/doorkeeper/dashboard_helper.rb +7 -7
  18. data/app/validators/redirect_uri_validator.rb +3 -2
  19. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  20. data/app/views/doorkeeper/applications/_form.html.erb +31 -19
  21. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  22. data/app/views/doorkeeper/applications/index.html.erb +18 -6
  23. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  24. data/app/views/doorkeeper/applications/show.html.erb +8 -5
  25. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  26. data/app/views/doorkeeper/authorizations/new.html.erb +4 -0
  27. data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
  28. data/config/locales/en.yml +15 -1
  29. data/gemfiles/rails_5_2.gemfile +1 -1
  30. data/lib/doorkeeper/config.rb +60 -23
  31. data/lib/doorkeeper/engine.rb +4 -0
  32. data/lib/doorkeeper/errors.rb +2 -5
  33. data/lib/doorkeeper/grape/helpers.rb +1 -1
  34. data/lib/doorkeeper/helpers/controller.rb +7 -2
  35. data/lib/doorkeeper/models/access_grant_mixin.rb +56 -0
  36. data/lib/doorkeeper/models/access_token_mixin.rb +37 -20
  37. data/lib/doorkeeper/models/application_mixin.rb +8 -1
  38. data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
  39. data/lib/doorkeeper/oauth/authorization/code.rb +31 -8
  40. data/lib/doorkeeper/oauth/authorization/context.rb +15 -0
  41. data/lib/doorkeeper/oauth/authorization/token.rb +23 -6
  42. data/lib/doorkeeper/oauth/authorization_code_request.rb +27 -2
  43. data/lib/doorkeeper/oauth/base_request.rb +18 -8
  44. data/lib/doorkeeper/oauth/client/credentials.rb +4 -2
  45. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +6 -1
  46. data/lib/doorkeeper/oauth/client_credentials/validation.rb +4 -2
  47. data/lib/doorkeeper/oauth/error_response.rb +11 -3
  48. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +0 -8
  49. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -0
  50. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -4
  51. data/lib/doorkeeper/oauth/pre_authorization.rb +45 -13
  52. data/lib/doorkeeper/oauth/refresh_token_request.rb +6 -1
  53. data/lib/doorkeeper/oauth/scopes.rb +1 -1
  54. data/lib/doorkeeper/oauth/token.rb +5 -2
  55. data/lib/doorkeeper/oauth/token_introspection.rb +2 -2
  56. data/lib/doorkeeper/oauth/token_response.rb +4 -2
  57. data/lib/doorkeeper/oauth.rb +13 -0
  58. data/lib/doorkeeper/orm/active_record/application.rb +14 -0
  59. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
  60. data/lib/doorkeeper/orm/active_record.rb +2 -0
  61. data/lib/doorkeeper/rails/helpers.rb +2 -4
  62. data/lib/doorkeeper/rails/routes.rb +13 -1
  63. data/lib/doorkeeper/rake/db.rake +40 -0
  64. data/lib/doorkeeper/rake/setup.rake +6 -0
  65. data/lib/doorkeeper/rake.rb +14 -0
  66. data/lib/doorkeeper/request/password.rb +1 -11
  67. data/lib/doorkeeper/request.rb +28 -28
  68. data/lib/doorkeeper/version.rb +5 -4
  69. data/lib/doorkeeper.rb +4 -17
  70. data/lib/generators/doorkeeper/application_owner_generator.rb +23 -18
  71. data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
  72. data/lib/generators/doorkeeper/install_generator.rb +17 -9
  73. data/lib/generators/doorkeeper/migration_generator.rb +23 -18
  74. data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
  75. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -24
  76. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  77. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
  78. data/lib/generators/doorkeeper/templates/initializer.rb +60 -9
  79. data/lib/generators/doorkeeper/templates/migration.rb.erb +1 -0
  80. data/lib/generators/doorkeeper/views_generator.rb +3 -1
  81. data/spec/controllers/application_metal_controller_spec.rb +50 -0
  82. data/spec/controllers/applications_controller_spec.rb +126 -13
  83. data/spec/controllers/authorizations_controller_spec.rb +250 -15
  84. data/spec/controllers/protected_resources_controller_spec.rb +16 -16
  85. data/spec/controllers/token_info_controller_spec.rb +4 -12
  86. data/spec/controllers/tokens_controller_spec.rb +12 -14
  87. data/spec/dummy/app/assets/config/manifest.js +2 -0
  88. data/spec/dummy/config/environments/test.rb +4 -5
  89. data/spec/dummy/config/initializers/doorkeeper.rb +6 -0
  90. data/spec/dummy/config/initializers/new_framework_defaults.rb +4 -0
  91. data/spec/dummy/config/routes.rb +3 -42
  92. data/spec/dummy/db/migrate/20111122132257_create_users.rb +3 -1
  93. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +3 -1
  94. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -1
  95. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +3 -1
  96. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +3 -1
  97. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
  98. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +13 -0
  99. data/spec/dummy/db/schema.rb +38 -37
  100. data/spec/generators/application_owner_generator_spec.rb +1 -1
  101. data/spec/generators/confidential_applications_generator_spec.rb +45 -0
  102. data/spec/generators/install_generator_spec.rb +1 -1
  103. data/spec/generators/migration_generator_spec.rb +1 -1
  104. data/spec/generators/pkce_generator_spec.rb +43 -0
  105. data/spec/generators/previous_refresh_token_generator_spec.rb +1 -1
  106. data/spec/generators/views_generator_spec.rb +1 -1
  107. data/spec/grape/grape_integration_spec.rb +1 -1
  108. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  109. data/spec/lib/config_spec.rb +59 -14
  110. data/spec/lib/doorkeeper_spec.rb +1 -126
  111. data/spec/lib/models/expirable_spec.rb +0 -3
  112. data/spec/lib/models/revocable_spec.rb +0 -2
  113. data/spec/lib/models/scopes_spec.rb +0 -4
  114. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
  115. data/spec/lib/oauth/authorization_code_request_spec.rb +24 -2
  116. data/spec/lib/oauth/base_request_spec.rb +16 -2
  117. data/spec/lib/oauth/base_response_spec.rb +1 -1
  118. data/spec/lib/oauth/client/credentials_spec.rb +5 -5
  119. data/spec/lib/oauth/client_credentials/creator_spec.rb +5 -1
  120. data/spec/lib/oauth/client_credentials/issuer_spec.rb +26 -7
  121. data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -3
  122. data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
  123. data/spec/lib/oauth/client_credentials_request_spec.rb +3 -5
  124. data/spec/lib/oauth/client_spec.rb +0 -3
  125. data/spec/lib/oauth/code_request_spec.rb +4 -2
  126. data/spec/lib/oauth/error_response_spec.rb +0 -3
  127. data/spec/lib/oauth/error_spec.rb +0 -2
  128. data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
  129. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -3
  130. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
  131. data/spec/lib/oauth/helpers/uri_checker_spec.rb +5 -2
  132. data/spec/lib/oauth/invalid_token_response_spec.rb +1 -4
  133. data/spec/lib/oauth/password_access_token_request_spec.rb +37 -2
  134. data/spec/lib/oauth/pre_authorization_spec.rb +40 -6
  135. data/spec/lib/oauth/refresh_token_request_spec.rb +11 -7
  136. data/spec/lib/oauth/scopes_spec.rb +0 -3
  137. data/spec/lib/oauth/token_request_spec.rb +4 -5
  138. data/spec/lib/oauth/token_response_spec.rb +0 -1
  139. data/spec/lib/oauth/token_spec.rb +37 -14
  140. data/spec/lib/orm/active_record/stale_records_cleaner_spec.rb +79 -0
  141. data/spec/lib/request/strategy_spec.rb +0 -1
  142. data/spec/lib/server_spec.rb +1 -1
  143. data/spec/models/doorkeeper/access_grant_spec.rb +1 -1
  144. data/spec/models/doorkeeper/access_token_spec.rb +50 -16
  145. data/spec/models/doorkeeper/application_spec.rb +51 -6
  146. data/spec/requests/applications/applications_request_spec.rb +89 -1
  147. data/spec/requests/applications/authorized_applications_spec.rb +1 -1
  148. data/spec/requests/endpoints/authorization_spec.rb +1 -1
  149. data/spec/requests/endpoints/token_spec.rb +7 -5
  150. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -1
  151. data/spec/requests/flows/authorization_code_spec.rb +197 -1
  152. data/spec/requests/flows/client_credentials_spec.rb +46 -6
  153. data/spec/requests/flows/implicit_grant_errors_spec.rb +1 -1
  154. data/spec/requests/flows/implicit_grant_spec.rb +38 -11
  155. data/spec/requests/flows/password_spec.rb +120 -23
  156. data/spec/requests/flows/refresh_token_spec.rb +2 -2
  157. data/spec/requests/flows/revoke_token_spec.rb +11 -11
  158. data/spec/requests/flows/skip_authorization_spec.rb +16 -11
  159. data/spec/requests/protected_resources/metal_spec.rb +1 -1
  160. data/spec/requests/protected_resources/private_api_spec.rb +1 -1
  161. data/spec/routing/custom_controller_routes_spec.rb +59 -7
  162. data/spec/routing/default_routes_spec.rb +2 -2
  163. data/spec/routing/scoped_routes_spec.rb +16 -2
  164. data/spec/spec_helper.rb +54 -3
  165. data/spec/spec_helper_integration.rb +2 -74
  166. data/spec/support/doorkeeper_rspec.rb +19 -0
  167. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  168. data/spec/support/helpers/request_spec_helper.rb +2 -2
  169. data/spec/support/helpers/url_helper.rb +7 -3
  170. data/spec/support/http_method_shim.rb +12 -16
  171. data/spec/validators/redirect_uri_validator_spec.rb +7 -1
  172. data/spec/version/version_spec.rb +3 -3
  173. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  174. metadata +32 -8
  175. data/spec/controllers/application_metal_controller.rb +0 -10
  176. /data/spec/support/dependencies/{factory_girl.rb → factory_bot.rb} +0 -0
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
4
4
  include AuthorizationRequestHelper
@@ -6,7 +6,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
6
6
  if Rails::VERSION::MAJOR >= 5
7
7
  class ActionDispatch::TestResponse
8
8
  def query_params
9
- @_query_params ||= begin
9
+ @query_params ||= begin
10
10
  fragment = URI.parse(location).fragment
11
11
  Rack::Utils.parse_query(fragment)
12
12
  end
@@ -15,7 +15,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
15
15
  else
16
16
  class ActionController::TestResponse
17
17
  def query_params
18
- @_query_params ||= begin
18
+ @query_params ||= begin
19
19
  fragment = URI.parse(location).fragment
20
20
  Rack::Utils.parse_query(fragment)
21
21
  end
@@ -34,11 +34,14 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
34
34
  before do
35
35
  allow(Doorkeeper.configuration).to receive(:grant_flows).and_return(["implicit"])
36
36
  allow(controller).to receive(:current_resource_owner).and_return(user)
37
+ allow(Doorkeeper.configuration).to receive(:custom_access_token_expires_in).and_return(proc { |context|
38
+ context.grant_type == Doorkeeper::OAuth::IMPLICIT ? 1234 : nil
39
+ })
37
40
  end
38
41
 
39
42
  describe 'POST #create' do
40
43
  before do
41
- post :create, client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri
44
+ post :create, params: { client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri }
42
45
  end
43
46
 
44
47
  it 'redirects after authorization' do
@@ -58,7 +61,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
58
61
  end
59
62
 
60
63
  it 'includes token expiration in fragment' do
61
- expect(response.query_params['expires_in'].to_i).to eq(2.hours.to_i)
64
+ expect(response.query_params['expires_in'].to_i).to eq(1234)
62
65
  end
63
66
 
64
67
  it 'issues the token for the current client' do
@@ -70,10 +73,48 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
70
73
  end
71
74
  end
72
75
 
76
+ describe "POST #create in API mode" do
77
+ before do
78
+ allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
79
+ post :create, params: { client_id: client.uid, response_type: "token", redirect_uri: client.redirect_uri }
80
+ end
81
+
82
+ let(:response_json_body) { JSON.parse(response.body) }
83
+ let(:redirect_uri) { response_json_body["redirect_uri"] }
84
+
85
+ it "renders success after authorization" do
86
+ expect(response).to be_successful
87
+ end
88
+
89
+ it "renders correct redirect uri" do
90
+ expect(redirect_uri).to match(/^#{client.redirect_uri}/)
91
+ end
92
+
93
+ it "includes access token in fragment" do
94
+ expect(redirect_uri.match(/access_token=([a-f0-9]+)&?/)[1]).to eq(Doorkeeper::AccessToken.first.token)
95
+ end
96
+
97
+ it "includes token type in fragment" do
98
+ expect(redirect_uri.match(/token_type=(\w+)&?/)[1]).to eq "bearer"
99
+ end
100
+
101
+ it "includes token expiration in fragment" do
102
+ expect(redirect_uri.match(/expires_in=(\d+)&?/)[1].to_i).to eq 1234
103
+ end
104
+
105
+ it "issues the token for the current client" do
106
+ expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
107
+ end
108
+
109
+ it "issues the token for the current resource owner" do
110
+ expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
111
+ end
112
+ end
113
+
73
114
  describe 'POST #create with errors' do
74
115
  before do
75
116
  default_scopes_exist :public
76
- post :create, client_id: client.uid, response_type: 'token', scope: 'invalid', redirect_uri: client.redirect_uri
117
+ post :create, params: { client_id: client.uid, response_type: 'token', scope: 'invalid', redirect_uri: client.redirect_uri }
77
118
  end
78
119
 
79
120
  it 'redirects after authorization' do
@@ -81,7 +122,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
81
122
  end
82
123
 
83
124
  it 'redirects to client redirect uri' do
84
- expect(response.location).to match(%r{^#{client.redirect_uri}})
125
+ expect(response.location).to match(/^#{client.redirect_uri}/)
85
126
  end
86
127
 
87
128
  it 'does not include access token in fragment' do
@@ -101,12 +142,47 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
101
142
  end
102
143
  end
103
144
 
145
+ describe 'POST #create in API mode with errors' do
146
+ before do
147
+ allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
148
+ default_scopes_exist :public
149
+ post :create, params: { client_id: client.uid, response_type: 'token', scope: 'invalid', redirect_uri: client.redirect_uri }
150
+ end
151
+
152
+ let(:response_json_body) { JSON.parse(response.body) }
153
+ let(:redirect_uri) { response_json_body['redirect_uri'] }
154
+
155
+ it 'renders 400 error' do
156
+ expect(response.status).to eq 401
157
+ end
158
+
159
+ it 'includes correct redirect URI' do
160
+ expect(redirect_uri).to match(/^#{client.redirect_uri}/)
161
+ end
162
+
163
+ it 'does not include access token in fragment' do
164
+ expect(redirect_uri.match(/access_token=([a-f0-9]+)&?/)).to be_nil
165
+ end
166
+
167
+ it 'includes error in redirect uri' do
168
+ expect(redirect_uri.match(/error=([a-z_]+)&?/)[1]).to eq 'invalid_scope'
169
+ end
170
+
171
+ it 'includes error description in redirect uri' do
172
+ expect(redirect_uri.match(/error_description=(.+)&?/)[1]).to_not be_nil
173
+ end
174
+
175
+ it 'does not issue any access token' do
176
+ expect(Doorkeeper::AccessToken.all).to be_empty
177
+ end
178
+ end
179
+
104
180
  describe 'POST #create with application already authorized' do
105
181
  before do
106
182
  allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
107
183
 
108
184
  access_token.save!
109
- post :create, client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri
185
+ post :create, params: { client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri }
110
186
  end
111
187
 
112
188
  it 'returns the existing access token in a fragment' do
@@ -118,13 +194,47 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
118
194
  end
119
195
  end
120
196
 
197
+ describe 'POST #create with callbacks' do
198
+ after do
199
+ client.update_attribute :redirect_uri, 'urn:ietf:wg:oauth:2.0:oob'
200
+ end
201
+
202
+ describe 'when successful' do
203
+ after do
204
+ post :create, params: { client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri }
205
+ end
206
+
207
+ it 'should call :before_successful_authorization callback' do
208
+ expect(Doorkeeper.configuration).to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
209
+ end
210
+
211
+ it 'should call :after_successful_authorization callback' do
212
+ expect(Doorkeeper.configuration).to receive_message_chain(:after_successful_authorization, :call).with(instance_of(described_class))
213
+ end
214
+ end
215
+
216
+ describe 'with errors' do
217
+ after do
218
+ post :create, params: { client_id: client.uid, response_type: 'token', redirect_uri: 'bad_uri' }
219
+ end
220
+
221
+ it 'should not call :before_successful_authorization callback' do
222
+ expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
223
+ end
224
+
225
+ it 'should not call :after_successful_authorization callback' do
226
+ expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
227
+ end
228
+ end
229
+ end
230
+
121
231
  describe 'GET #new token request with native url and skip_authorization true' do
122
232
  before do
123
233
  allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc do
124
234
  true
125
235
  end)
126
236
  client.update_attribute :redirect_uri, 'urn:ietf:wg:oauth:2.0:oob'
127
- get :new, client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri
237
+ get :new, params: { client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri }
128
238
  end
129
239
 
130
240
  it 'should redirect immediately' do
@@ -143,13 +253,12 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
143
253
 
144
254
  describe 'GET #new code request with native url and skip_authorization true' do
145
255
  before do
146
- allow(Doorkeeper.configuration).to receive(:grant_flows).
147
- and_return(%w[authorization_code])
256
+ allow(Doorkeeper.configuration).to receive(:grant_flows).and_return(%w[authorization_code])
148
257
  allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc do
149
258
  true
150
259
  end)
151
260
  client.update_attribute :redirect_uri, 'urn:ietf:wg:oauth:2.0:oob'
152
- get :new, client_id: client.uid, response_type: 'code', redirect_uri: client.redirect_uri
261
+ get :new, params: { client_id: client.uid, response_type: 'code', redirect_uri: client.redirect_uri }
153
262
  end
154
263
 
155
264
  it 'should redirect immediately' do
@@ -171,7 +280,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
171
280
  allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc do
172
281
  true
173
282
  end)
174
- get :new, client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri
283
+ get :new, params: { client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri }
175
284
  end
176
285
 
177
286
  it 'should redirect immediately' do
@@ -188,7 +297,7 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
188
297
  end
189
298
 
190
299
  it 'includes token expiration in fragment' do
191
- expect(response.query_params['expires_in'].to_i).to eq(2.hours.to_i)
300
+ expect(response.query_params['expires_in'].to_i).to eq(1234)
192
301
  end
193
302
 
194
303
  it 'issues the token for the current client' do
@@ -200,10 +309,72 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
200
309
  end
201
310
  end
202
311
 
312
+ describe 'GET #new in API mode' do
313
+ before do
314
+ allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
315
+ get :new, params: { client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri }
316
+ end
317
+
318
+ it 'should render success' do
319
+ expect(response).to be_successful
320
+ end
321
+
322
+ it "sets status to pre-authorization" do
323
+ expect(json_response["status"]).to eq(I18n.t('doorkeeper.pre_authorization.status'))
324
+ end
325
+
326
+ it "sets correct values" do
327
+ expect(json_response['client_id']).to eq(client.uid)
328
+ expect(json_response['redirect_uri']).to eq(client.redirect_uri)
329
+ expect(json_response['state']).to be_nil
330
+ expect(json_response['response_type']).to eq('token')
331
+ expect(json_response['scope']).to eq('')
332
+ end
333
+ end
334
+
335
+ describe 'GET #new in API mode with skip_authorization true' do
336
+ before do
337
+ allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { true })
338
+ allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
339
+
340
+ get :new, params: { client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri }
341
+ end
342
+
343
+ it 'should render success' do
344
+ expect(response).to be_successful
345
+ end
346
+
347
+ it 'should issue a token' do
348
+ expect(Doorkeeper::AccessToken.count).to be 1
349
+ end
350
+
351
+ it "sets status to redirect" do
352
+ expect(JSON.parse(response.body)["status"]).to eq("redirect")
353
+ end
354
+
355
+ it "sets redirect_uri to correct value" do
356
+ redirect_uri = JSON.parse(response.body)["redirect_uri"]
357
+ expect(redirect_uri).to_not be_nil
358
+ expect(redirect_uri.match(/token_type=(\w+)&?/)[1]).to eq "bearer"
359
+ expect(redirect_uri.match(/expires_in=(\d+)&?/)[1].to_i).to eq 1234
360
+ expect(
361
+ redirect_uri.match(/access_token=([a-f0-9]+)&?/)[1]
362
+ ).to eq Doorkeeper::AccessToken.first.token
363
+ end
364
+
365
+ it "issues the token for the current client" do
366
+ expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
367
+ end
368
+
369
+ it "issues the token for the current resource owner" do
370
+ expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
371
+ end
372
+ end
373
+
203
374
  describe 'GET #new with errors' do
204
375
  before do
205
376
  default_scopes_exist :public
206
- get :new, an_invalid: 'request'
377
+ get :new, params: { an_invalid: 'request' }
207
378
  end
208
379
 
209
380
  it 'does not redirect' do
@@ -215,4 +386,68 @@ describe Doorkeeper::AuthorizationsController, 'implicit grant flow' do
215
386
  expect(Doorkeeper::AccessToken.count).to eq 0
216
387
  end
217
388
  end
389
+
390
+ describe 'GET #new with callbacks' do
391
+ after do
392
+ client.update_attribute :redirect_uri, 'urn:ietf:wg:oauth:2.0:oob'
393
+ get :new, params: { client_id: client.uid, response_type: 'token', redirect_uri: client.redirect_uri }
394
+ end
395
+
396
+ describe 'when authorizing' do
397
+ before do
398
+ allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { true })
399
+ end
400
+
401
+ it 'should call :before_successful_authorization callback' do
402
+ expect(Doorkeeper.configuration).to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
403
+ end
404
+
405
+ it 'should call :after_successful_authorization callback' do
406
+ expect(Doorkeeper.configuration).to receive_message_chain(:after_successful_authorization, :call).with(instance_of(described_class))
407
+ end
408
+ end
409
+
410
+ describe 'when not authorizing' do
411
+ before do
412
+ allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { false })
413
+ end
414
+
415
+ it 'should not call :before_successful_authorization callback' do
416
+ expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
417
+ end
418
+
419
+ it 'should not call :after_successful_authorization callback' do
420
+ expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
421
+ end
422
+ end
423
+
424
+ describe 'when not authorizing in api mode' do
425
+ before do
426
+ allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { false })
427
+ allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
428
+ end
429
+
430
+ it 'should not call :before_successful_authorization callback' do
431
+ expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
432
+ end
433
+
434
+ it 'should not call :after_successful_authorization callback' do
435
+ expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
436
+ end
437
+ end
438
+ end
439
+
440
+ describe 'authorize response memoization' do
441
+ it 'memoizes the result of the authorization' do
442
+ strategy = double(:strategy, authorize: true)
443
+ expect(strategy).to receive(:authorize).once
444
+ allow(controller).to receive(:strategy) { strategy }
445
+ allow(controller).to receive(:create) do
446
+ 2.times { controller.send :authorize_response }
447
+ controller.render json: {}, status: :ok
448
+ end
449
+
450
+ post :create
451
+ end
452
+ end
218
453
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  module ControllerActions
4
4
  def index
@@ -33,12 +33,12 @@ describe 'doorkeeper authorize filter' do
33
33
 
34
34
  it 'access_token param' do
35
35
  expect(Doorkeeper::AccessToken).to receive(:by_token).with(token_string).and_return(token)
36
- get :index, access_token: token_string
36
+ get :index, params: { access_token: token_string }
37
37
  end
38
38
 
39
39
  it 'bearer_token param' do
40
40
  expect(Doorkeeper::AccessToken).to receive(:by_token).with(token_string).and_return(token)
41
- get :index, bearer_token: token_string
41
+ get :index, params: { bearer_token: token_string }
42
42
  end
43
43
 
44
44
  it 'Authorization header' do
@@ -57,7 +57,7 @@ describe 'doorkeeper authorize filter' do
57
57
  expect(Doorkeeper::AccessToken).to receive(:by_token).exactly(2).times.and_return(token)
58
58
  request.env['HTTP_AUTHORIZATION'] = "Bearer #{token_string}"
59
59
  get :index
60
- controller.send(:remove_instance_variable, :@_doorkeeper_token)
60
+ controller.send(:remove_instance_variable, :@doorkeeper_token)
61
61
  get :index
62
62
  end
63
63
  end
@@ -71,25 +71,25 @@ describe 'doorkeeper authorize filter' do
71
71
 
72
72
  context 'with valid token', token: :valid do
73
73
  it 'allows into index action' do
74
- get :index, access_token: token_string
74
+ get :index, params: { access_token: token_string }
75
75
  expect(response).to be_successful
76
76
  end
77
77
 
78
78
  it 'allows into show action' do
79
- get :show, id: '4', access_token: token_string
79
+ get :show, params: { id: '4', access_token: token_string }
80
80
  expect(response).to be_successful
81
81
  end
82
82
  end
83
83
 
84
84
  context 'with invalid token', token: :invalid do
85
85
  it 'does not allow into index action' do
86
- get :index, access_token: token_string
86
+ get :index, params: { access_token: token_string }
87
87
  expect(response.status).to eq 401
88
88
  expect(response.header['WWW-Authenticate']).to match(/^Bearer/)
89
89
  end
90
90
 
91
91
  it 'does not allow into show action' do
92
- get :show, id: '4', access_token: token_string
92
+ get :show, params: { id: '4', access_token: token_string }
93
93
  expect(response.status).to eq 401
94
94
  expect(response.header['WWW-Authenticate']).to match(/^Bearer/)
95
95
  end
@@ -115,7 +115,7 @@ describe 'doorkeeper authorize filter' do
115
115
  Doorkeeper::AccessToken
116
116
  ).to receive(:by_token).with(token_string).and_return(token)
117
117
 
118
- get :index, access_token: token_string
118
+ get :index, params: { access_token: token_string }
119
119
  expect(response).to be_successful
120
120
  end
121
121
 
@@ -129,7 +129,7 @@ describe 'doorkeeper authorize filter' do
129
129
  ).to receive(:by_token).with(token_string).and_return(token)
130
130
  expect(token).to receive(:acceptable?).with([:write]).and_return(false)
131
131
 
132
- get :index, access_token: token_string
132
+ get :index, params: { access_token: token_string }
133
133
  expect(response.status).to eq 403
134
134
  expect(response.header).to_not include('WWW-Authenticate')
135
135
  end
@@ -163,7 +163,7 @@ describe 'doorkeeper authorize filter' do
163
163
  end
164
164
 
165
165
  it 'it renders a custom JSON response', token: :invalid do
166
- get :index, access_token: token_string
166
+ get :index, params: { access_token: token_string }
167
167
  expect(response.status).to eq 401
168
168
  expect(response.content_type).to eq('application/json')
169
169
  expect(response.header['WWW-Authenticate']).to match(/^Bearer/)
@@ -193,7 +193,7 @@ describe 'doorkeeper authorize filter' do
193
193
  end
194
194
 
195
195
  it 'it renders a custom text response', token: :invalid do
196
- get :index, access_token: token_string
196
+ get :index, params: { access_token: token_string }
197
197
  expect(response.status).to eq 401
198
198
  expect(response.content_type).to eq('text/plain')
199
199
  expect(response.header['WWW-Authenticate']).to match(/^Bearer/)
@@ -243,7 +243,7 @@ describe 'doorkeeper authorize filter' do
243
243
  end
244
244
 
245
245
  it 'renders a custom JSON response' do
246
- get :index, access_token: token_string
246
+ get :index, params: { access_token: token_string }
247
247
  expect(response.header).to_not include('WWW-Authenticate')
248
248
  expect(response.content_type).to eq('application/json')
249
249
  expect(response.status).to eq 403
@@ -265,7 +265,7 @@ describe 'doorkeeper authorize filter' do
265
265
  end
266
266
 
267
267
  it 'overrides the default status code' do
268
- get :index, access_token: token_string
268
+ get :index, params: { access_token: token_string }
269
269
  expect(response.status).to eq 404
270
270
  end
271
271
  end
@@ -282,7 +282,7 @@ describe 'doorkeeper authorize filter' do
282
282
  end
283
283
 
284
284
  it 'renders a custom status code and text response' do
285
- get :index, access_token: token_string
285
+ get :index, params: { access_token: token_string }
286
286
  expect(response.header).to_not include('WWW-Authenticate')
287
287
  expect(response.status).to eq 403
288
288
  expect(response.body).to eq('Forbidden')
@@ -301,7 +301,7 @@ describe 'doorkeeper authorize filter' do
301
301
  end
302
302
 
303
303
  it 'overrides the default status code' do
304
- get :index, access_token: token_string
304
+ get :index, params: { access_token: token_string }
305
305
  expect(response.status).to eq 404
306
306
  end
307
307
  end
@@ -1,32 +1,24 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Doorkeeper::TokenInfoController do
4
4
  describe 'when requesting token info with valid token' do
5
5
  let(:doorkeeper_token) { FactoryBot.create(:access_token) }
6
6
 
7
- before(:each) do
8
- allow(controller).to receive(:doorkeeper_token) { doorkeeper_token }
9
- end
10
-
11
7
  describe 'successful request' do
12
- it 'responds with tokeninfo' do
13
- get :show
8
+ it 'responds with token info' do
9
+ get :show, params: { access_token: doorkeeper_token.token }
14
10
 
15
11
  expect(response.body).to eq(doorkeeper_token.to_json)
16
12
  end
17
13
 
18
14
  it 'responds with a 200 status' do
19
- get :show
15
+ get :show, params: { access_token: doorkeeper_token.token }
20
16
 
21
17
  expect(response.status).to eq 200
22
18
  end
23
19
  end
24
20
 
25
21
  describe 'invalid token response' do
26
- before(:each) do
27
- allow(controller).to receive(:doorkeeper_token).and_return(nil)
28
- end
29
-
30
22
  it 'responds with 401 when doorkeeper_token is not valid' do
31
23
  get :show
32
24
 
@@ -1,12 +1,9 @@
1
- require 'spec_helper_integration'
1
+ require 'spec_helper'
2
2
 
3
3
  describe Doorkeeper::TokensController do
4
4
  describe 'when authorization has succeeded' do
5
5
  let(:token) { double(:token, authorize: true) }
6
6
 
7
- before do
8
- allow(controller).to receive(:token) { token }
9
- end
10
7
 
11
8
  it 'returns the authorization' do
12
9
  skip 'verify need of these specs'
@@ -77,7 +74,8 @@ describe Doorkeeper::TokensController do
77
74
  expect(strategy).to receive(:authorize).once
78
75
  allow(controller).to receive(:strategy) { strategy }
79
76
  allow(controller).to receive(:create) do
80
- controller.send :authorize_response
77
+ 2.times { controller.send :authorize_response }
78
+ controller.render json: {}, status: :ok
81
79
  end
82
80
 
83
81
  post :create
@@ -92,7 +90,7 @@ describe Doorkeeper::TokensController do
92
90
  it 'responds with full token introspection' do
93
91
  request.headers['Authorization'] = "Bearer #{access_token.token}"
94
92
 
95
- post :introspect, token: access_token.token
93
+ post :introspect, params: { token: access_token.token }
96
94
 
97
95
  should_have_json 'active', true
98
96
  expect(json_response).to include('client_id', 'token_type', 'exp', 'iat')
@@ -106,7 +104,7 @@ describe Doorkeeper::TokensController do
106
104
  it 'responds with full token introspection' do
107
105
  request.headers['Authorization'] = basic_auth_header_for_client(client)
108
106
 
109
- post :introspect, token: access_token.token
107
+ post :introspect, params: { token: access_token.token }
110
108
 
111
109
  should_have_json 'active', true
112
110
  expect(json_response).to include('client_id', 'token_type', 'exp', 'iat')
@@ -121,7 +119,7 @@ describe Doorkeeper::TokensController do
121
119
  it 'responds with full token introspection' do
122
120
  request.headers['Authorization'] = basic_auth_header_for_client(client)
123
121
 
124
- post :introspect, token: access_token.token
122
+ post :introspect, params: { token: access_token.token }
125
123
 
126
124
  should_have_json 'active', true
127
125
  expect(json_response).to include('client_id', 'token_type', 'exp', 'iat')
@@ -137,7 +135,7 @@ describe Doorkeeper::TokensController do
137
135
  it 'responds with only active state' do
138
136
  request.headers['Authorization'] = basic_auth_header_for_client(different_client)
139
137
 
140
- post :introspect, token: access_token.token
138
+ post :introspect, params: { token: access_token.token }
141
139
 
142
140
  expect(response).to be_successful
143
141
 
@@ -153,7 +151,7 @@ describe Doorkeeper::TokensController do
153
151
  it 'responds with invalid_client error' do
154
152
  request.headers['Authorization'] = basic_auth_header_for_client(client)
155
153
 
156
- post :introspect, token: access_token.token
154
+ post :introspect, params: { token: access_token.token }
157
155
 
158
156
  expect(response).not_to be_successful
159
157
  response_status_should_be 401
@@ -170,7 +168,7 @@ describe Doorkeeper::TokensController do
170
168
  it 'responds with only active state' do
171
169
  request.headers['Authorization'] = basic_auth_header_for_client(client)
172
170
 
173
- post :introspect, token: SecureRandom.hex(16)
171
+ post :introspect, params: { token: SecureRandom.hex(16) }
174
172
 
175
173
  should_have_json 'active', false
176
174
  expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
@@ -184,7 +182,7 @@ describe Doorkeeper::TokensController do
184
182
  it 'responds with only active state' do
185
183
  request.headers['Authorization'] = basic_auth_header_for_client(client)
186
184
 
187
- post :introspect, token: access_token.token
185
+ post :introspect, params: { token: access_token.token }
188
186
 
189
187
  should_have_json 'active', false
190
188
  expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
@@ -198,7 +196,7 @@ describe Doorkeeper::TokensController do
198
196
  it 'responds with only active state' do
199
197
  request.headers['Authorization'] = basic_auth_header_for_client(client)
200
198
 
201
- post :introspect, token: access_token.token
199
+ post :introspect, params: { token: access_token.token }
202
200
 
203
201
  should_have_json 'active', false
204
202
  expect(json_response).not_to include('client_id', 'token_type', 'exp', 'iat')
@@ -209,7 +207,7 @@ describe Doorkeeper::TokensController do
209
207
  let(:access_token) { FactoryBot.create(:access_token) }
210
208
 
211
209
  it 'responds with invalid_request error' do
212
- post :introspect, token: access_token.token
210
+ post :introspect, params: { token: access_token.token }
213
211
 
214
212
  expect(response).not_to be_successful
215
213
  response_status_should_be 401
@@ -0,0 +1,2 @@
1
+ // JS and CSS bundles
2
+ //
@@ -7,6 +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
+ config.assets.enabled = true
11
+ config.assets.version = '1.0'
12
+ config.assets.digest = false
13
+
10
14
  # Do not eager load code on boot. This avoids loading your whole application
11
15
  # just for the purpose of running a single test. If you are using a tool that
12
16
  # preloads Rails for running tests, you may have to set it to true.
@@ -36,9 +40,4 @@ Dummy::Application.configure do
36
40
  config.active_support.deprecation = :stderr
37
41
 
38
42
  config.eager_load = true
39
-
40
- if DOORKEEPER_ORM == :active_record
41
- config.active_record.table_name_prefix = TABLE_NAME_PREFIX.to_s
42
- config.active_record.table_name_suffix = TABLE_NAME_SUFFIX.to_s
43
- end
44
43
  end
@@ -29,6 +29,12 @@ Doorkeeper.configure do
29
29
  # Issue access tokens with refresh token (disabled by default)
30
30
  use_refresh_token
31
31
 
32
+ # Forbids creating/updating applications with arbitrary scopes that are
33
+ # not in configuration, i.e. `default_scopes` or `optional_scopes`.
34
+ # (disabled by default)
35
+ #
36
+ # enforce_configured_scopes
37
+
32
38
  # Provide support for an owner to be assigned to each registered application (disabled by default)
33
39
  # Optional parameter confirmation: true (default false) if you want to enforce ownership of
34
40
  # a registered application