doorkeeper 5.2.2 → 5.3.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 +4 -4
- data/Appraisals +2 -2
- data/CHANGELOG.md +29 -2
- data/Gemfile +2 -2
- data/app/controllers/doorkeeper/application_controller.rb +2 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
- data/app/controllers/doorkeeper/applications_controller.rb +0 -1
- data/app/controllers/doorkeeper/authorizations_controller.rb +2 -2
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
- data/gemfiles/rails_5_0.gemfile +2 -2
- data/gemfiles/rails_5_1.gemfile +2 -2
- data/gemfiles/rails_5_2.gemfile +2 -2
- data/gemfiles/rails_6_0.gemfile +2 -2
- data/gemfiles/rails_master.gemfile +2 -2
- data/lib/doorkeeper/config.rb +71 -38
- data/lib/doorkeeper/grape/helpers.rb +1 -1
- data/lib/doorkeeper/helpers/controller.rb +10 -8
- data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
- data/lib/doorkeeper/models/access_token_mixin.rb +56 -18
- data/lib/doorkeeper/models/application_mixin.rb +3 -3
- data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
- data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
- data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
- data/lib/doorkeeper/oauth/authorization/code.rb +4 -4
- data/lib/doorkeeper/oauth/authorization/token.rb +9 -6
- data/lib/doorkeeper/oauth/authorization_code_request.rb +13 -6
- data/lib/doorkeeper/oauth/base_request.rb +8 -4
- data/lib/doorkeeper/oauth/client.rb +7 -8
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +16 -9
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
- data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +4 -4
- data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
- data/lib/doorkeeper/oauth/code_response.rb +2 -2
- data/lib/doorkeeper/oauth/error.rb +1 -1
- data/lib/doorkeeper/oauth/error_response.rb +5 -5
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -1
- data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
- data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
- data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -3
- data/lib/doorkeeper/oauth/pre_authorization.rb +12 -7
- data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -5
- data/lib/doorkeeper/oauth/token.rb +2 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +6 -6
- data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
- data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
- data/lib/doorkeeper/orm/active_record/application.rb +5 -95
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +3 -3
- data/lib/doorkeeper/orm/active_record.rb +3 -4
- data/lib/doorkeeper/rails/helpers.rb +4 -4
- data/lib/doorkeeper/rails/routes.rb +5 -7
- data/lib/doorkeeper/rake/db.rake +3 -3
- data/lib/doorkeeper/request/authorization_code.rb +3 -3
- data/lib/doorkeeper/request/client_credentials.rb +2 -2
- data/lib/doorkeeper/request/password.rb +2 -2
- data/lib/doorkeeper/request/refresh_token.rb +3 -3
- data/lib/doorkeeper/request.rb +1 -1
- data/lib/doorkeeper/server.rb +1 -1
- data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
- data/lib/doorkeeper/version.rb +2 -2
- data/lib/doorkeeper.rb +2 -3
- data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
- data/lib/generators/doorkeeper/migration_generator.rb +1 -1
- data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
- data/lib/generators/doorkeeper/templates/initializer.rb +39 -0
- data/spec/controllers/application_metal_controller_spec.rb +1 -1
- data/spec/controllers/applications_controller_spec.rb +3 -2
- data/spec/controllers/authorizations_controller_spec.rb +18 -18
- data/spec/controllers/protected_resources_controller_spec.rb +25 -17
- data/spec/controllers/token_info_controller_spec.rb +1 -1
- data/spec/controllers/tokens_controller_spec.rb +1 -1
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
- data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
- data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
- data/spec/generators/install_generator_spec.rb +1 -1
- data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
- data/spec/lib/config_spec.rb +62 -7
- data/spec/lib/doorkeeper_spec.rb +1 -1
- data/spec/lib/models/revocable_spec.rb +3 -3
- data/spec/lib/oauth/authorization_code_request_spec.rb +127 -125
- data/spec/lib/oauth/base_request_spec.rb +160 -158
- data/spec/lib/oauth/base_response_spec.rb +27 -29
- data/spec/lib/oauth/client/credentials_spec.rb +1 -1
- data/spec/lib/oauth/client_credentials/creator_spec.rb +42 -5
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
- data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
- data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
- data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
- data/spec/lib/oauth/client_spec.rb +26 -26
- data/spec/lib/oauth/code_request_spec.rb +34 -34
- data/spec/lib/oauth/code_response_spec.rb +21 -25
- data/spec/lib/oauth/error_response_spec.rb +42 -44
- data/spec/lib/oauth/error_spec.rb +12 -14
- data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
- data/spec/lib/oauth/invalid_request_response_spec.rb +48 -50
- data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
- data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
- data/spec/lib/oauth/pre_authorization_spec.rb +159 -161
- data/spec/lib/oauth/refresh_token_request_spec.rb +138 -139
- data/spec/lib/oauth/scopes_spec.rb +104 -106
- data/spec/lib/oauth/token_request_spec.rb +115 -111
- data/spec/lib/oauth/token_response_spec.rb +71 -73
- data/spec/lib/oauth/token_spec.rb +121 -123
- data/spec/models/doorkeeper/access_grant_spec.rb +3 -5
- data/spec/models/doorkeeper/access_token_spec.rb +7 -7
- data/spec/models/doorkeeper/application_spec.rb +104 -77
- data/spec/requests/applications/applications_request_spec.rb +1 -1
- data/spec/requests/endpoints/authorization_spec.rb +5 -3
- data/spec/requests/flows/authorization_code_spec.rb +34 -22
- data/spec/requests/flows/client_credentials_spec.rb +1 -1
- data/spec/requests/flows/password_spec.rb +32 -12
- data/spec/requests/flows/refresh_token_spec.rb +19 -19
- data/spec/requests/flows/revoke_token_spec.rb +18 -12
- data/spec/spec_helper.rb +1 -4
- data/spec/support/shared/controllers_shared_context.rb +33 -23
- data/spec/validators/redirect_uri_validator_spec.rb +1 -1
- metadata +6 -5
- data/spec/support/http_method_shim.rb +0 -29
|
@@ -7,152 +7,150 @@ module Doorkeeper
|
|
|
7
7
|
class AccessToken
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
let(:request) { double.as_null_object }
|
|
12
|
+
describe Doorkeeper::OAuth::Token do
|
|
13
|
+
describe ".from_request" do
|
|
14
|
+
let(:request) { double.as_null_object }
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
let(:method) do
|
|
17
|
+
->(*) { "token-value" }
|
|
18
|
+
end
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
it "accepts anything that responds to #call" do
|
|
21
|
+
expect(method).to receive(:call).with(request)
|
|
22
|
+
described_class.from_request request, method
|
|
23
|
+
end
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
it "delegates methods received as symbols to described_class class" do
|
|
26
|
+
expect(described_class).to receive(:from_params).with(request)
|
|
27
|
+
described_class.from_request request, :from_params
|
|
28
|
+
end
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
it "stops at the first credentials found" do
|
|
31
|
+
not_called_method = double
|
|
32
|
+
expect(not_called_method).not_to receive(:call)
|
|
33
|
+
described_class.from_request request, ->(_r) {}, method, not_called_method
|
|
34
|
+
end
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
it "returns the credential from extractor method" do
|
|
37
|
+
credentials = described_class.from_request request, method
|
|
38
|
+
expect(credentials).to eq("token-value")
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
describe ".from_access_token_param" do
|
|
43
|
+
it "returns token from access_token parameter" do
|
|
44
|
+
request = double parameters: { access_token: "some-token" }
|
|
45
|
+
token = described_class.from_access_token_param(request)
|
|
46
|
+
expect(token).to eq("some-token")
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
describe ".from_bearer_param" do
|
|
51
|
+
it "returns token from bearer_token parameter" do
|
|
52
|
+
request = double parameters: { bearer_token: "some-token" }
|
|
53
|
+
token = described_class.from_bearer_param(request)
|
|
54
|
+
expect(token).to eq("some-token")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
describe ".from_bearer_authorization" do
|
|
59
|
+
it "returns token from capitalized authorization bearer" do
|
|
60
|
+
request = double authorization: "Bearer SomeToken"
|
|
61
|
+
token = described_class.from_bearer_authorization(request)
|
|
62
|
+
expect(token).to eq("SomeToken")
|
|
63
|
+
end
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
it "returns token from lowercased authorization bearer" do
|
|
66
|
+
request = double authorization: "bearer SomeToken"
|
|
67
|
+
token = described_class.from_bearer_authorization(request)
|
|
68
|
+
expect(token).to eq("SomeToken")
|
|
69
|
+
end
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
it "does not return token if authorization is not bearer" do
|
|
72
|
+
request = double authorization: "MAC SomeToken"
|
|
73
|
+
token = described_class.from_bearer_authorization(request)
|
|
74
|
+
expect(token).to be_blank
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
describe ".from_basic_authorization" do
|
|
79
|
+
it "returns token from capitalized authorization basic" do
|
|
80
|
+
request = double authorization: "Basic #{Base64.encode64 "SomeToken:"}"
|
|
81
|
+
token = described_class.from_basic_authorization(request)
|
|
82
|
+
expect(token).to eq("SomeToken")
|
|
83
|
+
end
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
it "returns token from lowercased authorization basic" do
|
|
86
|
+
request = double authorization: "basic #{Base64.encode64 "SomeToken:"}"
|
|
87
|
+
token = described_class.from_basic_authorization(request)
|
|
88
|
+
expect(token).to eq("SomeToken")
|
|
89
|
+
end
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
it "does not return token if authorization is not basic" do
|
|
92
|
+
request = double authorization: "MAC #{Base64.encode64 "SomeToken:"}"
|
|
93
|
+
token = described_class.from_basic_authorization(request)
|
|
94
|
+
expect(token).to be_blank
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe ".authenticate" do
|
|
99
|
+
context "refresh tokens are disabled (default)" do
|
|
100
|
+
context "refresh tokens are enabled" do
|
|
101
|
+
it "does not revoke previous refresh_token if token was found" do
|
|
102
|
+
token = ->(_r) { "token" }
|
|
103
|
+
expect(
|
|
104
|
+
Doorkeeper::AccessToken,
|
|
105
|
+
).to receive(:by_token).with("token").and_return(token)
|
|
106
|
+
expect(token).not_to receive(:revoke_previous_refresh_token!)
|
|
107
|
+
described_class.authenticate double, token
|
|
95
108
|
end
|
|
96
109
|
end
|
|
97
110
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
AccessToken
|
|
105
|
-
).to receive(:by_token).with("token").and_return(token)
|
|
106
|
-
expect(token).not_to receive(:revoke_previous_refresh_token!)
|
|
107
|
-
Token.authenticate double, token
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it "calls the finder if token was returned" do
|
|
112
|
-
token = ->(_r) { "token" }
|
|
113
|
-
expect(AccessToken).to receive(:by_token).with("token")
|
|
114
|
-
Token.authenticate double, token
|
|
115
|
-
end
|
|
116
|
-
end
|
|
111
|
+
it "calls the finder if token was returned" do
|
|
112
|
+
token = ->(_r) { "token" }
|
|
113
|
+
expect(Doorkeeper::AccessToken).to receive(:by_token).with("token")
|
|
114
|
+
described_class.authenticate double, token
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
118
|
+
context "token hashing is enabled" do
|
|
119
|
+
include_context "with token hashing enabled"
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
121
|
+
let(:hashed_token) { hashed_or_plain_token_func.call("token") }
|
|
122
|
+
let(:token) { ->(_r) { "token" } }
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
it "searches with the hashed token" do
|
|
125
|
+
expect(
|
|
126
|
+
Doorkeeper::AccessToken,
|
|
127
|
+
).to receive(:find_by).with(token: hashed_token).and_return(token)
|
|
128
|
+
described_class.authenticate double, token
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
it "revokes previous refresh_token if token was found" do
|
|
141
|
-
token = ->(_r) { "token" }
|
|
142
|
-
expect(
|
|
143
|
-
AccessToken
|
|
144
|
-
).to receive(:by_token).with("token").and_return(token)
|
|
145
|
-
expect(token).to receive(:revoke_previous_refresh_token!)
|
|
146
|
-
Token.authenticate double, token
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
it "calls the finder if token was returned" do
|
|
150
|
-
token = ->(_r) { "token" }
|
|
151
|
-
expect(AccessToken).to receive(:by_token).with("token")
|
|
152
|
-
Token.authenticate double, token
|
|
153
|
-
end
|
|
132
|
+
context "refresh tokens are enabled" do
|
|
133
|
+
before do
|
|
134
|
+
Doorkeeper.configure do
|
|
135
|
+
orm DOORKEEPER_ORM
|
|
136
|
+
use_refresh_token
|
|
154
137
|
end
|
|
155
138
|
end
|
|
139
|
+
|
|
140
|
+
it "revokes previous refresh_token if token was found" do
|
|
141
|
+
token = ->(_r) { "token" }
|
|
142
|
+
expect(
|
|
143
|
+
Doorkeeper::AccessToken,
|
|
144
|
+
).to receive(:by_token).with("token").and_return(token)
|
|
145
|
+
expect(token).to receive(:revoke_previous_refresh_token!)
|
|
146
|
+
described_class.authenticate double, token
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "calls the finder if token was returned" do
|
|
150
|
+
token = ->(_r) { "token" }
|
|
151
|
+
expect(Doorkeeper::AccessToken).to receive(:by_token).with("token")
|
|
152
|
+
described_class.authenticate double, token
|
|
153
|
+
end
|
|
156
154
|
end
|
|
157
155
|
end
|
|
158
156
|
end
|
|
@@ -81,9 +81,7 @@ describe Doorkeeper::AccessGrant do
|
|
|
81
81
|
)
|
|
82
82
|
|
|
83
83
|
# Not all the ORM support :id PK
|
|
84
|
-
if grant.respond_to?(:id)
|
|
85
|
-
expect(clazz.by_token(plain_text_token).id).to eq(grant.id)
|
|
86
|
-
end
|
|
84
|
+
expect(clazz.by_token(plain_text_token).id).to eq(grant.id) if grant.respond_to?(:id)
|
|
87
85
|
|
|
88
86
|
# And it modifies the token value
|
|
89
87
|
grant.reload
|
|
@@ -141,7 +139,7 @@ describe Doorkeeper::AccessGrant do
|
|
|
141
139
|
it "matches application" do
|
|
142
140
|
access_grant_for_different_app = FactoryBot.create(
|
|
143
141
|
:access_grant,
|
|
144
|
-
default_attributes.merge(application: FactoryBot.create(:application))
|
|
142
|
+
default_attributes.merge(application: FactoryBot.create(:application)),
|
|
145
143
|
)
|
|
146
144
|
|
|
147
145
|
described_class.revoke_all_for(application.id, resource_owner)
|
|
@@ -152,7 +150,7 @@ describe Doorkeeper::AccessGrant do
|
|
|
152
150
|
it "matches resource owner" do
|
|
153
151
|
access_grant_for_different_owner = FactoryBot.create(
|
|
154
152
|
:access_grant,
|
|
155
|
-
default_attributes.merge(resource_owner_id: 90)
|
|
153
|
+
default_attributes.merge(resource_owner_id: 90),
|
|
156
154
|
)
|
|
157
155
|
|
|
158
156
|
described_class.revoke_all_for application.id, resource_owner
|
|
@@ -212,7 +212,7 @@ module Doorkeeper
|
|
|
212
212
|
end
|
|
213
213
|
|
|
214
214
|
expect { FactoryBot.create :access_token }.to(
|
|
215
|
-
raise_error(Doorkeeper::Errors::UnableToGenerateToken)
|
|
215
|
+
raise_error(Doorkeeper::Errors::UnableToGenerateToken),
|
|
216
216
|
)
|
|
217
217
|
end
|
|
218
218
|
|
|
@@ -234,7 +234,7 @@ module Doorkeeper
|
|
|
234
234
|
end
|
|
235
235
|
|
|
236
236
|
expect { FactoryBot.create :access_token }.to(
|
|
237
|
-
raise_error(LoadError)
|
|
237
|
+
raise_error(LoadError),
|
|
238
238
|
)
|
|
239
239
|
end
|
|
240
240
|
|
|
@@ -245,7 +245,7 @@ module Doorkeeper
|
|
|
245
245
|
end
|
|
246
246
|
|
|
247
247
|
expect { FactoryBot.create :access_token }.to(
|
|
248
|
-
raise_error(Doorkeeper::Errors::TokenGeneratorNotFound, /NotReal/)
|
|
248
|
+
raise_error(Doorkeeper::Errors::TokenGeneratorNotFound, /NotReal/),
|
|
249
249
|
)
|
|
250
250
|
end
|
|
251
251
|
end
|
|
@@ -468,7 +468,7 @@ module Doorkeeper
|
|
|
468
468
|
it "matches application" do
|
|
469
469
|
access_token_for_different_app = FactoryBot.create(
|
|
470
470
|
:access_token,
|
|
471
|
-
default_attributes.merge(application: FactoryBot.create(:application))
|
|
471
|
+
default_attributes.merge(application: FactoryBot.create(:application)),
|
|
472
472
|
)
|
|
473
473
|
|
|
474
474
|
AccessToken.revoke_all_for application.id, resource_owner
|
|
@@ -479,7 +479,7 @@ module Doorkeeper
|
|
|
479
479
|
it "matches resource owner" do
|
|
480
480
|
access_token_for_different_owner = FactoryBot.create(
|
|
481
481
|
:access_token,
|
|
482
|
-
default_attributes.merge(resource_owner_id: 90)
|
|
482
|
+
default_attributes.merge(resource_owner_id: 90),
|
|
483
483
|
)
|
|
484
484
|
|
|
485
485
|
AccessToken.revoke_all_for application.id, resource_owner
|
|
@@ -561,7 +561,7 @@ module Doorkeeper
|
|
|
561
561
|
|
|
562
562
|
it "excludes tokens with scopes that are not present in server scopes" do
|
|
563
563
|
FactoryBot.create :access_token, default_attributes.merge(
|
|
564
|
-
application: application, scopes: "public read"
|
|
564
|
+
application: application, scopes: "public read",
|
|
565
565
|
)
|
|
566
566
|
last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
|
|
567
567
|
expect(last_token).to be_nil
|
|
@@ -570,7 +570,7 @@ module Doorkeeper
|
|
|
570
570
|
it "excludes tokens with scopes that are not present in application scopes" do
|
|
571
571
|
application = FactoryBot.create :application, scopes: "private read"
|
|
572
572
|
FactoryBot.create :access_token, default_attributes.merge(
|
|
573
|
-
application: application
|
|
573
|
+
application: application,
|
|
574
574
|
)
|
|
575
575
|
last_token = AccessToken.matching_token_for(application, resource_owner_id, scopes)
|
|
576
576
|
expect(last_token).to be_nil
|
|
@@ -13,6 +13,78 @@ module Doorkeeper
|
|
|
13
13
|
let(:uid) { SecureRandom.hex(8) }
|
|
14
14
|
let(:secret) { SecureRandom.hex(8) }
|
|
15
15
|
|
|
16
|
+
it "is invalid without a name" do
|
|
17
|
+
new_application.name = nil
|
|
18
|
+
expect(new_application).not_to be_valid
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "is invalid without determining confidentiality" do
|
|
22
|
+
new_application.confidential = nil
|
|
23
|
+
expect(new_application).not_to be_valid
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "generates uid on create" do
|
|
27
|
+
expect(new_application.uid).to be_nil
|
|
28
|
+
new_application.save
|
|
29
|
+
expect(new_application.uid).not_to be_nil
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "generates uid on create if an empty string" do
|
|
33
|
+
new_application.uid = ""
|
|
34
|
+
new_application.save
|
|
35
|
+
expect(new_application.uid).not_to be_blank
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "generates uid on create unless one is set" do
|
|
39
|
+
new_application.uid = uid
|
|
40
|
+
new_application.save
|
|
41
|
+
expect(new_application.uid).to eq(uid)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "is invalid without uid" do
|
|
45
|
+
new_application.save
|
|
46
|
+
new_application.uid = nil
|
|
47
|
+
expect(new_application).not_to be_valid
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "checks uniqueness of uid" do
|
|
51
|
+
app1 = FactoryBot.create(:application)
|
|
52
|
+
app2 = FactoryBot.create(:application)
|
|
53
|
+
app2.uid = app1.uid
|
|
54
|
+
expect(app2).not_to be_valid
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "expects database to throw an error when uids are the same" do
|
|
58
|
+
app1 = FactoryBot.create(:application)
|
|
59
|
+
app2 = FactoryBot.create(:application)
|
|
60
|
+
app2.uid = app1.uid
|
|
61
|
+
expect { app2.save!(validate: false) }.to raise_error(uniqueness_error)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "generate secret on create" do
|
|
65
|
+
expect(new_application.secret).to be_nil
|
|
66
|
+
new_application.save
|
|
67
|
+
expect(new_application.secret).not_to be_nil
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "generate secret on create if is blank string" do
|
|
71
|
+
new_application.secret = ""
|
|
72
|
+
new_application.save
|
|
73
|
+
expect(new_application.secret).not_to be_blank
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "generate secret on create unless one is set" do
|
|
77
|
+
new_application.secret = secret
|
|
78
|
+
new_application.save
|
|
79
|
+
expect(new_application.secret).to eq(secret)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "is invalid without secret" do
|
|
83
|
+
new_application.save
|
|
84
|
+
new_application.secret = nil
|
|
85
|
+
expect(new_application).not_to be_valid
|
|
86
|
+
end
|
|
87
|
+
|
|
16
88
|
context "application_owner is enabled" do
|
|
17
89
|
before do
|
|
18
90
|
Doorkeeper.configure do
|
|
@@ -48,40 +120,6 @@ module Doorkeeper
|
|
|
48
120
|
end
|
|
49
121
|
end
|
|
50
122
|
|
|
51
|
-
it "is invalid without a name" do
|
|
52
|
-
new_application.name = nil
|
|
53
|
-
expect(new_application).not_to be_valid
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "is invalid without determining confidentiality" do
|
|
57
|
-
new_application.confidential = nil
|
|
58
|
-
expect(new_application).not_to be_valid
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "generates uid on create" do
|
|
62
|
-
expect(new_application.uid).to be_nil
|
|
63
|
-
new_application.save
|
|
64
|
-
expect(new_application.uid).not_to be_nil
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
it "generates uid on create if an empty string" do
|
|
68
|
-
new_application.uid = ""
|
|
69
|
-
new_application.save
|
|
70
|
-
expect(new_application.uid).not_to be_blank
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it "generates uid on create unless one is set" do
|
|
74
|
-
new_application.uid = uid
|
|
75
|
-
new_application.save
|
|
76
|
-
expect(new_application.uid).to eq(uid)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
it "is invalid without uid" do
|
|
80
|
-
new_application.save
|
|
81
|
-
new_application.uid = nil
|
|
82
|
-
expect(new_application).not_to be_valid
|
|
83
|
-
end
|
|
84
|
-
|
|
85
123
|
context "redirect URI" do
|
|
86
124
|
context "when grant flows allow blank redirect URI" do
|
|
87
125
|
before do
|
|
@@ -127,44 +165,6 @@ module Doorkeeper
|
|
|
127
165
|
end
|
|
128
166
|
end
|
|
129
167
|
|
|
130
|
-
it "checks uniqueness of uid" do
|
|
131
|
-
app1 = FactoryBot.create(:application)
|
|
132
|
-
app2 = FactoryBot.create(:application)
|
|
133
|
-
app2.uid = app1.uid
|
|
134
|
-
expect(app2).not_to be_valid
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
it "expects database to throw an error when uids are the same" do
|
|
138
|
-
app1 = FactoryBot.create(:application)
|
|
139
|
-
app2 = FactoryBot.create(:application)
|
|
140
|
-
app2.uid = app1.uid
|
|
141
|
-
expect { app2.save!(validate: false) }.to raise_error(uniqueness_error)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
it "generate secret on create" do
|
|
145
|
-
expect(new_application.secret).to be_nil
|
|
146
|
-
new_application.save
|
|
147
|
-
expect(new_application.secret).not_to be_nil
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
it "generate secret on create if is blank string" do
|
|
151
|
-
new_application.secret = ""
|
|
152
|
-
new_application.save
|
|
153
|
-
expect(new_application.secret).not_to be_blank
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
it "generate secret on create unless one is set" do
|
|
157
|
-
new_application.secret = secret
|
|
158
|
-
new_application.save
|
|
159
|
-
expect(new_application.secret).to eq(secret)
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
it "is invalid without secret" do
|
|
163
|
-
new_application.save
|
|
164
|
-
new_application.secret = nil
|
|
165
|
-
expect(new_application).not_to be_valid
|
|
166
|
-
end
|
|
167
|
-
|
|
168
168
|
context "with hashing enabled" do
|
|
169
169
|
include_context "with application hashing enabled"
|
|
170
170
|
let(:app) { FactoryBot.create :application }
|
|
@@ -238,7 +238,7 @@ module Doorkeeper
|
|
|
238
238
|
end
|
|
239
239
|
end
|
|
240
240
|
|
|
241
|
-
describe
|
|
241
|
+
describe "#ordered_by" do
|
|
242
242
|
let(:applications) { FactoryBot.create_list(:application, 5) }
|
|
243
243
|
|
|
244
244
|
context "when a direction is not specified" do
|
|
@@ -281,7 +281,7 @@ module Doorkeeper
|
|
|
281
281
|
end
|
|
282
282
|
end
|
|
283
283
|
|
|
284
|
-
describe
|
|
284
|
+
describe "#authorized_for" do
|
|
285
285
|
let(:resource_owner) { double(:resource_owner, id: 10) }
|
|
286
286
|
|
|
287
287
|
it "is empty if the application is not authorized for anyone" do
|
|
@@ -313,7 +313,7 @@ module Doorkeeper
|
|
|
313
313
|
end
|
|
314
314
|
end
|
|
315
315
|
|
|
316
|
-
describe
|
|
316
|
+
describe "#revoke_tokens_and_grants_for" do
|
|
317
317
|
it "revokes all access tokens and access grants" do
|
|
318
318
|
application_id = 42
|
|
319
319
|
resource_owner = double
|
|
@@ -326,7 +326,7 @@ module Doorkeeper
|
|
|
326
326
|
end
|
|
327
327
|
end
|
|
328
328
|
|
|
329
|
-
describe
|
|
329
|
+
describe "#by_uid_and_secret" do
|
|
330
330
|
context "when application is private/confidential" do
|
|
331
331
|
it "finds the application via uid/secret" do
|
|
332
332
|
app = FactoryBot.create :application
|
|
@@ -360,7 +360,7 @@ module Doorkeeper
|
|
|
360
360
|
end
|
|
361
361
|
end
|
|
362
362
|
|
|
363
|
-
describe
|
|
363
|
+
describe "#confidential?" do
|
|
364
364
|
subject { FactoryBot.create(:application, confidential: confidential).confidential? }
|
|
365
365
|
|
|
366
366
|
context "when application is private/confidential" do
|
|
@@ -373,5 +373,32 @@ module Doorkeeper
|
|
|
373
373
|
it { expect(subject).to eq(false) }
|
|
374
374
|
end
|
|
375
375
|
end
|
|
376
|
+
|
|
377
|
+
describe "#as_json" do
|
|
378
|
+
let(:app) { FactoryBot.create :application, secret: "123123123" }
|
|
379
|
+
|
|
380
|
+
before do
|
|
381
|
+
allow(Doorkeeper.configuration)
|
|
382
|
+
.to receive(:application_secret_strategy).and_return(Doorkeeper::SecretStoring::Plain)
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
it "includes plaintext secret" do
|
|
386
|
+
expect(app.as_json).to include("secret" => "123123123")
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
it "respects custom options" do
|
|
390
|
+
expect(app.as_json(except: :secret)).not_to include("secret")
|
|
391
|
+
expect(app.as_json(only: :id)).to match("id" => app.id)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# AR specific
|
|
395
|
+
if DOORKEEPER_ORM == :active_record
|
|
396
|
+
it "correctly works with #to_json" do
|
|
397
|
+
ActiveRecord::Base.include_root_in_json = true
|
|
398
|
+
expect(app.to_json(include_root_in_json: true)).to match(/application.+?:\{/)
|
|
399
|
+
ActiveRecord::Base.include_root_in_json = false
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
end
|
|
376
403
|
end
|
|
377
404
|
end
|
|
@@ -79,9 +79,11 @@ feature "Authorization endpoint" do
|
|
|
79
79
|
scenario "raises exception on forged requests" do
|
|
80
80
|
allowing_forgery_protection do
|
|
81
81
|
expect do
|
|
82
|
-
page.driver.post authorization_endpoint_url(
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
page.driver.post authorization_endpoint_url(
|
|
83
|
+
client_id: @client.uid,
|
|
84
|
+
redirect_uri: @client.redirect_uri,
|
|
85
|
+
response_type: "code",
|
|
86
|
+
)
|
|
85
87
|
end.to raise_error(ActionController::InvalidAuthenticityToken)
|
|
86
88
|
end
|
|
87
89
|
end
|