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,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
2
4
|
|
|
3
5
|
module Doorkeeper::OAuth
|
|
4
6
|
describe PasswordAccessTokenRequest do
|
|
@@ -16,87 +18,134 @@ module Doorkeeper::OAuth
|
|
|
16
18
|
let(:client) { FactoryBot.create(:application) }
|
|
17
19
|
let(:owner) { double :owner, id: 99 }
|
|
18
20
|
|
|
21
|
+
before do
|
|
22
|
+
allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
|
|
23
|
+
end
|
|
24
|
+
|
|
19
25
|
subject do
|
|
20
26
|
PasswordAccessTokenRequest.new(server, client, owner)
|
|
21
27
|
end
|
|
22
28
|
|
|
23
|
-
it
|
|
29
|
+
it "issues a new token for the client" do
|
|
24
30
|
expect do
|
|
25
31
|
subject.authorize
|
|
26
32
|
end.to change { client.reload.access_tokens.count }.by(1)
|
|
27
|
-
|
|
33
|
+
|
|
34
|
+
expect(client.reload.access_tokens.max_by(&:created_at).expires_in).to eq(1234)
|
|
28
35
|
end
|
|
29
36
|
|
|
30
|
-
it
|
|
37
|
+
it "issues a new token without a client" do
|
|
31
38
|
expect do
|
|
32
39
|
subject.client = nil
|
|
33
40
|
subject.authorize
|
|
34
41
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
35
42
|
end
|
|
36
43
|
|
|
37
|
-
it
|
|
44
|
+
it "does not issue a new token with an invalid client" do
|
|
38
45
|
expect do
|
|
39
46
|
subject.client = nil
|
|
40
|
-
subject.parameters = { client_id:
|
|
47
|
+
subject.parameters = { client_id: "bad_id" }
|
|
41
48
|
subject.authorize
|
|
42
|
-
end.
|
|
49
|
+
end.not_to(change { Doorkeeper::AccessToken.count })
|
|
43
50
|
|
|
44
51
|
expect(subject.error).to eq(:invalid_client)
|
|
45
52
|
end
|
|
46
53
|
|
|
47
|
-
it
|
|
54
|
+
it "requires the owner" do
|
|
48
55
|
subject.resource_owner = nil
|
|
49
56
|
subject.validate
|
|
50
57
|
expect(subject.error).to eq(:invalid_grant)
|
|
51
58
|
end
|
|
52
59
|
|
|
53
|
-
it
|
|
60
|
+
it "optionally accepts the client" do
|
|
54
61
|
subject.client = nil
|
|
55
62
|
expect(subject).to be_valid
|
|
56
63
|
end
|
|
57
64
|
|
|
58
|
-
it
|
|
65
|
+
it "creates token even when there is already one (default)" do
|
|
59
66
|
FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
|
|
67
|
+
|
|
60
68
|
expect do
|
|
61
69
|
subject.authorize
|
|
62
70
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
63
71
|
end
|
|
64
72
|
|
|
65
|
-
it
|
|
73
|
+
it "skips token creation if there is already one reusable" do
|
|
66
74
|
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
|
67
75
|
FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
|
|
76
|
+
|
|
68
77
|
expect do
|
|
69
78
|
subject.authorize
|
|
70
|
-
end.
|
|
79
|
+
end.not_to(change { Doorkeeper::AccessToken.count })
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "creates token when there is already one but non reusable" do
|
|
83
|
+
allow(Doorkeeper.configuration).to receive(:reuse_access_token).and_return(true)
|
|
84
|
+
FactoryBot.create(:access_token, application_id: client.id, resource_owner_id: owner.id)
|
|
85
|
+
allow_any_instance_of(Doorkeeper::AccessToken).to receive(:reusable?).and_return(false)
|
|
86
|
+
|
|
87
|
+
expect do
|
|
88
|
+
subject.authorize
|
|
89
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
71
90
|
end
|
|
72
91
|
|
|
73
92
|
it "calls configured request callback methods" do
|
|
74
|
-
expect(Doorkeeper.configuration.before_successful_strategy_response)
|
|
75
|
-
|
|
93
|
+
expect(Doorkeeper.configuration.before_successful_strategy_response)
|
|
94
|
+
.to receive(:call).with(subject).once
|
|
95
|
+
|
|
96
|
+
expect(Doorkeeper.configuration.after_successful_strategy_response)
|
|
97
|
+
.to receive(:call).with(subject, instance_of(Doorkeeper::OAuth::TokenResponse)).once
|
|
98
|
+
|
|
76
99
|
subject.authorize
|
|
77
100
|
end
|
|
78
101
|
|
|
79
|
-
describe
|
|
102
|
+
describe "with scopes" do
|
|
80
103
|
subject do
|
|
81
|
-
PasswordAccessTokenRequest.new(server, client, owner, scope:
|
|
104
|
+
PasswordAccessTokenRequest.new(server, client, owner, scope: "public")
|
|
82
105
|
end
|
|
83
106
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
107
|
+
context "when scopes_by_grant_type is not configured for grant_type" do
|
|
108
|
+
it "returns error when scopes are invalid" do
|
|
109
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("another"))
|
|
110
|
+
subject.validate
|
|
111
|
+
expect(subject.error).to eq(:invalid_scope)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "creates the token with scopes if scopes are valid" do
|
|
115
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
|
116
|
+
expect do
|
|
117
|
+
subject.authorize
|
|
118
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
119
|
+
|
|
120
|
+
expect(Doorkeeper::AccessToken.last.scopes).to include("public")
|
|
121
|
+
end
|
|
88
122
|
end
|
|
89
123
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
124
|
+
context "when scopes_by_grant_type is configured for grant_type" do
|
|
125
|
+
it "returns error when scopes are valid but not permitted for grant_type" do
|
|
126
|
+
allow(server)
|
|
127
|
+
.to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
|
128
|
+
allow(Doorkeeper.configuration)
|
|
129
|
+
.to receive(:scopes_by_grant_type).and_return(password: "another")
|
|
130
|
+
subject.validate
|
|
131
|
+
expect(subject.error).to eq(:invalid_scope)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "creates the token with scopes if scopes are valid and permitted for grant_type" do
|
|
135
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
|
136
|
+
allow(Doorkeeper.configuration)
|
|
137
|
+
.to receive(:scopes_by_grant_type).and_return(password: [:public])
|
|
138
|
+
|
|
139
|
+
expect do
|
|
140
|
+
subject.authorize
|
|
141
|
+
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
142
|
+
|
|
143
|
+
expect(Doorkeeper::AccessToken.last.scopes).to include("public")
|
|
144
|
+
end
|
|
96
145
|
end
|
|
97
146
|
end
|
|
98
147
|
|
|
99
|
-
describe
|
|
148
|
+
describe "with custom expiry" do
|
|
100
149
|
let(:server) do
|
|
101
150
|
double(
|
|
102
151
|
:server,
|
|
@@ -104,26 +153,38 @@ module Doorkeeper::OAuth
|
|
|
104
153
|
access_token_expires_in: 2.hours,
|
|
105
154
|
refresh_token_enabled?: false,
|
|
106
155
|
custom_access_token_expires_in: lambda { |context|
|
|
107
|
-
context.scopes.exists?(
|
|
156
|
+
if context.scopes.exists?("public")
|
|
157
|
+
222
|
|
158
|
+
elsif context.scopes.exists?("magic")
|
|
159
|
+
Float::INFINITY
|
|
160
|
+
end
|
|
108
161
|
}
|
|
109
162
|
)
|
|
110
163
|
end
|
|
111
164
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
165
|
+
before do
|
|
166
|
+
allow(server).to receive(:option_defined?).with(:custom_access_token_expires_in).and_return(true)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
it "checks scopes" do
|
|
170
|
+
subject = PasswordAccessTokenRequest.new(server, client, owner, scope: "public")
|
|
171
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("public"))
|
|
172
|
+
|
|
115
173
|
expect do
|
|
116
174
|
subject.authorize
|
|
117
175
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
176
|
+
|
|
118
177
|
expect(Doorkeeper::AccessToken.last.expires_in).to eq(222)
|
|
119
178
|
end
|
|
120
179
|
|
|
121
|
-
it
|
|
122
|
-
subject = PasswordAccessTokenRequest.new(server, client, owner, scope:
|
|
123
|
-
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string(
|
|
180
|
+
it "falls back to the default otherwise" do
|
|
181
|
+
subject = PasswordAccessTokenRequest.new(server, client, owner, scope: "private")
|
|
182
|
+
allow(server).to receive(:scopes).and_return(Doorkeeper::OAuth::Scopes.from_string("private"))
|
|
183
|
+
|
|
124
184
|
expect do
|
|
125
185
|
subject.authorize
|
|
126
186
|
end.to change { Doorkeeper::AccessToken.count }.by(1)
|
|
187
|
+
|
|
127
188
|
expect(Doorkeeper::AccessToken.last.expires_in).to eq(2.hours)
|
|
128
189
|
end
|
|
129
190
|
end
|
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
2
4
|
|
|
3
5
|
module Doorkeeper::OAuth
|
|
4
6
|
describe PreAuthorization do
|
|
5
7
|
let(:server) do
|
|
6
8
|
server = Doorkeeper.configuration
|
|
7
9
|
allow(server).to receive(:default_scopes).and_return(Scopes.new)
|
|
8
|
-
allow(server).to receive(:scopes).and_return(Scopes.from_string(
|
|
10
|
+
allow(server).to receive(:scopes).and_return(Scopes.from_string("public profile"))
|
|
9
11
|
server
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
let(:application) do
|
|
13
15
|
application = double :application
|
|
14
|
-
allow(application).to receive(:scopes).and_return(Scopes.from_string(
|
|
16
|
+
allow(application).to receive(:scopes).and_return(Scopes.from_string(""))
|
|
15
17
|
application
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
let(:client) do
|
|
19
|
-
double :client, redirect_uri:
|
|
21
|
+
double :client, redirect_uri: "http://tst.com/auth", application: application
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
let :attributes do
|
|
23
25
|
{
|
|
24
|
-
response_type:
|
|
25
|
-
redirect_uri:
|
|
26
|
-
state:
|
|
26
|
+
response_type: "code",
|
|
27
|
+
redirect_uri: "http://tst.com/auth",
|
|
28
|
+
state: "save-this",
|
|
27
29
|
}
|
|
28
30
|
end
|
|
29
31
|
|
|
@@ -31,133 +33,157 @@ module Doorkeeper::OAuth
|
|
|
31
33
|
PreAuthorization.new(server, client, attributes)
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
it
|
|
36
|
+
it "is authorizable when request is valid" do
|
|
35
37
|
expect(subject).to be_authorizable
|
|
36
38
|
end
|
|
37
39
|
|
|
38
|
-
it
|
|
39
|
-
subject.response_type =
|
|
40
|
+
it "accepts code as response type" do
|
|
41
|
+
subject.response_type = "code"
|
|
40
42
|
expect(subject).to be_authorizable
|
|
41
43
|
end
|
|
42
44
|
|
|
43
|
-
it
|
|
44
|
-
allow(server).to receive(:grant_flows).and_return([
|
|
45
|
-
subject.response_type =
|
|
45
|
+
it "accepts token as response type" do
|
|
46
|
+
allow(server).to receive(:grant_flows).and_return(["implicit"])
|
|
47
|
+
subject.response_type = "token"
|
|
46
48
|
expect(subject).to be_authorizable
|
|
47
49
|
end
|
|
48
50
|
|
|
49
|
-
context
|
|
51
|
+
context "when using default grant flows" do
|
|
50
52
|
it 'accepts "code" as response type' do
|
|
51
|
-
subject.response_type =
|
|
53
|
+
subject.response_type = "code"
|
|
52
54
|
expect(subject).to be_authorizable
|
|
53
55
|
end
|
|
54
56
|
|
|
55
57
|
it 'accepts "token" as response type' do
|
|
56
|
-
allow(server).to receive(:grant_flows).and_return([
|
|
57
|
-
subject.response_type =
|
|
58
|
+
allow(server).to receive(:grant_flows).and_return(["implicit"])
|
|
59
|
+
subject.response_type = "token"
|
|
58
60
|
expect(subject).to be_authorizable
|
|
59
61
|
end
|
|
60
62
|
end
|
|
61
63
|
|
|
62
|
-
context
|
|
64
|
+
context "when authorization code grant flow is disabled" do
|
|
63
65
|
before do
|
|
64
|
-
allow(server).to receive(:grant_flows).and_return([
|
|
66
|
+
allow(server).to receive(:grant_flows).and_return(["implicit"])
|
|
65
67
|
end
|
|
66
68
|
|
|
67
69
|
it 'does not accept "code" as response type' do
|
|
68
|
-
subject.response_type =
|
|
70
|
+
subject.response_type = "code"
|
|
69
71
|
expect(subject).not_to be_authorizable
|
|
70
72
|
end
|
|
71
73
|
end
|
|
72
74
|
|
|
73
|
-
context
|
|
75
|
+
context "when implicit grant flow is disabled" do
|
|
74
76
|
before do
|
|
75
|
-
allow(server).to receive(:grant_flows).and_return([
|
|
77
|
+
allow(server).to receive(:grant_flows).and_return(["authorization_code"])
|
|
76
78
|
end
|
|
77
79
|
|
|
78
80
|
it 'does not accept "token" as response type' do
|
|
79
|
-
subject.response_type =
|
|
81
|
+
subject.response_type = "token"
|
|
80
82
|
expect(subject).not_to be_authorizable
|
|
81
83
|
end
|
|
82
84
|
end
|
|
83
85
|
|
|
84
|
-
context
|
|
85
|
-
it
|
|
86
|
-
subject.scope =
|
|
86
|
+
context "client application does not restrict valid scopes" do
|
|
87
|
+
it "accepts valid scopes" do
|
|
88
|
+
subject.scope = "public"
|
|
89
|
+
expect(subject).to be_authorizable
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "rejects (globally) non-valid scopes" do
|
|
93
|
+
subject.scope = "invalid"
|
|
94
|
+
expect(subject).not_to be_authorizable
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "accepts scopes which are permitted for grant_type" do
|
|
98
|
+
allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
|
|
99
|
+
subject.scope = "public"
|
|
87
100
|
expect(subject).to be_authorizable
|
|
88
101
|
end
|
|
89
102
|
|
|
90
|
-
it
|
|
91
|
-
|
|
103
|
+
it "rejects scopes which are not permitted for grant_type" do
|
|
104
|
+
allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
|
|
105
|
+
subject.scope = "public"
|
|
92
106
|
expect(subject).not_to be_authorizable
|
|
93
107
|
end
|
|
94
108
|
end
|
|
95
109
|
|
|
96
|
-
context
|
|
110
|
+
context "client application restricts valid scopes" do
|
|
97
111
|
let(:application) do
|
|
98
112
|
application = double :application
|
|
99
|
-
allow(application).to receive(:scopes).and_return(Scopes.from_string(
|
|
113
|
+
allow(application).to receive(:scopes).and_return(Scopes.from_string("public nonsense"))
|
|
100
114
|
application
|
|
101
115
|
end
|
|
102
116
|
|
|
103
|
-
it
|
|
104
|
-
subject.scope =
|
|
117
|
+
it "accepts valid scopes" do
|
|
118
|
+
subject.scope = "public"
|
|
105
119
|
expect(subject).to be_authorizable
|
|
106
120
|
end
|
|
107
121
|
|
|
108
|
-
it
|
|
109
|
-
subject.scope =
|
|
122
|
+
it "rejects (globally) non-valid scopes" do
|
|
123
|
+
subject.scope = "invalid"
|
|
110
124
|
expect(subject).not_to be_authorizable
|
|
111
125
|
end
|
|
112
126
|
|
|
113
|
-
it
|
|
114
|
-
subject.scope =
|
|
127
|
+
it "rejects (application level) non-valid scopes" do
|
|
128
|
+
subject.scope = "profile"
|
|
115
129
|
expect(subject).to_not be_authorizable
|
|
116
130
|
end
|
|
131
|
+
|
|
132
|
+
it "accepts scopes which are permitted for grant_type" do
|
|
133
|
+
allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
|
|
134
|
+
subject.scope = "public"
|
|
135
|
+
expect(subject).to be_authorizable
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "rejects scopes which are not permitted for grant_type" do
|
|
139
|
+
allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
|
|
140
|
+
subject.scope = "public"
|
|
141
|
+
expect(subject).not_to be_authorizable
|
|
142
|
+
end
|
|
117
143
|
end
|
|
118
144
|
|
|
119
|
-
it
|
|
120
|
-
allow(server).to receive(:default_scopes).and_return(Scopes.from_string(
|
|
145
|
+
it "uses default scopes when none is required" do
|
|
146
|
+
allow(server).to receive(:default_scopes).and_return(Scopes.from_string("default"))
|
|
121
147
|
subject.scope = nil
|
|
122
|
-
expect(subject.scope).to eq(
|
|
123
|
-
expect(subject.scopes).to eq(Scopes.from_string(
|
|
148
|
+
expect(subject.scope).to eq("default")
|
|
149
|
+
expect(subject.scopes).to eq(Scopes.from_string("default"))
|
|
124
150
|
end
|
|
125
151
|
|
|
126
|
-
context
|
|
127
|
-
let(:native_redirect_uri) {
|
|
152
|
+
context "with native redirect uri" do
|
|
153
|
+
let(:native_redirect_uri) { "urn:ietf:wg:oauth:2.0:oob" }
|
|
128
154
|
|
|
129
|
-
it
|
|
155
|
+
it "accepts redirect_uri when it matches with the client" do
|
|
130
156
|
subject.redirect_uri = native_redirect_uri
|
|
131
157
|
allow(subject.client).to receive(:redirect_uri) { native_redirect_uri }
|
|
132
158
|
expect(subject).to be_authorizable
|
|
133
159
|
end
|
|
134
160
|
|
|
135
|
-
it
|
|
136
|
-
subject.redirect_uri =
|
|
161
|
+
it "invalidates redirect_uri when it does'n match with the client" do
|
|
162
|
+
subject.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
|
|
137
163
|
expect(subject).not_to be_authorizable
|
|
138
164
|
end
|
|
139
165
|
end
|
|
140
166
|
|
|
141
|
-
it
|
|
142
|
-
subject.redirect_uri =
|
|
167
|
+
it "matches the redirect uri against client's one" do
|
|
168
|
+
subject.redirect_uri = "http://nothesame.com"
|
|
143
169
|
expect(subject).not_to be_authorizable
|
|
144
170
|
end
|
|
145
171
|
|
|
146
|
-
it
|
|
147
|
-
expect(subject.state).to eq(
|
|
172
|
+
it "stores the state" do
|
|
173
|
+
expect(subject.state).to eq("save-this")
|
|
148
174
|
end
|
|
149
175
|
|
|
150
|
-
it
|
|
151
|
-
subject.response_type =
|
|
176
|
+
it "rejects if response type is not allowed" do
|
|
177
|
+
subject.response_type = "whops"
|
|
152
178
|
expect(subject).not_to be_authorizable
|
|
153
179
|
end
|
|
154
180
|
|
|
155
|
-
it
|
|
181
|
+
it "requires an existing client" do
|
|
156
182
|
subject.client = nil
|
|
157
183
|
expect(subject).not_to be_authorizable
|
|
158
184
|
end
|
|
159
185
|
|
|
160
|
-
it
|
|
186
|
+
it "requires a redirect uri" do
|
|
161
187
|
subject.redirect_uri = nil
|
|
162
188
|
expect(subject).not_to be_authorizable
|
|
163
189
|
end
|
|
@@ -182,7 +208,7 @@ module Doorkeeper::OAuth
|
|
|
182
208
|
expect(json[:response_type]).to eq subject.response_type
|
|
183
209
|
expect(json[:scope]).to eq subject.scope
|
|
184
210
|
expect(json[:client_name]).to eq client_name
|
|
185
|
-
expect(json[:status]).to eq I18n.t(
|
|
211
|
+
expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
|
|
186
212
|
end
|
|
187
213
|
end
|
|
188
214
|
end
|