doorkeeper 4.4.3 → 5.0.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 +5 -5
- data/.gitignore +1 -0
- data/.gitlab-ci.yml +16 -0
- data/.travis.yml +7 -0
- data/Appraisals +2 -2
- data/Dangerfile +64 -0
- data/Gemfile +1 -1
- data/NEWS.md +98 -8
- data/README.md +110 -12
- 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 +6 -3
- data/app/controllers/doorkeeper/application_metal_controller.rb +6 -0
- data/app/controllers/doorkeeper/applications_controller.rb +46 -24
- data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +21 -2
- data/app/controllers/doorkeeper/token_info_controller.rb +2 -0
- data/app/controllers/doorkeeper/tokens_controller.rb +4 -6
- data/app/helpers/doorkeeper/dashboard_helper.rb +9 -7
- data/app/validators/redirect_uri_validator.rb +5 -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 +25 -26
- data/gemfiles/rails_5_2.gemfile +1 -1
- data/gemfiles/rails_master.gemfile +4 -1
- data/lib/doorkeeper/config.rb +81 -40
- data/lib/doorkeeper/engine.rb +6 -0
- data/lib/doorkeeper/errors.rb +17 -3
- data/lib/doorkeeper/grape/authorization_decorator.rb +2 -0
- data/lib/doorkeeper/grape/helpers.rb +3 -1
- data/lib/doorkeeper/helpers/controller.rb +9 -2
- data/lib/doorkeeper/models/access_grant_mixin.rb +73 -0
- data/lib/doorkeeper/models/access_token_mixin.rb +44 -25
- data/lib/doorkeeper/models/application_mixin.rb +2 -0
- data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +2 -0
- data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +2 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +2 -0
- data/lib/doorkeeper/models/concerns/scopes.rb +3 -1
- data/lib/doorkeeper/oauth/authorization/code.rb +33 -8
- data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +38 -14
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +2 -0
- data/lib/doorkeeper/oauth/authorization_code_request.rb +29 -2
- data/lib/doorkeeper/oauth/base_request.rb +22 -9
- data/lib/doorkeeper/oauth/base_response.rb +2 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +3 -1
- data/lib/doorkeeper/oauth/client.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +4 -1
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -2
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +5 -5
- data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -3
- data/lib/doorkeeper/oauth/code_request.rb +2 -0
- data/lib/doorkeeper/oauth/code_response.rb +2 -0
- data/lib/doorkeeper/oauth/error.rb +2 -0
- data/lib/doorkeeper/oauth/error_response.rb +21 -3
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +9 -2
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +2 -8
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -0
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +5 -2
- data/lib/doorkeeper/oauth/invalid_token_response.rb +18 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -4
- data/lib/doorkeeper/oauth/pre_authorization.rb +43 -11
- data/lib/doorkeeper/oauth/refresh_token_request.rb +16 -3
- data/lib/doorkeeper/oauth/scopes.rb +3 -1
- data/lib/doorkeeper/oauth/token.rb +7 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +4 -2
- data/lib/doorkeeper/oauth/token_request.rb +2 -0
- data/lib/doorkeeper/oauth/token_response.rb +6 -2
- data/lib/doorkeeper/oauth.rb +13 -0
- data/lib/doorkeeper/orm/active_record/application.rb +75 -12
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
- data/lib/doorkeeper/orm/active_record.rb +4 -0
- data/lib/doorkeeper/rails/helpers.rb +6 -4
- data/lib/doorkeeper/rails/routes/mapper.rb +2 -0
- data/lib/doorkeeper/rails/routes/mapping.rb +2 -0
- data/lib/doorkeeper/rails/routes.rb +23 -8
- 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 +1 -1
- data/lib/doorkeeper/request/client_credentials.rb +1 -1
- data/lib/doorkeeper/request/code.rb +1 -1
- data/lib/doorkeeper/request/password.rb +1 -1
- data/lib/doorkeeper/request/refresh_token.rb +1 -1
- data/lib/doorkeeper/request/strategy.rb +2 -0
- data/lib/doorkeeper/request/token.rb +1 -1
- data/lib/doorkeeper/request.rb +29 -34
- data/lib/doorkeeper/server.rb +2 -0
- data/lib/doorkeeper/stale_records_cleaner.rb +20 -0
- data/lib/doorkeeper/validations.rb +2 -0
- data/lib/doorkeeper/version.rb +6 -24
- data/lib/doorkeeper.rb +20 -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 +96 -13
- data/lib/generators/doorkeeper/templates/migration.rb.erb +2 -3
- 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 +123 -14
- data/spec/controllers/authorizations_controller_spec.rb +334 -51
- data/spec/controllers/protected_resources_controller_spec.rb +60 -18
- data/spec/controllers/token_info_controller_spec.rb +4 -12
- data/spec/controllers/tokens_controller_spec.rb +17 -20
- data/spec/dummy/Rakefile +1 -1
- data/spec/dummy/app/assets/config/manifest.js +2 -0
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +1 -1
- data/spec/dummy/app/controllers/home_controller.rb +1 -2
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/config/boot.rb +2 -4
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/environments/test.rb +5 -6
- data/spec/dummy/config/initializers/doorkeeper.rb +12 -6
- data/spec/dummy/config/initializers/new_framework_defaults.rb +2 -0
- data/spec/dummy/config/initializers/secret_token.rb +1 -1
- data/spec/dummy/config/routes.rb +3 -42
- data/spec/dummy/config.ru +1 -1
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +4 -4
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +1 -1
- 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/dummy/script/rails +4 -3
- data/spec/factories.rb +6 -6
- 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 +5 -2
- 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/templates/routes.rb +0 -1
- data/spec/generators/views_generator_spec.rb +2 -2
- data/spec/grape/grape_integration_spec.rb +2 -2
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
- data/spec/lib/config_spec.rb +105 -39
- data/spec/lib/doorkeeper_spec.rb +6 -131
- 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 +17 -7
- data/spec/lib/oauth/base_request_spec.rb +49 -11
- data/spec/lib/oauth/base_response_spec.rb +1 -1
- data/spec/lib/oauth/client/credentials_spec.rb +2 -4
- data/spec/lib/oauth/client_credentials/creator_spec.rb +5 -1
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +24 -7
- data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
- data/spec/lib/oauth/client_credentials_integration_spec.rb +2 -2
- 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 +5 -3
- data/spec/lib/oauth/code_response_spec.rb +1 -1
- 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 +8 -11
- data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +22 -13
- data/spec/lib/oauth/invalid_token_response_spec.rb +1 -4
- data/spec/lib/oauth/password_access_token_request_spec.rb +53 -6
- data/spec/lib/oauth/pre_authorization_spec.rb +33 -4
- data/spec/lib/oauth/refresh_token_request_spec.rb +22 -14
- data/spec/lib/oauth/scopes_spec.rb +0 -3
- data/spec/lib/oauth/token_request_spec.rb +8 -9
- data/spec/lib/oauth/token_response_spec.rb +0 -1
- data/spec/lib/oauth/token_spec.rb +40 -14
- data/spec/lib/request/strategy_spec.rb +0 -1
- data/spec/lib/server_spec.rb +7 -7
- data/spec/lib/stale_records_cleaner_spec.rb +89 -0
- data/spec/models/doorkeeper/access_grant_spec.rb +44 -1
- data/spec/models/doorkeeper/access_token_spec.rb +80 -32
- data/spec/models/doorkeeper/application_spec.rb +293 -221
- 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 +3 -3
- data/spec/requests/endpoints/token_spec.rb +7 -5
- data/spec/requests/flows/authorization_code_errors_spec.rb +2 -2
- data/spec/requests/flows/authorization_code_spec.rb +258 -2
- data/spec/requests/flows/client_credentials_spec.rb +46 -6
- data/spec/requests/flows/implicit_grant_errors_spec.rb +3 -3
- data/spec/requests/flows/implicit_grant_spec.rb +38 -11
- data/spec/requests/flows/password_spec.rb +61 -3
- data/spec/requests/flows/refresh_token_spec.rb +59 -2
- data/spec/requests/flows/revoke_token_spec.rb +20 -20
- 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 +3 -3
- 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 +20 -0
- data/spec/support/helpers/authorization_request_helper.rb +4 -4
- data/spec/support/helpers/model_helper.rb +8 -4
- data/spec/support/helpers/request_spec_helper.rb +10 -2
- data/spec/support/helpers/url_helper.rb +18 -14
- data/spec/support/http_method_shim.rb +12 -16
- data/spec/support/shared/controllers_shared_context.rb +56 -0
- data/spec/validators/redirect_uri_validator_spec.rb +9 -3
- data/spec/version/version_spec.rb +3 -3
- data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
- metadata +54 -35
- 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,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
feature 'Implicit Grant Flow (feature spec)' do
|
4
4
|
background do
|
@@ -17,6 +17,29 @@ feature 'Implicit Grant Flow (feature spec)' do
|
|
17
17
|
|
18
18
|
i_should_be_on_client_callback @client
|
19
19
|
end
|
20
|
+
|
21
|
+
context 'when application scopes are present and no scope is passed' do
|
22
|
+
background do
|
23
|
+
@client.update_attributes(scopes: 'public write read')
|
24
|
+
end
|
25
|
+
|
26
|
+
scenario 'access token has no scopes' do
|
27
|
+
default_scopes_exist :admin
|
28
|
+
visit authorization_endpoint_url(client: @client, response_type: 'token')
|
29
|
+
click_on 'Authorize'
|
30
|
+
access_token_should_exist_for @client, @resource_owner
|
31
|
+
token = Doorkeeper::AccessToken.first
|
32
|
+
expect(token.scopes).to be_empty
|
33
|
+
end
|
34
|
+
|
35
|
+
scenario 'access token has scopes which are common in application scopees and default scopes' do
|
36
|
+
default_scopes_exist :public, :write
|
37
|
+
visit authorization_endpoint_url(client: @client, response_type: 'token')
|
38
|
+
click_on 'Authorize'
|
39
|
+
access_token_should_exist_for @client, @resource_owner
|
40
|
+
access_token_should_have_scopes :public, :write
|
41
|
+
end
|
42
|
+
end
|
20
43
|
end
|
21
44
|
|
22
45
|
describe 'Implicit Grant Flow (request spec)' do
|
@@ -34,11 +57,13 @@ describe 'Implicit Grant Flow (request spec)' do
|
|
34
57
|
token = client_is_authorized(@client, @resource_owner)
|
35
58
|
|
36
59
|
post "/oauth/authorize",
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
60
|
+
params: {
|
61
|
+
client_id: @client.uid,
|
62
|
+
state: '',
|
63
|
+
redirect_uri: @client.redirect_uri,
|
64
|
+
response_type: 'token',
|
65
|
+
commit: 'Authorize'
|
66
|
+
}
|
42
67
|
|
43
68
|
expect(response.location).not_to include(token.token)
|
44
69
|
end
|
@@ -49,11 +74,13 @@ describe 'Implicit Grant Flow (request spec)' do
|
|
49
74
|
token = client_is_authorized(@client, @resource_owner)
|
50
75
|
|
51
76
|
post "/oauth/authorize",
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
77
|
+
params: {
|
78
|
+
client_id: @client.uid,
|
79
|
+
state: '',
|
80
|
+
redirect_uri: @client.redirect_uri,
|
81
|
+
response_type: 'token',
|
82
|
+
commit: 'Authorize'
|
83
|
+
}
|
57
84
|
|
58
85
|
expect(response.location).to include(token.token)
|
59
86
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Resource Owner Password Credentials Flow not set up' do
|
4
4
|
before do
|
@@ -7,7 +7,7 @@ describe 'Resource Owner Password Credentials Flow not set up' do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
context 'with valid user credentials' do
|
10
|
-
it '
|
10
|
+
it 'does not issue new token' do
|
11
11
|
expect do
|
12
12
|
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
13
13
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
@@ -57,7 +57,11 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
57
57
|
context "when client_secret incorrect" do
|
58
58
|
it "should not issue new token" do
|
59
59
|
expect do
|
60
|
-
post password_token_endpoint_url(
|
60
|
+
post password_token_endpoint_url(
|
61
|
+
client_id: @client.uid,
|
62
|
+
client_secret: 'foobar',
|
63
|
+
resource_owner: @resource_owner
|
64
|
+
)
|
61
65
|
end.not_to(change { Doorkeeper::AccessToken.count })
|
62
66
|
|
63
67
|
expect(response).not_to be_ok
|
@@ -140,6 +144,60 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
140
144
|
end
|
141
145
|
end
|
142
146
|
|
147
|
+
context 'when application scopes are present and differs from configured default scopes and no scope is passed' do
|
148
|
+
before do
|
149
|
+
default_scopes_exist :public
|
150
|
+
@client.update_attributes(scopes: 'abc')
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'issues new token without any scope' do
|
154
|
+
expect do
|
155
|
+
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
156
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
157
|
+
|
158
|
+
token = Doorkeeper::AccessToken.first
|
159
|
+
|
160
|
+
expect(token.application_id).to eq @client.id
|
161
|
+
expect(token.scopes).to be_empty
|
162
|
+
should_have_json 'access_token', token.token
|
163
|
+
should_not_have_json 'scope'
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'when application scopes contain some of the default scopes and no scope is passed' do
|
168
|
+
before do
|
169
|
+
@client.update_attributes(scopes: 'read write public')
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'issues new token with one default scope that are present in application scopes' do
|
173
|
+
default_scopes_exist :public, :admin
|
174
|
+
|
175
|
+
expect do
|
176
|
+
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
177
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
178
|
+
|
179
|
+
token = Doorkeeper::AccessToken.first
|
180
|
+
|
181
|
+
expect(token.application_id).to eq @client.id
|
182
|
+
should_have_json 'access_token', token.token
|
183
|
+
should_have_json 'scope', 'public'
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'issues new token with multiple default scopes that are present in application scopes' do
|
187
|
+
default_scopes_exist :public, :read, :update
|
188
|
+
|
189
|
+
expect do
|
190
|
+
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
191
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
192
|
+
|
193
|
+
token = Doorkeeper::AccessToken.first
|
194
|
+
|
195
|
+
expect(token.application_id).to eq @client.id
|
196
|
+
should_have_json 'access_token', token.token
|
197
|
+
should_have_json 'scope', 'public read'
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
143
201
|
context 'with invalid scopes' do
|
144
202
|
subject do
|
145
203
|
post password_token_endpoint_url(client: @client,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Refresh Token Flow' do
|
4
4
|
before do
|
@@ -6,6 +6,7 @@ describe 'Refresh Token Flow' do
|
|
6
6
|
orm DOORKEEPER_ORM
|
7
7
|
use_refresh_token
|
8
8
|
end
|
9
|
+
|
9
10
|
client_exists
|
10
11
|
end
|
11
12
|
|
@@ -14,7 +15,7 @@ describe 'Refresh Token Flow' do
|
|
14
15
|
authorization_code_exists application: @client
|
15
16
|
end
|
16
17
|
|
17
|
-
it 'client gets the refresh token and
|
18
|
+
it 'client gets the refresh token and refreshes it' do
|
18
19
|
post token_endpoint_url(code: @authorization.token, client: @client)
|
19
20
|
|
20
21
|
token = Doorkeeper::AccessToken.first
|
@@ -95,6 +96,62 @@ describe 'Refresh Token Flow' do
|
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
99
|
+
context "public & private clients" do
|
100
|
+
let(:public_client) do
|
101
|
+
FactoryBot.create(
|
102
|
+
:application,
|
103
|
+
confidential: false
|
104
|
+
)
|
105
|
+
end
|
106
|
+
|
107
|
+
let(:token_for_private_client) do
|
108
|
+
FactoryBot.create(
|
109
|
+
:access_token,
|
110
|
+
application: @client,
|
111
|
+
resource_owner_id: 1,
|
112
|
+
use_refresh_token: true
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
let(:token_for_public_client) do
|
117
|
+
FactoryBot.create(
|
118
|
+
:access_token,
|
119
|
+
application: public_client,
|
120
|
+
resource_owner_id: 1,
|
121
|
+
use_refresh_token: true
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'issues a new token without client_secret when refresh token was issued to a public client' do
|
126
|
+
post refresh_token_endpoint_url(
|
127
|
+
client_id: public_client.uid,
|
128
|
+
refresh_token: token_for_public_client.refresh_token
|
129
|
+
)
|
130
|
+
|
131
|
+
new_token = Doorkeeper::AccessToken.last
|
132
|
+
should_have_json 'access_token', new_token.token
|
133
|
+
should_have_json 'refresh_token', new_token.refresh_token
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'returns an error without credentials' do
|
137
|
+
post refresh_token_endpoint_url(refresh_token: token_for_private_client.refresh_token)
|
138
|
+
|
139
|
+
should_not_have_json 'refresh_token'
|
140
|
+
should_have_json 'error', 'invalid_grant'
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'returns an error with wrong credentials' do
|
144
|
+
post refresh_token_endpoint_url(
|
145
|
+
client_id: '1',
|
146
|
+
client_secret: '1',
|
147
|
+
refresh_token: token_for_private_client.refresh_token
|
148
|
+
)
|
149
|
+
|
150
|
+
should_not_have_json 'refresh_token'
|
151
|
+
should_have_json 'error', 'invalid_client'
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
98
155
|
it 'client gets an error for invalid refresh token' do
|
99
156
|
post refresh_token_endpoint_url(client: @client, refresh_token: 'invalid')
|
100
157
|
should_not_have_json 'refresh_token'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Revoke Token Flow' do
|
4
4
|
before do
|
@@ -10,9 +10,9 @@ describe 'Revoke Token Flow' do
|
|
10
10
|
let(:resource_owner) { User.create!(name: 'John', password: 'sekret') }
|
11
11
|
let(:access_token) do
|
12
12
|
FactoryBot.create(:access_token,
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
application: client_application,
|
14
|
+
resource_owner_id: resource_owner.id,
|
15
|
+
use_refresh_token: true)
|
16
16
|
end
|
17
17
|
|
18
18
|
context 'with authenticated, confidential OAuth 2.0 client/application' do
|
@@ -24,7 +24,7 @@ describe 'Revoke Token Flow' do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should revoke the access token provided' do
|
27
|
-
post revocation_token_endpoint_url, { token: access_token.token }, headers
|
27
|
+
post revocation_token_endpoint_url, params: { token: access_token.token }, headers: headers
|
28
28
|
|
29
29
|
access_token.reload
|
30
30
|
|
@@ -33,7 +33,7 @@ describe 'Revoke Token Flow' do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'should revoke the refresh token provided' do
|
36
|
-
post revocation_token_endpoint_url, { token: access_token.refresh_token }, headers
|
36
|
+
post revocation_token_endpoint_url, params: { token: access_token.refresh_token }, headers: headers
|
37
37
|
|
38
38
|
access_token.reload
|
39
39
|
|
@@ -44,7 +44,7 @@ describe 'Revoke Token Flow' do
|
|
44
44
|
context 'with invalid token to revoke' do
|
45
45
|
it 'should not revoke any tokens and respond successfully' do
|
46
46
|
num_prev_revoked_tokens = Doorkeeper::AccessToken.where(revoked_at: nil).count
|
47
|
-
post revocation_token_endpoint_url, { token: 'I_AM_AN_INVALID_TOKEN' }, headers
|
47
|
+
post revocation_token_endpoint_url, params: { token: 'I_AM_AN_INVALID_TOKEN' }, headers: headers
|
48
48
|
|
49
49
|
# The authorization server responds with HTTP status code 200 even if
|
50
50
|
# token is invalid
|
@@ -60,7 +60,7 @@ describe 'Revoke Token Flow' do
|
|
60
60
|
{ 'HTTP_AUTHORIZATION' => "Basic #{credentials}" }
|
61
61
|
end
|
62
62
|
it 'should not revoke any tokens and respond successfully' do
|
63
|
-
post revocation_token_endpoint_url, { token: access_token.token }, headers
|
63
|
+
post revocation_token_endpoint_url, params: { token: access_token.token }, headers: headers
|
64
64
|
|
65
65
|
access_token.reload
|
66
66
|
|
@@ -71,7 +71,7 @@ describe 'Revoke Token Flow' do
|
|
71
71
|
|
72
72
|
context 'with no credentials and a valid token' do
|
73
73
|
it 'should not revoke any tokens and respond successfully' do
|
74
|
-
post revocation_token_endpoint_url, { token: access_token.token }
|
74
|
+
post revocation_token_endpoint_url, params: { token: access_token.token }
|
75
75
|
|
76
76
|
access_token.reload
|
77
77
|
|
@@ -90,7 +90,7 @@ describe 'Revoke Token Flow' do
|
|
90
90
|
end
|
91
91
|
|
92
92
|
it 'should not revoke the token as its unauthorized' do
|
93
|
-
post revocation_token_endpoint_url, { token: access_token.token }, headers
|
93
|
+
post revocation_token_endpoint_url, params: { token: access_token.token }, headers: headers
|
94
94
|
|
95
95
|
access_token.reload
|
96
96
|
|
@@ -103,13 +103,13 @@ describe 'Revoke Token Flow' do
|
|
103
103
|
context 'with public OAuth 2.0 client/application' do
|
104
104
|
let(:access_token) do
|
105
105
|
FactoryBot.create(:access_token,
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
application: nil,
|
107
|
+
resource_owner_id: resource_owner.id,
|
108
|
+
use_refresh_token: true)
|
109
109
|
end
|
110
110
|
|
111
111
|
it 'should revoke the access token provided' do
|
112
|
-
post revocation_token_endpoint_url, { token: access_token.token }
|
112
|
+
post revocation_token_endpoint_url, params: { token: access_token.token }
|
113
113
|
|
114
114
|
access_token.reload
|
115
115
|
|
@@ -118,7 +118,7 @@ describe 'Revoke Token Flow' do
|
|
118
118
|
end
|
119
119
|
|
120
120
|
it 'should revoke the refresh token provided' do
|
121
|
-
post revocation_token_endpoint_url, { token: access_token.refresh_token }
|
121
|
+
post revocation_token_endpoint_url, params: { token: access_token.refresh_token }
|
122
122
|
|
123
123
|
access_token.reload
|
124
124
|
|
@@ -129,13 +129,13 @@ describe 'Revoke Token Flow' do
|
|
129
129
|
context 'with a valid token issued for a confidential client' do
|
130
130
|
let(:access_token) do
|
131
131
|
FactoryBot.create(:access_token,
|
132
|
-
|
133
|
-
|
134
|
-
|
132
|
+
application: client_application,
|
133
|
+
resource_owner_id: resource_owner.id,
|
134
|
+
use_refresh_token: true)
|
135
135
|
end
|
136
136
|
|
137
137
|
it 'should not revoke the access token provided' do
|
138
|
-
post revocation_token_endpoint_url, { token: access_token.token }
|
138
|
+
post revocation_token_endpoint_url, params: { token: access_token.token }
|
139
139
|
|
140
140
|
access_token.reload
|
141
141
|
|
@@ -144,7 +144,7 @@ describe 'Revoke Token Flow' do
|
|
144
144
|
end
|
145
145
|
|
146
146
|
it 'should not revoke the refresh token provided' do
|
147
|
-
post revocation_token_endpoint_url, { token: access_token.token }
|
147
|
+
post revocation_token_endpoint_url, params: { token: access_token.token }
|
148
148
|
|
149
149
|
access_token.reload
|
150
150
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
feature 'Skip authorization form' do
|
4
4
|
background do
|
@@ -15,13 +15,24 @@ feature 'Skip authorization form' do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
scenario 'skips the authorization and return a new grant code' do
|
18
|
-
client_is_authorized(@client, @resource_owner, scopes:
|
19
|
-
visit authorization_endpoint_url(client: @client)
|
18
|
+
client_is_authorized(@client, @resource_owner, scopes: "public")
|
19
|
+
visit authorization_endpoint_url(client: @client, scope: "public")
|
20
|
+
|
21
|
+
i_should_not_see "Authorize"
|
22
|
+
client_should_be_authorized @client
|
23
|
+
i_should_be_on_client_callback @client
|
24
|
+
url_should_have_param "code", Doorkeeper::AccessGrant.first.token
|
25
|
+
end
|
26
|
+
|
27
|
+
scenario "skips the authorization if other scopes are not requested" do
|
28
|
+
client_exists scopes: "public read write"
|
29
|
+
client_is_authorized(@client, @resource_owner, scopes: "public")
|
30
|
+
visit authorization_endpoint_url(client: @client, scope: "public")
|
20
31
|
|
21
|
-
i_should_not_see
|
32
|
+
i_should_not_see "Authorize"
|
22
33
|
client_should_be_authorized @client
|
23
34
|
i_should_be_on_client_callback @client
|
24
|
-
url_should_have_param
|
35
|
+
url_should_have_param "code", Doorkeeper::AccessGrant.first.token
|
25
36
|
end
|
26
37
|
|
27
38
|
scenario 'does not skip authorization when scopes differ (new request has fewer scopes)' do
|
@@ -43,12 +54,6 @@ feature 'Skip authorization form' do
|
|
43
54
|
access_grant_should_have_scopes :public
|
44
55
|
end
|
45
56
|
|
46
|
-
scenario 'doesn not skip authorization when scopes are greater' do
|
47
|
-
client_is_authorized(@client, @resource_owner, scopes: 'public')
|
48
|
-
visit authorization_endpoint_url(client: @client, scope: 'public write')
|
49
|
-
i_should_see 'Authorize'
|
50
|
-
end
|
51
|
-
|
52
57
|
scenario 'creates grant with new scope when scopes are greater' do
|
53
58
|
client_is_authorized(@client, @resource_owner, scopes: 'public')
|
54
59
|
visit authorization_endpoint_url(client: @client, scope: 'public write')
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
feature 'Private API' do
|
4
4
|
background do
|
@@ -41,10 +41,10 @@ feature 'Private API' do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
scenario 'access token with no default scopes' do
|
44
|
-
Doorkeeper.configuration.instance_eval
|
44
|
+
Doorkeeper.configuration.instance_eval do
|
45
45
|
@default_scopes = Doorkeeper::OAuth::Scopes.from_array([:public])
|
46
46
|
@scopes = default_scopes + optional_scopes
|
47
|
-
|
47
|
+
end
|
48
48
|
@token.update_attribute :scopes, 'dummy'
|
49
49
|
with_access_token_header @token.token
|
50
50
|
visit '/full_protected_resources'
|
@@ -1,27 +1,79 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Custom controller for routes' do
|
4
|
-
|
4
|
+
before :all do
|
5
|
+
Rails.application.routes.disable_clear_and_finalize = true
|
6
|
+
|
7
|
+
Rails.application.routes.draw do
|
8
|
+
scope 'inner_space' do
|
9
|
+
use_doorkeeper scope: 'scope' do
|
10
|
+
controllers authorizations: 'custom_authorizations',
|
11
|
+
tokens: 'custom_authorizations',
|
12
|
+
applications: 'custom_authorizations',
|
13
|
+
token_info: 'custom_authorizations'
|
14
|
+
|
15
|
+
as authorizations: 'custom_auth',
|
16
|
+
tokens: 'custom_token',
|
17
|
+
token_info: 'custom_token_info'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
scope 'space' do
|
22
|
+
use_doorkeeper do
|
23
|
+
controllers authorizations: 'custom_authorizations',
|
24
|
+
tokens: 'custom_authorizations',
|
25
|
+
applications: 'custom_authorizations',
|
26
|
+
token_info: 'custom_authorizations'
|
27
|
+
|
28
|
+
as authorizations: 'custom_auth',
|
29
|
+
tokens: 'custom_token',
|
30
|
+
token_info: 'custom_token_info'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
scope 'outer_space' do
|
35
|
+
use_doorkeeper do
|
36
|
+
controllers authorizations: 'custom_authorizations',
|
37
|
+
tokens: 'custom_authorizations',
|
38
|
+
token_info: 'custom_authorizations'
|
39
|
+
|
40
|
+
as authorizations: 'custom_auth',
|
41
|
+
tokens: 'custom_token',
|
42
|
+
token_info: 'custom_token_info'
|
43
|
+
|
44
|
+
skip_controllers :tokens, :applications, :token_info
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
after :all do
|
51
|
+
Rails.application.routes.clear!
|
52
|
+
|
53
|
+
load File.expand_path('../dummy/config/routes.rb', __dir__)
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'GET /inner_space/scope/authorize routes to custom authorizations controller' do
|
5
57
|
expect(get('/inner_space/scope/authorize')).to route_to('custom_authorizations#new')
|
6
58
|
end
|
7
59
|
|
8
|
-
it 'POST /
|
60
|
+
it 'POST /inner_space/scope/authorize routes to custom authorizations controller' do
|
9
61
|
expect(post('/inner_space/scope/authorize')).to route_to('custom_authorizations#create')
|
10
62
|
end
|
11
63
|
|
12
|
-
it 'DELETE /
|
64
|
+
it 'DELETE /inner_space/scope/authorize routes to custom authorizations controller' do
|
13
65
|
expect(delete('/inner_space/scope/authorize')).to route_to('custom_authorizations#destroy')
|
14
66
|
end
|
15
67
|
|
16
|
-
it 'POST /
|
68
|
+
it 'POST /inner_space/scope/token routes to tokens controller' do
|
17
69
|
expect(post('/inner_space/scope/token')).to route_to('custom_authorizations#create')
|
18
70
|
end
|
19
71
|
|
20
|
-
it 'GET /
|
72
|
+
it 'GET /inner_space/scope/applications routes to applications controller' do
|
21
73
|
expect(get('/inner_space/scope/applications')).to route_to('custom_authorizations#index')
|
22
74
|
end
|
23
75
|
|
24
|
-
it 'GET /
|
76
|
+
it 'GET /inner_space/scope/token/info routes to the token_info controller' do
|
25
77
|
expect(get('/inner_space/scope/token/info')).to route_to('custom_authorizations#show')
|
26
78
|
end
|
27
79
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Default routes' do
|
4
4
|
it 'GET /oauth/authorize routes to authorizations controller' do
|
@@ -33,7 +33,7 @@ describe 'Default routes' do
|
|
33
33
|
expect(get('/oauth/authorized_applications')).to route_to('doorkeeper/authorized_applications#index')
|
34
34
|
end
|
35
35
|
|
36
|
-
it 'GET /oauth/token/info route to authorized
|
36
|
+
it 'GET /oauth/token/info route to authorized TokenInfo controller' do
|
37
37
|
expect(get('/oauth/token/info')).to route_to('doorkeeper/token_info#show')
|
38
38
|
end
|
39
39
|
end
|
@@ -1,6 +1,20 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'Scoped routes' do
|
4
|
+
before :all do
|
5
|
+
Rails.application.routes.disable_clear_and_finalize = true
|
6
|
+
|
7
|
+
Rails.application.routes.draw do
|
8
|
+
use_doorkeeper scope: 'scope'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
after :all do
|
13
|
+
Rails.application.routes.clear!
|
14
|
+
|
15
|
+
load File.expand_path('../dummy/config/routes.rb', __dir__)
|
16
|
+
end
|
17
|
+
|
4
18
|
it 'GET /scope/authorize routes to authorizations controller' do
|
5
19
|
expect(get('/scope/authorize')).to route_to('doorkeeper/authorizations#new')
|
6
20
|
end
|
@@ -25,7 +39,7 @@ describe 'Scoped routes' do
|
|
25
39
|
expect(get('/scope/authorized_applications')).to route_to('doorkeeper/authorized_applications#index')
|
26
40
|
end
|
27
41
|
|
28
|
-
it 'GET /scope/token/info route to
|
42
|
+
it 'GET /scope/token/info route to authorized TokenInfo controller' do
|
29
43
|
expect(get('/scope/token/info')).to route_to('doorkeeper/token_info#show')
|
30
44
|
end
|
31
45
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,55 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '../app'))
|
1
|
+
require 'coveralls'
|
3
2
|
|
4
|
-
|
3
|
+
Coveralls.wear!('rails') do
|
4
|
+
add_filter('/spec/')
|
5
|
+
add_filter('/lib/generators/doorkeeper/templates/')
|
6
|
+
end
|
7
|
+
|
8
|
+
ENV['RAILS_ENV'] ||= 'test'
|
9
|
+
|
10
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
11
|
+
|
12
|
+
require "#{File.dirname(__FILE__)}/support/doorkeeper_rspec.rb"
|
13
|
+
|
14
|
+
DOORKEEPER_ORM = Doorkeeper::RSpec.detect_orm
|
15
|
+
|
16
|
+
require 'dummy/config/environment'
|
17
|
+
require 'rspec/rails'
|
18
|
+
require 'capybara/rspec'
|
19
|
+
require 'database_cleaner'
|
20
|
+
require 'generator_spec/test_case'
|
21
|
+
|
22
|
+
# Load JRuby SQLite3 if in that platform
|
23
|
+
if defined? JRUBY_VERSION
|
24
|
+
require 'jdbc/sqlite3'
|
25
|
+
Jdbc::SQLite3.load_driver
|
26
|
+
end
|
27
|
+
|
28
|
+
Doorkeeper::RSpec.print_configuration_info
|
29
|
+
|
30
|
+
# Remove after dropping support of Rails 4.2
|
31
|
+
require "#{File.dirname(__FILE__)}/support/http_method_shim.rb"
|
32
|
+
|
33
|
+
require "support/orm/#{DOORKEEPER_ORM}"
|
34
|
+
|
35
|
+
Dir["#{File.dirname(__FILE__)}/support/{dependencies,helpers,shared}/*.rb"].each { |file| require file }
|
36
|
+
|
37
|
+
RSpec.configure do |config|
|
38
|
+
config.infer_spec_type_from_file_location!
|
39
|
+
config.mock_with :rspec
|
40
|
+
|
41
|
+
config.infer_base_class_for_anonymous_controllers = false
|
42
|
+
|
43
|
+
config.include RSpec::Rails::RequestExampleGroup, type: :request
|
44
|
+
|
45
|
+
config.before do
|
46
|
+
DatabaseCleaner.start
|
47
|
+
Doorkeeper.configure { orm DOORKEEPER_ORM }
|
48
|
+
end
|
49
|
+
|
50
|
+
config.after do
|
51
|
+
DatabaseCleaner.clean
|
52
|
+
end
|
53
|
+
|
54
|
+
config.order = 'random'
|
55
|
+
end
|