doorkeeper 5.3.3 → 5.4.0.rc1
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 +0 -14
- data/CHANGELOG.md +35 -10
- data/Dangerfile +7 -7
- data/Dockerfile +2 -2
- data/Gemfile +9 -9
- data/README.md +6 -4
- data/app/controllers/doorkeeper/applications_controller.rb +7 -7
- data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
- data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
- data/app/views/doorkeeper/applications/show.html.erb +19 -2
- data/bin/console +14 -0
- data/config/locales/en.yml +3 -1
- data/doorkeeper.gemspec +1 -1
- data/gemfiles/rails_5_0.gemfile +8 -7
- data/gemfiles/rails_5_1.gemfile +8 -7
- data/gemfiles/rails_5_2.gemfile +8 -7
- data/gemfiles/rails_6_0.gemfile +8 -7
- data/gemfiles/rails_master.gemfile +8 -7
- data/lib/doorkeeper.rb +106 -79
- data/lib/doorkeeper/config.rb +40 -17
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +28 -14
- data/lib/doorkeeper/grape/helpers.rb +1 -1
- data/lib/doorkeeper/models/access_grant_mixin.rb +9 -11
- data/lib/doorkeeper/models/access_token_mixin.rb +100 -41
- data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
- data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
- data/lib/doorkeeper/oauth/authorization/code.rb +14 -5
- data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
- data/lib/doorkeeper/oauth/authorization/token.rb +7 -11
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
- data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
- data/lib/doorkeeper/oauth/base_request.rb +11 -19
- data/lib/doorkeeper/oauth/client.rb +1 -1
- data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +25 -7
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
- data/lib/doorkeeper/oauth/code_request.rb +1 -1
- data/lib/doorkeeper/oauth/code_response.rb +6 -2
- data/lib/doorkeeper/oauth/error_response.rb +2 -4
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
- data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
- data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
- data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -5
- data/lib/doorkeeper/oauth/pre_authorization.rb +32 -27
- data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
- data/lib/doorkeeper/oauth/token.rb +1 -1
- data/lib/doorkeeper/oauth/token_introspection.rb +3 -3
- data/lib/doorkeeper/oauth/token_request.rb +2 -2
- data/lib/doorkeeper/oauth/token_response.rb +1 -1
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +7 -2
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +6 -2
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +9 -64
- data/lib/doorkeeper/rails/routes.rb +13 -17
- data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
- data/lib/doorkeeper/rails/routes/registry.rb +45 -0
- data/lib/doorkeeper/request/strategy.rb +2 -2
- data/lib/doorkeeper/server.rb +3 -3
- data/lib/doorkeeper/version.rb +3 -3
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
- data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +39 -3
- data/lib/generators/doorkeeper/templates/migration.rb.erb +2 -0
- data/spec/controllers/applications_controller_spec.rb +2 -2
- data/spec/controllers/authorizations_controller_spec.rb +165 -30
- data/spec/controllers/tokens_controller_spec.rb +6 -5
- data/spec/dummy/app/helpers/application_helper.rb +1 -1
- data/spec/dummy/app/models/user.rb +5 -1
- data/spec/dummy/config/application.rb +6 -4
- data/spec/dummy/config/boot.rb +4 -4
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/routes.rb +4 -4
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +2 -2
- data/spec/dummy/db/schema.rb +3 -1
- data/spec/factories.rb +1 -1
- data/spec/generators/enable_polymorphic_resource_owner_generator_spec.rb +47 -0
- data/spec/lib/config_spec.rb +15 -11
- data/spec/lib/models/revocable_spec.rb +2 -3
- data/spec/lib/models/scopes_spec.rb +8 -0
- data/spec/lib/oauth/authorization_code_request_spec.rb +25 -15
- data/spec/lib/oauth/base_request_spec.rb +6 -20
- data/spec/lib/oauth/client_credentials/creator_spec.rb +90 -89
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +84 -86
- data/spec/lib/oauth/client_credentials/validation_spec.rb +38 -40
- data/spec/lib/oauth/client_credentials_request_spec.rb +5 -4
- data/spec/lib/oauth/code_request_spec.rb +1 -1
- data/spec/lib/oauth/code_response_spec.rb +5 -1
- data/spec/lib/oauth/error_response_spec.rb +1 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +24 -13
- data/spec/lib/oauth/pre_authorization_spec.rb +13 -18
- data/spec/lib/oauth/refresh_token_request_spec.rb +19 -30
- data/spec/lib/oauth/token_request_spec.rb +14 -7
- data/spec/lib/option_spec.rb +51 -0
- data/spec/lib/stale_records_cleaner_spec.rb +18 -5
- data/spec/models/doorkeeper/access_grant_spec.rb +18 -4
- data/spec/models/doorkeeper/access_token_spec.rb +507 -479
- data/spec/models/doorkeeper/application_spec.rb +22 -62
- data/spec/requests/endpoints/token_spec.rb +5 -1
- data/spec/requests/flows/authorization_code_errors_spec.rb +4 -1
- data/spec/requests/flows/authorization_code_spec.rb +6 -1
- data/spec/requests/flows/client_credentials_spec.rb +41 -0
- data/spec/requests/flows/refresh_token_spec.rb +16 -8
- data/spec/requests/flows/revoke_token_spec.rb +143 -104
- data/spec/support/helpers/access_token_request_helper.rb +1 -0
- data/spec/support/helpers/authorization_request_helper.rb +4 -4
- data/spec/support/helpers/config_helper.rb +1 -1
- data/spec/support/shared/controllers_shared_context.rb +2 -2
- data/spec/support/shared/models_shared_examples.rb +6 -4
- metadata +16 -5
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module Rails
|
5
|
+
# Abstract router module that implements base behavior
|
6
|
+
# for generating and mapping Rails routes.
|
7
|
+
#
|
8
|
+
# Could be reused in Doorkeeper extensions.
|
9
|
+
#
|
10
|
+
module AbstractRouter
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
attr_reader :routes
|
14
|
+
|
15
|
+
def initialize(routes, mapper = Mapper.new, &block)
|
16
|
+
@routes = routes
|
17
|
+
@mapping = mapper.map(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_routes!(**_options)
|
21
|
+
raise NotImplementedError, "must be redefined for #{self.class.name}!"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def map_route(name, method)
|
27
|
+
return if @mapping.skipped?(name)
|
28
|
+
|
29
|
+
send(method, @mapping[name])
|
30
|
+
|
31
|
+
mapping[name] = @mapping[name]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module Rails
|
5
|
+
class Routes
|
6
|
+
# Thread-safe registry of any Doorkeeper additional routes.
|
7
|
+
# Used to allow implementing of Doorkeeper extensions that must
|
8
|
+
# use their own routes.
|
9
|
+
#
|
10
|
+
module Registry
|
11
|
+
ROUTES_ACCESS_LOCK = Mutex.new
|
12
|
+
ROUTES_DEFINITION_LOCK = Mutex.new
|
13
|
+
|
14
|
+
InvalidRouterClass = Class.new(StandardError)
|
15
|
+
|
16
|
+
# Collection of additional registered routes for Doorkeeper.
|
17
|
+
#
|
18
|
+
# @return [Array<Object>] set of registered routes
|
19
|
+
#
|
20
|
+
def registered_routes
|
21
|
+
ROUTES_DEFINITION_LOCK.synchronize do
|
22
|
+
@registered_routes ||= Set.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Registers additional routes in the Doorkeeper registry
|
27
|
+
#
|
28
|
+
# @param [Object] routes
|
29
|
+
# routes class
|
30
|
+
#
|
31
|
+
def register_routes(routes)
|
32
|
+
if !routes.is_a?(Module) || !(routes < AbstractRouter)
|
33
|
+
raise InvalidRouterClass, "routes class must include Doorkeeper::Rails::AbstractRouter"
|
34
|
+
end
|
35
|
+
|
36
|
+
ROUTES_ACCESS_LOCK.synchronize do
|
37
|
+
registered_routes << routes
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
alias register register_routes
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/doorkeeper/server.rb
CHANGED
@@ -2,19 +2,19 @@
|
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
class Server
|
5
|
-
|
5
|
+
attr_reader :context
|
6
6
|
|
7
7
|
def initialize(context = nil)
|
8
8
|
@context = context
|
9
9
|
end
|
10
10
|
|
11
11
|
def authorization_request(strategy)
|
12
|
-
klass = Request.authorization_strategy
|
12
|
+
klass = Request.authorization_strategy(strategy)
|
13
13
|
klass.new(self)
|
14
14
|
end
|
15
15
|
|
16
16
|
def token_request(strategy)
|
17
|
-
klass = Request.token_strategy
|
17
|
+
klass = Request.token_strategy(strategy)
|
18
18
|
klass.new(self)
|
19
19
|
end
|
20
20
|
|
data/lib/doorkeeper/version.rb
CHANGED
@@ -12,7 +12,7 @@ module Doorkeeper
|
|
12
12
|
source_root File.expand_path("templates", __dir__)
|
13
13
|
desc "Add confidential column to Doorkeeper applications"
|
14
14
|
|
15
|
-
def
|
15
|
+
def confidential_applications
|
16
16
|
migration_template(
|
17
17
|
"add_confidential_to_applications.rb.erb",
|
18
18
|
"db/migrate/add_confidential_to_applications.rb",
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/generators"
|
4
|
+
require "rails/generators/active_record"
|
5
|
+
|
6
|
+
module Doorkeeper
|
7
|
+
# Generates migration with polymorphic resource owner required
|
8
|
+
# database columns for Doorkeeper Access Token and Access Grant
|
9
|
+
# models.
|
10
|
+
#
|
11
|
+
class EnablePolymorphicResourceOwnerGenerator < ::Rails::Generators::Base
|
12
|
+
include ::Rails::Generators::Migration
|
13
|
+
source_root File.expand_path("templates", __dir__)
|
14
|
+
desc "Provide support for polymorphic Resource Owner."
|
15
|
+
|
16
|
+
def enable_polymorphic_resource_owner
|
17
|
+
migration_template(
|
18
|
+
"enable_polymorphic_resource_owner_migration.rb.erb",
|
19
|
+
"db/migrate/enable_polymorphic_resource_owner.rb",
|
20
|
+
migration_version: migration_version,
|
21
|
+
)
|
22
|
+
gsub_file(
|
23
|
+
"config/initializers/doorkeeper.rb",
|
24
|
+
"# use_polymorphic_resource_owner",
|
25
|
+
"use_polymorphic_resource_owner",
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.next_migration_number(dirname)
|
30
|
+
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def migration_version
|
36
|
+
"[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class EnablePolymorphicResourceOwner < ActiveRecord::Migration<%= migration_version %>
|
4
|
+
def change
|
5
|
+
add_column :oauth_access_tokens, :resource_owner_type, :string
|
6
|
+
add_column :oauth_access_grants, :resource_owner_type, :string
|
7
|
+
change_column_null :oauth_access_grants, :resource_owner_type, false
|
8
|
+
|
9
|
+
add_index :oauth_access_tokens,
|
10
|
+
[:resource_owner_id, :resource_owner_type],
|
11
|
+
name: 'polymorphic_owner_oauth_access_tokens'
|
12
|
+
|
13
|
+
add_index :oauth_access_grants,
|
14
|
+
[:resource_owner_id, :resource_owner_type],
|
15
|
+
name: 'polymorphic_owner_oauth_access_grants'
|
16
|
+
end
|
17
|
+
end
|
@@ -58,6 +58,23 @@ Doorkeeper.configure do
|
|
58
58
|
# end
|
59
59
|
# end
|
60
60
|
|
61
|
+
# Enables polymorphic Resource Owner association for Access Tokens and Access Grants.
|
62
|
+
# By default this option is disabled.
|
63
|
+
#
|
64
|
+
# Make sure you properly setup you database and have all the required columns (run
|
65
|
+
# `bundle exec rails generate doorkeeper:enable_polymorphic_resource_owner` and execute Rails
|
66
|
+
# migrations).
|
67
|
+
#
|
68
|
+
# If this option enabled, Doorkeeper will store not only Resource Owner primary key
|
69
|
+
# value, but also it's type (class name). See "Polymorphic Associations" section of
|
70
|
+
# Rails guides: https://guides.rubyonrails.org/association_basics.html#polymorphic-associations
|
71
|
+
#
|
72
|
+
# [NOTE] If you apply this option on already existing project don't forget to manually
|
73
|
+
# update `resource_owner_type` column in the database and fix migration template as it will
|
74
|
+
# set NOT NULL constraint for Access Grants table.
|
75
|
+
#
|
76
|
+
# use_polymorphic_resource_owner
|
77
|
+
|
61
78
|
# If you are planning to use Doorkeeper in Rails 5 API-only application, then you might
|
62
79
|
# want to use API mode that will skip all the views management and change the way how
|
63
80
|
# Doorkeeper responds to a requests.
|
@@ -360,6 +377,17 @@ Doorkeeper.configure do
|
|
360
377
|
# client.grant_flows.include?(grant_flow)
|
361
378
|
# end
|
362
379
|
|
380
|
+
# If you need arbitrary Resource Owner-Client authorization you can enable this option
|
381
|
+
# and implement the check your need. Config option must respond to #call and return
|
382
|
+
# true in case resource owner authorized for the specific application or false in other
|
383
|
+
# cases.
|
384
|
+
#
|
385
|
+
# Be default all Resource Owners are authorized to any Client (application).
|
386
|
+
#
|
387
|
+
# authorize_resource_owner_for_client do |client, resource_owner|
|
388
|
+
# resource_owner.admin? || client.owners_whitelist.include?(resource_owner)
|
389
|
+
# end
|
390
|
+
|
363
391
|
# Hook into the strategies' request & response life-cycle in case your
|
364
392
|
# application needs advanced customization or logging:
|
365
393
|
#
|
@@ -372,17 +400,25 @@ Doorkeeper.configure do
|
|
372
400
|
# end
|
373
401
|
|
374
402
|
# Hook into Authorization flow in order to implement Single Sign Out
|
375
|
-
# or add any other functionality.
|
403
|
+
# or add any other functionality. Inside the block you have an access
|
404
|
+
# to `controller` (authorizations controller instance) and `context`
|
405
|
+
# (Doorkeeper::OAuth::Hooks::Context instance) which provides pre auth
|
406
|
+
# or auth objects with issued token based on hook type (before or after).
|
376
407
|
#
|
377
|
-
# before_successful_authorization do |controller|
|
408
|
+
# before_successful_authorization do |controller, context|
|
378
409
|
# Rails.logger.info(controller.request.params.inspect)
|
410
|
+
#
|
411
|
+
# Rails.logger.info(context.pre_auth.inspect)
|
379
412
|
# end
|
380
413
|
#
|
381
|
-
# after_successful_authorization do |controller|
|
414
|
+
# after_successful_authorization do |controller, context|
|
382
415
|
# controller.session[:logout_urls] <<
|
383
416
|
# Doorkeeper::Application
|
384
417
|
# .find_by(controller.request.params.slice(:redirect_uri))
|
385
418
|
# .logout_uri
|
419
|
+
#
|
420
|
+
# Rails.logger.info(context.auth.inspect)
|
421
|
+
# Rails.logger.info(context.issued_token)
|
386
422
|
# end
|
387
423
|
|
388
424
|
# Under some circumstances you might want to have applications auto-approved,
|
@@ -167,8 +167,8 @@ module Doorkeeper
|
|
167
167
|
|
168
168
|
# We don't know the application secret here (because its hashed) so we can not assert its text on the page
|
169
169
|
# Instead, we read it from the page and then check if it matches the application secret
|
170
|
-
code_element =
|
171
|
-
secret_from_page = code_element[1]
|
170
|
+
code_element = /code.*id="secret">\s*\K([^<]*)/m.match(response.body)
|
171
|
+
secret_from_page = code_element[1].strip
|
172
172
|
|
173
173
|
expect(response.body).to have_selector("code#application_id", text: application.uid)
|
174
174
|
expect(response.body).to have_selector("code#secret")
|
@@ -16,7 +16,14 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
16
16
|
|
17
17
|
let(:client) { FactoryBot.create :application }
|
18
18
|
let(:user) { User.create!(name: "Joe", password: "sekret") }
|
19
|
-
|
19
|
+
|
20
|
+
let(:access_token) do
|
21
|
+
FactoryBot.build :access_token,
|
22
|
+
resource_owner_id: user.id,
|
23
|
+
resource_owner_type: user.class.name,
|
24
|
+
application_id: client.id,
|
25
|
+
scopes: "default"
|
26
|
+
end
|
20
27
|
|
21
28
|
before do
|
22
29
|
Doorkeeper.configure do
|
@@ -136,6 +143,37 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
136
143
|
end
|
137
144
|
end
|
138
145
|
|
146
|
+
context "when user cannot access application" do
|
147
|
+
before do
|
148
|
+
allow(Doorkeeper.configuration).to receive(:authorize_resource_owner_for_client).and_return(->(*_) { false })
|
149
|
+
post :create, params: {
|
150
|
+
client_id: client.uid,
|
151
|
+
response_type: "token",
|
152
|
+
redirect_uri: client.redirect_uri,
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
let(:response_json_body) { JSON.parse(response.body) }
|
157
|
+
|
158
|
+
it "renders 400 error" do
|
159
|
+
expect(response.status).to eq 401
|
160
|
+
end
|
161
|
+
|
162
|
+
it "includes error name" do
|
163
|
+
expect(response_json_body["error"]).to eq("invalid_client")
|
164
|
+
end
|
165
|
+
|
166
|
+
it "includes error description" do
|
167
|
+
expect(response_json_body["error_description"]).to eq(
|
168
|
+
translated_error_message(:invalid_client),
|
169
|
+
)
|
170
|
+
end
|
171
|
+
|
172
|
+
it "does not issue any access token" do
|
173
|
+
expect(Doorkeeper::AccessToken.all).to be_empty
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
139
177
|
context "when other error happens" do
|
140
178
|
before do
|
141
179
|
default_scopes_exist :public
|
@@ -207,6 +245,39 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
207
245
|
end
|
208
246
|
end
|
209
247
|
|
248
|
+
context "when user cannot access application" do
|
249
|
+
before do
|
250
|
+
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
251
|
+
allow(Doorkeeper.configuration).to receive(:authorize_resource_owner_for_client).and_return(->(*_) { false })
|
252
|
+
|
253
|
+
post :create, params: {
|
254
|
+
client_id: client.uid,
|
255
|
+
response_type: "token",
|
256
|
+
redirect_uri: client.redirect_uri,
|
257
|
+
}
|
258
|
+
end
|
259
|
+
|
260
|
+
let(:response_json_body) { JSON.parse(response.body) }
|
261
|
+
|
262
|
+
it "renders 400 error" do
|
263
|
+
expect(response.status).to eq 401
|
264
|
+
end
|
265
|
+
|
266
|
+
it "includes error name" do
|
267
|
+
expect(response_json_body["error"]).to eq("invalid_client")
|
268
|
+
end
|
269
|
+
|
270
|
+
it "includes error description" do
|
271
|
+
expect(response_json_body["error_description"]).to eq(
|
272
|
+
translated_error_message(:invalid_client),
|
273
|
+
)
|
274
|
+
end
|
275
|
+
|
276
|
+
it "does not issue any access token" do
|
277
|
+
expect(Doorkeeper::AccessToken.all).to be_empty
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
210
281
|
context "when other error happens" do
|
211
282
|
before do
|
212
283
|
allow(Doorkeeper.config).to receive(:api_only).and_return(true)
|
@@ -287,12 +358,14 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
287
358
|
|
288
359
|
it "should call :before_successful_authorization callback" do
|
289
360
|
expect(Doorkeeper.config)
|
290
|
-
.to receive_message_chain(:before_successful_authorization, :call)
|
361
|
+
.to receive_message_chain(:before_successful_authorization, :call)
|
362
|
+
.with(instance_of(described_class), instance_of(Doorkeeper::OAuth::Hooks::Context))
|
291
363
|
end
|
292
364
|
|
293
365
|
it "should call :after_successful_authorization callback" do
|
294
366
|
expect(Doorkeeper.config)
|
295
|
-
.to receive_message_chain(:after_successful_authorization, :call)
|
367
|
+
.to receive_message_chain(:after_successful_authorization, :call)
|
368
|
+
.with(instance_of(described_class), instance_of(Doorkeeper::OAuth::Hooks::Context))
|
296
369
|
end
|
297
370
|
end
|
298
371
|
|
@@ -482,46 +555,106 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
482
555
|
end
|
483
556
|
|
484
557
|
describe "GET #new with errors" do
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
558
|
+
context "without valid params" do
|
559
|
+
before do
|
560
|
+
default_scopes_exist :public
|
561
|
+
get :new, params: { an_invalid: "request" }
|
562
|
+
end
|
489
563
|
|
490
|
-
|
491
|
-
|
564
|
+
it "does not redirect" do
|
565
|
+
expect(response).to_not be_redirect
|
566
|
+
end
|
567
|
+
|
568
|
+
it "does not issue any token" do
|
569
|
+
expect(Doorkeeper::AccessGrant.count).to eq 0
|
570
|
+
expect(Doorkeeper::AccessToken.count).to eq 0
|
571
|
+
end
|
492
572
|
end
|
493
573
|
|
494
|
-
|
495
|
-
|
496
|
-
|
574
|
+
context "when user cannot access application" do
|
575
|
+
before do
|
576
|
+
allow(Doorkeeper.configuration).to receive(:authorize_resource_owner_for_client).and_return(->(*_) { false })
|
577
|
+
|
578
|
+
get :new, params: {
|
579
|
+
client_id: client.uid,
|
580
|
+
response_type: "token",
|
581
|
+
redirect_uri: client.redirect_uri,
|
582
|
+
}
|
583
|
+
end
|
584
|
+
|
585
|
+
it "does not redirect" do
|
586
|
+
expect(response).to_not be_redirect
|
587
|
+
end
|
588
|
+
|
589
|
+
it "does not issue any token" do
|
590
|
+
expect(Doorkeeper::AccessGrant.count).to eq 0
|
591
|
+
expect(Doorkeeper::AccessToken.count).to eq 0
|
592
|
+
end
|
497
593
|
end
|
498
594
|
end
|
499
595
|
|
500
596
|
describe "GET #new in API mode with errors" do
|
501
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
502
|
-
|
503
597
|
before do
|
504
|
-
default_scopes_exist :public
|
505
598
|
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
506
|
-
|
599
|
+
default_scopes_exist :public
|
507
600
|
end
|
508
601
|
|
509
|
-
|
510
|
-
|
511
|
-
|
602
|
+
context "without valid params" do
|
603
|
+
before do
|
604
|
+
get :new, params: { an_invalid: "request" }
|
605
|
+
end
|
512
606
|
|
513
|
-
|
514
|
-
|
515
|
-
|
607
|
+
let(:response_json_body) { JSON.parse(response.body) }
|
608
|
+
|
609
|
+
it "should render bad request" do
|
610
|
+
expect(response).to have_http_status(:bad_request)
|
611
|
+
end
|
612
|
+
|
613
|
+
it "includes error in body" do
|
614
|
+
expect(response_json_body["error"]).to eq("invalid_request")
|
615
|
+
end
|
516
616
|
|
517
|
-
|
518
|
-
|
519
|
-
|
617
|
+
it "includes error description in body" do
|
618
|
+
expect(response_json_body["error_description"])
|
619
|
+
.to eq(translated_invalid_request_error_message(:missing_param, :client_id))
|
620
|
+
end
|
621
|
+
|
622
|
+
it "does not issue any token" do
|
623
|
+
expect(Doorkeeper::AccessGrant.count).to eq 0
|
624
|
+
expect(Doorkeeper::AccessToken.count).to eq 0
|
625
|
+
end
|
520
626
|
end
|
521
627
|
|
522
|
-
|
523
|
-
|
524
|
-
|
628
|
+
context "when user cannot access application" do
|
629
|
+
before do
|
630
|
+
allow(Doorkeeper.configuration).to receive(:authorize_resource_owner_for_client).and_return(->(*_) { false })
|
631
|
+
|
632
|
+
get :new, params: {
|
633
|
+
client_id: client.uid,
|
634
|
+
response_type: "token",
|
635
|
+
redirect_uri: client.redirect_uri,
|
636
|
+
}
|
637
|
+
end
|
638
|
+
|
639
|
+
let(:response_json_body) { JSON.parse(response.body) }
|
640
|
+
|
641
|
+
it "should render bad request" do
|
642
|
+
expect(response).to have_http_status(:bad_request)
|
643
|
+
end
|
644
|
+
|
645
|
+
it "includes error in body" do
|
646
|
+
expect(response_json_body["error"]).to eq("invalid_client")
|
647
|
+
end
|
648
|
+
|
649
|
+
it "includes error description in body" do
|
650
|
+
expect(response_json_body["error_description"])
|
651
|
+
.to eq(translated_error_message(:invalid_client))
|
652
|
+
end
|
653
|
+
|
654
|
+
it "does not issue any token" do
|
655
|
+
expect(Doorkeeper::AccessGrant.count).to eq 0
|
656
|
+
expect(Doorkeeper::AccessToken.count).to eq 0
|
657
|
+
end
|
525
658
|
end
|
526
659
|
end
|
527
660
|
|
@@ -538,12 +671,14 @@ describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
|
538
671
|
|
539
672
|
it "should call :before_successful_authorization callback" do
|
540
673
|
expect(Doorkeeper.configuration)
|
541
|
-
.to receive_message_chain(:before_successful_authorization, :call)
|
674
|
+
.to receive_message_chain(:before_successful_authorization, :call)
|
675
|
+
.with(instance_of(described_class), instance_of(Doorkeeper::OAuth::Hooks::Context))
|
542
676
|
end
|
543
677
|
|
544
678
|
it "should call :after_successful_authorization callback" do
|
545
679
|
expect(Doorkeeper.configuration)
|
546
|
-
.to receive_message_chain(:after_successful_authorization, :call)
|
680
|
+
.to receive_message_chain(:after_successful_authorization, :call)
|
681
|
+
.with(instance_of(described_class), instance_of(Doorkeeper::OAuth::Hooks::Context))
|
547
682
|
end
|
548
683
|
end
|
549
684
|
|