doorkeeper 5.2.0.rc1 → 5.2.0
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.
- checksums.yaml +4 -4
- data/Appraisals +1 -1
- data/CHANGELOG.md +33 -2
- data/CONTRIBUTING.md +7 -0
- data/Dangerfile +1 -1
- data/Dockerfile +29 -0
- data/Gemfile +1 -1
- data/README.md +9 -1
- data/app/controllers/doorkeeper/application_controller.rb +1 -1
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -1
- data/app/controllers/doorkeeper/authorizations_controller.rb +14 -7
- data/app/controllers/doorkeeper/tokens_controller.rb +14 -1
- data/config/locales/en.yml +5 -1
- data/doorkeeper.gemspec +8 -0
- data/gemfiles/rails_6_0.gemfile +1 -1
- data/lib/doorkeeper/config.rb +64 -9
- data/lib/doorkeeper/errors.rb +13 -18
- data/lib/doorkeeper/helpers/controller.rb +6 -2
- data/lib/doorkeeper/models/access_token_mixin.rb +43 -2
- data/lib/doorkeeper/oauth/authorization/code.rb +1 -5
- data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -9
- data/lib/doorkeeper/oauth/base_request.rb +2 -0
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +14 -0
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +8 -0
- data/lib/doorkeeper/oauth/code_request.rb +5 -11
- data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +70 -37
- data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +16 -7
- data/lib/doorkeeper/oauth/token_request.rb +4 -18
- data/lib/doorkeeper/orm/active_record/application.rb +1 -1
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
- data/lib/doorkeeper/orm/active_record.rb +2 -2
- data/lib/doorkeeper/request/authorization_code.rb +2 -0
- data/lib/doorkeeper/request.rb +6 -11
- data/lib/doorkeeper/server.rb +2 -6
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +1 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +88 -43
- data/lib/generators/doorkeeper/templates/migration.rb.erb +1 -1
- data/spec/controllers/authorizations_controller_spec.rb +140 -61
- data/spec/controllers/protected_resources_controller_spec.rb +3 -3
- data/spec/controllers/tokens_controller_spec.rb +140 -40
- data/spec/dummy/config/initializers/doorkeeper.rb +47 -20
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +1 -1
- data/spec/lib/config_spec.rb +32 -1
- data/spec/lib/oauth/authorization_code_request_spec.rb +11 -1
- data/spec/lib/oauth/base_request_spec.rb +33 -16
- data/spec/lib/oauth/client_credentials/creator_spec.rb +3 -0
- data/spec/lib/oauth/code_request_spec.rb +27 -28
- data/spec/lib/oauth/invalid_request_response_spec.rb +75 -0
- data/spec/lib/oauth/pre_authorization_spec.rb +80 -55
- data/spec/lib/oauth/refresh_token_request_spec.rb +1 -0
- data/spec/lib/oauth/token_request_spec.rb +20 -17
- data/spec/lib/server_spec.rb +0 -12
- data/spec/requests/endpoints/authorization_spec.rb +21 -5
- data/spec/requests/endpoints/token_spec.rb +1 -1
- data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
- data/spec/requests/flows/authorization_code_spec.rb +77 -23
- data/spec/requests/flows/client_credentials_spec.rb +38 -0
- data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
- data/spec/requests/flows/implicit_grant_spec.rb +9 -8
- data/spec/requests/flows/password_spec.rb +37 -0
- data/spec/requests/flows/refresh_token_spec.rb +1 -1
- data/spec/support/helpers/request_spec_helper.rb +14 -2
- data/spec/validators/redirect_uri_validator_spec.rb +1 -1
- metadata +15 -6
- data/app/validators/redirect_uri_validator.rb +0 -60
@@ -1,7 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
Doorkeeper.configure do
|
4
|
-
# Change the ORM that doorkeeper will use (
|
4
|
+
# Change the ORM that doorkeeper will use (requires ORM extensions installed).
|
5
|
+
# Check the list of supported ORMs here: https://github.com/doorkeeper-gem/doorkeeper#orms
|
5
6
|
orm :active_record
|
6
7
|
|
7
8
|
# This block will be called to check whether the resource owner is authenticated or not.
|
@@ -9,7 +10,7 @@ Doorkeeper.configure do
|
|
9
10
|
raise "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}"
|
10
11
|
# Put your resource owner authentication logic here.
|
11
12
|
# Example implementation:
|
12
|
-
# User.
|
13
|
+
# User.find_by(id: session[:user_id]) || redirect_to(new_user_session_url)
|
13
14
|
end
|
14
15
|
|
15
16
|
# If you didn't skip applications controller from Doorkeeper routes in your application routes.rb
|
@@ -39,18 +40,18 @@ Doorkeeper.configure do
|
|
39
40
|
#
|
40
41
|
# enforce_content_type
|
41
42
|
|
42
|
-
# Authorization Code expiration time (default 10 minutes).
|
43
|
+
# Authorization Code expiration time (default: 10 minutes).
|
43
44
|
#
|
44
45
|
# authorization_code_expires_in 10.minutes
|
45
46
|
|
46
|
-
# Access token expiration time (default 2 hours).
|
47
|
-
# If you want to disable expiration, set this to nil
|
47
|
+
# Access token expiration time (default: 2 hours).
|
48
|
+
# If you want to disable expiration, set this to `nil`.
|
48
49
|
#
|
49
50
|
# access_token_expires_in 2.hours
|
50
51
|
|
51
52
|
# Assign custom TTL for access tokens. Will be used instead of access_token_expires_in
|
52
53
|
# option if defined. In case the block returns `nil` value Doorkeeper fallbacks to
|
53
|
-
#
|
54
|
+
# +access_token_expires_in+ configuration option value. If you really need to issue a
|
54
55
|
# non-expiring access token (which is not recommended) then you need to return
|
55
56
|
# Float::INFINITY from this block.
|
56
57
|
#
|
@@ -65,12 +66,13 @@ Doorkeeper.configure do
|
|
65
66
|
# end
|
66
67
|
|
67
68
|
# Use a custom class for generating the access token.
|
68
|
-
# See https://
|
69
|
+
# See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-access-token-generator
|
69
70
|
#
|
70
71
|
# access_token_generator '::Doorkeeper::JWT'
|
71
72
|
|
72
|
-
# The controller Doorkeeper::ApplicationController inherits from.
|
73
|
-
# Defaults to ActionController::Base
|
73
|
+
# The controller +Doorkeeper::ApplicationController+ inherits from.
|
74
|
+
# Defaults to +ActionController::Base+ unless +api_only+ is set, which changes the default to
|
75
|
+
# +ActionController::API+. The return value of this option must be a stringified class name.
|
74
76
|
# See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-base-controller
|
75
77
|
#
|
76
78
|
# base_controller 'ApplicationController'
|
@@ -128,11 +130,10 @@ Doorkeeper.configure do
|
|
128
130
|
#
|
129
131
|
# hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt'
|
130
132
|
|
131
|
-
# When the above option is enabled,
|
132
|
-
#
|
133
|
-
#
|
134
|
-
#
|
135
|
-
# you will probably want to enable the fallback to plain tokens.
|
133
|
+
# When the above option is enabled, and a hashed token or secret is not found,
|
134
|
+
# you can allow to fall back to another strategy. For users upgrading
|
135
|
+
# doorkeeper and wishing to enable hashing, you will probably want to enable
|
136
|
+
# the fallback to plain tokens.
|
136
137
|
#
|
137
138
|
# This will ensure that old access tokens and secrets
|
138
139
|
# will remain valid even if the hashing above is enabled.
|
@@ -141,8 +142,8 @@ Doorkeeper.configure do
|
|
141
142
|
|
142
143
|
# Issue access tokens with refresh token (disabled by default), you may also
|
143
144
|
# pass a block which accepts `context` to customize when to give a refresh
|
144
|
-
# token or not. Similar to
|
145
|
-
# the properties:
|
145
|
+
# token or not. Similar to +custom_access_token_expires_in+, `context` has
|
146
|
+
# the following properties:
|
146
147
|
#
|
147
148
|
# `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
|
148
149
|
# `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
|
@@ -151,7 +152,7 @@ Doorkeeper.configure do
|
|
151
152
|
# use_refresh_token
|
152
153
|
|
153
154
|
# Provide support for an owner to be assigned to each registered application (disabled by default)
|
154
|
-
# Optional parameter confirmation: true (default false) if you want to enforce ownership of
|
155
|
+
# Optional parameter confirmation: true (default: false) if you want to enforce ownership of
|
155
156
|
# a registered application
|
156
157
|
# NOTE: you must also run the rails g doorkeeper:application_owner generator
|
157
158
|
# to provide the necessary support
|
@@ -160,22 +161,22 @@ Doorkeeper.configure do
|
|
160
161
|
|
161
162
|
# Define access token scopes for your provider
|
162
163
|
# For more information go to
|
163
|
-
# https://
|
164
|
+
# https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes
|
164
165
|
#
|
165
166
|
# default_scopes :public
|
166
167
|
# optional_scopes :write, :update
|
167
168
|
|
168
|
-
#
|
169
|
+
# Allows to restrict only certain scopes for grant_type.
|
169
170
|
# By default, all the scopes will be available for all the grant types.
|
170
171
|
#
|
171
172
|
# Keys to this hash should be the name of grant_type and
|
172
173
|
# values should be the array of scopes for that grant type.
|
173
|
-
# Note: scopes should be from configured_scopes(i.e.
|
174
|
+
# Note: scopes should be from configured_scopes (i.e. default or optional)
|
174
175
|
#
|
175
176
|
# scopes_by_grant_type password: [:write], client_credentials: [:update]
|
176
177
|
|
177
178
|
# Forbids creating/updating applications with arbitrary scopes that are
|
178
|
-
# not in configuration, i.e.
|
179
|
+
# not in configuration, i.e. +default_scopes+ or +optional_scopes+.
|
179
180
|
# (disabled by default)
|
180
181
|
#
|
181
182
|
# enforce_configured_scopes
|
@@ -237,7 +238,7 @@ Doorkeeper.configure do
|
|
237
238
|
# is invalid, expired, revoked or has invalid scopes.
|
238
239
|
#
|
239
240
|
# If you want to render error response yourself (i.e. rescue exceptions),
|
240
|
-
# set
|
241
|
+
# set +handle_auth_errors+ to `:raise` and rescue Doorkeeper::Errors::InvalidToken
|
241
242
|
# or following specific errors:
|
242
243
|
#
|
243
244
|
# Doorkeeper::Errors::TokenForbidden, Doorkeeper::Errors::TokenExpired,
|
@@ -281,6 +282,37 @@ Doorkeeper.configure do
|
|
281
282
|
#
|
282
283
|
# grant_flows %w[authorization_code client_credentials]
|
283
284
|
|
285
|
+
# Allows to customize OAuth grant flows that +each+ application support.
|
286
|
+
# You can configure a custom block (or use a class respond to `#call`) that must
|
287
|
+
# return `true` in case Application instance supports requested OAuth grant flow
|
288
|
+
# during the authorization request to the server. This configuration +doesn't+
|
289
|
+
# set flows per application, it only allows to check if application supports
|
290
|
+
# specific grant flow.
|
291
|
+
#
|
292
|
+
# For example you can add an additional database column to `oauth_applications` table,
|
293
|
+
# say `t.array :grant_flows, default: []`, and store allowed grant flows that can
|
294
|
+
# be used with this application there. Then when authorization requested Doorkeeper
|
295
|
+
# will call this block to check if specific Application (passed with client_id and/or
|
296
|
+
# client_secret) is allowed to perform the request for the specific grant type
|
297
|
+
# (authorization, password, client_credentials, etc).
|
298
|
+
#
|
299
|
+
# Example of the block:
|
300
|
+
#
|
301
|
+
# ->(flow, client) { client.grant_flows.include?(flow) }
|
302
|
+
#
|
303
|
+
# In case this option invocation result is `false`, Doorkeeper server returns
|
304
|
+
# :unauthorized_client error and stops the request.
|
305
|
+
#
|
306
|
+
# @param allow_grant_flow_for_client [Proc] Block or any object respond to #call
|
307
|
+
# @return [Boolean] `true` if allow or `false` if forbid the request
|
308
|
+
#
|
309
|
+
# allow_grant_flow_for_client do |grant_flow, client|
|
310
|
+
# # `grant_flows` is an Array column with grant
|
311
|
+
# # flows that application supports
|
312
|
+
#
|
313
|
+
# client.grant_flows.include?(grant_flow)
|
314
|
+
# end
|
315
|
+
|
284
316
|
# Hook into the strategies' request & response life-cycle in case your
|
285
317
|
# application needs advanced customization or logging:
|
286
318
|
#
|
@@ -296,7 +328,7 @@ Doorkeeper.configure do
|
|
296
328
|
# or add any other functionality.
|
297
329
|
#
|
298
330
|
# before_successful_authorization do |controller|
|
299
|
-
# Rails.logger.info(params.inspect)
|
331
|
+
# Rails.logger.info(controller.request.params.inspect)
|
300
332
|
# end
|
301
333
|
#
|
302
334
|
# after_successful_authorization do |controller|
|
@@ -314,23 +346,13 @@ Doorkeeper.configure do
|
|
314
346
|
# client.superapp? or resource_owner.admin?
|
315
347
|
# end
|
316
348
|
|
317
|
-
# Configure custom constraints for the Token Introspection request.
|
318
|
-
# this configuration option allows to introspect
|
319
|
-
#
|
349
|
+
# Configure custom constraints for the Token Introspection request.
|
350
|
+
# By default this configuration option allows to introspect a token by another
|
351
|
+
# token of the same application, OR to introspect the token that belongs to
|
352
|
+
# authorized client (from authenticated client) OR when token doesn't
|
320
353
|
# belong to any client (public token). Otherwise requester has no access to the
|
321
354
|
# introspection and it will return response as stated in the RFC.
|
322
355
|
#
|
323
|
-
# You can define your custom check:
|
324
|
-
#
|
325
|
-
# allow_token_introspection do |token, authorized_client, _authorized_token|
|
326
|
-
# if token.application
|
327
|
-
# # `protected_resource` is a new database boolean column, for example
|
328
|
-
# token.application == authorized_client || authorized_client.protected_resource?
|
329
|
-
# else
|
330
|
-
# true
|
331
|
-
# end
|
332
|
-
# end
|
333
|
-
#
|
334
356
|
# Block arguments:
|
335
357
|
#
|
336
358
|
# @param token [Doorkeeper::AccessToken]
|
@@ -343,19 +365,42 @@ Doorkeeper.configure do
|
|
343
365
|
# @param authorized_token [Doorkeeper::AccessToken]
|
344
366
|
# Bearer token used to authorize the request
|
345
367
|
#
|
346
|
-
#
|
347
|
-
#
|
348
|
-
#
|
368
|
+
# In case the block returns `nil` or `false` introspection responses with 401 status code
|
369
|
+
# when using authorized token to introspect, or you'll get 200 with { "active": false } body
|
370
|
+
# when using authorized client to introspect as stated in the
|
371
|
+
# RFC 7662 section 2.2. Introspection Response.
|
372
|
+
#
|
373
|
+
# Using with caution:
|
374
|
+
# Keep in mind that these three parameters pass to block can be nil as following case:
|
375
|
+
# `authorized_client` is nil if and only if `authorized_token` is present, and vice versa.
|
376
|
+
# `token` will be nil if and only if `authorized_token` is present.
|
377
|
+
# So remember to use `&` or check if it is present before calling method on
|
378
|
+
# them to make sure you doesn't get NoMethodError exception.
|
379
|
+
#
|
380
|
+
# You can define your custom check:
|
381
|
+
#
|
382
|
+
# allow_token_introspection do |token, authorized_client, authorized_token|
|
383
|
+
# if authorized_token
|
384
|
+
# # customize: require `introspection` scope
|
385
|
+
# authorized_token.application == token&.application ||
|
386
|
+
# authorized_token.scopes.include?("introspection")
|
387
|
+
# elsif token.application
|
388
|
+
# # `protected_resource` is a new database boolean column, for example
|
389
|
+
# authorized_client == token.application || authorized_client.protected_resource?
|
390
|
+
# else
|
391
|
+
# # public token (when token.application is nil, token doesn't belong to any application)
|
392
|
+
# true
|
393
|
+
# end
|
394
|
+
# end
|
349
395
|
#
|
350
|
-
#
|
396
|
+
# Or you can completely disable any token introspection:
|
351
397
|
#
|
352
398
|
# allow_token_introspection false
|
353
399
|
#
|
354
|
-
# In such case every request for token introspection will get { "active": false } response.
|
355
400
|
# If you need to block the request at all, then configure your routes.rb or web-server
|
356
401
|
# like nginx to forbid the request.
|
357
402
|
|
358
|
-
# WWW-Authenticate Realm (default "Doorkeeper").
|
403
|
+
# WWW-Authenticate Realm (default: "Doorkeeper").
|
359
404
|
#
|
360
405
|
# realm "Doorkeeper"
|
361
406
|
end
|
@@ -24,7 +24,7 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
|
|
24
24
|
t.text :redirect_uri, null: false
|
25
25
|
t.datetime :created_at, null: false
|
26
26
|
t.datetime :revoked_at
|
27
|
-
t.string :scopes
|
27
|
+
t.string :scopes, null: false, default: ''
|
28
28
|
end
|
29
29
|
|
30
30
|
add_index :oauth_access_grants, :token, unique: true
|
@@ -14,16 +14,14 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def translated_error_message(key)
|
18
|
-
I18n.translate key, scope: %i[doorkeeper errors messages]
|
19
|
-
end
|
20
|
-
|
21
17
|
let(:client) { FactoryBot.create :application }
|
22
18
|
let(:user) { User.create!(name: "Joe", password: "sekret") }
|
23
|
-
let(:access_token) { FactoryBot.build :access_token, resource_owner_id: user.id, application_id: client.id }
|
19
|
+
let(:access_token) { FactoryBot.build :access_token, resource_owner_id: user.id, application_id: client.id, scopes: "default" }
|
24
20
|
|
25
21
|
before do
|
26
22
|
Doorkeeper.configure do
|
23
|
+
default_scopes :default
|
24
|
+
|
27
25
|
custom_access_token_expires_in(lambda do |context|
|
28
26
|
context.grant_type == Doorkeeper::OAuth::IMPLICIT ? 1234 : nil
|
29
27
|
end)
|
@@ -106,80 +104,146 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
106
104
|
end
|
107
105
|
|
108
106
|
describe "POST #create with errors" do
|
109
|
-
|
110
|
-
|
107
|
+
context "when missing client_id" do
|
108
|
+
before do
|
109
|
+
post :create, params: {
|
110
|
+
client_id: "",
|
111
|
+
response_type: "token",
|
112
|
+
redirect_uri: client.redirect_uri,
|
113
|
+
}
|
114
|
+
end
|
111
115
|
|
112
|
-
|
113
|
-
client_id: client.uid,
|
114
|
-
response_type: "token",
|
115
|
-
scope: "invalid",
|
116
|
-
redirect_uri: client.redirect_uri,
|
117
|
-
}
|
118
|
-
end
|
116
|
+
let(:response_json_body) { JSON.parse(response.body) }
|
119
117
|
|
120
|
-
|
121
|
-
|
122
|
-
|
118
|
+
it "renders 400 error" do
|
119
|
+
expect(response.status).to eq 400
|
120
|
+
end
|
123
121
|
|
124
|
-
|
125
|
-
|
126
|
-
|
122
|
+
it "includes error name" do
|
123
|
+
expect(response_json_body["error"]).to eq("invalid_request")
|
124
|
+
end
|
127
125
|
|
128
|
-
|
129
|
-
|
130
|
-
|
126
|
+
it "includes error description" do
|
127
|
+
expect(response_json_body["error_description"]).to eq(
|
128
|
+
translated_invalid_request_error_message(:missing_param, :client_id)
|
129
|
+
)
|
130
|
+
end
|
131
131
|
|
132
|
-
|
133
|
-
|
132
|
+
it "does not issue any access token" do
|
133
|
+
expect(Doorkeeper::AccessToken.all).to be_empty
|
134
|
+
end
|
134
135
|
end
|
135
136
|
|
136
|
-
|
137
|
-
|
138
|
-
|
137
|
+
context "when other error happens" do
|
138
|
+
before do
|
139
|
+
default_scopes_exist :public
|
140
|
+
|
141
|
+
post :create, params: {
|
142
|
+
client_id: client.uid,
|
143
|
+
response_type: "token",
|
144
|
+
scope: "invalid",
|
145
|
+
redirect_uri: client.redirect_uri,
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
it "redirects after authorization" do
|
150
|
+
expect(response).to be_redirect
|
151
|
+
end
|
152
|
+
|
153
|
+
it "redirects to client redirect uri" do
|
154
|
+
expect(response.location).to match(/^#{client.redirect_uri}/)
|
155
|
+
end
|
156
|
+
|
157
|
+
it "does not include access token in fragment" do
|
158
|
+
expect(response.query_params["access_token"]).to be_nil
|
159
|
+
end
|
160
|
+
|
161
|
+
it "includes error in fragment" do
|
162
|
+
expect(response.query_params["error"]).to eq("invalid_scope")
|
163
|
+
end
|
164
|
+
|
165
|
+
it "includes error description in fragment" do
|
166
|
+
expect(response.query_params["error_description"]).to eq(translated_error_message(:invalid_scope))
|
167
|
+
end
|
139
168
|
|
140
|
-
|
141
|
-
|
169
|
+
it "does not issue any access token" do
|
170
|
+
expect(Doorkeeper::AccessToken.all).to be_empty
|
171
|
+
end
|
142
172
|
end
|
143
173
|
end
|
144
174
|
|
145
175
|
describe "POST #create in API mode with errors" do
|
146
|
-
|
147
|
-
|
148
|
-
|
176
|
+
context "when missing client_id" do
|
177
|
+
before do
|
178
|
+
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
149
179
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
end
|
180
|
+
post :create, params: {
|
181
|
+
client_id: "",
|
182
|
+
response_type: "token",
|
183
|
+
redirect_uri: client.redirect_uri,
|
184
|
+
}
|
185
|
+
end
|
157
186
|
|
158
|
-
|
159
|
-
let(:redirect_uri) { response_json_body["redirect_uri"] }
|
187
|
+
let(:response_json_body) { JSON.parse(response.body) }
|
160
188
|
|
161
|
-
|
162
|
-
|
163
|
-
|
189
|
+
it "renders 400 error" do
|
190
|
+
expect(response.status).to eq 400
|
191
|
+
end
|
164
192
|
|
165
|
-
|
166
|
-
|
167
|
-
|
193
|
+
it "includes error name" do
|
194
|
+
expect(response_json_body["error"]).to eq("invalid_request")
|
195
|
+
end
|
168
196
|
|
169
|
-
|
170
|
-
|
171
|
-
|
197
|
+
it "includes error description" do
|
198
|
+
expect(response_json_body["error_description"]).to eq(
|
199
|
+
translated_invalid_request_error_message(:missing_param, :client_id)
|
200
|
+
)
|
201
|
+
end
|
172
202
|
|
173
|
-
|
174
|
-
|
203
|
+
it "does not issue any access token" do
|
204
|
+
expect(Doorkeeper::AccessToken.all).to be_empty
|
205
|
+
end
|
175
206
|
end
|
176
207
|
|
177
|
-
|
178
|
-
|
179
|
-
|
208
|
+
context "when other error happens" do
|
209
|
+
before do
|
210
|
+
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
211
|
+
default_scopes_exist :public
|
180
212
|
|
181
|
-
|
182
|
-
|
213
|
+
post :create, params: {
|
214
|
+
client_id: client.uid,
|
215
|
+
response_type: "token",
|
216
|
+
scope: "invalid",
|
217
|
+
redirect_uri: client.redirect_uri,
|
218
|
+
}
|
219
|
+
end
|
220
|
+
|
221
|
+
let(:response_json_body) { JSON.parse(response.body) }
|
222
|
+
let(:redirect_uri) { response_json_body["redirect_uri"] }
|
223
|
+
|
224
|
+
it "renders 400 error" do
|
225
|
+
expect(response.status).to eq 400
|
226
|
+
end
|
227
|
+
|
228
|
+
it "includes correct redirect URI" do
|
229
|
+
expect(redirect_uri).to match(/^#{client.redirect_uri}/)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "does not include access token in fragment" do
|
233
|
+
expect(redirect_uri.match(/access_token=([a-f0-9]+)&?/)).to be_nil
|
234
|
+
end
|
235
|
+
|
236
|
+
it "includes error in redirect uri" do
|
237
|
+
expect(redirect_uri.match(/error=([a-z_]+)&?/)[1]).to eq "invalid_scope"
|
238
|
+
end
|
239
|
+
|
240
|
+
it "includes error description in redirect uri" do
|
241
|
+
expect(redirect_uri.match(/error_description=(.+)&?/)[1]).to_not be_nil
|
242
|
+
end
|
243
|
+
|
244
|
+
it "does not issue any access token" do
|
245
|
+
expect(Doorkeeper::AccessToken.all).to be_empty
|
246
|
+
end
|
183
247
|
end
|
184
248
|
end
|
185
249
|
|
@@ -368,7 +432,7 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
368
432
|
expect(json_response["redirect_uri"]).to eq(client.redirect_uri)
|
369
433
|
expect(json_response["state"]).to be_nil
|
370
434
|
expect(json_response["response_type"]).to eq("token")
|
371
|
-
expect(json_response["scope"]).to eq("")
|
435
|
+
expect(json_response["scope"]).to eq("default")
|
372
436
|
end
|
373
437
|
end
|
374
438
|
|
@@ -445,12 +509,12 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
445
509
|
end
|
446
510
|
|
447
511
|
it "includes error in body" do
|
448
|
-
expect(response_json_body["error"]).to eq("
|
512
|
+
expect(response_json_body["error"]).to eq("invalid_request")
|
449
513
|
end
|
450
514
|
|
451
515
|
it "includes error description in body" do
|
452
516
|
expect(response_json_body["error_description"])
|
453
|
-
.to eq(
|
517
|
+
.to eq(translated_invalid_request_error_message(:missing_param, :client_id))
|
454
518
|
end
|
455
519
|
|
456
520
|
it "does not issue any token" do
|
@@ -513,6 +577,8 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
513
577
|
|
514
578
|
describe "authorize response memoization" do
|
515
579
|
it "memoizes the result of the authorization" do
|
580
|
+
pre_auth = double(:pre_auth, authorizable?: true)
|
581
|
+
allow(controller).to receive(:pre_auth) { pre_auth }
|
516
582
|
strategy = double(:strategy, authorize: true)
|
517
583
|
expect(strategy).to receive(:authorize).once
|
518
584
|
allow(controller).to receive(:strategy) { strategy }
|
@@ -524,4 +590,17 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
524
590
|
post :create
|
525
591
|
end
|
526
592
|
end
|
593
|
+
|
594
|
+
describe "strong parameters" do
|
595
|
+
it "ignores non-scalar scope parameter" do
|
596
|
+
get :new, params: {
|
597
|
+
client_id: client.uid,
|
598
|
+
response_type: "token",
|
599
|
+
redirect_uri: client.redirect_uri,
|
600
|
+
scope: { "0" => "profile" },
|
601
|
+
}
|
602
|
+
|
603
|
+
expect(response).to be_successful
|
604
|
+
end
|
605
|
+
end
|
527
606
|
end
|
@@ -166,7 +166,7 @@ describe "doorkeeper authorize filter" do
|
|
166
166
|
it "it renders a custom JSON response", token: :invalid do
|
167
167
|
get :index, params: { access_token: token_string }
|
168
168
|
expect(response.status).to eq 401
|
169
|
-
expect(response.content_type).to
|
169
|
+
expect(response.content_type).to include("application/json")
|
170
170
|
expect(response.header["WWW-Authenticate"]).to match(/^Bearer/)
|
171
171
|
|
172
172
|
expect(json_response).not_to be_nil
|
@@ -196,7 +196,7 @@ describe "doorkeeper authorize filter" do
|
|
196
196
|
it "it renders a custom text response", token: :invalid do
|
197
197
|
get :index, params: { access_token: token_string }
|
198
198
|
expect(response.status).to eq 401
|
199
|
-
expect(response.content_type).to
|
199
|
+
expect(response.content_type).to include("text/plain")
|
200
200
|
expect(response.header["WWW-Authenticate"]).to match(/^Bearer/)
|
201
201
|
expect(response.body).to eq("Unauthorized")
|
202
202
|
end
|
@@ -246,7 +246,7 @@ describe "doorkeeper authorize filter" do
|
|
246
246
|
it "renders a custom JSON response" do
|
247
247
|
get :index, params: { access_token: token_string }
|
248
248
|
expect(response.header).to_not include("WWW-Authenticate")
|
249
|
-
expect(response.content_type).to
|
249
|
+
expect(response.content_type).to include("application/json")
|
250
250
|
expect(response.status).to eq 403
|
251
251
|
|
252
252
|
expect(json_response).not_to be_nil
|