doorkeeper 5.3.3 → 5.5.0.rc2
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/CHANGELOG.md +125 -7
- data/README.md +6 -4
- data/app/controllers/doorkeeper/applications_controller.rb +4 -4
- data/app/controllers/doorkeeper/authorizations_controller.rb +46 -16
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +67 -22
- data/app/views/doorkeeper/applications/_form.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +35 -14
- data/app/views/doorkeeper/authorizations/form_post.html.erb +11 -0
- data/config/locales/en.yml +6 -2
- data/lib/doorkeeper.rb +111 -79
- data/lib/doorkeeper/config.rb +148 -94
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +26 -14
- data/lib/doorkeeper/config/validations.rb +53 -0
- data/lib/doorkeeper/engine.rb +1 -1
- data/lib/doorkeeper/grant_flow.rb +45 -0
- data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
- data/lib/doorkeeper/grant_flow/flow.rb +44 -0
- data/lib/doorkeeper/grant_flow/registry.rb +50 -0
- data/lib/doorkeeper/grape/helpers.rb +1 -1
- data/lib/doorkeeper/helpers/controller.rb +8 -4
- data/lib/doorkeeper/models/access_grant_mixin.rb +21 -18
- data/lib/doorkeeper/models/access_token_mixin.rb +110 -47
- data/lib/doorkeeper/models/application_mixin.rb +5 -4
- 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 +19 -6
- data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
- data/lib/doorkeeper/oauth/authorization/token.rb +18 -16
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
- data/lib/doorkeeper/oauth/authorization_code_request.rb +17 -14
- data/lib/doorkeeper/oauth/base_request.rb +12 -20
- 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 +27 -8
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +4 -2
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +4 -2
- data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
- data/lib/doorkeeper/oauth/code_request.rb +3 -3
- data/lib/doorkeeper/oauth/code_response.rb +22 -12
- data/lib/doorkeeper/oauth/error_response.rb +6 -7
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +2 -8
- 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 +24 -7
- data/lib/doorkeeper/oauth/pre_authorization.rb +63 -32
- data/lib/doorkeeper/oauth/refresh_token_request.rb +31 -22
- data/lib/doorkeeper/oauth/token.rb +5 -6
- data/lib/doorkeeper/oauth/token_introspection.rb +4 -8
- data/lib/doorkeeper/oauth/token_request.rb +3 -3
- data/lib/doorkeeper/oauth/token_response.rb +1 -1
- data/lib/doorkeeper/orm/active_record.rb +14 -7
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +8 -3
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +7 -3
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +6 -3
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +5 -0
- data/lib/doorkeeper/rails/routes.rb +14 -20
- 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.rb +49 -12
- data/lib/doorkeeper/request/refresh_token.rb +2 -1
- data/lib/doorkeeper/request/strategy.rb +2 -2
- data/lib/doorkeeper/server.rb +4 -4
- data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
- data/lib/doorkeeper/version.rb +3 -7
- 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 +3 -1
- 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 +48 -10
- data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
- metadata +30 -300
- data/Appraisals +0 -40
- data/CODE_OF_CONDUCT.md +0 -46
- data/CONTRIBUTING.md +0 -49
- data/Dangerfile +0 -67
- data/Dockerfile +0 -29
- data/Gemfile +0 -25
- data/NEWS.md +0 -1
- data/RELEASING.md +0 -11
- data/Rakefile +0 -28
- data/SECURITY.md +0 -15
- data/UPGRADE.md +0 -2
- data/bin/console +0 -16
- data/doorkeeper.gemspec +0 -42
- data/gemfiles/rails_5_0.gemfile +0 -18
- data/gemfiles/rails_5_1.gemfile +0 -18
- data/gemfiles/rails_5_2.gemfile +0 -18
- data/gemfiles/rails_6_0.gemfile +0 -18
- data/gemfiles/rails_master.gemfile +0 -18
- data/spec/controllers/application_metal_controller_spec.rb +0 -64
- data/spec/controllers/applications_controller_spec.rb +0 -274
- data/spec/controllers/authorizations_controller_spec.rb +0 -608
- data/spec/controllers/protected_resources_controller_spec.rb +0 -361
- data/spec/controllers/token_info_controller_spec.rb +0 -50
- data/spec/controllers/tokens_controller_spec.rb +0 -498
- data/spec/dummy/Rakefile +0 -9
- data/spec/dummy/app/assets/config/manifest.js +0 -2
- data/spec/dummy/app/controllers/application_controller.rb +0 -5
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
- data/spec/dummy/app/controllers/home_controller.rb +0 -18
- data/spec/dummy/app/controllers/metal_controller.rb +0 -13
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
- data/spec/dummy/app/helpers/application_helper.rb +0 -7
- data/spec/dummy/app/models/user.rb +0 -7
- data/spec/dummy/app/views/home/index.html.erb +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/config.ru +0 -6
- data/spec/dummy/config/application.rb +0 -49
- data/spec/dummy/config/boot.rb +0 -7
- data/spec/dummy/config/database.yml +0 -15
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -31
- data/spec/dummy/config/environments/production.rb +0 -64
- data/spec/dummy/config/environments/test.rb +0 -45
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
- data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
- data/spec/dummy/config/initializers/secret_token.rb +0 -10
- data/spec/dummy/config/initializers/session_store.rb +0 -10
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
- data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -13
- data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
- data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
- data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
- data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
- data/spec/dummy/db/schema.rb +0 -68
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -26
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +0 -9
- data/spec/factories.rb +0 -30
- data/spec/generators/application_owner_generator_spec.rb +0 -28
- data/spec/generators/confidential_applications_generator_spec.rb +0 -29
- data/spec/generators/install_generator_spec.rb +0 -36
- data/spec/generators/migration_generator_spec.rb +0 -28
- data/spec/generators/pkce_generator_spec.rb +0 -28
- data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
- data/spec/generators/templates/routes.rb +0 -4
- data/spec/generators/views_generator_spec.rb +0 -29
- data/spec/grape/grape_integration_spec.rb +0 -137
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
- data/spec/lib/config_spec.rb +0 -809
- data/spec/lib/doorkeeper_spec.rb +0 -27
- data/spec/lib/models/expirable_spec.rb +0 -61
- data/spec/lib/models/reusable_spec.rb +0 -40
- data/spec/lib/models/revocable_spec.rb +0 -59
- data/spec/lib/models/scopes_spec.rb +0 -53
- data/spec/lib/models/secret_storable_spec.rb +0 -135
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
- data/spec/lib/oauth/authorization_code_request_spec.rb +0 -170
- data/spec/lib/oauth/base_request_spec.rb +0 -224
- data/spec/lib/oauth/base_response_spec.rb +0 -45
- data/spec/lib/oauth/client/credentials_spec.rb +0 -90
- data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -134
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
- data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
- data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
- data/spec/lib/oauth/client_credentials_request_spec.rb +0 -107
- data/spec/lib/oauth/client_spec.rb +0 -38
- data/spec/lib/oauth/code_request_spec.rb +0 -46
- data/spec/lib/oauth/code_response_spec.rb +0 -32
- data/spec/lib/oauth/error_response_spec.rb +0 -64
- data/spec/lib/oauth/error_spec.rb +0 -21
- data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
- data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
- data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
- data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
- data/spec/lib/oauth/password_access_token_request_spec.rb +0 -190
- data/spec/lib/oauth/pre_authorization_spec.rb +0 -223
- data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
- data/spec/lib/oauth/scopes_spec.rb +0 -146
- data/spec/lib/oauth/token_request_spec.rb +0 -157
- data/spec/lib/oauth/token_response_spec.rb +0 -84
- data/spec/lib/oauth/token_spec.rb +0 -156
- data/spec/lib/request/strategy_spec.rb +0 -54
- data/spec/lib/secret_storing/base_spec.rb +0 -60
- data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
- data/spec/lib/secret_storing/plain_spec.rb +0 -44
- data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
- data/spec/lib/server_spec.rb +0 -49
- data/spec/lib/stale_records_cleaner_spec.rb +0 -89
- data/spec/models/doorkeeper/access_grant_spec.rb +0 -161
- data/spec/models/doorkeeper/access_token_spec.rb +0 -622
- data/spec/models/doorkeeper/application_spec.rb +0 -482
- data/spec/requests/applications/applications_request_spec.rb +0 -259
- data/spec/requests/applications/authorized_applications_spec.rb +0 -32
- data/spec/requests/endpoints/authorization_spec.rb +0 -91
- data/spec/requests/endpoints/token_spec.rb +0 -75
- data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
- data/spec/requests/flows/authorization_code_spec.rb +0 -525
- data/spec/requests/flows/client_credentials_spec.rb +0 -166
- data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
- data/spec/requests/flows/implicit_grant_spec.rb +0 -91
- data/spec/requests/flows/password_spec.rb +0 -316
- data/spec/requests/flows/refresh_token_spec.rb +0 -233
- data/spec/requests/flows/revoke_token_spec.rb +0 -157
- data/spec/requests/flows/skip_authorization_spec.rb +0 -66
- data/spec/requests/protected_resources/metal_spec.rb +0 -16
- data/spec/requests/protected_resources/private_api_spec.rb +0 -83
- data/spec/routing/custom_controller_routes_spec.rb +0 -133
- data/spec/routing/default_routes_spec.rb +0 -41
- data/spec/routing/scoped_routes_spec.rb +0 -47
- data/spec/spec_helper.rb +0 -54
- data/spec/spec_helper_integration.rb +0 -4
- data/spec/support/dependencies/factory_bot.rb +0 -4
- data/spec/support/doorkeeper_rspec.rb +0 -22
- data/spec/support/helpers/access_token_request_helper.rb +0 -13
- data/spec/support/helpers/authorization_request_helper.rb +0 -43
- data/spec/support/helpers/config_helper.rb +0 -11
- data/spec/support/helpers/model_helper.rb +0 -78
- data/spec/support/helpers/request_spec_helper.rb +0 -110
- data/spec/support/helpers/url_helper.rb +0 -62
- data/spec/support/orm/active_record.rb +0 -5
- data/spec/support/shared/controllers_shared_context.rb +0 -133
- data/spec/support/shared/hashing_shared_context.rb +0 -36
- data/spec/support/shared/models_shared_examples.rb +0 -54
- data/spec/validators/redirect_uri_validator_spec.rb +0 -183
- data/spec/version/version_spec.rb +0 -17
data/gemfiles/rails_6_0.gemfile
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "rails", "~> 6.0.0"
|
6
|
-
gem "rspec-core", git: "https://github.com/rspec/rspec-core.git"
|
7
|
-
gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
|
8
|
-
gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
|
9
|
-
gem "rspec-rails", "4.0.0.beta3"
|
10
|
-
gem "rspec-support", git: "https://github.com/rspec/rspec-support.git"
|
11
|
-
gem "rubocop", "~> 0.75"
|
12
|
-
gem "rubocop-performance"
|
13
|
-
gem "bcrypt", "~> 3.1", require: false
|
14
|
-
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
|
15
|
-
gem "sqlite3", "~> 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
|
16
|
-
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw]
|
17
|
-
|
18
|
-
gemspec path: "../"
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# This file was generated by Appraisal
|
2
|
-
|
3
|
-
source "https://rubygems.org"
|
4
|
-
|
5
|
-
gem "rails", git: "https://github.com/rails/rails"
|
6
|
-
gem "rspec-core", git: "https://github.com/rspec/rspec-core.git"
|
7
|
-
gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
|
8
|
-
gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
|
9
|
-
gem "rspec-rails", "4.0.0.beta3"
|
10
|
-
gem "rspec-support", git: "https://github.com/rspec/rspec-support.git"
|
11
|
-
gem "rubocop", "~> 0.75"
|
12
|
-
gem "rubocop-performance"
|
13
|
-
gem "bcrypt", "~> 3.1", require: false
|
14
|
-
gem "activerecord-jdbcsqlite3-adapter", platform: :jruby
|
15
|
-
gem "sqlite3", "~> 1.4", platform: [:ruby, :mswin, :mingw, :x64_mingw]
|
16
|
-
gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw]
|
17
|
-
|
18
|
-
gemspec path: "../"
|
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper_integration"
|
4
|
-
|
5
|
-
describe Doorkeeper::ApplicationMetalController do
|
6
|
-
controller(Doorkeeper::ApplicationMetalController) do
|
7
|
-
def index
|
8
|
-
render json: {}, status: 200
|
9
|
-
end
|
10
|
-
|
11
|
-
def create
|
12
|
-
render json: {}, status: 200
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
it "lazy run hooks" do
|
17
|
-
i = 0
|
18
|
-
ActiveSupport.on_load(:doorkeeper_metal_controller) { i += 1 }
|
19
|
-
|
20
|
-
expect(i).to eq 1
|
21
|
-
end
|
22
|
-
|
23
|
-
describe "enforce_content_type" do
|
24
|
-
before { allow(Doorkeeper.config).to receive(:enforce_content_type).and_return(flag) }
|
25
|
-
|
26
|
-
context "enabled" do
|
27
|
-
let(:flag) { true }
|
28
|
-
|
29
|
-
it "returns a 200 for the requests without body" do
|
30
|
-
get :index, params: {}
|
31
|
-
expect(response).to have_http_status 200
|
32
|
-
end
|
33
|
-
|
34
|
-
it "returns a 200 for the requests with body and correct media type" do
|
35
|
-
post :create, params: {}, as: :url_encoded_form
|
36
|
-
expect(response).to have_http_status 200
|
37
|
-
end
|
38
|
-
|
39
|
-
it "returns a 415 for the requests with body and incorrect media type" do
|
40
|
-
post :create, params: {}, as: :json
|
41
|
-
expect(response).to have_http_status 415
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "disabled" do
|
46
|
-
let(:flag) { false }
|
47
|
-
|
48
|
-
it "returns a 200 for the correct media type" do
|
49
|
-
get :index, as: :url_encoded_form
|
50
|
-
expect(response).to have_http_status 200
|
51
|
-
end
|
52
|
-
|
53
|
-
it "returns a 200 for an incorrect media type" do
|
54
|
-
get :index, as: :json
|
55
|
-
expect(response).to have_http_status 200
|
56
|
-
end
|
57
|
-
|
58
|
-
it "returns a 200 for the requests with body and incorrect media type" do
|
59
|
-
post :create, params: {}, as: :json
|
60
|
-
expect(response).to have_http_status 200
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,274 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
module Doorkeeper
|
6
|
-
describe ApplicationsController do
|
7
|
-
context "JSON API" do
|
8
|
-
render_views
|
9
|
-
|
10
|
-
before do
|
11
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
12
|
-
allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) { true })
|
13
|
-
end
|
14
|
-
|
15
|
-
it "creates an application" do
|
16
|
-
expect do
|
17
|
-
post :create, params: {
|
18
|
-
doorkeeper_application: {
|
19
|
-
name: "Example",
|
20
|
-
redirect_uri: "https://example.com",
|
21
|
-
}, format: :json,
|
22
|
-
}
|
23
|
-
end.to(change { Doorkeeper::Application.count })
|
24
|
-
|
25
|
-
expect(response).to be_successful
|
26
|
-
|
27
|
-
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
28
|
-
|
29
|
-
application = Application.last
|
30
|
-
secret_from_response = json_response["secret"]
|
31
|
-
expect(application.secret_matches?(secret_from_response)).to be_truthy
|
32
|
-
|
33
|
-
expect(json_response["name"]).to eq("Example")
|
34
|
-
expect(json_response["redirect_uri"]).to eq("https://example.com")
|
35
|
-
end
|
36
|
-
|
37
|
-
it "returns validation errors on wrong create params" do
|
38
|
-
expect do
|
39
|
-
post :create, params: {
|
40
|
-
doorkeeper_application: {
|
41
|
-
name: "Example",
|
42
|
-
}, format: :json,
|
43
|
-
}
|
44
|
-
end.not_to(change { Doorkeeper::Application.count })
|
45
|
-
|
46
|
-
expect(response).to have_http_status(422)
|
47
|
-
|
48
|
-
expect(json_response).to include("errors")
|
49
|
-
end
|
50
|
-
|
51
|
-
it "returns validations on wrong create params (unspecified scheme)" do
|
52
|
-
expect do
|
53
|
-
post :create, params: {
|
54
|
-
doorkeeper_application: {
|
55
|
-
name: "Example",
|
56
|
-
redirect_uri: "app.com:80",
|
57
|
-
}, format: :json,
|
58
|
-
}
|
59
|
-
end.not_to(change { Doorkeeper::Application.count })
|
60
|
-
|
61
|
-
expect(response).to have_http_status(422)
|
62
|
-
|
63
|
-
expect(json_response).to include("errors")
|
64
|
-
end
|
65
|
-
|
66
|
-
it "returns application info" do
|
67
|
-
application = FactoryBot.create(:application, name: "Change me")
|
68
|
-
|
69
|
-
get :show, params: { id: application.id, format: :json }
|
70
|
-
|
71
|
-
expect(response).to be_successful
|
72
|
-
|
73
|
-
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
74
|
-
end
|
75
|
-
|
76
|
-
it "updates application" do
|
77
|
-
application = FactoryBot.create(:application, name: "Change me")
|
78
|
-
|
79
|
-
put :update, params: {
|
80
|
-
id: application.id,
|
81
|
-
doorkeeper_application: {
|
82
|
-
name: "Example App",
|
83
|
-
redirect_uri: "https://example.com",
|
84
|
-
}, format: :json,
|
85
|
-
}
|
86
|
-
|
87
|
-
expect(application.reload.name).to eq "Example App"
|
88
|
-
|
89
|
-
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
90
|
-
end
|
91
|
-
|
92
|
-
it "returns validation errors on wrong update params" do
|
93
|
-
application = FactoryBot.create(:application, name: "Change me")
|
94
|
-
|
95
|
-
put :update, params: {
|
96
|
-
id: application.id,
|
97
|
-
doorkeeper_application: {
|
98
|
-
name: "Example App",
|
99
|
-
redirect_uri: "localhost:3000",
|
100
|
-
}, format: :json,
|
101
|
-
}
|
102
|
-
|
103
|
-
expect(response).to have_http_status(422)
|
104
|
-
|
105
|
-
expect(json_response).to include("errors")
|
106
|
-
end
|
107
|
-
|
108
|
-
it "destroys an application" do
|
109
|
-
application = FactoryBot.create(:application)
|
110
|
-
|
111
|
-
delete :destroy, params: { id: application.id, format: :json }
|
112
|
-
|
113
|
-
expect(response).to have_http_status(204)
|
114
|
-
expect(Application.count).to be_zero
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
context "when admin is not authenticated" do
|
119
|
-
before do
|
120
|
-
allow(Doorkeeper.config).to receive(:authenticate_admin).and_return(proc do
|
121
|
-
redirect_to main_app.root_url
|
122
|
-
end)
|
123
|
-
end
|
124
|
-
|
125
|
-
it "redirects as set in Doorkeeper.authenticate_admin" do
|
126
|
-
get :index
|
127
|
-
expect(response).to redirect_to(controller.main_app.root_url)
|
128
|
-
end
|
129
|
-
|
130
|
-
it "does not create application" do
|
131
|
-
expect do
|
132
|
-
post :create, params: {
|
133
|
-
doorkeeper_application: {
|
134
|
-
name: "Example",
|
135
|
-
redirect_uri: "https://example.com",
|
136
|
-
},
|
137
|
-
}
|
138
|
-
end.not_to(change { Doorkeeper::Application.count })
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
context "when admin is authenticated" do
|
143
|
-
context "when application secrets are hashed" do
|
144
|
-
before do
|
145
|
-
allow(Doorkeeper.configuration)
|
146
|
-
.to receive(:application_secret_strategy).and_return(Doorkeeper::SecretStoring::Sha256Hash)
|
147
|
-
end
|
148
|
-
|
149
|
-
it "shows the application secret after creating a new application" do
|
150
|
-
expect do
|
151
|
-
post :create, params: {
|
152
|
-
doorkeeper_application: {
|
153
|
-
name: "Example",
|
154
|
-
redirect_uri: "https://example.com",
|
155
|
-
},
|
156
|
-
}
|
157
|
-
end.to change { Doorkeeper::Application.count }.by(1)
|
158
|
-
|
159
|
-
application = Application.last
|
160
|
-
|
161
|
-
secret_from_flash = flash[:application_secret]
|
162
|
-
expect(secret_from_flash).not_to be_empty
|
163
|
-
expect(application.secret_matches?(secret_from_flash)).to be_truthy
|
164
|
-
expect(response).to redirect_to(controller.main_app.oauth_application_url(application.id))
|
165
|
-
|
166
|
-
get :show, params: { id: application.id, format: :html }
|
167
|
-
|
168
|
-
# We don't know the application secret here (because its hashed) so we can not assert its text on the page
|
169
|
-
# Instead, we read it from the page and then check if it matches the application secret
|
170
|
-
code_element = %r{<code.*id="secret".*>(.*)<\/code>}.match(response.body)
|
171
|
-
secret_from_page = code_element[1]
|
172
|
-
|
173
|
-
expect(response.body).to have_selector("code#application_id", text: application.uid)
|
174
|
-
expect(response.body).to have_selector("code#secret")
|
175
|
-
expect(secret_from_page).not_to be_empty
|
176
|
-
expect(application.secret_matches?(secret_from_page)).to be_truthy
|
177
|
-
end
|
178
|
-
|
179
|
-
it "does not show an application secret when application did already exist" do
|
180
|
-
application = FactoryBot.create(:application)
|
181
|
-
get :show, params: { id: application.id, format: :html }
|
182
|
-
|
183
|
-
expect(response.body).to have_selector("code#application_id", text: application.uid)
|
184
|
-
expect(response.body).to have_selector("code#secret", text: "")
|
185
|
-
end
|
186
|
-
|
187
|
-
it "returns the application details in a json response" do
|
188
|
-
expect do
|
189
|
-
post :create, params: {
|
190
|
-
doorkeeper_application: {
|
191
|
-
name: "Example",
|
192
|
-
redirect_uri: "https://example.com",
|
193
|
-
}, format: :json,
|
194
|
-
}
|
195
|
-
end.to(change { Doorkeeper::Application.count })
|
196
|
-
|
197
|
-
expect(response).to be_successful
|
198
|
-
|
199
|
-
expect(json_response).to include("id", "name", "uid", "secret", "redirect_uri", "scopes")
|
200
|
-
|
201
|
-
application = Application.last
|
202
|
-
secret_from_response = json_response["secret"]
|
203
|
-
expect(application.secret_matches?(secret_from_response)).to be_truthy
|
204
|
-
|
205
|
-
expect(json_response["name"]).to eq("Example")
|
206
|
-
expect(json_response["redirect_uri"]).to eq("https://example.com")
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
render_views
|
211
|
-
|
212
|
-
before do
|
213
|
-
allow(Doorkeeper.configuration).to receive(:authenticate_admin).and_return(->(*) { true })
|
214
|
-
end
|
215
|
-
|
216
|
-
it "sorts applications by created_at" do
|
217
|
-
first_application = FactoryBot.create(:application)
|
218
|
-
second_application = FactoryBot.create(:application)
|
219
|
-
expect(Doorkeeper::Application).to receive(:ordered_by).and_call_original
|
220
|
-
|
221
|
-
get :index
|
222
|
-
|
223
|
-
expect(response.body).to have_selector("tbody tr:first-child#application_#{first_application.id}")
|
224
|
-
expect(response.body).to have_selector("tbody tr:last-child#application_#{second_application.id}")
|
225
|
-
end
|
226
|
-
|
227
|
-
it "creates application" do
|
228
|
-
expect do
|
229
|
-
post :create, params: {
|
230
|
-
doorkeeper_application: {
|
231
|
-
name: "Example",
|
232
|
-
redirect_uri: "https://example.com",
|
233
|
-
},
|
234
|
-
}
|
235
|
-
end.to change { Doorkeeper::Application.count }.by(1)
|
236
|
-
|
237
|
-
expect(response).to be_redirect
|
238
|
-
end
|
239
|
-
|
240
|
-
it "shows application details" do
|
241
|
-
application = FactoryBot.create(:application)
|
242
|
-
get :show, params: { id: application.id, format: :html }
|
243
|
-
|
244
|
-
expect(response.body).to have_selector("code#application_id", text: application.uid)
|
245
|
-
expect(response.body).to have_selector("code#secret", text: application.plaintext_secret)
|
246
|
-
end
|
247
|
-
|
248
|
-
it "does not allow mass assignment of uid or secret" do
|
249
|
-
application = FactoryBot.create(:application)
|
250
|
-
put :update, params: {
|
251
|
-
id: application.id,
|
252
|
-
doorkeeper_application: {
|
253
|
-
uid: "1A2B3C4D",
|
254
|
-
secret: "1A2B3C4D",
|
255
|
-
},
|
256
|
-
}
|
257
|
-
|
258
|
-
expect(application.reload.uid).not_to eq "1A2B3C4D"
|
259
|
-
end
|
260
|
-
|
261
|
-
it "updates application" do
|
262
|
-
application = FactoryBot.create(:application)
|
263
|
-
put :update, params: {
|
264
|
-
id: application.id, doorkeeper_application: {
|
265
|
-
name: "Example",
|
266
|
-
redirect_uri: "https://example.com",
|
267
|
-
},
|
268
|
-
}
|
269
|
-
|
270
|
-
expect(application.reload.name).to eq "Example"
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
@@ -1,608 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
describe Doorkeeper::AuthorizationsController, "implicit grant flow" do
|
6
|
-
include AuthorizationRequestHelper
|
7
|
-
|
8
|
-
class ActionDispatch::TestResponse
|
9
|
-
def query_params
|
10
|
-
@query_params ||= begin
|
11
|
-
fragment = URI.parse(location).fragment
|
12
|
-
Rack::Utils.parse_query(fragment)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
let(:client) { FactoryBot.create :application }
|
18
|
-
let(:user) { User.create!(name: "Joe", password: "sekret") }
|
19
|
-
let(:access_token) { FactoryBot.build :access_token, resource_owner_id: user.id, application_id: client.id, scopes: "default" }
|
20
|
-
|
21
|
-
before do
|
22
|
-
Doorkeeper.configure do
|
23
|
-
default_scopes :default
|
24
|
-
|
25
|
-
custom_access_token_expires_in(lambda do |context|
|
26
|
-
context.grant_type == Doorkeeper::OAuth::IMPLICIT ? 1234 : nil
|
27
|
-
end)
|
28
|
-
end
|
29
|
-
|
30
|
-
allow(Doorkeeper.config).to receive(:grant_flows).and_return(["implicit"])
|
31
|
-
allow(Doorkeeper.config).to receive(:authenticate_resource_owner).and_return(->(_) { authenticator_method })
|
32
|
-
allow(controller).to receive(:authenticator_method).and_return(user)
|
33
|
-
expect(controller).to receive(:authenticator_method).at_most(:once)
|
34
|
-
end
|
35
|
-
|
36
|
-
describe "POST #create" do
|
37
|
-
before do
|
38
|
-
post :create, params: { client_id: client.uid, response_type: "token", redirect_uri: client.redirect_uri }
|
39
|
-
end
|
40
|
-
|
41
|
-
it "redirects after authorization" do
|
42
|
-
expect(response).to be_redirect
|
43
|
-
end
|
44
|
-
|
45
|
-
it "redirects to client redirect uri" do
|
46
|
-
expect(response.location).to match(/^#{client.redirect_uri}/)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "includes access token in fragment" do
|
50
|
-
expect(response.query_params["access_token"]).to eq(Doorkeeper::AccessToken.first.token)
|
51
|
-
end
|
52
|
-
|
53
|
-
it "includes token type in fragment" do
|
54
|
-
expect(response.query_params["token_type"]).to eq("Bearer")
|
55
|
-
end
|
56
|
-
|
57
|
-
it "includes token expiration in fragment" do
|
58
|
-
expect(response.query_params["expires_in"].to_i).to eq(1234)
|
59
|
-
end
|
60
|
-
|
61
|
-
it "issues the token for the current client" do
|
62
|
-
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "issues the token for the current resource owner" do
|
66
|
-
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe "POST #create in API mode" do
|
71
|
-
before do
|
72
|
-
allow(Doorkeeper.config).to receive(:api_only).and_return(true)
|
73
|
-
post :create, params: { client_id: client.uid, response_type: "token", redirect_uri: client.redirect_uri }
|
74
|
-
end
|
75
|
-
|
76
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
77
|
-
let(:redirect_uri) { response_json_body["redirect_uri"] }
|
78
|
-
|
79
|
-
it "renders success after authorization" do
|
80
|
-
expect(response).to be_successful
|
81
|
-
end
|
82
|
-
|
83
|
-
it "renders correct redirect uri" do
|
84
|
-
expect(redirect_uri).to match(/^#{client.redirect_uri}/)
|
85
|
-
end
|
86
|
-
|
87
|
-
it "includes access token in fragment" do
|
88
|
-
expect(redirect_uri.match(/access_token=([a-zA-Z0-9\-_]+)&?/)[1]).to eq(Doorkeeper::AccessToken.first.token)
|
89
|
-
end
|
90
|
-
|
91
|
-
it "includes token type in fragment" do
|
92
|
-
expect(redirect_uri.match(/token_type=(\w+)&?/)[1]).to eq "Bearer"
|
93
|
-
end
|
94
|
-
|
95
|
-
it "includes token expiration in fragment" do
|
96
|
-
expect(redirect_uri.match(/expires_in=(\d+)&?/)[1].to_i).to eq 1234
|
97
|
-
end
|
98
|
-
|
99
|
-
it "issues the token for the current client" do
|
100
|
-
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
101
|
-
end
|
102
|
-
|
103
|
-
it "issues the token for the current resource owner" do
|
104
|
-
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
describe "POST #create with errors" do
|
109
|
-
context "when missing client_id" do
|
110
|
-
before do
|
111
|
-
post :create, params: {
|
112
|
-
client_id: "",
|
113
|
-
response_type: "token",
|
114
|
-
redirect_uri: client.redirect_uri,
|
115
|
-
}
|
116
|
-
end
|
117
|
-
|
118
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
119
|
-
|
120
|
-
it "renders 400 error" do
|
121
|
-
expect(response.status).to eq 400
|
122
|
-
end
|
123
|
-
|
124
|
-
it "includes error name" do
|
125
|
-
expect(response_json_body["error"]).to eq("invalid_request")
|
126
|
-
end
|
127
|
-
|
128
|
-
it "includes error description" do
|
129
|
-
expect(response_json_body["error_description"]).to eq(
|
130
|
-
translated_invalid_request_error_message(:missing_param, :client_id),
|
131
|
-
)
|
132
|
-
end
|
133
|
-
|
134
|
-
it "does not issue any access token" do
|
135
|
-
expect(Doorkeeper::AccessToken.all).to be_empty
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
context "when other error happens" do
|
140
|
-
before do
|
141
|
-
default_scopes_exist :public
|
142
|
-
|
143
|
-
post :create, params: {
|
144
|
-
client_id: client.uid,
|
145
|
-
response_type: "token",
|
146
|
-
scope: "invalid",
|
147
|
-
redirect_uri: client.redirect_uri,
|
148
|
-
}
|
149
|
-
end
|
150
|
-
|
151
|
-
it "redirects after authorization" do
|
152
|
-
expect(response).to be_redirect
|
153
|
-
end
|
154
|
-
|
155
|
-
it "redirects to client redirect uri" do
|
156
|
-
expect(response.location).to match(/^#{client.redirect_uri}/)
|
157
|
-
end
|
158
|
-
|
159
|
-
it "does not include access token in fragment" do
|
160
|
-
expect(response.query_params["access_token"]).to be_nil
|
161
|
-
end
|
162
|
-
|
163
|
-
it "includes error in fragment" do
|
164
|
-
expect(response.query_params["error"]).to eq("invalid_scope")
|
165
|
-
end
|
166
|
-
|
167
|
-
it "includes error description in fragment" do
|
168
|
-
expect(response.query_params["error_description"]).to eq(translated_error_message(:invalid_scope))
|
169
|
-
end
|
170
|
-
|
171
|
-
it "does not issue any access token" do
|
172
|
-
expect(Doorkeeper::AccessToken.all).to be_empty
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe "POST #create in API mode with errors" do
|
178
|
-
context "when missing client_id" do
|
179
|
-
before do
|
180
|
-
allow(Doorkeeper.config).to receive(:api_only).and_return(true)
|
181
|
-
|
182
|
-
post :create, params: {
|
183
|
-
client_id: "",
|
184
|
-
response_type: "token",
|
185
|
-
redirect_uri: client.redirect_uri,
|
186
|
-
}
|
187
|
-
end
|
188
|
-
|
189
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
190
|
-
|
191
|
-
it "renders 400 error" do
|
192
|
-
expect(response.status).to eq 400
|
193
|
-
end
|
194
|
-
|
195
|
-
it "includes error name" do
|
196
|
-
expect(response_json_body["error"]).to eq("invalid_request")
|
197
|
-
end
|
198
|
-
|
199
|
-
it "includes error description" do
|
200
|
-
expect(response_json_body["error_description"]).to eq(
|
201
|
-
translated_invalid_request_error_message(:missing_param, :client_id),
|
202
|
-
)
|
203
|
-
end
|
204
|
-
|
205
|
-
it "does not issue any access token" do
|
206
|
-
expect(Doorkeeper::AccessToken.all).to be_empty
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
context "when other error happens" do
|
211
|
-
before do
|
212
|
-
allow(Doorkeeper.config).to receive(:api_only).and_return(true)
|
213
|
-
default_scopes_exist :public
|
214
|
-
|
215
|
-
post :create, params: {
|
216
|
-
client_id: client.uid,
|
217
|
-
response_type: "token",
|
218
|
-
scope: "invalid",
|
219
|
-
redirect_uri: client.redirect_uri,
|
220
|
-
}
|
221
|
-
end
|
222
|
-
|
223
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
224
|
-
let(:redirect_uri) { response_json_body["redirect_uri"] }
|
225
|
-
|
226
|
-
it "renders 400 error" do
|
227
|
-
expect(response.status).to eq 400
|
228
|
-
end
|
229
|
-
|
230
|
-
it "includes correct redirect URI" do
|
231
|
-
expect(redirect_uri).to match(/^#{client.redirect_uri}/)
|
232
|
-
end
|
233
|
-
|
234
|
-
it "does not include access token in fragment" do
|
235
|
-
expect(redirect_uri.match(/access_token=([a-f0-9]+)&?/)).to be_nil
|
236
|
-
end
|
237
|
-
|
238
|
-
it "includes error in redirect uri" do
|
239
|
-
expect(redirect_uri.match(/error=([a-z_]+)&?/)[1]).to eq "invalid_scope"
|
240
|
-
end
|
241
|
-
|
242
|
-
it "includes error description in redirect uri" do
|
243
|
-
expect(redirect_uri.match(/error_description=(.+)&?/)[1]).to_not be_nil
|
244
|
-
end
|
245
|
-
|
246
|
-
it "does not issue any access token" do
|
247
|
-
expect(Doorkeeper::AccessToken.all).to be_empty
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
describe "POST #create with application already authorized" do
|
253
|
-
before do
|
254
|
-
allow(Doorkeeper.config).to receive(:reuse_access_token).and_return(true)
|
255
|
-
|
256
|
-
access_token.save!
|
257
|
-
|
258
|
-
post :create, params: {
|
259
|
-
client_id: client.uid,
|
260
|
-
response_type: "token",
|
261
|
-
redirect_uri: client.redirect_uri,
|
262
|
-
}
|
263
|
-
end
|
264
|
-
|
265
|
-
it "returns the existing access token in a fragment" do
|
266
|
-
expect(response.query_params["access_token"]).to eq(access_token.token)
|
267
|
-
end
|
268
|
-
|
269
|
-
it "does not creates a new access token" do
|
270
|
-
expect(Doorkeeper::AccessToken.count).to eq(1)
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
describe "POST #create with callbacks" do
|
275
|
-
after do
|
276
|
-
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
277
|
-
end
|
278
|
-
|
279
|
-
describe "when successful" do
|
280
|
-
after do
|
281
|
-
post :create, params: {
|
282
|
-
client_id: client.uid,
|
283
|
-
response_type: "token",
|
284
|
-
redirect_uri: client.redirect_uri,
|
285
|
-
}
|
286
|
-
end
|
287
|
-
|
288
|
-
it "should call :before_successful_authorization callback" do
|
289
|
-
expect(Doorkeeper.config)
|
290
|
-
.to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
|
291
|
-
end
|
292
|
-
|
293
|
-
it "should call :after_successful_authorization callback" do
|
294
|
-
expect(Doorkeeper.config)
|
295
|
-
.to receive_message_chain(:after_successful_authorization, :call).with(instance_of(described_class))
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
describe "with errors" do
|
300
|
-
after do
|
301
|
-
post :create, params: { client_id: client.uid, response_type: "token", redirect_uri: "bad_uri" }
|
302
|
-
end
|
303
|
-
|
304
|
-
it "should not call :before_successful_authorization callback" do
|
305
|
-
expect(Doorkeeper.config).not_to receive(:before_successful_authorization)
|
306
|
-
end
|
307
|
-
|
308
|
-
it "should not call :after_successful_authorization callback" do
|
309
|
-
expect(Doorkeeper.config).not_to receive(:after_successful_authorization)
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
|
314
|
-
describe "GET #new token request with native url and skip_authorization true" do
|
315
|
-
before do
|
316
|
-
allow(Doorkeeper.config).to receive(:skip_authorization).and_return(proc do
|
317
|
-
true
|
318
|
-
end)
|
319
|
-
|
320
|
-
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
321
|
-
|
322
|
-
get :new, params: {
|
323
|
-
client_id: client.uid,
|
324
|
-
response_type: "token",
|
325
|
-
redirect_uri: client.redirect_uri,
|
326
|
-
}
|
327
|
-
end
|
328
|
-
|
329
|
-
it "should redirect immediately" do
|
330
|
-
expect(response).to be_redirect
|
331
|
-
expect(response.location).to match(%r{/oauth/token/info\?access_token=})
|
332
|
-
end
|
333
|
-
|
334
|
-
it "should not issue a grant" do
|
335
|
-
expect(Doorkeeper::AccessGrant.count).to be 0
|
336
|
-
end
|
337
|
-
|
338
|
-
it "should issue a token" do
|
339
|
-
expect(Doorkeeper::AccessToken.count).to be 1
|
340
|
-
end
|
341
|
-
end
|
342
|
-
|
343
|
-
describe "GET #new code request with native url and skip_authorization true" do
|
344
|
-
before do
|
345
|
-
allow(Doorkeeper.config).to receive(:grant_flows).and_return(%w[authorization_code])
|
346
|
-
allow(Doorkeeper.config).to receive(:skip_authorization).and_return(proc do
|
347
|
-
true
|
348
|
-
end)
|
349
|
-
|
350
|
-
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
351
|
-
|
352
|
-
get :new, params: {
|
353
|
-
client_id: client.uid,
|
354
|
-
response_type: "code",
|
355
|
-
redirect_uri: client.redirect_uri,
|
356
|
-
}
|
357
|
-
end
|
358
|
-
|
359
|
-
it "should redirect immediately" do
|
360
|
-
expect(response).to be_redirect
|
361
|
-
expect(response.location)
|
362
|
-
.to match(%r{/oauth/authorize/native\?code=#{Doorkeeper::AccessGrant.first.token}})
|
363
|
-
end
|
364
|
-
|
365
|
-
it "should issue a grant" do
|
366
|
-
expect(Doorkeeper::AccessGrant.count).to be 1
|
367
|
-
end
|
368
|
-
|
369
|
-
it "should not issue a token" do
|
370
|
-
expect(Doorkeeper::AccessToken.count).to be 0
|
371
|
-
end
|
372
|
-
end
|
373
|
-
|
374
|
-
describe "GET #new with skip_authorization true" do
|
375
|
-
before do
|
376
|
-
allow(Doorkeeper.config).to receive(:skip_authorization).and_return(proc do
|
377
|
-
true
|
378
|
-
end)
|
379
|
-
|
380
|
-
get :new, params: {
|
381
|
-
client_id: client.uid,
|
382
|
-
response_type: "token",
|
383
|
-
redirect_uri: client.redirect_uri,
|
384
|
-
}
|
385
|
-
end
|
386
|
-
|
387
|
-
it "should redirect immediately" do
|
388
|
-
expect(response).to be_redirect
|
389
|
-
expect(response.location).to match(/^#{client.redirect_uri}/)
|
390
|
-
end
|
391
|
-
|
392
|
-
it "should issue a token" do
|
393
|
-
expect(Doorkeeper::AccessToken.count).to be 1
|
394
|
-
end
|
395
|
-
|
396
|
-
it "includes token type in fragment" do
|
397
|
-
expect(response.query_params["token_type"]).to eq("Bearer")
|
398
|
-
end
|
399
|
-
|
400
|
-
it "includes token expiration in fragment" do
|
401
|
-
expect(response.query_params["expires_in"].to_i).to eq(1234)
|
402
|
-
end
|
403
|
-
|
404
|
-
it "issues the token for the current client" do
|
405
|
-
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
406
|
-
end
|
407
|
-
|
408
|
-
it "issues the token for the current resource owner" do
|
409
|
-
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
describe "GET #new in API mode" do
|
414
|
-
before do
|
415
|
-
allow(Doorkeeper.config).to receive(:api_only).and_return(true)
|
416
|
-
|
417
|
-
get :new, params: {
|
418
|
-
client_id: client.uid,
|
419
|
-
response_type: "token",
|
420
|
-
redirect_uri: client.redirect_uri,
|
421
|
-
}
|
422
|
-
end
|
423
|
-
|
424
|
-
it "should render success" do
|
425
|
-
expect(response).to be_successful
|
426
|
-
end
|
427
|
-
|
428
|
-
it "sets status to pre-authorization" do
|
429
|
-
expect(json_response["status"]).to eq(I18n.t("doorkeeper.pre_authorization.status"))
|
430
|
-
end
|
431
|
-
|
432
|
-
it "sets correct values" do
|
433
|
-
expect(json_response["client_id"]).to eq(client.uid)
|
434
|
-
expect(json_response["redirect_uri"]).to eq(client.redirect_uri)
|
435
|
-
expect(json_response["state"]).to be_nil
|
436
|
-
expect(json_response["response_type"]).to eq("token")
|
437
|
-
expect(json_response["scope"]).to eq("default")
|
438
|
-
end
|
439
|
-
end
|
440
|
-
|
441
|
-
describe "GET #new in API mode with skip_authorization true" do
|
442
|
-
before do
|
443
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { true })
|
444
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
445
|
-
|
446
|
-
get :new, params: {
|
447
|
-
client_id: client.uid,
|
448
|
-
response_type: "token",
|
449
|
-
redirect_uri: client.redirect_uri,
|
450
|
-
}
|
451
|
-
end
|
452
|
-
|
453
|
-
it "should render success" do
|
454
|
-
expect(response).to be_successful
|
455
|
-
end
|
456
|
-
|
457
|
-
it "should issue a token" do
|
458
|
-
expect(Doorkeeper::AccessToken.count).to be 1
|
459
|
-
end
|
460
|
-
|
461
|
-
it "sets status to redirect" do
|
462
|
-
expect(JSON.parse(response.body)["status"]).to eq("redirect")
|
463
|
-
end
|
464
|
-
|
465
|
-
it "sets redirect_uri to correct value" do
|
466
|
-
redirect_uri = JSON.parse(response.body)["redirect_uri"]
|
467
|
-
expect(redirect_uri).to_not be_nil
|
468
|
-
expect(redirect_uri.match(/token_type=(\w+)&?/)[1]).to eq "Bearer"
|
469
|
-
expect(redirect_uri.match(/expires_in=(\d+)&?/)[1].to_i).to eq 1234
|
470
|
-
expect(
|
471
|
-
redirect_uri.match(/access_token=([a-zA-Z0-9\-_]+)&?/)[1],
|
472
|
-
).to eq Doorkeeper::AccessToken.first.token
|
473
|
-
end
|
474
|
-
|
475
|
-
it "issues the token for the current client" do
|
476
|
-
expect(Doorkeeper::AccessToken.first.application_id).to eq(client.id)
|
477
|
-
end
|
478
|
-
|
479
|
-
it "issues the token for the current resource owner" do
|
480
|
-
expect(Doorkeeper::AccessToken.first.resource_owner_id).to eq(user.id)
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
describe "GET #new with errors" do
|
485
|
-
before do
|
486
|
-
default_scopes_exist :public
|
487
|
-
get :new, params: { an_invalid: "request" }
|
488
|
-
end
|
489
|
-
|
490
|
-
it "does not redirect" do
|
491
|
-
expect(response).to_not be_redirect
|
492
|
-
end
|
493
|
-
|
494
|
-
it "does not issue any token" do
|
495
|
-
expect(Doorkeeper::AccessGrant.count).to eq 0
|
496
|
-
expect(Doorkeeper::AccessToken.count).to eq 0
|
497
|
-
end
|
498
|
-
end
|
499
|
-
|
500
|
-
describe "GET #new in API mode with errors" do
|
501
|
-
let(:response_json_body) { JSON.parse(response.body) }
|
502
|
-
|
503
|
-
before do
|
504
|
-
default_scopes_exist :public
|
505
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
506
|
-
get :new, params: { an_invalid: "request" }
|
507
|
-
end
|
508
|
-
|
509
|
-
it "should render bad request" do
|
510
|
-
expect(response).to have_http_status(:bad_request)
|
511
|
-
end
|
512
|
-
|
513
|
-
it "includes error in body" do
|
514
|
-
expect(response_json_body["error"]).to eq("invalid_request")
|
515
|
-
end
|
516
|
-
|
517
|
-
it "includes error description in body" do
|
518
|
-
expect(response_json_body["error_description"])
|
519
|
-
.to eq(translated_invalid_request_error_message(:missing_param, :client_id))
|
520
|
-
end
|
521
|
-
|
522
|
-
it "does not issue any token" do
|
523
|
-
expect(Doorkeeper::AccessGrant.count).to eq 0
|
524
|
-
expect(Doorkeeper::AccessToken.count).to eq 0
|
525
|
-
end
|
526
|
-
end
|
527
|
-
|
528
|
-
describe "GET #new with callbacks" do
|
529
|
-
after do
|
530
|
-
client.update_attribute :redirect_uri, "urn:ietf:wg:oauth:2.0:oob"
|
531
|
-
get :new, params: { client_id: client.uid, response_type: "token", redirect_uri: client.redirect_uri }
|
532
|
-
end
|
533
|
-
|
534
|
-
describe "when authorizing" do
|
535
|
-
before do
|
536
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { true })
|
537
|
-
end
|
538
|
-
|
539
|
-
it "should call :before_successful_authorization callback" do
|
540
|
-
expect(Doorkeeper.configuration)
|
541
|
-
.to receive_message_chain(:before_successful_authorization, :call).with(instance_of(described_class))
|
542
|
-
end
|
543
|
-
|
544
|
-
it "should call :after_successful_authorization callback" do
|
545
|
-
expect(Doorkeeper.configuration)
|
546
|
-
.to receive_message_chain(:after_successful_authorization, :call).with(instance_of(described_class))
|
547
|
-
end
|
548
|
-
end
|
549
|
-
|
550
|
-
describe "when not authorizing" do
|
551
|
-
before do
|
552
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { false })
|
553
|
-
end
|
554
|
-
|
555
|
-
it "should not call :before_successful_authorization callback" do
|
556
|
-
expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
|
557
|
-
end
|
558
|
-
|
559
|
-
it "should not call :after_successful_authorization callback" do
|
560
|
-
expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
|
561
|
-
end
|
562
|
-
end
|
563
|
-
|
564
|
-
describe "when not authorizing in api mode" do
|
565
|
-
before do
|
566
|
-
allow(Doorkeeper.configuration).to receive(:skip_authorization).and_return(proc { false })
|
567
|
-
allow(Doorkeeper.configuration).to receive(:api_only).and_return(true)
|
568
|
-
end
|
569
|
-
|
570
|
-
it "should not call :before_successful_authorization callback" do
|
571
|
-
expect(Doorkeeper.configuration).not_to receive(:before_successful_authorization)
|
572
|
-
end
|
573
|
-
|
574
|
-
it "should not call :after_successful_authorization callback" do
|
575
|
-
expect(Doorkeeper.configuration).not_to receive(:after_successful_authorization)
|
576
|
-
end
|
577
|
-
end
|
578
|
-
end
|
579
|
-
|
580
|
-
describe "authorize response memoization" do
|
581
|
-
it "memoizes the result of the authorization" do
|
582
|
-
pre_auth = double(:pre_auth, authorizable?: true)
|
583
|
-
allow(controller).to receive(:pre_auth) { pre_auth }
|
584
|
-
strategy = double(:strategy, authorize: true)
|
585
|
-
expect(strategy).to receive(:authorize).once
|
586
|
-
allow(controller).to receive(:strategy) { strategy }
|
587
|
-
allow(controller).to receive(:create) do
|
588
|
-
2.times { controller.send :authorize_response }
|
589
|
-
controller.render json: {}, status: :ok
|
590
|
-
end
|
591
|
-
|
592
|
-
post :create
|
593
|
-
end
|
594
|
-
end
|
595
|
-
|
596
|
-
describe "strong parameters" do
|
597
|
-
it "ignores non-scalar scope parameter" do
|
598
|
-
get :new, params: {
|
599
|
-
client_id: client.uid,
|
600
|
-
response_type: "token",
|
601
|
-
redirect_uri: client.redirect_uri,
|
602
|
-
scope: { "0" => "profile" },
|
603
|
-
}
|
604
|
-
|
605
|
-
expect(response).to be_successful
|
606
|
-
end
|
607
|
-
end
|
608
|
-
end
|