doorkeeper 5.3.3 → 5.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of doorkeeper might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Appraisals +0 -14
- data/CHANGELOG.md +35 -10
- data/Dangerfile +7 -7
- data/Dockerfile +2 -2
- data/Gemfile +9 -9
- data/README.md +6 -4
- data/app/controllers/doorkeeper/applications_controller.rb +7 -7
- data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
- data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
- data/app/views/doorkeeper/applications/show.html.erb +19 -2
- data/bin/console +14 -0
- data/config/locales/en.yml +3 -1
- data/doorkeeper.gemspec +1 -1
- data/gemfiles/rails_5_0.gemfile +8 -7
- data/gemfiles/rails_5_1.gemfile +8 -7
- data/gemfiles/rails_5_2.gemfile +8 -7
- data/gemfiles/rails_6_0.gemfile +8 -7
- data/gemfiles/rails_master.gemfile +8 -7
- data/lib/doorkeeper.rb +106 -79
- data/lib/doorkeeper/config.rb +40 -17
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +28 -14
- data/lib/doorkeeper/grape/helpers.rb +1 -1
- data/lib/doorkeeper/models/access_grant_mixin.rb +9 -11
- data/lib/doorkeeper/models/access_token_mixin.rb +100 -41
- data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
- data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
- data/lib/doorkeeper/oauth/authorization/code.rb +14 -5
- data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
- data/lib/doorkeeper/oauth/authorization/token.rb +7 -11
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
- data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
- data/lib/doorkeeper/oauth/base_request.rb +11 -19
- data/lib/doorkeeper/oauth/client.rb +1 -1
- data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +25 -7
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
- data/lib/doorkeeper/oauth/code_request.rb +1 -1
- data/lib/doorkeeper/oauth/code_response.rb +6 -2
- data/lib/doorkeeper/oauth/error_response.rb +2 -4
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
- data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
- data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
- data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -5
- data/lib/doorkeeper/oauth/pre_authorization.rb +32 -27
- data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
- data/lib/doorkeeper/oauth/token.rb +1 -1
- data/lib/doorkeeper/oauth/token_introspection.rb +3 -3
- data/lib/doorkeeper/oauth/token_request.rb +2 -2
- data/lib/doorkeeper/oauth/token_response.rb +1 -1
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +7 -2
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +6 -2
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +9 -64
- data/lib/doorkeeper/rails/routes.rb +13 -17
- data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
- data/lib/doorkeeper/rails/routes/registry.rb +45 -0
- data/lib/doorkeeper/request/strategy.rb +2 -2
- data/lib/doorkeeper/server.rb +3 -3
- data/lib/doorkeeper/version.rb +3 -3
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
- data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +39 -3
- data/lib/generators/doorkeeper/templates/migration.rb.erb +2 -0
- data/spec/controllers/applications_controller_spec.rb +2 -2
- data/spec/controllers/authorizations_controller_spec.rb +165 -30
- data/spec/controllers/tokens_controller_spec.rb +6 -5
- data/spec/dummy/app/helpers/application_helper.rb +1 -1
- data/spec/dummy/app/models/user.rb +5 -1
- data/spec/dummy/config/application.rb +6 -4
- data/spec/dummy/config/boot.rb +4 -4
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/routes.rb +4 -4
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +2 -2
- data/spec/dummy/db/schema.rb +3 -1
- data/spec/factories.rb +1 -1
- data/spec/generators/enable_polymorphic_resource_owner_generator_spec.rb +47 -0
- data/spec/lib/config_spec.rb +15 -11
- data/spec/lib/models/revocable_spec.rb +2 -3
- data/spec/lib/models/scopes_spec.rb +8 -0
- data/spec/lib/oauth/authorization_code_request_spec.rb +25 -15
- data/spec/lib/oauth/base_request_spec.rb +6 -20
- data/spec/lib/oauth/client_credentials/creator_spec.rb +90 -89
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +84 -86
- data/spec/lib/oauth/client_credentials/validation_spec.rb +38 -40
- data/spec/lib/oauth/client_credentials_request_spec.rb +5 -4
- data/spec/lib/oauth/code_request_spec.rb +1 -1
- data/spec/lib/oauth/code_response_spec.rb +5 -1
- data/spec/lib/oauth/error_response_spec.rb +1 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +24 -13
- data/spec/lib/oauth/pre_authorization_spec.rb +13 -18
- data/spec/lib/oauth/refresh_token_request_spec.rb +19 -30
- data/spec/lib/oauth/token_request_spec.rb +14 -7
- data/spec/lib/option_spec.rb +51 -0
- data/spec/lib/stale_records_cleaner_spec.rb +18 -5
- data/spec/models/doorkeeper/access_grant_spec.rb +18 -4
- data/spec/models/doorkeeper/access_token_spec.rb +507 -479
- data/spec/models/doorkeeper/application_spec.rb +22 -62
- data/spec/requests/endpoints/token_spec.rb +5 -1
- data/spec/requests/flows/authorization_code_errors_spec.rb +4 -1
- data/spec/requests/flows/authorization_code_spec.rb +6 -1
- data/spec/requests/flows/client_credentials_spec.rb +41 -0
- data/spec/requests/flows/refresh_token_spec.rb +16 -8
- data/spec/requests/flows/revoke_token_spec.rb +143 -104
- data/spec/support/helpers/access_token_request_helper.rb +1 -0
- data/spec/support/helpers/authorization_request_helper.rb +4 -4
- data/spec/support/helpers/config_helper.rb +1 -1
- data/spec/support/shared/controllers_shared_context.rb +2 -2
- data/spec/support/shared/models_shared_examples.rb +6 -4
- metadata +16 -5
@@ -2,58 +2,56 @@
|
|
2
2
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
let(:request) { double :request, client: client, scopes: nil }
|
5
|
+
describe Doorkeeper::OAuth::ClientCredentials::Validator do
|
6
|
+
let(:server) { double :server, scopes: nil }
|
7
|
+
let(:application) { double scopes: nil }
|
8
|
+
let(:client) { double application: application }
|
9
|
+
let(:request) { double :request, client: client, scopes: nil }
|
11
10
|
|
12
|
-
|
11
|
+
subject { described_class.new(server, request) }
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
it "is valid with valid request" do
|
14
|
+
expect(subject).to be_valid
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
17
|
+
it "is invalid when client is not present" do
|
18
|
+
allow(request).to receive(:client).and_return(nil)
|
19
|
+
expect(subject).not_to be_valid
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with scopes" do
|
23
|
+
it "is invalid when scopes are not included in the server" do
|
24
|
+
server_scopes = Doorkeeper::OAuth::Scopes.from_string "email"
|
25
|
+
allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
|
26
|
+
allow(server).to receive(:scopes).and_return(server_scopes)
|
27
|
+
allow(request).to receive(:scopes).and_return(
|
28
|
+
Doorkeeper::OAuth::Scopes.from_string("invalid"),
|
29
|
+
)
|
20
30
|
expect(subject).not_to be_valid
|
21
31
|
end
|
22
32
|
|
23
|
-
context "with scopes" do
|
24
|
-
it "is
|
25
|
-
|
33
|
+
context "with application scopes" do
|
34
|
+
it "is valid when scopes are included in the application" do
|
35
|
+
application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
|
36
|
+
server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
|
37
|
+
allow(application).to receive(:scopes).and_return(application_scopes)
|
38
|
+
allow(server).to receive(:scopes).and_return(server_scopes)
|
39
|
+
allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
|
40
|
+
allow(request).to receive(:scopes).and_return(application_scopes)
|
41
|
+
expect(subject).to be_valid
|
42
|
+
end
|
43
|
+
|
44
|
+
it "is invalid when scopes are not included in the application" do
|
45
|
+
application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
|
46
|
+
server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
|
47
|
+
allow(application).to receive(:scopes).and_return(application_scopes)
|
26
48
|
allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
|
27
49
|
allow(server).to receive(:scopes).and_return(server_scopes)
|
28
50
|
allow(request).to receive(:scopes).and_return(
|
29
|
-
Doorkeeper::OAuth::Scopes.from_string("
|
51
|
+
Doorkeeper::OAuth::Scopes.from_string("email"),
|
30
52
|
)
|
31
53
|
expect(subject).not_to be_valid
|
32
54
|
end
|
33
|
-
|
34
|
-
context "with application scopes" do
|
35
|
-
it "is valid when scopes are included in the application" do
|
36
|
-
application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
|
37
|
-
server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
|
38
|
-
allow(application).to receive(:scopes).and_return(application_scopes)
|
39
|
-
allow(server).to receive(:scopes).and_return(server_scopes)
|
40
|
-
allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
|
41
|
-
allow(request).to receive(:scopes).and_return(application_scopes)
|
42
|
-
expect(subject).to be_valid
|
43
|
-
end
|
44
|
-
|
45
|
-
it "is invalid when scopes are not included in the application" do
|
46
|
-
application_scopes = Doorkeeper::OAuth::Scopes.from_string "app"
|
47
|
-
server_scopes = Doorkeeper::OAuth::Scopes.from_string "email app"
|
48
|
-
allow(application).to receive(:scopes).and_return(application_scopes)
|
49
|
-
allow(request).to receive(:grant_type).and_return(Doorkeeper::OAuth::CLIENT_CREDENTIALS)
|
50
|
-
allow(server).to receive(:scopes).and_return(server_scopes)
|
51
|
-
allow(request).to receive(:scopes).and_return(
|
52
|
-
Doorkeeper::OAuth::Scopes.from_string("email"),
|
53
|
-
)
|
54
|
-
expect(subject).not_to be_valid
|
55
|
-
end
|
56
|
-
end
|
57
55
|
end
|
58
56
|
end
|
59
57
|
end
|
@@ -12,7 +12,7 @@ describe Doorkeeper::OAuth::ClientCredentialsRequest do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
let(:application) { FactoryBot.create(:application, scopes: "") }
|
15
|
-
let(:client) { double :client, application: application }
|
15
|
+
let(:client) { double :client, application: application, scopes: "" }
|
16
16
|
let(:token_creator) { double :issuer, create: true, token: double }
|
17
17
|
|
18
18
|
before do
|
@@ -22,7 +22,7 @@ describe Doorkeeper::OAuth::ClientCredentialsRequest do
|
|
22
22
|
subject { Doorkeeper::OAuth::ClientCredentialsRequest.new(server, client) }
|
23
23
|
|
24
24
|
before do
|
25
|
-
subject.issuer
|
25
|
+
allow(subject).to receive(:issuer).and_return(token_creator)
|
26
26
|
end
|
27
27
|
|
28
28
|
it "issues an access token for the current client" do
|
@@ -37,7 +37,8 @@ describe Doorkeeper::OAuth::ClientCredentialsRequest do
|
|
37
37
|
|
38
38
|
context "if issue was not created" do
|
39
39
|
before do
|
40
|
-
|
40
|
+
issuer = double create: false, error: :invalid
|
41
|
+
allow(subject).to receive(:issuer).and_return(issuer)
|
41
42
|
end
|
42
43
|
|
43
44
|
it "has an error response" do
|
@@ -65,7 +66,7 @@ describe Doorkeeper::OAuth::ClientCredentialsRequest do
|
|
65
66
|
|
66
67
|
it "issues an access token with requested scopes" do
|
67
68
|
subject = Doorkeeper::OAuth::ClientCredentialsRequest.new(server, client, scope: "email")
|
68
|
-
subject.issuer
|
69
|
+
allow(subject).to receive(:issuer).and_return(token_creator)
|
69
70
|
expect(token_creator).to receive(:create).with(client, Doorkeeper::OAuth::Scopes.from_string("email"))
|
70
71
|
subject.authorize
|
71
72
|
end
|
@@ -15,8 +15,12 @@ describe Doorkeeper::OAuth::CodeResponse do
|
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
18
|
+
let :owner do
|
19
|
+
FactoryBot.create(:resource_owner)
|
20
|
+
end
|
21
|
+
|
18
22
|
let :auth do
|
19
|
-
Doorkeeper::OAuth::Authorization::Token.new(pre_auth,
|
23
|
+
Doorkeeper::OAuth::Authorization::Token.new(pre_auth, owner).tap do |c|
|
20
24
|
c.issue_token
|
21
25
|
allow(c.token).to receive(:expires_in_seconds).and_return(3600)
|
22
26
|
end
|
@@ -56,7 +56,7 @@ describe Doorkeeper::OAuth::ErrorResponse do
|
|
56
56
|
describe "WWW-Authenticate header" do
|
57
57
|
subject { error_response.headers["WWW-Authenticate"] }
|
58
58
|
|
59
|
-
it { expect(subject).to include("realm=\"#{error_response.realm}\"") }
|
59
|
+
it { expect(subject).to include("realm=\"#{error_response.send(:realm)}\"") }
|
60
60
|
it { expect(subject).to include("error=\"#{error_response.name}\"") }
|
61
61
|
it { expect(subject).to include("error_description=\"#{error_response.description}\"") }
|
62
62
|
end
|
@@ -15,7 +15,7 @@ describe Doorkeeper::OAuth::PasswordAccessTokenRequest do
|
|
15
15
|
)
|
16
16
|
end
|
17
17
|
let(:client) { FactoryBot.create(:application) }
|
18
|
-
let(:owner) {
|
18
|
+
let(:owner) { FactoryBot.create(:resource_owner) }
|
19
19
|
|
20
20
|
before do
|
21
21
|
allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
|
@@ -34,16 +34,17 @@ describe Doorkeeper::OAuth::PasswordAccessTokenRequest do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
it "issues a new token without a client" do
|
37
|
+
subject = described_class.new(server, nil, owner)
|
38
|
+
expect(subject).to be_valid
|
39
|
+
|
37
40
|
expect do
|
38
|
-
subject.client = nil
|
39
41
|
subject.authorize
|
40
42
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
41
43
|
end
|
42
44
|
|
43
45
|
it "does not issue a new token with an invalid client" do
|
46
|
+
subject = described_class.new(server, nil, owner, { client_id: "bad_id" })
|
44
47
|
expect do
|
45
|
-
subject.client = nil
|
46
|
-
subject.parameters = { client_id: "bad_id" }
|
47
48
|
subject.authorize
|
48
49
|
end.not_to(change { Doorkeeper::AccessToken.count })
|
49
50
|
|
@@ -51,18 +52,18 @@ describe Doorkeeper::OAuth::PasswordAccessTokenRequest do
|
|
51
52
|
end
|
52
53
|
|
53
54
|
it "requires the owner" do
|
54
|
-
subject
|
55
|
+
subject = described_class.new(server, client, nil)
|
55
56
|
subject.validate
|
56
57
|
expect(subject.error).to eq(:invalid_grant)
|
57
58
|
end
|
58
59
|
|
59
|
-
it "optionally accepts the client" do
|
60
|
-
subject.client = nil
|
61
|
-
expect(subject).to be_valid
|
62
|
-
end
|
63
|
-
|
64
60
|
it "creates token even when there is already one (default)" do
|
65
|
-
FactoryBot.create(
|
61
|
+
FactoryBot.create(
|
62
|
+
:access_token,
|
63
|
+
application_id: client.id,
|
64
|
+
resource_owner_id: owner.id,
|
65
|
+
resource_owner_type: owner.class.name,
|
66
|
+
)
|
66
67
|
|
67
68
|
expect do
|
68
69
|
subject.authorize
|
@@ -71,7 +72,12 @@ describe Doorkeeper::OAuth::PasswordAccessTokenRequest do
|
|
71
72
|
|
72
73
|
it "skips token creation if there is already one reusable" do
|
73
74
|
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
74
|
-
FactoryBot.create(
|
75
|
+
FactoryBot.create(
|
76
|
+
:access_token,
|
77
|
+
application_id: client.id,
|
78
|
+
resource_owner_id: owner.id,
|
79
|
+
resource_owner_type: owner.class.name,
|
80
|
+
)
|
75
81
|
|
76
82
|
expect do
|
77
83
|
subject.authorize
|
@@ -80,7 +86,12 @@ describe Doorkeeper::OAuth::PasswordAccessTokenRequest do
|
|
80
86
|
|
81
87
|
it "creates token when there is already one but non reusable" do
|
82
88
|
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
83
|
-
FactoryBot.create(
|
89
|
+
FactoryBot.create(
|
90
|
+
:access_token,
|
91
|
+
application_id: client.id,
|
92
|
+
resource_owner_id: owner.id,
|
93
|
+
resource_owner_type: owner.class.name,
|
94
|
+
)
|
84
95
|
allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
|
85
96
|
|
86
97
|
expect do
|
@@ -19,6 +19,7 @@ describe Doorkeeper::OAuth::PreAuthorization do
|
|
19
19
|
response_type: "code",
|
20
20
|
redirect_uri: "https://app.com/callback",
|
21
21
|
state: "save-this",
|
22
|
+
current_resource_owner: Object.new,
|
22
23
|
}
|
23
24
|
end
|
24
25
|
|
@@ -177,6 +178,14 @@ describe Doorkeeper::OAuth::PreAuthorization do
|
|
177
178
|
expect(subject).not_to be_authorizable
|
178
179
|
end
|
179
180
|
|
181
|
+
context "when resource_owner cannot access client application" do
|
182
|
+
before { allow(Doorkeeper.configuration).to receive(:authorize_resource_owner_for_client).and_return(->(*_) { false }) }
|
183
|
+
|
184
|
+
it "is not authorizable" do
|
185
|
+
expect(subject).not_to be_authorizable
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
180
189
|
describe "as_json" do
|
181
190
|
before { subject.authorizable? }
|
182
191
|
|
@@ -194,30 +203,16 @@ describe Doorkeeper::OAuth::PreAuthorization do
|
|
194
203
|
end
|
195
204
|
end
|
196
205
|
|
197
|
-
context "when
|
206
|
+
context "when called without params" do
|
198
207
|
let(:json) { subject.as_json }
|
199
208
|
|
200
209
|
include_examples "returns the pre authorization"
|
201
210
|
end
|
202
211
|
|
203
|
-
context "when
|
204
|
-
|
205
|
-
let(:custom_attributes) { { custom_id: "1234", custom_name: "a pretty good name" } }
|
206
|
-
let(:json) { subject.as_json(custom_attributes) }
|
207
|
-
|
208
|
-
include_examples "returns the pre authorization"
|
212
|
+
context "when called with params" do
|
213
|
+
let(:json) { subject.as_json(foo: "bar") }
|
209
214
|
|
210
|
-
|
211
|
-
expect(json[:custom_id]).to eq custom_attributes[:custom_id]
|
212
|
-
expect(json[:custom_name]).to eq custom_attributes[:custom_name]
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
context "when attributes is not a hash" do
|
217
|
-
let(:json) { subject.as_json(nil) }
|
218
|
-
|
219
|
-
include_examples "returns the pre authorization"
|
220
|
-
end
|
215
|
+
include_examples "returns the pre authorization"
|
221
216
|
end
|
222
217
|
end
|
223
218
|
end
|
@@ -4,8 +4,7 @@ require "spec_helper"
|
|
4
4
|
|
5
5
|
describe Doorkeeper::OAuth::RefreshTokenRequest do
|
6
6
|
let(:server) do
|
7
|
-
double :server,
|
8
|
-
access_token_expires_in: 2.minutes
|
7
|
+
double :server, access_token_expires_in: 2.minutes
|
9
8
|
end
|
10
9
|
|
11
10
|
let(:refresh_token) do
|
@@ -20,28 +19,22 @@ describe Doorkeeper::OAuth::RefreshTokenRequest do
|
|
20
19
|
allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(false)
|
21
20
|
end
|
22
21
|
|
23
|
-
subject { described_class.new
|
22
|
+
subject { described_class.new(server, refresh_token, credentials) }
|
24
23
|
|
25
24
|
it "issues a new token for the client" do
|
26
25
|
expect { subject.authorize }.to change { client.reload.access_tokens.count }.by(1)
|
27
26
|
# #sort_by used for MongoDB ORM extensions for valid ordering
|
28
|
-
expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(
|
27
|
+
expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(refresh_token.expires_in)
|
29
28
|
end
|
30
29
|
|
31
|
-
it "issues a new token for the client with
|
32
|
-
server = double :server,
|
33
|
-
access_token_expires_in: 2.minutes,
|
34
|
-
custom_access_token_expires_in: lambda { |context|
|
35
|
-
context.grant_type == Doorkeeper::OAuth::REFRESH_TOKEN ? 1234 : nil
|
36
|
-
}
|
37
|
-
|
30
|
+
it "issues a new token for the client with the same expiry as of original token" do
|
38
31
|
allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
|
39
32
|
allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(false)
|
40
33
|
|
41
34
|
described_class.new(server, refresh_token, credentials).authorize
|
42
35
|
|
43
36
|
# #sort_by used for MongoDB ORM extensions for valid ordering
|
44
|
-
expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(
|
37
|
+
expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(refresh_token.expires_in)
|
45
38
|
end
|
46
39
|
|
47
40
|
it "revokes the previous token" do
|
@@ -59,22 +52,26 @@ describe Doorkeeper::OAuth::RefreshTokenRequest do
|
|
59
52
|
end
|
60
53
|
|
61
54
|
it "requires the refresh token" do
|
62
|
-
|
63
|
-
|
64
|
-
expect(
|
65
|
-
expect(
|
55
|
+
request = described_class.new(server, nil, credentials)
|
56
|
+
request.validate
|
57
|
+
expect(request.error).to eq(:invalid_request)
|
58
|
+
expect(request.missing_param).to eq(:refresh_token)
|
66
59
|
end
|
67
60
|
|
68
61
|
it "requires credentials to be valid if provided" do
|
69
|
-
|
70
|
-
|
71
|
-
|
62
|
+
credentials = Doorkeeper::OAuth::Client::Credentials.new("invalid", "invalid")
|
63
|
+
request = described_class.new(server, refresh_token, credentials)
|
64
|
+
request.validate
|
65
|
+
expect(request.error).to eq(:invalid_client)
|
72
66
|
end
|
73
67
|
|
74
68
|
it "requires the token's client and current client to match" do
|
75
|
-
|
76
|
-
|
77
|
-
|
69
|
+
other_app = FactoryBot.create(:application)
|
70
|
+
credentials = Doorkeeper::OAuth::Client::Credentials.new(other_app.uid, other_app.secret)
|
71
|
+
|
72
|
+
request = described_class.new(server, refresh_token, credentials)
|
73
|
+
request.validate
|
74
|
+
expect(request.error).to eq(:invalid_grant)
|
78
75
|
end
|
79
76
|
|
80
77
|
it "rejects revoked tokens" do
|
@@ -91,14 +88,6 @@ describe Doorkeeper::OAuth::RefreshTokenRequest do
|
|
91
88
|
end
|
92
89
|
|
93
90
|
context "refresh tokens expire on access token use" do
|
94
|
-
let(:server) do
|
95
|
-
double :server,
|
96
|
-
access_token_expires_in: 2.minutes,
|
97
|
-
custom_access_token_expires_in: lambda { |context|
|
98
|
-
context.grant_type == Doorkeeper::OAuth::REFRESH_TOKEN ? 1234 : nil
|
99
|
-
}
|
100
|
-
end
|
101
|
-
|
102
91
|
before do
|
103
92
|
allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(true)
|
104
93
|
end
|
@@ -8,7 +8,7 @@ describe Doorkeeper::OAuth::TokenRequest do
|
|
8
8
|
end
|
9
9
|
|
10
10
|
let :pre_auth do
|
11
|
-
server = Doorkeeper.
|
11
|
+
server = Doorkeeper.config
|
12
12
|
allow(server).to receive(:default_scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
13
13
|
allow(server).to receive(:grant_flows).and_return(Doorkeeper::OAuth::Scopes.from_string("implicit"))
|
14
14
|
|
@@ -26,7 +26,7 @@ describe Doorkeeper::OAuth::TokenRequest do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
let :owner do
|
29
|
-
|
29
|
+
FactoryBot.create(:doorkeeper_testing_user)
|
30
30
|
end
|
31
31
|
|
32
32
|
subject do
|
@@ -116,9 +116,13 @@ describe Doorkeeper::OAuth::TokenRequest do
|
|
116
116
|
it "creates a new token if scopes do not match" do
|
117
117
|
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
118
118
|
FactoryBot.create(
|
119
|
-
:access_token,
|
120
|
-
|
119
|
+
:access_token,
|
120
|
+
application_id: pre_auth.client.id,
|
121
|
+
resource_owner_id: owner.id,
|
122
|
+
resource_owner_type: owner.class.name,
|
123
|
+
scopes: "",
|
121
124
|
)
|
125
|
+
|
122
126
|
expect do
|
123
127
|
subject.authorize
|
124
128
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
@@ -131,7 +135,7 @@ describe Doorkeeper::OAuth::TokenRequest do
|
|
131
135
|
|
132
136
|
FactoryBot.create(
|
133
137
|
:access_token, application_id: pre_auth.client.id,
|
134
|
-
resource_owner_id: owner.id, scopes: "public",
|
138
|
+
resource_owner_id: owner.id, resource_owner_type: owner.class.name, scopes: "public",
|
135
139
|
)
|
136
140
|
|
137
141
|
expect { subject.authorize }.not_to(change { Doorkeeper::AccessToken.count })
|
@@ -143,8 +147,11 @@ describe Doorkeeper::OAuth::TokenRequest do
|
|
143
147
|
allow(application.scopes).to receive(:all?).and_return(true)
|
144
148
|
|
145
149
|
FactoryBot.create(
|
146
|
-
:access_token,
|
147
|
-
|
150
|
+
:access_token,
|
151
|
+
application_id: pre_auth.client.id,
|
152
|
+
resource_owner_id: owner.id,
|
153
|
+
resource_owner_type: owner.class.name,
|
154
|
+
scopes: "public",
|
148
155
|
)
|
149
156
|
|
150
157
|
allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
|