doorkeeper 5.0.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.hound.yml +2 -1
- data/.rubocop.yml +37 -4
- data/.travis.yml +16 -21
- data/Appraisals +29 -7
- data/Dangerfile +67 -0
- data/Gemfile +19 -5
- data/NEWS.md +107 -10
- data/README.md +75 -470
- data/Rakefile +10 -8
- data/app/controllers/doorkeeper/application_controller.rb +3 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +4 -13
- data/app/controllers/doorkeeper/applications_controller.rb +21 -7
- data/app/controllers/doorkeeper/authorizations_controller.rb +3 -3
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -0
- data/app/controllers/doorkeeper/token_info_controller.rb +4 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +13 -11
- data/app/helpers/doorkeeper/dashboard_helper.rb +3 -1
- data/app/validators/redirect_uri_validator.rb +7 -2
- data/app/views/doorkeeper/applications/_form.html.erb +6 -0
- data/app/views/doorkeeper/applications/show.html.erb +1 -1
- data/app/views/layouts/doorkeeper/admin.html.erb +5 -3
- data/bin/console +16 -0
- data/config/locales/en.yml +1 -0
- data/doorkeeper.gemspec +28 -24
- data/gemfiles/rails_5_0.gemfile +9 -4
- data/gemfiles/rails_5_1.gemfile +9 -4
- data/gemfiles/rails_5_2.gemfile +10 -5
- data/gemfiles/rails_6_0.gemfile +17 -0
- data/gemfiles/rails_master.gemfile +9 -9
- data/lib/doorkeeper/config/option.rb +64 -0
- data/lib/doorkeeper/config.rb +197 -76
- data/lib/doorkeeper/engine.rb +3 -1
- data/lib/doorkeeper/errors.rb +17 -0
- data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
- data/lib/doorkeeper/grape/helpers.rb +5 -3
- data/lib/doorkeeper/helpers/controller.rb +5 -2
- data/lib/doorkeeper/models/access_grant_mixin.rb +25 -6
- data/lib/doorkeeper/models/access_token_mixin.rb +68 -22
- data/lib/doorkeeper/models/application_mixin.rb +45 -1
- data/lib/doorkeeper/models/concerns/accessible.rb +2 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +6 -2
- data/lib/doorkeeper/models/concerns/orderable.rb +2 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +3 -6
- data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +4 -1
- data/lib/doorkeeper/models/concerns/scopes.rb +7 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +108 -0
- data/lib/doorkeeper/oauth/authorization/code.rb +4 -2
- data/lib/doorkeeper/oauth/authorization/context.rb +2 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +14 -7
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +3 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +8 -4
- data/lib/doorkeeper/oauth/base_request.rb +2 -0
- data/lib/doorkeeper/oauth/base_response.rb +2 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +2 -0
- data/lib/doorkeeper/oauth/client.rb +3 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -0
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +2 -0
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +7 -4
- data/lib/doorkeeper/oauth/client_credentials_request.rb +3 -1
- data/lib/doorkeeper/oauth/code_request.rb +2 -0
- data/lib/doorkeeper/oauth/code_response.rb +4 -2
- data/lib/doorkeeper/oauth/error.rb +2 -0
- data/lib/doorkeeper/oauth/error_response.rb +20 -6
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +10 -3
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +25 -8
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +15 -1
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +42 -3
- data/lib/doorkeeper/oauth/invalid_token_response.rb +22 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +13 -5
- data/lib/doorkeeper/oauth/refresh_token_request.rb +15 -4
- data/lib/doorkeeper/oauth/scopes.rb +7 -3
- data/lib/doorkeeper/oauth/token.rb +4 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +76 -8
- data/lib/doorkeeper/oauth/token_request.rb +2 -0
- data/lib/doorkeeper/oauth/token_response.rb +11 -9
- data/lib/doorkeeper/oauth.rb +5 -5
- data/lib/doorkeeper/orm/active_record/access_grant.rb +27 -13
- data/lib/doorkeeper/orm/active_record/access_token.rb +6 -13
- data/lib/doorkeeper/orm/active_record/application.rb +26 -7
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +10 -3
- data/lib/doorkeeper/orm/active_record.rb +8 -6
- data/lib/doorkeeper/rails/helpers.rb +5 -1
- data/lib/doorkeeper/rails/routes/mapper.rb +2 -0
- data/lib/doorkeeper/rails/routes/mapping.rb +9 -7
- data/lib/doorkeeper/rails/routes.rb +19 -12
- data/lib/doorkeeper/rake/db.rake +17 -17
- data/lib/doorkeeper/rake.rb +1 -1
- data/lib/doorkeeper/request/authorization_code.rb +2 -0
- data/lib/doorkeeper/request/client_credentials.rb +2 -0
- data/lib/doorkeeper/request/code.rb +2 -0
- data/lib/doorkeeper/request/password.rb +2 -0
- data/lib/doorkeeper/request/refresh_token.rb +2 -0
- data/lib/doorkeeper/request/strategy.rb +2 -0
- data/lib/doorkeeper/request/token.rb +2 -0
- data/lib/doorkeeper/request.rb +3 -1
- data/lib/doorkeeper/secret_storing/base.rb +64 -0
- data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
- data/lib/doorkeeper/secret_storing/plain.rb +33 -0
- data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
- 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 +4 -2
- data/lib/doorkeeper.rb +69 -59
- 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 +138 -13
- data/lib/generators/doorkeeper/templates/migration.rb.erb +17 -10
- data/lib/generators/doorkeeper/views_generator.rb +6 -4
- data/spec/controllers/application_metal_controller_spec.rb +24 -10
- data/spec/controllers/applications_controller_spec.rb +76 -78
- data/spec/controllers/authorizations_controller_spec.rb +189 -142
- data/spec/controllers/protected_resources_controller_spec.rb +111 -67
- data/spec/controllers/token_info_controller_spec.rb +14 -12
- data/spec/controllers/tokens_controller_spec.rb +170 -112
- data/spec/dummy/Rakefile +3 -1
- data/spec/dummy/app/controllers/application_controller.rb +3 -1
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +3 -1
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +4 -2
- data/spec/dummy/app/controllers/home_controller.rb +6 -5
- 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/application.rb +26 -2
- data/spec/dummy/config/boot.rb +2 -4
- data/spec/dummy/config/environment.rb +1 -1
- 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 +4 -2
- data/spec/dummy/config/initializers/backtrace_silencers.rb +2 -0
- data/spec/dummy/config/initializers/doorkeeper.rb +7 -3
- 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/config.ru +3 -1
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +20 -13
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +1 -1
- data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +2 -0
- data/spec/dummy/db/schema.rb +1 -1
- data/spec/dummy/script/rails +7 -4
- data/spec/factories.rb +11 -9
- 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 +19 -14
- 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 -1
- data/spec/generators/views_generator_spec.rb +14 -12
- data/spec/grape/grape_integration_spec.rb +35 -33
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +9 -7
- data/spec/lib/config_spec.rb +290 -104
- data/spec/lib/doorkeeper_spec.rb +8 -6
- data/spec/lib/models/expirable_spec.rb +22 -8
- data/spec/lib/models/reusable_spec.rb +40 -0
- data/spec/lib/models/revocable_spec.rb +8 -6
- data/spec/lib/models/scopes_spec.rb +27 -13
- data/spec/lib/models/secret_storable_spec.rb +135 -0
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +17 -15
- data/spec/lib/oauth/authorization_code_request_spec.rb +43 -17
- data/spec/lib/oauth/base_request_spec.rb +24 -12
- data/spec/lib/oauth/base_response_spec.rb +3 -1
- data/spec/lib/oauth/client/credentials_spec.rb +26 -24
- data/spec/lib/oauth/client_credentials/creator_spec.rb +56 -10
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +27 -20
- data/spec/lib/oauth/client_credentials/validation_spec.rb +21 -15
- data/spec/lib/oauth/client_credentials_integration_spec.rb +8 -6
- 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 +10 -8
- data/spec/lib/oauth/code_response_spec.rb +9 -7
- data/spec/lib/oauth/error_response_spec.rb +19 -11
- 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 +68 -31
- data/spec/lib/oauth/helpers/unique_token_spec.rb +8 -6
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +124 -93
- data/spec/lib/oauth/invalid_token_response_spec.rb +3 -1
- data/spec/lib/oauth/password_access_token_request_spec.rb +95 -34
- data/spec/lib/oauth/pre_authorization_spec.rb +80 -54
- data/spec/lib/oauth/refresh_token_request_spec.rb +46 -39
- data/spec/lib/oauth/scopes_spec.rb +63 -61
- data/spec/lib/oauth/token_request_spec.rb +80 -25
- data/spec/lib/oauth/token_response_spec.rb +40 -38
- data/spec/lib/oauth/token_spec.rb +64 -45
- data/spec/lib/request/strategy_spec.rb +3 -1
- data/spec/lib/secret_storing/base_spec.rb +60 -0
- data/spec/lib/secret_storing/bcrypt_spec.rb +49 -0
- data/spec/lib/secret_storing/plain_spec.rb +44 -0
- data/spec/lib/secret_storing/sha256_hash_spec.rb +48 -0
- data/spec/lib/server_spec.rb +20 -18
- data/spec/lib/{orm/active_record/stale_records_cleaner_spec.rb → stale_records_cleaner_spec.rb} +28 -18
- data/spec/models/doorkeeper/access_grant_spec.rb +80 -15
- data/spec/models/doorkeeper/access_token_spec.rb +212 -83
- data/spec/models/doorkeeper/application_spec.rb +146 -49
- data/spec/requests/applications/applications_request_spec.rb +100 -68
- data/spec/requests/applications/authorized_applications_spec.rb +20 -18
- data/spec/requests/endpoints/authorization_spec.rb +27 -25
- data/spec/requests/endpoints/token_spec.rb +38 -36
- data/spec/requests/flows/authorization_code_errors_spec.rb +27 -25
- data/spec/requests/flows/authorization_code_spec.rb +260 -158
- data/spec/requests/flows/client_credentials_spec.rb +54 -52
- data/spec/requests/flows/implicit_grant_errors_spec.rb +11 -9
- data/spec/requests/flows/implicit_grant_spec.rb +27 -25
- data/spec/requests/flows/password_spec.rb +64 -56
- data/spec/requests/flows/refresh_token_spec.rb +91 -32
- data/spec/requests/flows/revoke_token_spec.rb +49 -63
- 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 +37 -35
- data/spec/routing/custom_controller_routes_spec.rb +71 -65
- data/spec/routing/default_routes_spec.rb +22 -20
- data/spec/routing/scoped_routes_spec.rb +20 -18
- data/spec/spec_helper.rb +15 -13
- data/spec/spec_helper_integration.rb +3 -1
- data/spec/support/dependencies/factory_bot.rb +3 -1
- data/spec/support/doorkeeper_rspec.rb +5 -2
- 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 +11 -5
- data/spec/support/helpers/request_spec_helper.rb +5 -3
- data/spec/support/helpers/url_helper.rb +20 -18
- 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 +68 -10
- data/spec/support/shared/hashing_shared_context.rb +36 -0
- data/spec/support/shared/models_shared_examples.rb +12 -10
- data/spec/validators/redirect_uri_validator_spec.rb +76 -47
- data/spec/version/version_spec.rb +7 -5
- metadata +70 -21
- data/gemfiles/rails_4_2.gemfile +0 -13
- data/spec/dummy/config/initializers/new_framework_defaults.rb +0 -10
|
@@ -1,119 +1,121 @@
|
|
|
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
|
-
expect(response.status).to eq(
|
|
63
|
+
expect(response.status).to eq(400)
|
|
62
64
|
end
|
|
63
65
|
end
|
|
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.
|
|
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
|
|
@@ -14,18 +16,18 @@ feature 'Implicit Grant Flow Errors' do
|
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
19
|
+
%i[client_id invalid_client],
|
|
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.
|
|
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,16 +53,21 @@ 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
|
|
58
60
|
it "should not issue new token" do
|
|
59
61
|
expect do
|
|
60
|
-
post password_token_endpoint_url(
|
|
62
|
+
post password_token_endpoint_url(
|
|
63
|
+
client_id: @client.uid,
|
|
64
|
+
client_secret: "foobar",
|
|
65
|
+
resource_owner: @resource_owner
|
|
66
|
+
)
|
|
61
67
|
end.not_to(change { Doorkeeper::AccessToken.count })
|
|
62
68
|
|
|
63
|
-
expect(response).
|
|
69
|
+
expect(response.status).to eq(401)
|
|
70
|
+
should_have_json "error", "invalid_client"
|
|
64
71
|
end
|
|
65
72
|
end
|
|
66
73
|
end
|
|
@@ -75,7 +82,7 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
|
75
82
|
token = Doorkeeper::AccessToken.first
|
|
76
83
|
|
|
77
84
|
expect(token.application_id).to eq @client.id
|
|
78
|
-
should_have_json
|
|
85
|
+
should_have_json "access_token", token.token
|
|
79
86
|
end
|
|
80
87
|
|
|
81
88
|
context "when client_secret absent" do
|
|
@@ -84,12 +91,13 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
|
84
91
|
post password_token_endpoint_url(client_id: @client.uid, resource_owner: @resource_owner)
|
|
85
92
|
end.not_to(change { Doorkeeper::AccessToken.count })
|
|
86
93
|
|
|
87
|
-
expect(response).
|
|
94
|
+
expect(response.status).to eq(401)
|
|
95
|
+
should_have_json "error", "invalid_client"
|
|
88
96
|
end
|
|
89
97
|
end
|
|
90
98
|
end
|
|
91
99
|
|
|
92
|
-
it
|
|
100
|
+
it "should issue new token without client credentials" do
|
|
93
101
|
expect do
|
|
94
102
|
post password_token_endpoint_url(resource_owner: @resource_owner)
|
|
95
103
|
end.to(change { Doorkeeper::AccessToken.count }.by(1))
|
|
@@ -97,20 +105,20 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
|
97
105
|
token = Doorkeeper::AccessToken.first
|
|
98
106
|
|
|
99
107
|
expect(token.application_id).to be_nil
|
|
100
|
-
should_have_json
|
|
108
|
+
should_have_json "access_token", token.token
|
|
101
109
|
end
|
|
102
110
|
|
|
103
|
-
it
|
|
111
|
+
it "should issue a refresh token if enabled" do
|
|
104
112
|
config_is_set(:refresh_token_enabled, true)
|
|
105
113
|
|
|
106
114
|
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
|
107
115
|
|
|
108
116
|
token = Doorkeeper::AccessToken.first
|
|
109
117
|
|
|
110
|
-
should_have_json
|
|
118
|
+
should_have_json "refresh_token", token.refresh_token
|
|
111
119
|
end
|
|
112
120
|
|
|
113
|
-
it
|
|
121
|
+
it "should return the same token if it is still accessible" do
|
|
114
122
|
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
|
115
123
|
|
|
116
124
|
client_is_authorized(@client, @resource_owner)
|
|
@@ -118,54 +126,54 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
|
118
126
|
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
|
119
127
|
|
|
120
128
|
expect(Doorkeeper::AccessToken.count).to be(1)
|
|
121
|
-
should_have_json
|
|
129
|
+
should_have_json "access_token", Doorkeeper::AccessToken.first.token
|
|
122
130
|
end
|
|
123
131
|
|
|
124
|
-
context
|
|
132
|
+
context "with valid, default scope" do
|
|
125
133
|
before do
|
|
126
134
|
default_scopes_exist :public
|
|
127
135
|
end
|
|
128
136
|
|
|
129
|
-
it
|
|
137
|
+
it "should issue new token" do
|
|
130
138
|
expect do
|
|
131
|
-
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")
|
|
132
140
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
133
141
|
|
|
134
142
|
token = Doorkeeper::AccessToken.first
|
|
135
143
|
|
|
136
144
|
expect(token.application_id).to eq @client.id
|
|
137
|
-
should_have_json
|
|
138
|
-
should_have_json
|
|
145
|
+
should_have_json "access_token", token.token
|
|
146
|
+
should_have_json "scope", "public"
|
|
139
147
|
end
|
|
140
148
|
end
|
|
141
149
|
end
|
|
142
150
|
|
|
143
|
-
context
|
|
151
|
+
context "when application scopes are present and differs from configured default scopes and no scope is passed" do
|
|
144
152
|
before do
|
|
145
153
|
default_scopes_exist :public
|
|
146
|
-
@client.
|
|
154
|
+
@client.update(scopes: "abc")
|
|
147
155
|
end
|
|
148
156
|
|
|
149
|
-
it
|
|
157
|
+
it "issues new token without any scope" do
|
|
150
158
|
expect do
|
|
151
|
-
|
|
159
|
+
post password_token_endpoint_url(client: @client, resource_owner: @resource_owner)
|
|
152
160
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
153
161
|
|
|
154
162
|
token = Doorkeeper::AccessToken.first
|
|
155
163
|
|
|
156
164
|
expect(token.application_id).to eq @client.id
|
|
157
165
|
expect(token.scopes).to be_empty
|
|
158
|
-
should_have_json
|
|
159
|
-
should_not_have_json
|
|
166
|
+
should_have_json "access_token", token.token
|
|
167
|
+
should_not_have_json "scope"
|
|
160
168
|
end
|
|
161
169
|
end
|
|
162
170
|
|
|
163
|
-
context
|
|
171
|
+
context "when application scopes contain some of the default scopes and no scope is passed" do
|
|
164
172
|
before do
|
|
165
|
-
@client.
|
|
173
|
+
@client.update(scopes: "read write public")
|
|
166
174
|
end
|
|
167
175
|
|
|
168
|
-
it
|
|
176
|
+
it "issues new token with one default scope that are present in application scopes" do
|
|
169
177
|
default_scopes_exist :public, :admin
|
|
170
178
|
|
|
171
179
|
expect do
|
|
@@ -175,11 +183,11 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
|
175
183
|
token = Doorkeeper::AccessToken.first
|
|
176
184
|
|
|
177
185
|
expect(token.application_id).to eq @client.id
|
|
178
|
-
should_have_json
|
|
179
|
-
should_have_json
|
|
186
|
+
should_have_json "access_token", token.token
|
|
187
|
+
should_have_json "scope", "public"
|
|
180
188
|
end
|
|
181
189
|
|
|
182
|
-
it
|
|
190
|
+
it "issues new token with multiple default scopes that are present in application scopes" do
|
|
183
191
|
default_scopes_exist :public, :read, :update
|
|
184
192
|
|
|
185
193
|
expect do
|
|
@@ -189,62 +197,62 @@ describe 'Resource Owner Password Credentials Flow' do
|
|
|
189
197
|
token = Doorkeeper::AccessToken.first
|
|
190
198
|
|
|
191
199
|
expect(token.application_id).to eq @client.id
|
|
192
|
-
should_have_json
|
|
193
|
-
should_have_json
|
|
200
|
+
should_have_json "access_token", token.token
|
|
201
|
+
should_have_json "scope", "public read"
|
|
194
202
|
end
|
|
195
203
|
end
|
|
196
204
|
|
|
197
|
-
context
|
|
205
|
+
context "with invalid scopes" do
|
|
198
206
|
subject do
|
|
199
207
|
post password_token_endpoint_url(client: @client,
|
|
200
208
|
resource_owner: @resource_owner,
|
|
201
|
-
scope:
|
|
209
|
+
scope: "random")
|
|
202
210
|
end
|
|
203
211
|
|
|
204
|
-
it
|
|
212
|
+
it "should not issue new token" do
|
|
205
213
|
expect { subject }.to_not(change { Doorkeeper::AccessToken.count })
|
|
206
214
|
end
|
|
207
215
|
|
|
208
|
-
it
|
|
216
|
+
it "should return invalid_scope error" do
|
|
209
217
|
subject
|
|
210
|
-
should_have_json
|
|
211
|
-
should_have_json
|
|
212
|
-
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"
|
|
213
221
|
|
|
214
|
-
expect(response.status).to eq(
|
|
222
|
+
expect(response.status).to eq(400)
|
|
215
223
|
end
|
|
216
224
|
end
|
|
217
225
|
|
|
218
|
-
context
|
|
219
|
-
it
|
|
226
|
+
context "with invalid user credentials" do
|
|
227
|
+
it "should not issue new token with bad password" do
|
|
220
228
|
expect do
|
|
221
229
|
post password_token_endpoint_url(client: @client,
|
|
222
230
|
resource_owner_username: @resource_owner.name,
|
|
223
|
-
resource_owner_password:
|
|
231
|
+
resource_owner_password: "wrongpassword")
|
|
224
232
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
|
225
233
|
end
|
|
226
234
|
|
|
227
|
-
it
|
|
235
|
+
it "should not issue new token without credentials" do
|
|
228
236
|
expect do
|
|
229
237
|
post password_token_endpoint_url(client: @client)
|
|
230
238
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
|
231
239
|
end
|
|
232
240
|
end
|
|
233
241
|
|
|
234
|
-
context
|
|
235
|
-
it
|
|
242
|
+
context "with invalid confidential client credentials" do
|
|
243
|
+
it "should not issue new token with bad client credentials" do
|
|
236
244
|
expect do
|
|
237
245
|
post password_token_endpoint_url(client_id: @client.uid,
|
|
238
|
-
client_secret:
|
|
246
|
+
client_secret: "bad_secret",
|
|
239
247
|
resource_owner: @resource_owner)
|
|
240
248
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
|
241
249
|
end
|
|
242
250
|
end
|
|
243
251
|
|
|
244
|
-
context
|
|
245
|
-
it
|
|
252
|
+
context "with invalid public client id" do
|
|
253
|
+
it "should not issue new token with bad client id" do
|
|
246
254
|
expect do
|
|
247
|
-
post password_token_endpoint_url(client_id:
|
|
255
|
+
post password_token_endpoint_url(client_id: "bad_id", resource_owner: @resource_owner)
|
|
248
256
|
end.to_not(change { Doorkeeper::AccessToken.count })
|
|
249
257
|
end
|
|
250
258
|
end
|