doorkeeper 5.1.0.rc2 → 5.1.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/.hound.yml +2 -1
- data/.rubocop.yml +37 -4
- data/.travis.yml +4 -27
- data/Appraisals +8 -12
- data/Gemfile +6 -2
- data/NEWS.md +16 -0
- data/README.md +11 -2
- data/Rakefile +10 -8
- data/app/controllers/doorkeeper/application_controller.rb +1 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -13
- data/app/controllers/doorkeeper/applications_controller.rb +17 -5
- data/app/controllers/doorkeeper/token_info_controller.rb +1 -1
- data/app/controllers/doorkeeper/tokens_controller.rb +7 -7
- data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
- data/app/validators/redirect_uri_validator.rb +5 -2
- data/app/views/doorkeeper/applications/_form.html.erb +6 -0
- data/bin/console +5 -4
- data/config/locales/en.yml +1 -0
- data/doorkeeper.gemspec +24 -22
- data/gemfiles/rails_5_0.gemfile +2 -1
- data/gemfiles/rails_5_1.gemfile +2 -1
- data/gemfiles/rails_5_2.gemfile +2 -1
- data/gemfiles/rails_6_0.gemfile +1 -0
- data/gemfiles/rails_master.gemfile +1 -0
- data/lib/doorkeeper.rb +68 -66
- data/lib/doorkeeper/config.rb +53 -90
- data/lib/doorkeeper/config/option.rb +64 -0
- data/lib/doorkeeper/engine.rb +1 -1
- data/lib/doorkeeper/grape/authorization_decorator.rb +4 -4
- data/lib/doorkeeper/grape/helpers.rb +3 -3
- data/lib/doorkeeper/helpers/controller.rb +1 -1
- data/lib/doorkeeper/models/access_grant_mixin.rb +4 -2
- data/lib/doorkeeper/models/access_token_mixin.rb +10 -10
- data/lib/doorkeeper/models/application_mixin.rb +1 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +1 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +1 -6
- data/lib/doorkeeper/models/concerns/revocable.rb +2 -1
- data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +2 -0
- data/lib/doorkeeper/oauth.rb +5 -5
- data/lib/doorkeeper/oauth/authorization/code.rb +1 -1
- data/lib/doorkeeper/oauth/authorization/token.rb +9 -6
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +1 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +5 -3
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
- data/lib/doorkeeper/oauth/error_response.rb +5 -5
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +1 -1
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -1
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +2 -1
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +6 -2
- data/lib/doorkeeper/oauth/invalid_token_response.rb +1 -1
- data/lib/doorkeeper/oauth/pre_authorization.rb +4 -3
- data/lib/doorkeeper/oauth/refresh_token_request.rb +1 -1
- data/lib/doorkeeper/oauth/scopes.rb +5 -3
- data/lib/doorkeeper/oauth/token.rb +2 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +4 -4
- data/lib/doorkeeper/oauth/token_response.rb +9 -9
- data/lib/doorkeeper/orm/active_record.rb +6 -6
- data/lib/doorkeeper/orm/active_record/access_grant.rb +5 -12
- data/lib/doorkeeper/orm/active_record/access_token.rb +6 -13
- data/lib/doorkeeper/orm/active_record/application.rb +6 -5
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
- data/lib/doorkeeper/rails/helpers.rb +1 -1
- data/lib/doorkeeper/rails/routes.rb +11 -11
- data/lib/doorkeeper/rails/routes/mapping.rb +7 -7
- data/lib/doorkeeper/rake.rb +1 -1
- data/lib/doorkeeper/rake/db.rake +13 -13
- data/lib/doorkeeper/request.rb +1 -1
- data/lib/doorkeeper/secret_storing/base.rb +7 -6
- data/lib/doorkeeper/secret_storing/bcrypt.rb +4 -3
- data/lib/doorkeeper/secret_storing/plain.rb +4 -4
- data/lib/doorkeeper/secret_storing/sha256_hash.rb +3 -2
- data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
- data/lib/doorkeeper/version.rb +2 -2
- data/lib/generators/doorkeeper/application_owner_generator.rb +10 -9
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +10 -9
- data/lib/generators/doorkeeper/install_generator.rb +11 -9
- data/lib/generators/doorkeeper/migration_generator.rb +9 -9
- data/lib/generators/doorkeeper/pkce_generator.rb +10 -9
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +10 -9
- data/lib/generators/doorkeeper/templates/initializer.rb +30 -5
- data/lib/generators/doorkeeper/templates/migration.rb.erb +15 -7
- data/lib/generators/doorkeeper/views_generator.rb +6 -4
- data/spec/controllers/application_metal_controller_spec.rb +10 -10
- data/spec/controllers/applications_controller_spec.rb +54 -52
- data/spec/controllers/authorizations_controller_spec.rb +136 -142
- data/spec/controllers/protected_resources_controller_spec.rb +78 -76
- data/spec/controllers/token_info_controller_spec.rb +13 -11
- data/spec/controllers/tokens_controller_spec.rb +109 -94
- data/spec/dummy/Rakefile +3 -1
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +2 -0
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -2
- data/spec/dummy/app/controllers/home_controller.rb +5 -3
- data/spec/dummy/app/controllers/metal_controller.rb +2 -0
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +4 -2
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/user.rb +2 -0
- data/spec/dummy/config.ru +3 -1
- data/spec/dummy/config/application.rb +13 -0
- data/spec/dummy/config/environments/development.rb +2 -0
- data/spec/dummy/config/environments/production.rb +2 -0
- data/spec/dummy/config/environments/test.rb +3 -1
- data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
- data/spec/dummy/config/initializers/doorkeeper.rb +5 -2
- data/spec/dummy/config/initializers/secret_token.rb +3 -1
- data/spec/dummy/config/initializers/session_store.rb +3 -1
- data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +17 -10
- data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +2 -0
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/dummy/script/rails +5 -3
- data/spec/factories.rb +5 -3
- data/spec/generators/application_owner_generator_spec.rb +13 -26
- data/spec/generators/confidential_applications_generator_spec.rb +12 -28
- data/spec/generators/install_generator_spec.rb +17 -15
- data/spec/generators/migration_generator_spec.rb +13 -26
- data/spec/generators/pkce_generator_spec.rb +11 -26
- data/spec/generators/previous_refresh_token_generator_spec.rb +16 -29
- data/spec/generators/templates/routes.rb +2 -0
- data/spec/generators/views_generator_spec.rb +14 -12
- data/spec/grape/grape_integration_spec.rb +34 -32
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +9 -7
- data/spec/lib/config_spec.rb +137 -136
- data/spec/lib/doorkeeper_spec.rb +3 -1
- data/spec/lib/models/expirable_spec.rb +12 -10
- data/spec/lib/models/reusable_spec.rb +6 -6
- data/spec/lib/models/revocable_spec.rb +8 -6
- data/spec/lib/models/scopes_spec.rb +19 -17
- data/spec/lib/models/secret_storable_spec.rb +71 -49
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +17 -15
- data/spec/lib/oauth/authorization_code_request_spec.rb +18 -12
- data/spec/lib/oauth/base_request_spec.rb +20 -8
- data/spec/lib/oauth/base_response_spec.rb +3 -1
- data/spec/lib/oauth/client/credentials_spec.rb +24 -22
- data/spec/lib/oauth/client_credentials/creator_spec.rb +13 -11
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -18
- data/spec/lib/oauth/client_credentials/validation_spec.rb +17 -15
- data/spec/lib/oauth/client_credentials_integration_spec.rb +7 -5
- data/spec/lib/oauth/client_credentials_request_spec.rb +27 -21
- data/spec/lib/oauth/client_spec.rb +15 -13
- data/spec/lib/oauth/code_request_spec.rb +8 -6
- data/spec/lib/oauth/code_response_spec.rb +9 -7
- data/spec/lib/oauth/error_response_spec.rb +14 -12
- data/spec/lib/oauth/error_spec.rb +4 -2
- data/spec/lib/oauth/forbidden_token_response_spec.rb +7 -5
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +35 -33
- data/spec/lib/oauth/helpers/unique_token_spec.rb +8 -6
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +103 -101
- data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +52 -34
- data/spec/lib/oauth/pre_authorization_spec.rb +64 -62
- data/spec/lib/oauth/refresh_token_request_spec.rb +36 -33
- data/spec/lib/oauth/scopes_spec.rb +63 -61
- data/spec/lib/oauth/token_request_spec.rb +66 -26
- data/spec/lib/oauth/token_response_spec.rb +39 -37
- data/spec/lib/oauth/token_spec.rb +51 -49
- data/spec/lib/request/strategy_spec.rb +3 -1
- data/spec/lib/secret_storing/base_spec.rb +23 -23
- data/spec/lib/secret_storing/bcrypt_spec.rb +18 -18
- data/spec/lib/secret_storing/plain_spec.rb +17 -17
- data/spec/lib/secret_storing/sha256_hash_spec.rb +16 -16
- data/spec/lib/server_spec.rb +16 -14
- data/spec/lib/stale_records_cleaner_spec.rb +17 -17
- data/spec/models/doorkeeper/access_grant_spec.rb +30 -26
- data/spec/models/doorkeeper/access_token_spec.rb +97 -95
- data/spec/models/doorkeeper/application_spec.rb +98 -57
- data/spec/requests/applications/applications_request_spec.rb +98 -66
- data/spec/requests/applications/authorized_applications_spec.rb +20 -18
- data/spec/requests/endpoints/authorization_spec.rb +25 -23
- data/spec/requests/endpoints/token_spec.rb +38 -36
- data/spec/requests/flows/authorization_code_errors_spec.rb +26 -24
- data/spec/requests/flows/authorization_code_spec.rb +161 -159
- data/spec/requests/flows/client_credentials_spec.rb +53 -51
- data/spec/requests/flows/implicit_grant_errors_spec.rb +10 -8
- data/spec/requests/flows/implicit_grant_spec.rb +27 -25
- data/spec/requests/flows/password_spec.rb +56 -54
- data/spec/requests/flows/refresh_token_spec.rb +45 -43
- data/spec/requests/flows/revoke_token_spec.rb +29 -27
- data/spec/requests/flows/skip_authorization_spec.rb +23 -21
- data/spec/requests/protected_resources/metal_spec.rb +7 -5
- data/spec/requests/protected_resources/private_api_spec.rb +35 -33
- data/spec/routing/custom_controller_routes_spec.rb +67 -65
- data/spec/routing/default_routes_spec.rb +22 -20
- data/spec/routing/scoped_routes_spec.rb +20 -18
- data/spec/spec_helper.rb +14 -13
- data/spec/spec_helper_integration.rb +3 -1
- data/spec/support/dependencies/factory_bot.rb +3 -1
- data/spec/support/doorkeeper_rspec.rb +3 -1
- data/spec/support/helpers/access_token_request_helper.rb +3 -1
- data/spec/support/helpers/authorization_request_helper.rb +4 -2
- data/spec/support/helpers/config_helper.rb +2 -0
- data/spec/support/helpers/model_helper.rb +3 -1
- data/spec/support/helpers/request_spec_helper.rb +5 -3
- data/spec/support/helpers/url_helper.rb +9 -7
- data/spec/support/http_method_shim.rb +4 -9
- data/spec/support/orm/active_record.rb +3 -1
- data/spec/support/shared/controllers_shared_context.rb +18 -16
- data/spec/support/shared/hashing_shared_context.rb +3 -3
- data/spec/support/shared/models_shared_examples.rb +12 -10
- data/spec/validators/redirect_uri_validator_spec.rb +74 -45
- data/spec/version/version_spec.rb +7 -5
- metadata +12 -16
- data/gemfiles/rails_4_2.gemfile +0 -17
- data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -8
- data/spec/support/ruby_2_6_rails_4_2_patch.rb +0 -14
@@ -1,62 +1,64 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe "Client Credentials Request" do
|
4
6
|
let(:client) { FactoryBot.create :application }
|
5
7
|
|
6
|
-
context
|
7
|
-
it
|
8
|
+
context "a valid request" do
|
9
|
+
it "authorizes the client and returns the token response" do
|
8
10
|
headers = authorization client.uid, client.secret
|
9
|
-
params = { grant_type:
|
11
|
+
params = { grant_type: "client_credentials" }
|
10
12
|
|
11
|
-
post
|
13
|
+
post "/oauth/token", params: params, headers: headers
|
12
14
|
|
13
|
-
should_have_json
|
14
|
-
should_have_json_within
|
15
|
-
should_not_have_json
|
16
|
-
should_not_have_json
|
15
|
+
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
16
|
+
should_have_json_within "expires_in", Doorkeeper.configuration.access_token_expires_in, 1
|
17
|
+
should_not_have_json "scope"
|
18
|
+
should_not_have_json "refresh_token"
|
17
19
|
|
18
|
-
should_not_have_json
|
19
|
-
should_not_have_json
|
20
|
+
should_not_have_json "error"
|
21
|
+
should_not_have_json "error_description"
|
20
22
|
end
|
21
23
|
|
22
|
-
context
|
24
|
+
context "with scopes" do
|
23
25
|
before do
|
24
26
|
optional_scopes_exist :write
|
25
27
|
default_scopes_exist :public
|
26
28
|
end
|
27
29
|
|
28
|
-
it
|
30
|
+
it "adds the scope to the token an returns in the response" do
|
29
31
|
headers = authorization client.uid, client.secret
|
30
|
-
params = { grant_type:
|
32
|
+
params = { grant_type: "client_credentials", scope: "write" }
|
31
33
|
|
32
|
-
post
|
34
|
+
post "/oauth/token", params: params, headers: headers
|
33
35
|
|
34
|
-
should_have_json
|
35
|
-
should_have_json
|
36
|
+
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
37
|
+
should_have_json "scope", "write"
|
36
38
|
end
|
37
39
|
|
38
|
-
context
|
39
|
-
it
|
40
|
+
context "that are default" do
|
41
|
+
it "adds the scope to the token an returns in the response" do
|
40
42
|
headers = authorization client.uid, client.secret
|
41
|
-
params = { grant_type:
|
43
|
+
params = { grant_type: "client_credentials", scope: "public" }
|
42
44
|
|
43
|
-
post
|
45
|
+
post "/oauth/token", params: params, headers: headers
|
44
46
|
|
45
|
-
should_have_json
|
46
|
-
should_have_json
|
47
|
+
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
48
|
+
should_have_json "scope", "public"
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
50
|
-
context
|
51
|
-
it
|
52
|
+
context "that are invalid" do
|
53
|
+
it "does not authorize the client and returns the error" do
|
52
54
|
headers = authorization client.uid, client.secret
|
53
|
-
params = { grant_type:
|
55
|
+
params = { grant_type: "client_credentials", scope: "random" }
|
54
56
|
|
55
|
-
post
|
57
|
+
post "/oauth/token", params: params, headers: headers
|
56
58
|
|
57
|
-
should_have_json
|
58
|
-
should_have_json
|
59
|
-
should_not_have_json
|
59
|
+
should_have_json "error", "invalid_scope"
|
60
|
+
should_have_json "error_description", translated_error_message(:invalid_scope)
|
61
|
+
should_not_have_json "access_token"
|
60
62
|
|
61
63
|
expect(response.status).to eq(400)
|
62
64
|
end
|
@@ -64,56 +66,56 @@ describe 'Client Credentials Request' do
|
|
64
66
|
end
|
65
67
|
end
|
66
68
|
|
67
|
-
context
|
69
|
+
context "when application scopes contain some of the default scopes and no scope is passed" do
|
68
70
|
before do
|
69
|
-
client.update(scopes:
|
71
|
+
client.update(scopes: "read write public")
|
70
72
|
end
|
71
73
|
|
72
|
-
it
|
74
|
+
it "issues new token with one default scope that are present in application scopes" do
|
73
75
|
default_scopes_exist :public
|
74
76
|
|
75
77
|
headers = authorization client.uid, client.secret
|
76
|
-
params = { grant_type:
|
78
|
+
params = { grant_type: "client_credentials" }
|
77
79
|
|
78
80
|
expect do
|
79
|
-
post
|
81
|
+
post "/oauth/token", params: params, headers: headers
|
80
82
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
81
83
|
|
82
84
|
token = Doorkeeper::AccessToken.first
|
83
85
|
|
84
86
|
expect(token.application_id).to eq client.id
|
85
|
-
should_have_json
|
86
|
-
should_have_json
|
87
|
+
should_have_json "access_token", token.token
|
88
|
+
should_have_json "scope", "public"
|
87
89
|
end
|
88
90
|
|
89
|
-
it
|
91
|
+
it "issues new token with multiple default scopes that are present in application scopes" do
|
90
92
|
default_scopes_exist :public, :read, :update
|
91
93
|
|
92
94
|
headers = authorization client.uid, client.secret
|
93
|
-
params = { grant_type:
|
95
|
+
params = { grant_type: "client_credentials" }
|
94
96
|
|
95
97
|
expect do
|
96
|
-
post
|
98
|
+
post "/oauth/token", params: params, headers: headers
|
97
99
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
98
100
|
|
99
101
|
token = Doorkeeper::AccessToken.first
|
100
102
|
|
101
103
|
expect(token.application_id).to eq client.id
|
102
|
-
should_have_json
|
103
|
-
should_have_json
|
104
|
+
should_have_json "access_token", token.token
|
105
|
+
should_have_json "scope", "public read"
|
104
106
|
end
|
105
107
|
end
|
106
108
|
|
107
|
-
context
|
108
|
-
it
|
109
|
+
context "an invalid request" do
|
110
|
+
it "does not authorize the client and returns the error" do
|
109
111
|
headers = {}
|
110
|
-
params = { grant_type:
|
112
|
+
params = { grant_type: "client_credentials" }
|
111
113
|
|
112
|
-
post
|
114
|
+
post "/oauth/token", params: params, headers: headers
|
113
115
|
|
114
|
-
should_have_json
|
115
|
-
should_have_json
|
116
|
-
should_not_have_json
|
116
|
+
should_have_json "error", "invalid_client"
|
117
|
+
should_have_json "error_description", translated_error_message(:invalid_client)
|
118
|
+
should_not_have_json "access_token"
|
117
119
|
|
118
120
|
expect(response.status).to eq(401)
|
119
121
|
end
|
@@ -121,6 +123,6 @@ describe 'Client Credentials Request' do
|
|
121
123
|
|
122
124
|
def authorization(username, password)
|
123
125
|
credentials = ActionController::HttpAuthentication::Basic.encode_credentials username, password
|
124
|
-
{
|
126
|
+
{ "HTTP_AUTHORIZATION" => credentials }
|
125
127
|
end
|
126
128
|
end
|
@@ -1,8 +1,10 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
feature "Implicit Grant Flow Errors" do
|
4
6
|
background do
|
5
|
-
config_is_set(:authenticate_resource_owner) { User.first || redirect_to(
|
7
|
+
config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
|
6
8
|
config_is_set(:grant_flows, ["implicit"])
|
7
9
|
client_exists
|
8
10
|
create_resource_owner
|
@@ -15,17 +17,17 @@ feature 'Implicit Grant Flow Errors' do
|
|
15
17
|
|
16
18
|
[
|
17
19
|
%i[client_id invalid_client],
|
18
|
-
%i[redirect_uri invalid_redirect_uri]
|
20
|
+
%i[redirect_uri invalid_redirect_uri],
|
19
21
|
].each do |error|
|
20
22
|
scenario "displays #{error.last} error for invalid #{error.first}" do
|
21
|
-
visit authorization_endpoint_url(client: @client, error.first =>
|
22
|
-
i_should_not_see
|
23
|
+
visit authorization_endpoint_url(client: @client, error.first => "invalid", response_type: "token")
|
24
|
+
i_should_not_see "Authorize"
|
23
25
|
i_should_see_translated_error_message error.last
|
24
26
|
end
|
25
27
|
|
26
28
|
scenario "displays #{error.last} error when #{error.first} is missing" do
|
27
|
-
visit authorization_endpoint_url(client: @client, error.first =>
|
28
|
-
i_should_not_see
|
29
|
+
visit authorization_endpoint_url(client: @client, error.first => "", response_type: "token")
|
30
|
+
i_should_not_see "Authorize"
|
29
31
|
i_should_see_translated_error_message error.last
|
30
32
|
end
|
31
33
|
end
|
@@ -1,57 +1,59 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
feature "Implicit Grant Flow (feature spec)" do
|
4
6
|
background do
|
5
|
-
config_is_set(:authenticate_resource_owner) { User.first || redirect_to(
|
7
|
+
config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
|
6
8
|
config_is_set(:grant_flows, ["implicit"])
|
7
9
|
client_exists
|
8
10
|
create_resource_owner
|
9
11
|
sign_in
|
10
12
|
end
|
11
13
|
|
12
|
-
scenario
|
13
|
-
visit authorization_endpoint_url(client: @client, response_type:
|
14
|
-
click_on
|
14
|
+
scenario "resource owner authorizes the client" do
|
15
|
+
visit authorization_endpoint_url(client: @client, response_type: "token")
|
16
|
+
click_on "Authorize"
|
15
17
|
|
16
18
|
access_token_should_exist_for @client, @resource_owner
|
17
19
|
|
18
20
|
i_should_be_on_client_callback @client
|
19
21
|
end
|
20
22
|
|
21
|
-
context
|
23
|
+
context "when application scopes are present and no scope is passed" do
|
22
24
|
background do
|
23
|
-
@client.update(scopes:
|
25
|
+
@client.update(scopes: "public write read")
|
24
26
|
end
|
25
27
|
|
26
|
-
scenario
|
28
|
+
scenario "access token has no scopes" do
|
27
29
|
default_scopes_exist :admin
|
28
|
-
visit authorization_endpoint_url(client: @client, response_type:
|
29
|
-
click_on
|
30
|
+
visit authorization_endpoint_url(client: @client, response_type: "token")
|
31
|
+
click_on "Authorize"
|
30
32
|
access_token_should_exist_for @client, @resource_owner
|
31
33
|
token = Doorkeeper::AccessToken.first
|
32
34
|
expect(token.scopes).to be_empty
|
33
35
|
end
|
34
36
|
|
35
|
-
scenario
|
37
|
+
scenario "access token has scopes which are common in application scopees and default scopes" do
|
36
38
|
default_scopes_exist :public, :write
|
37
|
-
visit authorization_endpoint_url(client: @client, response_type:
|
38
|
-
click_on
|
39
|
+
visit authorization_endpoint_url(client: @client, response_type: "token")
|
40
|
+
click_on "Authorize"
|
39
41
|
access_token_should_exist_for @client, @resource_owner
|
40
42
|
access_token_should_have_scopes :public, :write
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
45
|
-
describe
|
47
|
+
describe "Implicit Grant Flow (request spec)" do
|
46
48
|
before do
|
47
|
-
config_is_set(:authenticate_resource_owner) { User.first || redirect_to(
|
49
|
+
config_is_set(:authenticate_resource_owner) { User.first || redirect_to("/sign_in") }
|
48
50
|
config_is_set(:grant_flows, ["implicit"])
|
49
51
|
client_exists
|
50
52
|
create_resource_owner
|
51
53
|
end
|
52
54
|
|
53
|
-
context
|
54
|
-
it
|
55
|
+
context "token reuse" do
|
56
|
+
it "should return a new token each request" do
|
55
57
|
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(false)
|
56
58
|
|
57
59
|
token = client_is_authorized(@client, @resource_owner)
|
@@ -59,16 +61,16 @@ describe 'Implicit Grant Flow (request spec)' do
|
|
59
61
|
post "/oauth/authorize",
|
60
62
|
params: {
|
61
63
|
client_id: @client.uid,
|
62
|
-
state:
|
64
|
+
state: "",
|
63
65
|
redirect_uri: @client.redirect_uri,
|
64
|
-
response_type:
|
65
|
-
commit:
|
66
|
+
response_type: "token",
|
67
|
+
commit: "Authorize",
|
66
68
|
}
|
67
69
|
|
68
70
|
expect(response.location).not_to include(token.token)
|
69
71
|
end
|
70
72
|
|
71
|
-
it
|
73
|
+
it "should return the same token if it is still accessible" do
|
72
74
|
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
73
75
|
|
74
76
|
token = client_is_authorized(@client, @resource_owner)
|
@@ -76,10 +78,10 @@ describe 'Implicit Grant Flow (request spec)' do
|
|
76
78
|
post "/oauth/authorize",
|
77
79
|
params: {
|
78
80
|
client_id: @client.uid,
|
79
|
-
state:
|
81
|
+
state: "",
|
80
82
|
redirect_uri: @client.redirect_uri,
|
81
|
-
response_type:
|
82
|
-
commit:
|
83
|
+
response_type: "token",
|
84
|
+
commit: "Authorize",
|
83
85
|
}
|
84
86
|
|
85
87
|
expect(response.location).to include(token.token)
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe "Resource Owner Password Credentials Flow not set up" do
|
4
6
|
before do
|
5
7
|
client_exists
|
6
8
|
create_resource_owner
|
7
9
|
end
|
8
10
|
|
9
|
-
context
|
10
|
-
it
|
11
|
+
context "with valid user credentials" do
|
12
|
+
it "does not issue new token" do
|
11
13
|
expect do
|
12
14
|
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
13
15
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
@@ -15,8 +17,8 @@ describe 'Resource Owner Password Credentials Flow not set up' do
|
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
|
-
describe
|
19
|
-
let(:client_attributes) { {} }
|
20
|
+
describe "Resource Owner Password Credentials Flow" do
|
21
|
+
let(:client_attributes) { { redirect_uri: nil } }
|
20
22
|
|
21
23
|
before do
|
22
24
|
config_is_set(:grant_flows, ["password"])
|
@@ -25,7 +27,7 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
25
27
|
create_resource_owner
|
26
28
|
end
|
27
29
|
|
28
|
-
context
|
30
|
+
context "with valid user credentials" do
|
29
31
|
context "with non-confidential/public client" do
|
30
32
|
let(:client_attributes) { { confidential: false } }
|
31
33
|
|
@@ -38,7 +40,7 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
38
40
|
token = Doorkeeper::AccessToken.first
|
39
41
|
|
40
42
|
expect(token.application_id).to eq @client.id
|
41
|
-
should_have_json
|
43
|
+
should_have_json "access_token", token.token
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
@@ -51,7 +53,7 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
51
53
|
token = Doorkeeper::AccessToken.first
|
52
54
|
|
53
55
|
expect(token.application_id).to eq @client.id
|
54
|
-
should_have_json
|
56
|
+
should_have_json "access_token", token.token
|
55
57
|
end
|
56
58
|
|
57
59
|
context "when client_secret incorrect" do
|
@@ -59,13 +61,13 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
59
61
|
expect do
|
60
62
|
post password_token_endpoint_url(
|
61
63
|
client_id: @client.uid,
|
62
|
-
client_secret:
|
64
|
+
client_secret: "foobar",
|
63
65
|
resource_owner: @resource_owner
|
64
66
|
)
|
65
67
|
end.not_to(change { Doorkeeper::AccessToken.count })
|
66
68
|
|
67
69
|
expect(response.status).to eq(401)
|
68
|
-
should_have_json
|
70
|
+
should_have_json "error", "invalid_client"
|
69
71
|
end
|
70
72
|
end
|
71
73
|
end
|
@@ -80,7 +82,7 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
80
82
|
token = Doorkeeper::AccessToken.first
|
81
83
|
|
82
84
|
expect(token.application_id).to eq @client.id
|
83
|
-
should_have_json
|
85
|
+
should_have_json "access_token", token.token
|
84
86
|
end
|
85
87
|
|
86
88
|
context "when client_secret absent" do
|
@@ -90,12 +92,12 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
90
92
|
end.not_to(change { Doorkeeper::AccessToken.count })
|
91
93
|
|
92
94
|
expect(response.status).to eq(401)
|
93
|
-
should_have_json
|
95
|
+
should_have_json "error", "invalid_client"
|
94
96
|
end
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
98
|
-
it
|
100
|
+
it "should issue new token without client credentials" do
|
99
101
|
expect do
|
100
102
|
post password_token_endpoint_url(resource_owner: @resource_owner)
|
101
103
|
end.to(change { Doorkeeper::AccessToken.count }.by(1))
|
@@ -103,20 +105,20 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
103
105
|
token = Doorkeeper::AccessToken.first
|
104
106
|
|
105
107
|
expect(token.application_id).to be_nil
|
106
|
-
should_have_json
|
108
|
+
should_have_json "access_token", token.token
|
107
109
|
end
|
108
110
|
|
109
|
-
it
|
111
|
+
it "should issue a refresh token if enabled" do
|
110
112
|
config_is_set(:refresh_token_enabled, true)
|
111
113
|
|
112
114
|
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
113
115
|
|
114
116
|
token = Doorkeeper::AccessToken.first
|
115
117
|
|
116
|
-
should_have_json
|
118
|
+
should_have_json "refresh_token", token.refresh_token
|
117
119
|
end
|
118
120
|
|
119
|
-
it
|
121
|
+
it "should return the same token if it is still accessible" do
|
120
122
|
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
121
123
|
|
122
124
|
client_is_authorized(@client, @resource_owner)
|
@@ -124,35 +126,35 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
124
126
|
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
125
127
|
|
126
128
|
expect(Doorkeeper::AccessToken.count).to be(1)
|
127
|
-
should_have_json
|
129
|
+
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
128
130
|
end
|
129
131
|
|
130
|
-
context
|
132
|
+
context "with valid, default scope" do
|
131
133
|
before do
|
132
134
|
default_scopes_exist :public
|
133
135
|
end
|
134
136
|
|
135
|
-
it
|
137
|
+
it "should issue new token" do
|
136
138
|
expect do
|
137
|
-
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner, scope:
|
139
|
+
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner, scope: "public")
|
138
140
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
139
141
|
|
140
142
|
token = Doorkeeper::AccessToken.first
|
141
143
|
|
142
144
|
expect(token.application_id).to eq @client.id
|
143
|
-
should_have_json
|
144
|
-
should_have_json
|
145
|
+
should_have_json "access_token", token.token
|
146
|
+
should_have_json "scope", "public"
|
145
147
|
end
|
146
148
|
end
|
147
149
|
end
|
148
150
|
|
149
|
-
context
|
151
|
+
context "when application scopes are present and differs from configured default scopes and no scope is passed" do
|
150
152
|
before do
|
151
153
|
default_scopes_exist :public
|
152
|
-
@client.update(scopes:
|
154
|
+
@client.update(scopes: "abc")
|
153
155
|
end
|
154
156
|
|
155
|
-
it
|
157
|
+
it "issues new token without any scope" do
|
156
158
|
expect do
|
157
159
|
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
158
160
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
@@ -161,17 +163,17 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
161
163
|
|
162
164
|
expect(token.application_id).to eq @client.id
|
163
165
|
expect(token.scopes).to be_empty
|
164
|
-
should_have_json
|
165
|
-
should_not_have_json
|
166
|
+
should_have_json "access_token", token.token
|
167
|
+
should_not_have_json "scope"
|
166
168
|
end
|
167
169
|
end
|
168
170
|
|
169
|
-
context
|
171
|
+
context "when application scopes contain some of the default scopes and no scope is passed" do
|
170
172
|
before do
|
171
|
-
@client.update(scopes:
|
173
|
+
@client.update(scopes: "read write public")
|
172
174
|
end
|
173
175
|
|
174
|
-
it
|
176
|
+
it "issues new token with one default scope that are present in application scopes" do
|
175
177
|
default_scopes_exist :public, :admin
|
176
178
|
|
177
179
|
expect do
|
@@ -181,11 +183,11 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
181
183
|
token = Doorkeeper::AccessToken.first
|
182
184
|
|
183
185
|
expect(token.application_id).to eq @client.id
|
184
|
-
should_have_json
|
185
|
-
should_have_json
|
186
|
+
should_have_json "access_token", token.token
|
187
|
+
should_have_json "scope", "public"
|
186
188
|
end
|
187
189
|
|
188
|
-
it
|
190
|
+
it "issues new token with multiple default scopes that are present in application scopes" do
|
189
191
|
default_scopes_exist :public, :read, :update
|
190
192
|
|
191
193
|
expect do
|
@@ -195,62 +197,62 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
195
197
|
token = Doorkeeper::AccessToken.first
|
196
198
|
|
197
199
|
expect(token.application_id).to eq @client.id
|
198
|
-
should_have_json
|
199
|
-
should_have_json
|
200
|
+
should_have_json "access_token", token.token
|
201
|
+
should_have_json "scope", "public read"
|
200
202
|
end
|
201
203
|
end
|
202
204
|
|
203
|
-
context
|
205
|
+
context "with invalid scopes" do
|
204
206
|
subject do
|
205
207
|
post password_token_endpoint_url(client: @client,
|
206
208
|
resource_owner: @resource_owner,
|
207
|
-
scope:
|
209
|
+
scope: "random")
|
208
210
|
end
|
209
211
|
|
210
|
-
it
|
212
|
+
it "should not issue new token" do
|
211
213
|
expect { subject }.to_not(change { Doorkeeper::AccessToken.count })
|
212
214
|
end
|
213
215
|
|
214
|
-
it
|
216
|
+
it "should return invalid_scope error" do
|
215
217
|
subject
|
216
|
-
should_have_json
|
217
|
-
should_have_json
|
218
|
-
should_not_have_json
|
218
|
+
should_have_json "error", "invalid_scope"
|
219
|
+
should_have_json "error_description", translated_error_message(:invalid_scope)
|
220
|
+
should_not_have_json "access_token"
|
219
221
|
|
220
222
|
expect(response.status).to eq(400)
|
221
223
|
end
|
222
224
|
end
|
223
225
|
|
224
|
-
context
|
225
|
-
it
|
226
|
+
context "with invalid user credentials" do
|
227
|
+
it "should not issue new token with bad password" do
|
226
228
|
expect do
|
227
229
|
post password_token_endpoint_url(client: @client,
|
228
230
|
resource_owner_username: @resource_owner.name,
|
229
|
-
resource_owner_password:
|
231
|
+
resource_owner_password: "wrongpassword")
|
230
232
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
231
233
|
end
|
232
234
|
|
233
|
-
it
|
235
|
+
it "should not issue new token without credentials" do
|
234
236
|
expect do
|
235
237
|
post password_token_endpoint_url(client: @client)
|
236
238
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
237
239
|
end
|
238
240
|
end
|
239
241
|
|
240
|
-
context
|
241
|
-
it
|
242
|
+
context "with invalid confidential client credentials" do
|
243
|
+
it "should not issue new token with bad client credentials" do
|
242
244
|
expect do
|
243
245
|
post password_token_endpoint_url(client_id: @client.uid,
|
244
|
-
client_secret:
|
246
|
+
client_secret: "bad_secret",
|
245
247
|
resource_owner: @resource_owner)
|
246
248
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
247
249
|
end
|
248
250
|
end
|
249
251
|
|
250
|
-
context
|
251
|
-
it
|
252
|
+
context "with invalid public client id" do
|
253
|
+
it "should not issue new token with bad client id" do
|
252
254
|
expect do
|
253
|
-
post password_token_endpoint_url(client_id:
|
255
|
+
post password_token_endpoint_url(client_id: "bad_id", resource_owner: @resource_owner)
|
254
256
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
255
257
|
end
|
256
258
|
end
|