doorkeeper 5.2.0 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Appraisals +2 -2
- data/CHANGELOG.md +40 -2
- data/Gemfile +2 -2
- data/app/controllers/doorkeeper/application_controller.rb +2 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
- data/app/controllers/doorkeeper/applications_controller.rb +0 -1
- data/app/controllers/doorkeeper/authorizations_controller.rb +2 -2
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
- data/config/locales/en.yml +1 -1
- data/gemfiles/rails_5_0.gemfile +2 -2
- data/gemfiles/rails_5_1.gemfile +2 -2
- data/gemfiles/rails_5_2.gemfile +2 -2
- data/gemfiles/rails_6_0.gemfile +2 -2
- data/gemfiles/rails_master.gemfile +2 -2
- data/lib/doorkeeper/config.rb +71 -38
- data/lib/doorkeeper/grape/helpers.rb +1 -1
- data/lib/doorkeeper/helpers/controller.rb +12 -8
- data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
- data/lib/doorkeeper/models/access_token_mixin.rb +56 -18
- data/lib/doorkeeper/models/application_mixin.rb +3 -3
- data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
- data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
- data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
- data/lib/doorkeeper/oauth/authorization/code.rb +4 -4
- data/lib/doorkeeper/oauth/authorization/token.rb +9 -6
- data/lib/doorkeeper/oauth/authorization_code_request.rb +13 -6
- data/lib/doorkeeper/oauth/base_request.rb +8 -4
- data/lib/doorkeeper/oauth/client.rb +7 -8
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +16 -9
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
- data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +4 -4
- data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
- data/lib/doorkeeper/oauth/code_response.rb +2 -2
- data/lib/doorkeeper/oauth/error.rb +1 -1
- data/lib/doorkeeper/oauth/error_response.rb +5 -5
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -1
- data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
- data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
- data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -3
- data/lib/doorkeeper/oauth/pre_authorization.rb +12 -7
- data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -5
- data/lib/doorkeeper/oauth/token.rb +2 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +6 -6
- data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
- data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
- data/lib/doorkeeper/orm/active_record/application.rb +5 -89
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +3 -3
- data/lib/doorkeeper/orm/active_record.rb +3 -4
- data/lib/doorkeeper/rails/helpers.rb +4 -4
- data/lib/doorkeeper/rails/routes.rb +5 -7
- data/lib/doorkeeper/rake/db.rake +3 -3
- data/lib/doorkeeper/request/authorization_code.rb +3 -3
- data/lib/doorkeeper/request/client_credentials.rb +2 -2
- data/lib/doorkeeper/request/password.rb +2 -2
- data/lib/doorkeeper/request/refresh_token.rb +3 -3
- data/lib/doorkeeper/request.rb +1 -1
- data/lib/doorkeeper/server.rb +1 -1
- data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +2 -3
- data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
- data/lib/generators/doorkeeper/migration_generator.rb +1 -1
- data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
- data/lib/generators/doorkeeper/templates/initializer.rb +39 -0
- data/spec/controllers/application_metal_controller_spec.rb +1 -1
- data/spec/controllers/applications_controller_spec.rb +3 -2
- data/spec/controllers/authorizations_controller_spec.rb +20 -18
- data/spec/controllers/protected_resources_controller_spec.rb +25 -17
- data/spec/controllers/token_info_controller_spec.rb +1 -1
- data/spec/controllers/tokens_controller_spec.rb +1 -1
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
- data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
- data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
- data/spec/generators/install_generator_spec.rb +1 -1
- data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
- data/spec/lib/config_spec.rb +62 -7
- data/spec/lib/doorkeeper_spec.rb +1 -1
- data/spec/lib/models/revocable_spec.rb +3 -3
- data/spec/lib/oauth/authorization_code_request_spec.rb +127 -123
- data/spec/lib/oauth/base_request_spec.rb +160 -158
- data/spec/lib/oauth/base_response_spec.rb +27 -29
- data/spec/lib/oauth/client/credentials_spec.rb +1 -1
- data/spec/lib/oauth/client_credentials/creator_spec.rb +42 -5
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
- data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
- data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
- data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
- data/spec/lib/oauth/client_spec.rb +26 -26
- data/spec/lib/oauth/code_request_spec.rb +34 -34
- data/spec/lib/oauth/code_response_spec.rb +21 -25
- data/spec/lib/oauth/error_response_spec.rb +42 -44
- data/spec/lib/oauth/error_spec.rb +12 -14
- data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
- data/spec/lib/oauth/invalid_request_response_spec.rb +48 -50
- data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
- data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
- data/spec/lib/oauth/pre_authorization_spec.rb +159 -161
- data/spec/lib/oauth/refresh_token_request_spec.rb +138 -139
- data/spec/lib/oauth/scopes_spec.rb +104 -106
- data/spec/lib/oauth/token_request_spec.rb +115 -111
- data/spec/lib/oauth/token_response_spec.rb +71 -73
- data/spec/lib/oauth/token_spec.rb +121 -123
- data/spec/models/doorkeeper/access_grant_spec.rb +21 -4
- data/spec/models/doorkeeper/access_token_spec.rb +42 -11
- data/spec/models/doorkeeper/application_spec.rb +114 -77
- data/spec/requests/applications/applications_request_spec.rb +1 -1
- data/spec/requests/endpoints/authorization_spec.rb +5 -3
- data/spec/requests/flows/authorization_code_spec.rb +34 -22
- data/spec/requests/flows/client_credentials_spec.rb +1 -1
- data/spec/requests/flows/password_spec.rb +32 -12
- data/spec/requests/flows/refresh_token_spec.rb +19 -19
- data/spec/requests/flows/revoke_token_spec.rb +18 -12
- data/spec/spec_helper.rb +1 -4
- data/spec/support/shared/controllers_shared_context.rb +33 -23
- data/spec/validators/redirect_uri_validator_spec.rb +1 -1
- metadata +6 -5
- data/spec/support/http_method_shim.rb +0 -29
|
@@ -7,7 +7,7 @@ class AddConfidentialToApplications < ActiveRecord::Migration[5.1]
|
|
|
7
7
|
:confidential,
|
|
8
8
|
:boolean,
|
|
9
9
|
null: false,
|
|
10
|
-
default: true # maintaining backwards compatibility: require secrets
|
|
10
|
+
default: true, # maintaining backwards compatibility: require secrets
|
|
11
11
|
)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -16,7 +16,7 @@ describe "Doorkeeper::InstallGenerator" do
|
|
|
16
16
|
FileUtils.mkdir(::File.expand_path("db", Pathname(destination_root)))
|
|
17
17
|
FileUtils.copy_file(
|
|
18
18
|
::File.expand_path("../templates/routes.rb", __FILE__),
|
|
19
|
-
::File.expand_path("config/routes.rb", Pathname.new(destination_root))
|
|
19
|
+
::File.expand_path("config/routes.rb", Pathname.new(destination_root)),
|
|
20
20
|
)
|
|
21
21
|
run_generator
|
|
22
22
|
end
|
|
@@ -14,7 +14,7 @@ describe "Doorkeeper::PreviousRefreshTokenGenerator" do
|
|
|
14
14
|
prepare_destination
|
|
15
15
|
|
|
16
16
|
allow_any_instance_of(Doorkeeper::PreviousRefreshTokenGenerator).to(
|
|
17
|
-
receive(:no_previous_refresh_token_column?).and_return(true)
|
|
17
|
+
receive(:no_previous_refresh_token_column?).and_return(true),
|
|
18
18
|
)
|
|
19
19
|
end
|
|
20
20
|
|
|
@@ -32,7 +32,7 @@ describe "Doorkeeper::PreviousRefreshTokenGenerator" do
|
|
|
32
32
|
context "already exist" do
|
|
33
33
|
it "does not create a migration" do
|
|
34
34
|
allow_any_instance_of(Doorkeeper::PreviousRefreshTokenGenerator).to(
|
|
35
|
-
receive(:no_previous_refresh_token_column?).and_call_original
|
|
35
|
+
receive(:no_previous_refresh_token_column?).and_call_original,
|
|
36
36
|
)
|
|
37
37
|
|
|
38
38
|
run_generator
|
data/spec/lib/config_spec.rb
CHANGED
|
@@ -22,7 +22,7 @@ describe Doorkeeper, "configuration" do
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
expect(Rails.logger).to receive(:warn).with(
|
|
25
|
-
I18n.t("doorkeeper.errors.messages.resource_owner_authenticator_not_configured")
|
|
25
|
+
I18n.t("doorkeeper.errors.messages.resource_owner_authenticator_not_configured"),
|
|
26
26
|
)
|
|
27
27
|
subject.authenticate_resource_owner.call(nil)
|
|
28
28
|
end
|
|
@@ -45,7 +45,7 @@ describe Doorkeeper, "configuration" do
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
expect(Rails.logger).to receive(:warn).with(
|
|
48
|
-
I18n.t("doorkeeper.errors.messages.credential_flow_not_configured")
|
|
48
|
+
I18n.t("doorkeeper.errors.messages.credential_flow_not_configured"),
|
|
49
49
|
)
|
|
50
50
|
subject.resource_owner_from_credentials.call(nil)
|
|
51
51
|
end
|
|
@@ -471,7 +471,7 @@ describe Doorkeeper, "configuration" do
|
|
|
471
471
|
describe "access_token_generator" do
|
|
472
472
|
it "is 'Doorkeeper::OAuth::Helpers::UniqueToken' by default" do
|
|
473
473
|
expect(Doorkeeper.configuration.access_token_generator).to(
|
|
474
|
-
eq("Doorkeeper::OAuth::Helpers::UniqueToken")
|
|
474
|
+
eq("Doorkeeper::OAuth::Helpers::UniqueToken"),
|
|
475
475
|
)
|
|
476
476
|
end
|
|
477
477
|
|
|
@@ -549,6 +549,8 @@ describe Doorkeeper, "configuration" do
|
|
|
549
549
|
end
|
|
550
550
|
|
|
551
551
|
if DOORKEEPER_ORM == :active_record
|
|
552
|
+
class FakeCustomModel; end
|
|
553
|
+
|
|
552
554
|
describe "active_record_options" do
|
|
553
555
|
let(:models) { [Doorkeeper::AccessGrant, Doorkeeper::AccessToken, Doorkeeper::Application] }
|
|
554
556
|
|
|
@@ -566,11 +568,62 @@ describe Doorkeeper, "configuration" do
|
|
|
566
568
|
Doorkeeper.configure do
|
|
567
569
|
orm DOORKEEPER_ORM
|
|
568
570
|
active_record_options(
|
|
569
|
-
establish_connection: Rails.configuration.database_configuration[Rails.env]
|
|
571
|
+
establish_connection: Rails.configuration.database_configuration[Rails.env],
|
|
570
572
|
)
|
|
571
573
|
end
|
|
572
574
|
end
|
|
573
575
|
end
|
|
576
|
+
|
|
577
|
+
describe "access_token_class" do
|
|
578
|
+
it "uses default doorkeeper value" do
|
|
579
|
+
expect(subject.access_token_class).to eq("Doorkeeper::AccessToken")
|
|
580
|
+
expect(subject.access_token_model).to be(Doorkeeper::AccessToken)
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
it "can change the value" do
|
|
584
|
+
Doorkeeper.configure do
|
|
585
|
+
orm DOORKEEPER_ORM
|
|
586
|
+
access_token_class "FakeCustomModel"
|
|
587
|
+
end
|
|
588
|
+
|
|
589
|
+
expect(subject.access_token_class).to eq("FakeCustomModel")
|
|
590
|
+
expect(subject.access_token_model).to be(FakeCustomModel)
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
describe "access_grant_class" do
|
|
595
|
+
it "uses default doorkeeper value" do
|
|
596
|
+
expect(subject.access_grant_class).to eq("Doorkeeper::AccessGrant")
|
|
597
|
+
expect(subject.access_grant_model).to be(Doorkeeper::AccessGrant)
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
it "can change the value" do
|
|
601
|
+
Doorkeeper.configure do
|
|
602
|
+
orm DOORKEEPER_ORM
|
|
603
|
+
access_grant_class "FakeCustomModel"
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
expect(subject.access_grant_class).to eq("FakeCustomModel")
|
|
607
|
+
expect(subject.access_grant_model).to be(FakeCustomModel)
|
|
608
|
+
end
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
describe "application_class" do
|
|
612
|
+
it "uses default doorkeeper value" do
|
|
613
|
+
expect(subject.application_class).to eq("Doorkeeper::Application")
|
|
614
|
+
expect(subject.application_model).to be(Doorkeeper::Application)
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
it "can change the value" do
|
|
618
|
+
Doorkeeper.configure do
|
|
619
|
+
orm DOORKEEPER_ORM
|
|
620
|
+
application_class "FakeCustomModel"
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
expect(subject.application_class).to eq("FakeCustomModel")
|
|
624
|
+
expect(subject.application_model).to be(FakeCustomModel)
|
|
625
|
+
end
|
|
626
|
+
end
|
|
574
627
|
end
|
|
575
628
|
|
|
576
629
|
describe "api_only" do
|
|
@@ -651,8 +704,10 @@ describe Doorkeeper, "configuration" do
|
|
|
651
704
|
Doorkeeper.configure do
|
|
652
705
|
hash_token_secrets using: "Doorkeeper::SecretStoring::BCrypt"
|
|
653
706
|
end
|
|
654
|
-
end.to raise_error(
|
|
655
|
-
|
|
707
|
+
end.to raise_error(
|
|
708
|
+
ArgumentError,
|
|
709
|
+
/can only be used for storing application secrets/,
|
|
710
|
+
)
|
|
656
711
|
end
|
|
657
712
|
end
|
|
658
713
|
|
|
@@ -729,7 +784,7 @@ describe Doorkeeper, "configuration" do
|
|
|
729
784
|
describe "options deprecation" do
|
|
730
785
|
it "prints a warning message when an option is deprecated" do
|
|
731
786
|
expect(Kernel).to receive(:warn).with(
|
|
732
|
-
"[DOORKEEPER] native_redirect_uri has been deprecated and will soon be removed"
|
|
787
|
+
"[DOORKEEPER] native_redirect_uri has been deprecated and will soon be removed",
|
|
733
788
|
)
|
|
734
789
|
Doorkeeper.configure do
|
|
735
790
|
native_redirect_uri "urn:ietf:wg:oauth:2.0:oob"
|
data/spec/lib/doorkeeper_spec.rb
CHANGED
|
@@ -7,7 +7,7 @@ describe Doorkeeper do
|
|
|
7
7
|
let(:request) { double }
|
|
8
8
|
|
|
9
9
|
it "calls OAuth::Token#authenticate" do
|
|
10
|
-
token_strategies = Doorkeeper.
|
|
10
|
+
token_strategies = Doorkeeper.config.access_token_methods
|
|
11
11
|
|
|
12
12
|
expect(Doorkeeper::OAuth::Token).to receive(:authenticate)
|
|
13
13
|
.with(request, *token_strategies)
|
|
@@ -40,15 +40,15 @@ describe "Revocable" do
|
|
|
40
40
|
`previous_refresh_token` attribute" do
|
|
41
41
|
previous_token = FactoryBot.create(
|
|
42
42
|
:access_token,
|
|
43
|
-
refresh_token: "refresh_token"
|
|
43
|
+
refresh_token: "refresh_token",
|
|
44
44
|
)
|
|
45
45
|
current_token = FactoryBot.create(
|
|
46
46
|
:access_token,
|
|
47
|
-
previous_refresh_token: previous_token.refresh_token
|
|
47
|
+
previous_refresh_token: previous_token.refresh_token,
|
|
48
48
|
)
|
|
49
49
|
|
|
50
50
|
expect_any_instance_of(
|
|
51
|
-
Doorkeeper::AccessToken
|
|
51
|
+
Doorkeeper::AccessToken,
|
|
52
52
|
).to receive(:revoke).and_call_original
|
|
53
53
|
current_token.revoke_previous_refresh_token!
|
|
54
54
|
|
|
@@ -2,165 +2,169 @@
|
|
|
2
2
|
|
|
3
3
|
require "spec_helper"
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
5
|
+
describe Doorkeeper::OAuth::AuthorizationCodeRequest do
|
|
6
|
+
let(:server) do
|
|
7
|
+
double :server,
|
|
8
|
+
access_token_expires_in: 2.days,
|
|
9
|
+
refresh_token_enabled?: false,
|
|
10
|
+
custom_access_token_expires_in: lambda { |context|
|
|
11
|
+
context.grant_type == Doorkeeper::OAuth::AUTHORIZATION_CODE ? 1234 : nil
|
|
12
|
+
}
|
|
13
|
+
end
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
let(:grant) { FactoryBot.create :access_grant }
|
|
16
|
+
let(:client) { grant.application }
|
|
17
|
+
let(:redirect_uri) { client.redirect_uri }
|
|
18
|
+
let(:params) { { redirect_uri: redirect_uri } }
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
before do
|
|
21
|
+
allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
|
|
22
|
+
end
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
subject do
|
|
25
|
+
described_class.new(server, grant, client, params)
|
|
26
|
+
end
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
it "issues a new token for the client" do
|
|
29
|
+
expect do
|
|
30
|
+
subject.authorize
|
|
31
|
+
end.to change { client.reload.access_tokens.count }.by(1)
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(1234)
|
|
34
|
+
end
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
it "issues the token with same grant's scopes" do
|
|
37
|
+
subject.authorize
|
|
38
|
+
expect(Doorkeeper::AccessToken.last.scopes).to eq(grant.scopes)
|
|
39
|
+
end
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
it "revokes the grant" do
|
|
42
|
+
expect { subject.authorize }.to(change { grant.reload.accessible? })
|
|
43
|
+
end
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
it "requires the grant to be accessible" do
|
|
46
|
+
grant.revoke
|
|
47
|
+
subject.validate
|
|
48
|
+
expect(subject.error).to eq(:invalid_grant)
|
|
49
|
+
end
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
it "requires the grant" do
|
|
52
|
+
subject.grant = nil
|
|
53
|
+
subject.validate
|
|
54
|
+
expect(subject.error).to eq(:invalid_grant)
|
|
55
|
+
end
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
it "requires the client" do
|
|
58
|
+
subject.client = nil
|
|
59
|
+
subject.validate
|
|
60
|
+
expect(subject.error).to eq(:invalid_client)
|
|
61
|
+
end
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
it "requires the redirect_uri" do
|
|
64
|
+
subject.redirect_uri = nil
|
|
65
|
+
subject.validate
|
|
66
|
+
expect(subject.error).to eq(:invalid_request)
|
|
67
|
+
expect(subject.missing_param).to eq(:redirect_uri)
|
|
68
|
+
end
|
|
70
69
|
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
it "invalid code_verifier param because server does not support pkce" do
|
|
71
|
+
# Some other ORMs work relies on #respond_to? so it's not a good idea to stub it :\
|
|
72
|
+
allow_any_instance_of(Doorkeeper::AccessGrant).to receive(:respond_to?).with(anything).and_call_original
|
|
73
|
+
allow_any_instance_of(Doorkeeper::AccessGrant).to receive(:respond_to?).with(:code_challenge).and_return(false)
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
subject.code_verifier = "a45a9fea-0676-477e-95b1-a40f72ac3cfb"
|
|
76
|
+
subject.validate
|
|
77
|
+
expect(subject.error).to eq(:invalid_request)
|
|
78
|
+
expect(subject.invalid_request_reason).to eq(:not_support_pkce)
|
|
79
|
+
end
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
81
|
+
it "matches the redirect_uri with grant's one" do
|
|
82
|
+
subject.redirect_uri = "http://other.com"
|
|
83
|
+
subject.validate
|
|
84
|
+
expect(subject.error).to eq(:invalid_grant)
|
|
85
|
+
end
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
it "matches the client with grant's one" do
|
|
88
|
+
subject.client = FactoryBot.create :application
|
|
89
|
+
subject.validate
|
|
90
|
+
expect(subject.error).to eq(:invalid_grant)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it "skips token creation if there is a matching one reusable" do
|
|
94
|
+
scopes = grant.scopes
|
|
95
|
+
|
|
96
|
+
Doorkeeper.configure do
|
|
97
|
+
orm DOORKEEPER_ORM
|
|
98
|
+
reuse_access_token
|
|
99
|
+
default_scopes(*scopes)
|
|
90
100
|
end
|
|
91
101
|
|
|
92
|
-
|
|
93
|
-
|
|
102
|
+
FactoryBot.create(
|
|
103
|
+
:access_token, application_id: client.id,
|
|
104
|
+
resource_owner_id: grant.resource_owner_id, scopes: grant.scopes.to_s,
|
|
105
|
+
)
|
|
94
106
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
reuse_access_token
|
|
98
|
-
default_scopes(*scopes)
|
|
99
|
-
end
|
|
107
|
+
expect { subject.authorize }.to_not(change { Doorkeeper::AccessToken.count })
|
|
108
|
+
end
|
|
100
109
|
|
|
101
|
-
|
|
102
|
-
|
|
110
|
+
it "creates token if there is a matching one but non reusable" do
|
|
111
|
+
scopes = grant.scopes
|
|
103
112
|
|
|
104
|
-
|
|
113
|
+
Doorkeeper.configure do
|
|
114
|
+
orm DOORKEEPER_ORM
|
|
115
|
+
reuse_access_token
|
|
116
|
+
default_scopes(*scopes)
|
|
105
117
|
end
|
|
106
118
|
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
FactoryBot.create(
|
|
120
|
+
:access_token, application_id: client.id,
|
|
121
|
+
resource_owner_id: grant.resource_owner_id, scopes: grant.scopes.to_s,
|
|
122
|
+
)
|
|
109
123
|
|
|
110
|
-
|
|
111
|
-
orm DOORKEEPER_ORM
|
|
112
|
-
reuse_access_token
|
|
113
|
-
default_scopes(*scopes)
|
|
114
|
-
end
|
|
124
|
+
allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
|
|
115
125
|
|
|
116
|
-
|
|
117
|
-
|
|
126
|
+
expect { subject.authorize }.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
127
|
+
end
|
|
118
128
|
|
|
119
|
-
|
|
129
|
+
it "calls configured request callback methods" do
|
|
130
|
+
expect(Doorkeeper.configuration.before_successful_strategy_response)
|
|
131
|
+
.to receive(:call).with(subject).once
|
|
132
|
+
expect(Doorkeeper.configuration.after_successful_strategy_response)
|
|
133
|
+
.to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
|
|
120
134
|
|
|
121
|
-
|
|
122
|
-
|
|
135
|
+
subject.authorize
|
|
136
|
+
end
|
|
123
137
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
.to receive(:call).with(subject).once
|
|
127
|
-
expect(Doorkeeper.configuration.after_successful_strategy_response)
|
|
128
|
-
.to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
|
|
138
|
+
context "when redirect_uri contains some query params" do
|
|
139
|
+
let(:redirect_uri) { client.redirect_uri + "?query=q" }
|
|
129
140
|
|
|
130
|
-
|
|
141
|
+
it "compares only host part with grant's redirect_uri" do
|
|
142
|
+
subject.validate
|
|
143
|
+
expect(subject.error).to eq(nil)
|
|
131
144
|
end
|
|
145
|
+
end
|
|
132
146
|
|
|
133
|
-
|
|
134
|
-
|
|
147
|
+
context "when redirect_uri is not an URI" do
|
|
148
|
+
let(:redirect_uri) { "123d#!s" }
|
|
135
149
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
end
|
|
150
|
+
it "responds with invalid_grant" do
|
|
151
|
+
subject.validate
|
|
152
|
+
expect(subject.error).to eq(:invalid_grant)
|
|
140
153
|
end
|
|
154
|
+
end
|
|
141
155
|
|
|
142
|
-
|
|
143
|
-
|
|
156
|
+
context "when redirect_uri is the native one" do
|
|
157
|
+
let(:redirect_uri) { "urn:ietf:wg:oauth:2.0:oob" }
|
|
144
158
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
end
|
|
159
|
+
it "invalidates when redirect_uri of the grant is not native" do
|
|
160
|
+
subject.validate
|
|
161
|
+
expect(subject.error).to eq(:invalid_grant)
|
|
149
162
|
end
|
|
150
163
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
subject.validate
|
|
156
|
-
expect(subject.error).to eq(:invalid_grant)
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
it "validates when redirect_uri of the grant is also native" do
|
|
160
|
-
allow(grant).to receive(:redirect_uri) { redirect_uri }
|
|
161
|
-
subject.validate
|
|
162
|
-
expect(subject.error).to eq(nil)
|
|
163
|
-
end
|
|
164
|
+
it "validates when redirect_uri of the grant is also native" do
|
|
165
|
+
allow(grant).to receive(:redirect_uri) { redirect_uri }
|
|
166
|
+
subject.validate
|
|
167
|
+
expect(subject.error).to eq(nil)
|
|
164
168
|
end
|
|
165
169
|
end
|
|
166
170
|
end
|