doorkeeper 4.4.3 → 5.0.0
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/.gitignore +1 -0
- data/.gitlab-ci.yml +16 -0
- data/.travis.yml +2 -0
- data/Appraisals +2 -2
- data/Gemfile +1 -1
- data/NEWS.md +61 -8
- data/README.md +92 -9
- data/Rakefile +6 -0
- data/UPGRADE.md +2 -0
- data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
- data/app/controllers/doorkeeper/application_controller.rb +4 -3
- data/app/controllers/doorkeeper/application_metal_controller.rb +4 -0
- data/app/controllers/doorkeeper/applications_controller.rb +42 -22
- data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +19 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +2 -6
- data/app/helpers/doorkeeper/dashboard_helper.rb +7 -7
- data/app/validators/redirect_uri_validator.rb +3 -2
- data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
- data/app/views/doorkeeper/applications/_form.html.erb +25 -24
- data/app/views/doorkeeper/applications/edit.html.erb +1 -1
- data/app/views/doorkeeper/applications/index.html.erb +17 -7
- data/app/views/doorkeeper/applications/new.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +6 -6
- data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
- data/app/views/doorkeeper/authorizations/new.html.erb +4 -0
- data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
- data/config/locales/en.yml +10 -1
- data/doorkeeper.gemspec +18 -20
- data/gemfiles/rails_5_2.gemfile +1 -1
- data/gemfiles/rails_master.gemfile +4 -1
- data/lib/doorkeeper/config.rb +75 -39
- data/lib/doorkeeper/engine.rb +4 -0
- data/lib/doorkeeper/errors.rb +2 -5
- data/lib/doorkeeper/grape/helpers.rb +1 -1
- data/lib/doorkeeper/helpers/controller.rb +7 -2
- data/lib/doorkeeper/models/access_grant_mixin.rb +71 -0
- data/lib/doorkeeper/models/access_token_mixin.rb +39 -22
- data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
- data/lib/doorkeeper/oauth/authorization/code.rb +31 -8
- data/lib/doorkeeper/oauth/authorization/context.rb +15 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +36 -14
- data/lib/doorkeeper/oauth/authorization_code_request.rb +27 -2
- data/lib/doorkeeper/oauth/base_request.rb +20 -9
- data/lib/doorkeeper/oauth/client/credentials.rb +1 -1
- data/lib/doorkeeper/oauth/client.rb +0 -2
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -1
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +6 -3
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +4 -6
- data/lib/doorkeeper/oauth/client_credentials_request.rb +0 -4
- data/lib/doorkeeper/oauth/error_response.rb +11 -3
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +0 -8
- data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -4
- data/lib/doorkeeper/oauth/pre_authorization.rb +41 -11
- data/lib/doorkeeper/oauth/refresh_token_request.rb +6 -1
- data/lib/doorkeeper/oauth/scopes.rb +1 -1
- data/lib/doorkeeper/oauth/token.rb +5 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +2 -2
- data/lib/doorkeeper/oauth/token_response.rb +4 -2
- data/lib/doorkeeper/oauth.rb +13 -0
- data/lib/doorkeeper/orm/active_record/application.rb +22 -14
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
- data/lib/doorkeeper/orm/active_record.rb +2 -0
- data/lib/doorkeeper/rails/helpers.rb +2 -4
- data/lib/doorkeeper/rails/routes.rb +14 -6
- data/lib/doorkeeper/rake/db.rake +40 -0
- data/lib/doorkeeper/rake/setup.rake +6 -0
- data/lib/doorkeeper/rake.rb +14 -0
- data/lib/doorkeeper/request/authorization_code.rb +0 -2
- data/lib/doorkeeper/request/client_credentials.rb +0 -2
- data/lib/doorkeeper/request/code.rb +0 -2
- data/lib/doorkeeper/request/password.rb +0 -2
- data/lib/doorkeeper/request/refresh_token.rb +0 -2
- data/lib/doorkeeper/request/token.rb +0 -2
- data/lib/doorkeeper/request.rb +28 -35
- data/lib/doorkeeper/version.rb +5 -25
- data/lib/doorkeeper.rb +19 -17
- data/lib/generators/doorkeeper/application_owner_generator.rb +23 -18
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
- data/lib/generators/doorkeeper/install_generator.rb +17 -9
- data/lib/generators/doorkeeper/migration_generator.rb +23 -18
- data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -24
- data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
- data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +76 -11
- data/lib/generators/doorkeeper/views_generator.rb +3 -1
- data/spec/controllers/application_metal_controller_spec.rb +50 -0
- data/spec/controllers/applications_controller_spec.rb +126 -13
- data/spec/controllers/authorizations_controller_spec.rb +277 -47
- data/spec/controllers/protected_resources_controller_spec.rb +16 -16
- data/spec/controllers/token_info_controller_spec.rb +4 -12
- data/spec/controllers/tokens_controller_spec.rb +13 -15
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/dummy/config/environments/test.rb +4 -5
- data/spec/dummy/config/initializers/doorkeeper.rb +10 -5
- data/spec/dummy/config/initializers/new_framework_defaults.rb +4 -0
- data/spec/dummy/config/routes.rb +3 -42
- data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
- data/spec/dummy/db/migrate/{20180210183654_add_confidential_to_application.rb → 20180210183654_add_confidential_to_applications.rb} +1 -1
- data/spec/dummy/db/schema.rb +36 -36
- data/spec/generators/application_owner_generator_spec.rb +1 -1
- data/spec/generators/confidential_applications_generator_spec.rb +45 -0
- data/spec/generators/install_generator_spec.rb +1 -1
- data/spec/generators/migration_generator_spec.rb +1 -1
- data/spec/generators/pkce_generator_spec.rb +43 -0
- data/spec/generators/previous_refresh_token_generator_spec.rb +1 -1
- data/spec/generators/views_generator_spec.rb +1 -1
- data/spec/grape/grape_integration_spec.rb +1 -1
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
- data/spec/lib/config_spec.rb +80 -31
- data/spec/lib/doorkeeper_spec.rb +1 -126
- data/spec/lib/models/expirable_spec.rb +0 -3
- data/spec/lib/models/revocable_spec.rb +0 -2
- data/spec/lib/models/scopes_spec.rb +0 -4
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
- data/spec/lib/oauth/authorization_code_request_spec.rb +9 -2
- data/spec/lib/oauth/base_request_spec.rb +40 -2
- data/spec/lib/oauth/base_response_spec.rb +1 -1
- data/spec/lib/oauth/client/credentials_spec.rb +1 -3
- data/spec/lib/oauth/client_credentials/creator_spec.rb +5 -1
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +26 -7
- data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -3
- data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
- data/spec/lib/oauth/client_credentials_request_spec.rb +3 -5
- data/spec/lib/oauth/client_spec.rb +0 -3
- data/spec/lib/oauth/code_request_spec.rb +4 -2
- data/spec/lib/oauth/error_response_spec.rb +0 -3
- data/spec/lib/oauth/error_spec.rb +0 -2
- data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -3
- data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +5 -7
- data/spec/lib/oauth/invalid_token_response_spec.rb +1 -4
- data/spec/lib/oauth/password_access_token_request_spec.rb +37 -2
- data/spec/lib/oauth/pre_authorization_spec.rb +33 -4
- data/spec/lib/oauth/refresh_token_request_spec.rb +11 -7
- data/spec/lib/oauth/scopes_spec.rb +0 -3
- data/spec/lib/oauth/token_request_spec.rb +4 -5
- data/spec/lib/oauth/token_response_spec.rb +0 -1
- data/spec/lib/oauth/token_spec.rb +37 -14
- data/spec/lib/orm/active_record/stale_records_cleaner_spec.rb +79 -0
- data/spec/lib/request/strategy_spec.rb +0 -1
- data/spec/lib/server_spec.rb +1 -1
- data/spec/models/doorkeeper/access_grant_spec.rb +44 -1
- data/spec/models/doorkeeper/access_token_spec.rb +66 -22
- data/spec/models/doorkeeper/application_spec.rb +14 -47
- data/spec/requests/applications/applications_request_spec.rb +134 -1
- data/spec/requests/applications/authorized_applications_spec.rb +1 -1
- data/spec/requests/endpoints/authorization_spec.rb +1 -1
- data/spec/requests/endpoints/token_spec.rb +7 -5
- data/spec/requests/flows/authorization_code_errors_spec.rb +1 -1
- data/spec/requests/flows/authorization_code_spec.rb +197 -1
- data/spec/requests/flows/client_credentials_spec.rb +46 -6
- data/spec/requests/flows/implicit_grant_errors_spec.rb +1 -1
- data/spec/requests/flows/implicit_grant_spec.rb +38 -11
- data/spec/requests/flows/password_spec.rb +56 -2
- data/spec/requests/flows/refresh_token_spec.rb +2 -2
- data/spec/requests/flows/revoke_token_spec.rb +11 -11
- data/spec/requests/flows/skip_authorization_spec.rb +16 -11
- data/spec/requests/protected_resources/metal_spec.rb +1 -1
- data/spec/requests/protected_resources/private_api_spec.rb +1 -1
- data/spec/routing/custom_controller_routes_spec.rb +59 -7
- data/spec/routing/default_routes_spec.rb +2 -2
- data/spec/routing/scoped_routes_spec.rb +16 -2
- data/spec/spec_helper.rb +54 -3
- data/spec/spec_helper_integration.rb +2 -74
- data/spec/support/dependencies/{factory_girl.rb → factory_bot.rb} +0 -0
- data/spec/support/doorkeeper_rspec.rb +19 -0
- data/spec/support/helpers/authorization_request_helper.rb +4 -4
- data/spec/support/helpers/request_spec_helper.rb +10 -2
- data/spec/support/helpers/url_helper.rb +7 -3
- data/spec/support/http_method_shim.rb +12 -16
- data/spec/validators/redirect_uri_validator_spec.rb +7 -1
- data/spec/version/version_spec.rb +3 -3
- data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
- metadata +37 -33
- data/lib/generators/doorkeeper/add_client_confidentiality_generator.rb +0 -31
- data/lib/generators/doorkeeper/templates/add_confidential_to_application_migration.rb.erb +0 -11
- data/spec/controllers/application_metal_controller.rb +0 -10
@@ -1,12 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_model'
|
3
|
-
require 'doorkeeper'
|
4
|
-
require 'doorkeeper/oauth/forbidden_token_response'
|
5
2
|
|
6
3
|
module Doorkeeper::OAuth
|
7
4
|
describe ForbiddenTokenResponse do
|
8
5
|
describe '#name' do
|
9
|
-
it
|
6
|
+
it { expect(subject.name).to eq(:invalid_scope) }
|
10
7
|
end
|
11
8
|
|
12
9
|
describe '#status' do
|
@@ -1,15 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'uri'
|
3
|
-
require 'doorkeeper/oauth/helpers/uri_checker'
|
4
2
|
|
5
3
|
module Doorkeeper::OAuth::Helpers
|
6
4
|
describe URIChecker do
|
7
5
|
describe '.valid?' do
|
8
|
-
it 'is valid for native uris' do
|
9
|
-
uri = 'urn:ietf:wg:oauth:2.0:oob'
|
10
|
-
expect(URIChecker.valid?(uri)).to be_truthy
|
11
|
-
end
|
12
|
-
|
13
6
|
it 'is valid for valid uris' do
|
14
7
|
uri = 'http://app.co'
|
15
8
|
expect(URIChecker.valid?(uri)).to be_truthy
|
@@ -49,6 +42,11 @@ module Doorkeeper::OAuth::Helpers
|
|
49
42
|
uri = ' '
|
50
43
|
expect(URIChecker.valid?(uri)).to be_falsey
|
51
44
|
end
|
45
|
+
|
46
|
+
it 'is valid for native uris' do
|
47
|
+
uri = 'urn:ietf:wg:oauth:2.0:oob'
|
48
|
+
expect(URIChecker.valid?(uri)).to be_truthy
|
49
|
+
end
|
52
50
|
end
|
53
51
|
|
54
52
|
describe '.matches?' do
|
@@ -1,12 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_model'
|
3
|
-
require 'doorkeeper'
|
4
|
-
require 'doorkeeper/oauth/invalid_token_response'
|
5
2
|
|
6
3
|
module Doorkeeper::OAuth
|
7
4
|
describe InvalidTokenResponse do
|
8
5
|
describe "#name" do
|
9
|
-
it
|
6
|
+
it { expect(subject.name).to eq(:invalid_token) }
|
10
7
|
end
|
11
8
|
|
12
9
|
describe "#status" do
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
module Doorkeeper::OAuth
|
4
4
|
describe PasswordAccessTokenRequest do
|
@@ -8,7 +8,9 @@ module Doorkeeper::OAuth
|
|
8
8
|
default_scopes: Doorkeeper::OAuth::Scopes.new,
|
9
9
|
access_token_expires_in: 2.hours,
|
10
10
|
refresh_token_enabled?: false,
|
11
|
-
custom_access_token_expires_in:
|
11
|
+
custom_access_token_expires_in: lambda { |context|
|
12
|
+
context.grant_type == Doorkeeper::OAuth::PASSWORD ? 1234 : nil
|
13
|
+
}
|
12
14
|
)
|
13
15
|
end
|
14
16
|
let(:client) { FactoryBot.create(:application) }
|
@@ -22,6 +24,7 @@ module Doorkeeper::OAuth
|
|
22
24
|
expect do
|
23
25
|
subject.authorize
|
24
26
|
end.to change { client.reload.access_tokens.count }.by(1)
|
27
|
+
expect(client.reload.access_tokens.sort_by(&:created_at).last.expires_in).to eq(1234)
|
25
28
|
end
|
26
29
|
|
27
30
|
it 'issues a new token without a client' do
|
@@ -92,5 +95,37 @@ module Doorkeeper::OAuth
|
|
92
95
|
expect(Doorkeeper::AccessToken.last.scopes).to include('public')
|
93
96
|
end
|
94
97
|
end
|
98
|
+
|
99
|
+
describe 'with custom expiry' do
|
100
|
+
let(:server) do
|
101
|
+
double(
|
102
|
+
:server,
|
103
|
+
default_scopes: Doorkeeper::OAuth::Scopes.new,
|
104
|
+
access_token_expires_in: 2.hours,
|
105
|
+
refresh_token_enabled?: false,
|
106
|
+
custom_access_token_expires_in: lambda { |context|
|
107
|
+
context.scopes.exists?('public') ? 222 : nil
|
108
|
+
}
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'checks scopes' do
|
113
|
+
subject = PasswordAccessTokenRequest.new(server, client, owner, scope: 'public')
|
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)
|
118
|
+
expect(Doorkeeper::AccessToken.last.expires_in).to eq(222)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'falls back to the default otherwise' do
|
122
|
+
subject = PasswordAccessTokenRequest.new(server, client, owner, scope: 'private')
|
123
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string('private'))
|
124
|
+
expect do
|
125
|
+
subject.authorize
|
126
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
127
|
+
expect(Doorkeeper::AccessToken.last.expires_in).to eq(2.hours)
|
128
|
+
end
|
129
|
+
end
|
95
130
|
end
|
96
131
|
end
|
@@ -1,13 +1,13 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
module Doorkeeper::OAuth
|
4
4
|
describe PreAuthorization do
|
5
|
-
let(:server)
|
5
|
+
let(:server) do
|
6
6
|
server = Doorkeeper.configuration
|
7
7
|
allow(server).to receive(:default_scopes).and_return(Scopes.new)
|
8
8
|
allow(server).to receive(:scopes).and_return(Scopes.from_string('public profile'))
|
9
9
|
server
|
10
|
-
|
10
|
+
end
|
11
11
|
|
12
12
|
let(:application) do
|
13
13
|
application = double :application
|
@@ -133,11 +133,16 @@ module Doorkeeper::OAuth
|
|
133
133
|
end
|
134
134
|
|
135
135
|
it 'invalidates redirect_uri when it does\'n match with the client' do
|
136
|
-
subject.redirect_uri =
|
136
|
+
subject.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
|
137
137
|
expect(subject).not_to be_authorizable
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
+
it 'matches the redirect uri against client\'s one' do
|
142
|
+
subject.redirect_uri = 'http://nothesame.com'
|
143
|
+
expect(subject).not_to be_authorizable
|
144
|
+
end
|
145
|
+
|
141
146
|
it 'stores the state' do
|
142
147
|
expect(subject.state).to eq('save-this')
|
143
148
|
end
|
@@ -156,5 +161,29 @@ module Doorkeeper::OAuth
|
|
156
161
|
subject.redirect_uri = nil
|
157
162
|
expect(subject).not_to be_authorizable
|
158
163
|
end
|
164
|
+
|
165
|
+
describe "as_json" do
|
166
|
+
let(:client_id) { "client_uid_123" }
|
167
|
+
let(:client_name) { "Acme Co." }
|
168
|
+
|
169
|
+
before do
|
170
|
+
allow(client).to receive(:uid).and_return client_id
|
171
|
+
allow(client).to receive(:name).and_return client_name
|
172
|
+
end
|
173
|
+
|
174
|
+
let(:json) { subject.as_json({}) }
|
175
|
+
|
176
|
+
it { is_expected.to respond_to :as_json }
|
177
|
+
|
178
|
+
it "returns correct values" do
|
179
|
+
expect(json[:client_id]).to eq client_id
|
180
|
+
expect(json[:redirect_uri]).to eq subject.redirect_uri
|
181
|
+
expect(json[:state]).to eq subject.state
|
182
|
+
expect(json[:response_type]).to eq subject.response_type
|
183
|
+
expect(json[:scope]).to eq subject.scope
|
184
|
+
expect(json[:client_name]).to eq client_name
|
185
|
+
expect(json[:status]).to eq I18n.t('doorkeeper.pre_authorization.status')
|
186
|
+
end
|
187
|
+
end
|
159
188
|
end
|
160
189
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
module Doorkeeper::OAuth
|
4
4
|
describe RefreshTokenRequest do
|
@@ -9,7 +9,7 @@ module Doorkeeper::OAuth
|
|
9
9
|
let(:server) do
|
10
10
|
double :server,
|
11
11
|
access_token_expires_in: 2.minutes,
|
12
|
-
custom_access_token_expires_in: ->
|
12
|
+
custom_access_token_expires_in: ->(_context) { nil }
|
13
13
|
end
|
14
14
|
|
15
15
|
let(:refresh_token) do
|
@@ -30,7 +30,9 @@ module Doorkeeper::OAuth
|
|
30
30
|
it 'issues a new token for the client with custom expires_in' do
|
31
31
|
server = double :server,
|
32
32
|
access_token_expires_in: 2.minutes,
|
33
|
-
custom_access_token_expires_in:
|
33
|
+
custom_access_token_expires_in: lambda { |context|
|
34
|
+
context.grant_type == Doorkeeper::OAuth::REFRESH_TOKEN ? 1234 : nil
|
35
|
+
}
|
34
36
|
|
35
37
|
allow(Doorkeeper::AccessToken).to receive(:refresh_token_revoked_on_use?).and_return(false)
|
36
38
|
|
@@ -85,7 +87,9 @@ module Doorkeeper::OAuth
|
|
85
87
|
let(:server) do
|
86
88
|
double :server,
|
87
89
|
access_token_expires_in: 2.minutes,
|
88
|
-
custom_access_token_expires_in:
|
90
|
+
custom_access_token_expires_in: lambda { |context|
|
91
|
+
context.grant_type == Doorkeeper::OAuth::REFRESH_TOKEN ? 1234 : nil
|
92
|
+
}
|
89
93
|
end
|
90
94
|
|
91
95
|
before do
|
@@ -131,13 +135,13 @@ module Doorkeeper::OAuth
|
|
131
135
|
|
132
136
|
it 'transfers scopes from the old token to the new token' do
|
133
137
|
subject.authorize
|
134
|
-
expect(Doorkeeper::AccessToken.last.scopes).to eq([
|
138
|
+
expect(Doorkeeper::AccessToken.last.scopes).to eq(%i[public write])
|
135
139
|
end
|
136
140
|
|
137
141
|
it 'reduces scopes to the provided scopes' do
|
138
142
|
parameters[:scopes] = 'public'
|
139
143
|
subject.authorize
|
140
|
-
expect(Doorkeeper::AccessToken.last.scopes).to eq([
|
144
|
+
expect(Doorkeeper::AccessToken.last.scopes).to eq(%i[public])
|
141
145
|
end
|
142
146
|
|
143
147
|
it 'validates that scopes are included in the original access token' do
|
@@ -151,7 +155,7 @@ module Doorkeeper::OAuth
|
|
151
155
|
parameters[:scopes] = 'public update'
|
152
156
|
parameters[:scope] = 'public'
|
153
157
|
subject.authorize
|
154
|
-
expect(Doorkeeper::AccessToken.last.scopes).to eq([
|
158
|
+
expect(Doorkeeper::AccessToken.last.scopes).to eq(%i[public])
|
155
159
|
end
|
156
160
|
|
157
161
|
it 'uses params[:scope] in favor of scopes if present (invalid)' do
|
@@ -1,10 +1,9 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
module Doorkeeper::OAuth
|
4
4
|
describe TokenRequest do
|
5
5
|
let :application do
|
6
|
-
|
7
|
-
double(:application, id: 9990, scopes: scopes)
|
6
|
+
FactoryBot.create(:application, scopes: "public")
|
8
7
|
end
|
9
8
|
|
10
9
|
let :pre_auth do
|
@@ -51,8 +50,8 @@ module Doorkeeper::OAuth
|
|
51
50
|
before do
|
52
51
|
Doorkeeper.configure do
|
53
52
|
orm DOORKEEPER_ORM
|
54
|
-
custom_access_token_expires_in do |
|
55
|
-
1234
|
53
|
+
custom_access_token_expires_in do |context|
|
54
|
+
context.grant_type == Doorkeeper::OAuth::IMPLICIT ? 1234 : nil
|
56
55
|
end
|
57
56
|
end
|
58
57
|
end
|
@@ -1,6 +1,4 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'active_support/core_ext/string'
|
3
|
-
require 'doorkeeper/oauth/token'
|
4
2
|
|
5
3
|
module Doorkeeper
|
6
4
|
unless defined?(AccessToken)
|
@@ -14,7 +12,7 @@ module Doorkeeper
|
|
14
12
|
let(:request) { double.as_null_object }
|
15
13
|
|
16
14
|
let(:method) do
|
17
|
-
->(
|
15
|
+
->(*) { 'token-value' }
|
18
16
|
end
|
19
17
|
|
20
18
|
it 'accepts anything that responds to #call' do
|
@@ -96,19 +94,44 @@ module Doorkeeper
|
|
96
94
|
end
|
97
95
|
|
98
96
|
describe :authenticate do
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
97
|
+
context 'refresh tokens are disabled (default)' do
|
98
|
+
context 'refresh tokens are enabled' do
|
99
|
+
it 'does not revoke previous refresh_token if token was found' do
|
100
|
+
token = ->(_r) { 'token' }
|
101
|
+
expect(
|
102
|
+
AccessToken
|
103
|
+
).to receive(:by_token).with('token').and_return(token)
|
104
|
+
expect(token).not_to receive(:revoke_previous_refresh_token!)
|
105
|
+
Token.authenticate double, token
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'calls the finder if token was returned' do
|
110
|
+
token = ->(_r) { 'token' }
|
111
|
+
expect(AccessToken).to receive(:by_token).with('token')
|
112
|
+
Token.authenticate double, token
|
113
|
+
end
|
103
114
|
end
|
104
115
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
116
|
+
context 'refresh tokens are enabled' do
|
117
|
+
before do
|
118
|
+
Doorkeeper.configure { use_refresh_token }
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'revokes previous refresh_token if token was found' do
|
122
|
+
token = ->(_r) { 'token' }
|
123
|
+
expect(
|
124
|
+
AccessToken
|
125
|
+
).to receive(:by_token).with('token').and_return(token)
|
126
|
+
expect(token).to receive(:revoke_previous_refresh_token!)
|
127
|
+
Token.authenticate double, token
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'calls the finder if token was returned' do
|
131
|
+
token = ->(_r) { 'token' }
|
132
|
+
expect(AccessToken).to receive(:by_token).with('token')
|
133
|
+
Token.authenticate double, token
|
134
|
+
end
|
112
135
|
end
|
113
136
|
end
|
114
137
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Doorkeeper::Orm::ActiveRecord::StaleRecordsCleaner do
|
6
|
+
let(:cleaner) { described_class.new(model) }
|
7
|
+
let(:models_by_name) do
|
8
|
+
{
|
9
|
+
access_token: Doorkeeper::AccessToken,
|
10
|
+
access_grant: Doorkeeper::AccessGrant
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
%i[access_token access_grant].each do |model_name|
|
15
|
+
context "(#{model_name})" do
|
16
|
+
let(:model) { models_by_name.fetch(model_name) }
|
17
|
+
|
18
|
+
describe '#clean_revoked' do
|
19
|
+
subject { cleaner.clean_revoked }
|
20
|
+
|
21
|
+
context 'with revoked record' do
|
22
|
+
before do
|
23
|
+
FactoryBot.create model_name, revoked_at: Time.current - 1.minute
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'removes the record' do
|
27
|
+
expect { subject }.to change { model.count }.to(0)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with record revoked in the future' do
|
32
|
+
before do
|
33
|
+
FactoryBot.create model_name, revoked_at: Time.current + 1.minute
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'keeps the record' do
|
37
|
+
expect { subject }.not_to change { model.count }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'with unrevoked record' do
|
42
|
+
before do
|
43
|
+
FactoryBot.create model_name, revoked_at: nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'keeps the record' do
|
47
|
+
expect { subject }.not_to change { model.count }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#clean_expired' do
|
53
|
+
subject { cleaner.clean_expired(ttl) }
|
54
|
+
let(:ttl) { 500 }
|
55
|
+
let(:expiry_border) { ttl.seconds.ago }
|
56
|
+
|
57
|
+
context 'with record that is expired' do
|
58
|
+
before do
|
59
|
+
FactoryBot.create model_name, created_at: expiry_border - 1.minute
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'removes the record' do
|
63
|
+
expect { subject }.to change { model.count }.to(0)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with record that is not expired' do
|
68
|
+
before do
|
69
|
+
FactoryBot.create model_name, created_at: expiry_border + 1.minute
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'keeps the record' do
|
73
|
+
expect { subject }.not_to change { model.count }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/spec/lib/server_spec.rb
CHANGED
@@ -46,7 +46,7 @@ describe Doorkeeper::Server do
|
|
46
46
|
subject.authorization_request :code
|
47
47
|
end
|
48
48
|
|
49
|
-
it 'builds the request with
|
49
|
+
it 'builds the request with composite strategy name' do
|
50
50
|
allow(Doorkeeper.configuration).
|
51
51
|
to receive(:authorization_response_types).
|
52
52
|
and_return(['id_token token'])
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Doorkeeper::AccessGrant do
|
4
4
|
subject { FactoryBot.build(:access_grant) }
|
@@ -33,4 +33,47 @@ describe Doorkeeper::AccessGrant do
|
|
33
33
|
expect(subject).not_to be_valid
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
describe '.revoke_all_for' do
|
38
|
+
let(:resource_owner) { double(id: 100) }
|
39
|
+
let(:application) { FactoryBot.create :application }
|
40
|
+
let(:default_attributes) do
|
41
|
+
{
|
42
|
+
application: application,
|
43
|
+
resource_owner_id: resource_owner.id
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'revokes all tokens for given application and resource owner' do
|
48
|
+
FactoryBot.create :access_grant, default_attributes
|
49
|
+
|
50
|
+
described_class.revoke_all_for(application.id, resource_owner)
|
51
|
+
|
52
|
+
described_class.all.each do |token|
|
53
|
+
expect(token).to be_revoked
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'matches application' do
|
58
|
+
access_grant_for_different_app = FactoryBot.create(
|
59
|
+
:access_grant,
|
60
|
+
default_attributes.merge(application: FactoryBot.create(:application))
|
61
|
+
)
|
62
|
+
|
63
|
+
described_class.revoke_all_for(application.id, resource_owner)
|
64
|
+
|
65
|
+
expect(access_grant_for_different_app.reload).not_to be_revoked
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'matches resource owner' do
|
69
|
+
access_grant_for_different_owner = FactoryBot.create(
|
70
|
+
:access_grant,
|
71
|
+
default_attributes.merge(resource_owner_id: 90)
|
72
|
+
)
|
73
|
+
|
74
|
+
described_class.revoke_all_for application.id, resource_owner
|
75
|
+
|
76
|
+
expect(access_grant_for_different_owner.reload).not_to be_revoked
|
77
|
+
end
|
78
|
+
end
|
36
79
|
end
|