doorkeeper 5.2.6 → 5.3.3
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 +2 -2
- data/CHANGELOG.md +24 -5
- 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/authorizations_controller.rb +2 -2
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
- 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 +10 -8
- data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
- data/lib/doorkeeper/models/access_token_mixin.rb +54 -16
- 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 +7 -5
- 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 +3 -155
- 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 +187 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +3 -3
- data/lib/doorkeeper/orm/active_record.rb +3 -3
- 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 +2 -2
- 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 +18 -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 -125
- 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 +3 -5
- data/spec/models/doorkeeper/access_token_spec.rb +7 -7
- data/spec/models/doorkeeper/application_spec.rb +2 -2
- 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
@@ -44,15 +44,19 @@ module Doorkeeper::OAuth::Helpers
|
|
44
44
|
end
|
45
45
|
|
46
46
|
it "is valid if scope is included in the application scope list" do
|
47
|
-
expect(ScopeChecker.valid?(
|
48
|
-
|
49
|
-
|
47
|
+
expect(ScopeChecker.valid?(
|
48
|
+
scope_str: "app123",
|
49
|
+
server_scopes: server_scopes,
|
50
|
+
app_scopes: application_scopes,
|
51
|
+
)).to be_truthy
|
50
52
|
end
|
51
53
|
|
52
54
|
it "is invalid if any scope is not included in the application" do
|
53
|
-
expect(ScopeChecker.valid?(
|
54
|
-
|
55
|
-
|
55
|
+
expect(ScopeChecker.valid?(
|
56
|
+
scope_str: "svr",
|
57
|
+
server_scopes: server_scopes,
|
58
|
+
app_scopes: application_scopes,
|
59
|
+
)).to be_falsey
|
56
60
|
end
|
57
61
|
end
|
58
62
|
|
@@ -63,15 +67,19 @@ module Doorkeeper::OAuth::Helpers
|
|
63
67
|
|
64
68
|
context "with scopes_by_grant_type not configured for grant_type" do
|
65
69
|
it "is valid if the scope is in server scopes" do
|
66
|
-
expect(ScopeChecker.valid?(
|
67
|
-
|
68
|
-
|
70
|
+
expect(ScopeChecker.valid?(
|
71
|
+
scope_str: "scope1",
|
72
|
+
server_scopes: server_scopes,
|
73
|
+
grant_type: Doorkeeper::OAuth::PASSWORD,
|
74
|
+
)).to be_truthy
|
69
75
|
end
|
70
76
|
|
71
77
|
it "is invalid if the scope is not in server scopes" do
|
72
|
-
expect(ScopeChecker.valid?(
|
73
|
-
|
74
|
-
|
78
|
+
expect(ScopeChecker.valid?(
|
79
|
+
scope_str: "unknown",
|
80
|
+
server_scopes: server_scopes,
|
81
|
+
grant_type: Doorkeeper::OAuth::PASSWORD,
|
82
|
+
)).to be_falsey
|
75
83
|
end
|
76
84
|
end
|
77
85
|
|
@@ -82,15 +90,19 @@ module Doorkeeper::OAuth::Helpers
|
|
82
90
|
end
|
83
91
|
|
84
92
|
it "is valid if the scope is permitted for grant_type" do
|
85
|
-
expect(ScopeChecker.valid?(
|
86
|
-
|
87
|
-
|
93
|
+
expect(ScopeChecker.valid?(
|
94
|
+
scope_str: "scope1",
|
95
|
+
server_scopes: server_scopes,
|
96
|
+
grant_type: Doorkeeper::OAuth::PASSWORD,
|
97
|
+
)).to be_truthy
|
88
98
|
end
|
89
99
|
|
90
100
|
it "is invalid if the scope is permitted for grant_type" do
|
91
|
-
expect(ScopeChecker.valid?(
|
92
|
-
|
93
|
-
|
101
|
+
expect(ScopeChecker.valid?(
|
102
|
+
scope_str: "scope2",
|
103
|
+
server_scopes: server_scopes,
|
104
|
+
grant_type: Doorkeeper::OAuth::PASSWORD,
|
105
|
+
)).to be_falsey
|
94
106
|
end
|
95
107
|
end
|
96
108
|
end
|
@@ -2,73 +2,71 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
|
6
|
-
describe
|
7
|
-
|
8
|
-
|
9
|
-
end
|
5
|
+
describe Doorkeeper::OAuth::InvalidRequestResponse do
|
6
|
+
describe "#name" do
|
7
|
+
it { expect(subject.name).to eq(:invalid_request) }
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
describe "#status" do
|
11
|
+
it { expect(subject.status).to eq(:bad_request) }
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
14
|
+
describe ".from_request" do
|
15
|
+
let(:response) { described_class.from_request(request) }
|
17
16
|
|
18
|
-
|
19
|
-
|
17
|
+
context "missing param" do
|
18
|
+
let(:request) { double(missing_param: "some_param") }
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
it "sets a description" do
|
21
|
+
expect(response.description).to eq(
|
22
|
+
I18n.t(:missing_param, scope: %i[doorkeeper errors messages invalid_request], value: "some_param"),
|
23
|
+
)
|
24
|
+
end
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
end
|
26
|
+
it "sets the reason" do
|
27
|
+
expect(response.reason).to eq(:missing_param)
|
30
28
|
end
|
29
|
+
end
|
31
30
|
|
32
|
-
|
33
|
-
|
31
|
+
context "server doesn't support_pkce" do
|
32
|
+
let(:request) { double(invalid_request_reason: :not_support_pkce) }
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
it "sets a description" do
|
35
|
+
expect(response.description).to eq(
|
36
|
+
I18n.t(:not_support_pkce, scope: %i[doorkeeper errors messages invalid_request]),
|
37
|
+
)
|
38
|
+
end
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
40
|
+
it "sets the reason" do
|
41
|
+
expect(response.reason).to eq(:not_support_pkce)
|
44
42
|
end
|
43
|
+
end
|
45
44
|
|
46
|
-
|
47
|
-
|
45
|
+
context "request is not authorized" do
|
46
|
+
let(:request) { double(invalid_request_reason: :request_not_authorized) }
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
it "sets a description" do
|
49
|
+
expect(response.description).to eq(
|
50
|
+
I18n.t(:request_not_authorized, scope: %i[doorkeeper errors messages invalid_request]),
|
51
|
+
)
|
52
|
+
end
|
54
53
|
|
55
|
-
|
56
|
-
|
57
|
-
end
|
54
|
+
it "sets the reason" do
|
55
|
+
expect(response.reason).to eq(:request_not_authorized)
|
58
56
|
end
|
57
|
+
end
|
59
58
|
|
60
|
-
|
61
|
-
|
59
|
+
context "unknown reason" do
|
60
|
+
let(:request) { double(invalid_request_reason: :unknown_reason) }
|
62
61
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
it "sets a description" do
|
63
|
+
expect(response.description).to eq(
|
64
|
+
I18n.t(:unknown, scope: %i[doorkeeper errors messages invalid_request]),
|
65
|
+
)
|
66
|
+
end
|
68
67
|
|
69
|
-
|
70
|
-
|
71
|
-
end
|
68
|
+
it "unknown reason" do
|
69
|
+
expect(response.reason).to eq(:unknown_reason)
|
72
70
|
end
|
73
71
|
end
|
74
72
|
end
|
@@ -2,53 +2,51 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
|
6
|
-
describe
|
7
|
-
|
8
|
-
|
9
|
-
end
|
5
|
+
describe Doorkeeper::OAuth::InvalidTokenResponse do
|
6
|
+
describe "#name" do
|
7
|
+
it { expect(subject.name).to eq(:invalid_token) }
|
8
|
+
end
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
describe "#status" do
|
11
|
+
it { expect(subject.status).to eq(:unauthorized) }
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
14
|
+
describe ".from_access_token" do
|
15
|
+
let(:response) { described_class.from_access_token(access_token) }
|
17
16
|
|
18
|
-
|
19
|
-
|
17
|
+
context "revoked" do
|
18
|
+
let(:access_token) { double(revoked?: true, expired?: true) }
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
it "sets a description" do
|
21
|
+
expect(response.description).to include("revoked")
|
22
|
+
end
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
end
|
24
|
+
it "sets the reason" do
|
25
|
+
expect(response.reason).to eq(:revoked)
|
28
26
|
end
|
27
|
+
end
|
29
28
|
|
30
|
-
|
31
|
-
|
29
|
+
context "expired" do
|
30
|
+
let(:access_token) { double(revoked?: false, expired?: true) }
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
it "sets a description" do
|
33
|
+
expect(response.description).to include("expired")
|
34
|
+
end
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
end
|
36
|
+
it "sets the reason" do
|
37
|
+
expect(response.reason).to eq(:expired)
|
40
38
|
end
|
39
|
+
end
|
41
40
|
|
42
|
-
|
43
|
-
|
41
|
+
context "unknown" do
|
42
|
+
let(:access_token) { double(revoked?: false, expired?: false) }
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
it "sets a description" do
|
45
|
+
expect(response.description).to include("invalid")
|
46
|
+
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
end
|
48
|
+
it "sets the reason" do
|
49
|
+
expect(response.reason).to eq(:unknown)
|
52
50
|
end
|
53
51
|
end
|
54
52
|
end
|
@@ -2,191 +2,189 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
let(:owner) { double :owner, id: 99 }
|
5
|
+
describe Doorkeeper::OAuth::PasswordAccessTokenRequest do
|
6
|
+
let(:server) do
|
7
|
+
double(
|
8
|
+
:server,
|
9
|
+
default_scopes: Doorkeeper::OAuth::Scopes.new,
|
10
|
+
access_token_expires_in: 2.hours,
|
11
|
+
refresh_token_enabled?: false,
|
12
|
+
custom_access_token_expires_in: lambda { |context|
|
13
|
+
context.grant_type == Doorkeeper::OAuth::PASSWORD ? 1234 : nil
|
14
|
+
},
|
15
|
+
)
|
16
|
+
end
|
17
|
+
let(:client) { FactoryBot.create(:application) }
|
18
|
+
let(:owner) { double :owner, id: 99 }
|
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, client, owner)
|
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
|
-
|
41
|
-
|
42
|
-
|
36
|
+
it "issues a new token without a client" do
|
37
|
+
expect do
|
38
|
+
subject.client = nil
|
39
|
+
subject.authorize
|
40
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
41
|
+
end
|
43
42
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
43
|
+
it "does not issue a new token with an invalid client" do
|
44
|
+
expect do
|
45
|
+
subject.client = nil
|
46
|
+
subject.parameters = { client_id: "bad_id" }
|
47
|
+
subject.authorize
|
48
|
+
end.not_to(change { Doorkeeper::AccessToken.count })
|
50
49
|
|
51
|
-
|
52
|
-
|
50
|
+
expect(subject.error).to eq(:invalid_client)
|
51
|
+
end
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
53
|
+
it "requires the owner" do
|
54
|
+
subject.resource_owner = nil
|
55
|
+
subject.validate
|
56
|
+
expect(subject.error).to eq(:invalid_grant)
|
57
|
+
end
|
59
58
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
it "optionally accepts the client" do
|
60
|
+
subject.client = nil
|
61
|
+
expect(subject).to be_valid
|
62
|
+
end
|
64
63
|
|
65
|
-
|
66
|
-
|
64
|
+
it "creates token even when there is already one (default)" do
|
65
|
+
FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
|
67
66
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
67
|
+
expect do
|
68
|
+
subject.authorize
|
69
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
70
|
+
end
|
72
71
|
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
it "skips token creation if there is already one reusable" do
|
73
|
+
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
74
|
+
FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
|
76
75
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
expect do
|
77
|
+
subject.authorize
|
78
|
+
end.not_to(change { Doorkeeper::AccessToken.count })
|
79
|
+
end
|
81
80
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
81
|
+
it "creates token when there is already one but non reusable" do
|
82
|
+
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
83
|
+
FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
|
84
|
+
allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
|
86
85
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
86
|
+
expect do
|
87
|
+
subject.authorize
|
88
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
89
|
+
end
|
91
90
|
|
92
|
-
|
93
|
-
|
94
|
-
|
91
|
+
it "calls configured request callback methods" do
|
92
|
+
expect(Doorkeeper.configuration.before_successful_strategy_response)
|
93
|
+
.to receive(:call).with(subject).once
|
95
94
|
|
96
|
-
|
97
|
-
|
95
|
+
expect(Doorkeeper.configuration.after_successful_strategy_response)
|
96
|
+
.to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
|
98
97
|
|
99
|
-
|
98
|
+
subject.authorize
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "with scopes" do
|
102
|
+
subject do
|
103
|
+
described_class.new(server, client, owner, scope: "public")
|
100
104
|
end
|
101
105
|
|
102
|
-
|
103
|
-
|
104
|
-
|
106
|
+
context "when scopes_by_grant_type is not configured for grant_type" do
|
107
|
+
it "returns error when scopes are invalid" do
|
108
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("another"))
|
109
|
+
subject.validate
|
110
|
+
expect(subject.error).to eq(:invalid_scope)
|
105
111
|
end
|
106
112
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
subject.
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
it "creates the token with scopes if scopes are valid" do
|
115
|
-
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
116
|
-
expect do
|
117
|
-
subject.authorize
|
118
|
-
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
119
|
-
|
120
|
-
expect(Doorkeeper::AccessToken.last.scopes).to include("public")
|
121
|
-
end
|
122
|
-
end
|
113
|
+
it "creates the token with scopes if scopes are valid" do
|
114
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
115
|
+
expect do
|
116
|
+
subject.authorize
|
117
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
123
118
|
|
124
|
-
|
125
|
-
it "returns error when scopes are valid but not permitted for grant_type" do
|
126
|
-
allow(server)
|
127
|
-
.to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
128
|
-
allow(Doorkeeper.configuration)
|
129
|
-
.to receive(:scopes_by_grant_type).and_return(password: "another")
|
130
|
-
subject.validate
|
131
|
-
expect(subject.error).to eq(:invalid_scope)
|
132
|
-
end
|
133
|
-
|
134
|
-
it "creates the token with scopes if scopes are valid and permitted for grant_type" do
|
135
|
-
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
136
|
-
allow(Doorkeeper.configuration)
|
137
|
-
.to receive(:scopes_by_grant_type).and_return(password: [:public])
|
138
|
-
|
139
|
-
expect do
|
140
|
-
subject.authorize
|
141
|
-
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
142
|
-
|
143
|
-
expect(Doorkeeper::AccessToken.last.scopes).to include("public")
|
144
|
-
end
|
119
|
+
expect(Doorkeeper::AccessToken.last.scopes).to include("public")
|
145
120
|
end
|
146
121
|
end
|
147
122
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
:
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
if context.scopes.exists?("public")
|
157
|
-
222
|
158
|
-
elsif context.scopes.exists?("magic")
|
159
|
-
Float::INFINITY
|
160
|
-
end
|
161
|
-
}
|
162
|
-
)
|
163
|
-
end
|
164
|
-
|
165
|
-
before do
|
166
|
-
allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
|
123
|
+
context "when scopes_by_grant_type is configured for grant_type" do
|
124
|
+
it "returns error when scopes are valid but not permitted for grant_type" do
|
125
|
+
allow(server)
|
126
|
+
.to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
127
|
+
allow(Doorkeeper.configuration)
|
128
|
+
.to receive(:scopes_by_grant_type).and_return(password: "another")
|
129
|
+
subject.validate
|
130
|
+
expect(subject.error).to eq(:invalid_scope)
|
167
131
|
end
|
168
132
|
|
169
|
-
it "
|
170
|
-
subject = PasswordAccessTokenRequest.new(server, client, owner, scope: "public")
|
133
|
+
it "creates the token with scopes if scopes are valid and permitted for grant_type" do
|
171
134
|
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
135
|
+
allow(Doorkeeper.configuration)
|
136
|
+
.to receive(:scopes_by_grant_type).and_return(password: [:public])
|
172
137
|
|
173
138
|
expect do
|
174
139
|
subject.authorize
|
175
140
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
176
141
|
|
177
|
-
expect(Doorkeeper::AccessToken.last.
|
142
|
+
expect(Doorkeeper::AccessToken.last.scopes).to include("public")
|
178
143
|
end
|
144
|
+
end
|
145
|
+
end
|
179
146
|
|
180
|
-
|
181
|
-
|
182
|
-
|
147
|
+
describe "with custom expiry" do
|
148
|
+
let(:server) do
|
149
|
+
double(
|
150
|
+
:server,
|
151
|
+
default_scopes: Doorkeeper::OAuth::Scopes.new,
|
152
|
+
access_token_expires_in: 2.hours,
|
153
|
+
refresh_token_enabled?: false,
|
154
|
+
custom_access_token_expires_in: lambda { |context|
|
155
|
+
if context.scopes.exists?("public")
|
156
|
+
222
|
157
|
+
elsif context.scopes.exists?("magic")
|
158
|
+
Float::INFINITY
|
159
|
+
end
|
160
|
+
},
|
161
|
+
)
|
162
|
+
end
|
183
163
|
|
184
|
-
|
185
|
-
|
186
|
-
|
164
|
+
before do
|
165
|
+
allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
|
166
|
+
end
|
187
167
|
|
188
|
-
|
189
|
-
|
168
|
+
it "checks scopes" do
|
169
|
+
subject = described_class.new(server, client, owner, scope: "public")
|
170
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
171
|
+
|
172
|
+
expect do
|
173
|
+
subject.authorize
|
174
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
175
|
+
|
176
|
+
expect(Doorkeeper::AccessToken.last.expires_in).to eq(222)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "falls back to the default otherwise" do
|
180
|
+
subject = described_class.new(server, client, owner, scope: "private")
|
181
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("private"))
|
182
|
+
|
183
|
+
expect do
|
184
|
+
subject.authorize
|
185
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
186
|
+
|
187
|
+
expect(Doorkeeper::AccessToken.last.expires_in).to eq(2.hours)
|
190
188
|
end
|
191
189
|
end
|
192
190
|
end
|