doorkeeper 5.1.2 → 5.2.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of doorkeeper might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Appraisals +1 -1
- data/CHANGELOG.md +854 -0
- data/CONTRIBUTING.md +11 -9
- data/Dangerfile +2 -2
- data/Dockerfile +29 -0
- data/Gemfile +3 -2
- data/NEWS.md +1 -819
- data/README.md +11 -3
- data/RELEASING.md +6 -5
- data/app/controllers/doorkeeper/application_controller.rb +1 -1
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -1
- data/app/controllers/doorkeeper/applications_controller.rb +5 -3
- data/app/controllers/doorkeeper/authorizations_controller.rb +14 -7
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
- data/app/controllers/doorkeeper/tokens_controller.rb +32 -9
- data/app/views/doorkeeper/applications/_form.html.erb +0 -6
- data/app/views/doorkeeper/applications/show.html.erb +1 -1
- data/config/locales/en.yml +8 -2
- data/doorkeeper.gemspec +9 -1
- data/gemfiles/rails_5_0.gemfile +1 -0
- data/gemfiles/rails_5_1.gemfile +1 -0
- data/gemfiles/rails_5_2.gemfile +1 -0
- data/gemfiles/rails_6_0.gemfile +2 -1
- data/gemfiles/rails_master.gemfile +1 -0
- data/lib/doorkeeper/config/option.rb +13 -7
- data/lib/doorkeeper/config.rb +88 -6
- data/lib/doorkeeper/errors.rb +13 -18
- data/lib/doorkeeper/grape/helpers.rb +5 -1
- data/lib/doorkeeper/helpers/controller.rb +23 -4
- data/lib/doorkeeper/models/access_token_mixin.rb +43 -2
- data/lib/doorkeeper/oauth/authorization/code.rb +11 -13
- data/lib/doorkeeper/oauth/authorization/token.rb +1 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -9
- data/lib/doorkeeper/oauth/base_request.rb +2 -0
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +14 -0
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +8 -0
- data/lib/doorkeeper/oauth/code_request.rb +5 -11
- data/lib/doorkeeper/oauth/code_response.rb +2 -2
- data/lib/doorkeeper/oauth/error_response.rb +1 -1
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +18 -4
- data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
- data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +70 -37
- data/lib/doorkeeper/oauth/refresh_token_request.rb +13 -10
- data/lib/doorkeeper/oauth/token_introspection.rb +23 -13
- data/lib/doorkeeper/oauth/token_request.rb +4 -18
- data/lib/doorkeeper/orm/active_record/access_grant.rb +1 -1
- data/lib/doorkeeper/orm/active_record/access_token.rb +2 -2
- data/lib/doorkeeper/orm/active_record/application.rb +15 -69
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
- data/lib/doorkeeper/orm/active_record.rb +19 -3
- data/lib/doorkeeper/request/authorization_code.rb +2 -0
- data/lib/doorkeeper/request.rb +6 -11
- data/lib/doorkeeper/server.rb +2 -6
- data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +4 -0
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +6 -6
- data/lib/generators/doorkeeper/templates/initializer.rb +110 -33
- data/lib/generators/doorkeeper/templates/migration.rb.erb +4 -1
- data/spec/controllers/applications_controller_spec.rb +93 -0
- data/spec/controllers/authorizations_controller_spec.rb +143 -62
- data/spec/controllers/protected_resources_controller_spec.rb +3 -3
- data/spec/controllers/tokens_controller_spec.rb +205 -37
- data/spec/dummy/config/application.rb +3 -1
- data/spec/dummy/config/initializers/doorkeeper.rb +54 -9
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +1 -1
- data/spec/lib/config_spec.rb +43 -1
- data/spec/lib/oauth/authorization_code_request_spec.rb +13 -1
- data/spec/lib/oauth/base_request_spec.rb +33 -16
- data/spec/lib/oauth/client_credentials/creator_spec.rb +3 -0
- data/spec/lib/oauth/code_request_spec.rb +27 -28
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +17 -2
- data/spec/lib/oauth/invalid_request_response_spec.rb +75 -0
- data/spec/lib/oauth/pre_authorization_spec.rb +76 -66
- data/spec/lib/oauth/refresh_token_request_spec.rb +1 -0
- data/spec/lib/oauth/token_request_spec.rb +20 -17
- data/spec/lib/server_spec.rb +0 -12
- data/spec/models/doorkeeper/access_grant_spec.rb +21 -2
- data/spec/models/doorkeeper/access_token_spec.rb +35 -4
- data/spec/models/doorkeeper/application_spec.rb +275 -370
- data/spec/requests/endpoints/authorization_spec.rb +21 -5
- data/spec/requests/endpoints/token_spec.rb +1 -1
- data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
- data/spec/requests/flows/authorization_code_spec.rb +93 -27
- data/spec/requests/flows/client_credentials_spec.rb +38 -0
- data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
- data/spec/requests/flows/implicit_grant_spec.rb +9 -8
- data/spec/requests/flows/password_spec.rb +37 -0
- data/spec/requests/flows/refresh_token_spec.rb +1 -1
- data/spec/requests/flows/revoke_token_spec.rb +19 -11
- data/spec/support/doorkeeper_rspec.rb +1 -1
- data/spec/support/helpers/request_spec_helper.rb +14 -2
- data/spec/validators/redirect_uri_validator_spec.rb +40 -15
- metadata +16 -15
- data/.coveralls.yml +0 -1
- data/.github/ISSUE_TEMPLATE.md +0 -25
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
- data/.gitignore +0 -20
- data/.gitlab-ci.yml +0 -16
- data/.hound.yml +0 -3
- data/.rspec +0 -1
- data/.rubocop.yml +0 -50
- data/.travis.yml +0 -35
- data/app/validators/redirect_uri_validator.rb +0 -50
@@ -4,18 +4,23 @@ require "spec_helper"
|
|
4
4
|
|
5
5
|
module Doorkeeper::OAuth
|
6
6
|
describe CodeRequest do
|
7
|
-
let
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
7
|
+
let :pre_auth do
|
8
|
+
server = Doorkeeper.configuration
|
9
|
+
allow(server).to receive(:default_scopes).and_return(Scopes.from_string("public"))
|
10
|
+
allow(server).to receive(:grant_flows).and_return(Scopes.from_string("authorization_code"))
|
11
|
+
|
12
|
+
application = FactoryBot.create(:application, scopes: "public")
|
13
|
+
client = Doorkeeper::OAuth::Client.new(application)
|
14
|
+
|
15
|
+
attributes = {
|
16
|
+
client_id: client.uid,
|
17
|
+
response_type: "code",
|
18
|
+
redirect_uri: "https://app.com/callback",
|
19
|
+
}
|
20
|
+
|
21
|
+
pre_auth = PreAuthorization.new(server, attributes)
|
22
|
+
pre_auth.authorizable?
|
23
|
+
pre_auth
|
19
24
|
end
|
20
25
|
|
21
26
|
let(:owner) { double :owner, id: 8900 }
|
@@ -24,24 +29,18 @@ module Doorkeeper::OAuth
|
|
24
29
|
CodeRequest.new(pre_auth, owner)
|
25
30
|
end
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
subject.authorize
|
30
|
-
|
32
|
+
context "when pre_auth is authorized" do
|
33
|
+
it "creates an access grant and returns a code response" do
|
34
|
+
expect { subject.authorize }.to change { Doorkeeper::AccessGrant.count }.by(1)
|
35
|
+
expect(subject.authorize).to be_a(CodeResponse)
|
36
|
+
end
|
31
37
|
end
|
32
38
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
allow(pre_auth).to receive(:authorizable?).and_return(false)
|
39
|
-
expect { subject.authorize }.not_to(change { Doorkeeper::AccessGrant.count })
|
40
|
-
end
|
41
|
-
|
42
|
-
it "returns a error response" do
|
43
|
-
allow(pre_auth).to receive(:authorizable?).and_return(false)
|
44
|
-
expect(subject.authorize).to be_a(ErrorResponse)
|
39
|
+
context "when pre_auth is denied" do
|
40
|
+
it "does not create access grant and returns a error response" do
|
41
|
+
expect { subject.deny }.not_to(change { Doorkeeper::AccessGrant.count })
|
42
|
+
expect(subject.deny).to be_a(ErrorResponse)
|
43
|
+
end
|
45
44
|
end
|
46
45
|
end
|
47
46
|
end
|
@@ -40,13 +40,28 @@ module Doorkeeper::OAuth::Helpers
|
|
40
40
|
expect(URIChecker.valid?(uri)).to be_falsey
|
41
41
|
end
|
42
42
|
|
43
|
+
it "is invalid if localhost is resolved as as scheme (no scheme specified)" do
|
44
|
+
uri = "localhost:8080"
|
45
|
+
expect(URIChecker.valid?(uri)).to be_falsey
|
46
|
+
end
|
47
|
+
|
48
|
+
it "is invalid if scheme is missing #2" do
|
49
|
+
uri = "app.co:80"
|
50
|
+
expect(URIChecker.valid?(uri)).to be_falsey
|
51
|
+
end
|
52
|
+
|
43
53
|
it "is invalid if is not an uri" do
|
44
54
|
uri = " "
|
45
55
|
expect(URIChecker.valid?(uri)).to be_falsey
|
46
56
|
end
|
47
57
|
|
48
|
-
it "is valid for
|
49
|
-
uri = "
|
58
|
+
it "is valid for custom schemes" do
|
59
|
+
uri = "com.example.app:/test"
|
60
|
+
expect(URIChecker.valid?(uri)).to be_truthy
|
61
|
+
end
|
62
|
+
|
63
|
+
it "is valid for custom schemes with authority marker (common misconfiguration)" do
|
64
|
+
uri = "com.example.app://test"
|
50
65
|
expect(URIChecker.valid?(uri)).to be_truthy
|
51
66
|
end
|
52
67
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
module Doorkeeper::OAuth
|
6
|
+
describe InvalidRequestResponse do
|
7
|
+
describe "#name" do
|
8
|
+
it { expect(subject.name).to eq(:invalid_request) }
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#status" do
|
12
|
+
it { expect(subject.status).to eq(:bad_request) }
|
13
|
+
end
|
14
|
+
|
15
|
+
describe :from_request do
|
16
|
+
let(:response) { InvalidRequestResponse.from_request(request) }
|
17
|
+
|
18
|
+
context "missing param" do
|
19
|
+
let(:request) { double(missing_param: "some_param") }
|
20
|
+
|
21
|
+
it "sets a description" do
|
22
|
+
expect(response.description).to eq(
|
23
|
+
I18n.t(:missing_param, scope: %i[doorkeeper errors messages invalid_request], value: "some_param")
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "sets the reason" do
|
28
|
+
expect(response.reason).to eq(:missing_param)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "server doesn not support_pkce" do
|
33
|
+
let(:request) { double(invalid_request_reason: :not_support_pkce) }
|
34
|
+
|
35
|
+
it "sets a description" do
|
36
|
+
expect(response.description).to eq(
|
37
|
+
I18n.t(:not_support_pkce, scope: %i[doorkeeper errors messages invalid_request])
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "sets the reason" do
|
42
|
+
expect(response.reason).to eq(:not_support_pkce)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "request is not authorized" do
|
47
|
+
let(:request) { double(invalid_request_reason: :request_not_authorized) }
|
48
|
+
|
49
|
+
it "sets a description" do
|
50
|
+
expect(response.description).to eq(
|
51
|
+
I18n.t(:request_not_authorized, scope: %i[doorkeeper errors messages invalid_request])
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "sets the reason" do
|
56
|
+
expect(response.reason).to eq(:request_not_authorized)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "unknown reason" do
|
61
|
+
let(:request) { double(invalid_request_reason: :unknown_reason) }
|
62
|
+
|
63
|
+
it "sets a description" do
|
64
|
+
expect(response.description).to eq(
|
65
|
+
I18n.t(:unknown, scope: %i[doorkeeper errors messages invalid_request])
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "unknown reason" do
|
70
|
+
expect(response.reason).to eq(:unknown_reason)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -6,31 +6,25 @@ module Doorkeeper::OAuth
|
|
6
6
|
describe PreAuthorization do
|
7
7
|
let(:server) do
|
8
8
|
server = Doorkeeper.configuration
|
9
|
-
allow(server).to receive(:default_scopes).and_return(Scopes.
|
10
|
-
allow(server).to receive(:
|
9
|
+
allow(server).to receive(:default_scopes).and_return(Scopes.from_string("default"))
|
10
|
+
allow(server).to receive(:optional_scopes).and_return(Scopes.from_string("public profile"))
|
11
11
|
server
|
12
12
|
end
|
13
13
|
|
14
|
-
let(:application)
|
15
|
-
|
16
|
-
allow(application).to receive(:scopes).and_return(Scopes.from_string(""))
|
17
|
-
application
|
18
|
-
end
|
19
|
-
|
20
|
-
let(:client) do
|
21
|
-
double :client, redirect_uri: "http://tst.com/auth", application: application
|
22
|
-
end
|
14
|
+
let(:application) { FactoryBot.create(:application, redirect_uri: "https://app.com/callback") }
|
15
|
+
let(:client) { Client.find(application.uid) }
|
23
16
|
|
24
17
|
let :attributes do
|
25
18
|
{
|
19
|
+
client_id: client.uid,
|
26
20
|
response_type: "code",
|
27
|
-
redirect_uri: "
|
21
|
+
redirect_uri: "https://app.com/callback",
|
28
22
|
state: "save-this",
|
29
23
|
}
|
30
24
|
end
|
31
25
|
|
32
26
|
subject do
|
33
|
-
PreAuthorization.new(server,
|
27
|
+
PreAuthorization.new(server, attributes)
|
34
28
|
end
|
35
29
|
|
36
30
|
it "is authorizable when request is valid" do
|
@@ -38,25 +32,25 @@ module Doorkeeper::OAuth
|
|
38
32
|
end
|
39
33
|
|
40
34
|
it "accepts code as response type" do
|
41
|
-
|
35
|
+
attributes[:response_type] = "code"
|
42
36
|
expect(subject).to be_authorizable
|
43
37
|
end
|
44
38
|
|
45
39
|
it "accepts token as response type" do
|
46
40
|
allow(server).to receive(:grant_flows).and_return(["implicit"])
|
47
|
-
|
41
|
+
attributes[:response_type] = "token"
|
48
42
|
expect(subject).to be_authorizable
|
49
43
|
end
|
50
44
|
|
51
45
|
context "when using default grant flows" do
|
52
46
|
it 'accepts "code" as response type' do
|
53
|
-
|
47
|
+
attributes[:response_type] = "code"
|
54
48
|
expect(subject).to be_authorizable
|
55
49
|
end
|
56
50
|
|
57
51
|
it 'accepts "token" as response type' do
|
58
52
|
allow(server).to receive(:grant_flows).and_return(["implicit"])
|
59
|
-
|
53
|
+
attributes[:response_type] = "token"
|
60
54
|
expect(subject).to be_authorizable
|
61
55
|
end
|
62
56
|
end
|
@@ -67,7 +61,7 @@ module Doorkeeper::OAuth
|
|
67
61
|
end
|
68
62
|
|
69
63
|
it 'does not accept "code" as response type' do
|
70
|
-
|
64
|
+
attributes[:response_type] = "code"
|
71
65
|
expect(subject).not_to be_authorizable
|
72
66
|
end
|
73
67
|
end
|
@@ -78,94 +72,90 @@ module Doorkeeper::OAuth
|
|
78
72
|
end
|
79
73
|
|
80
74
|
it 'does not accept "token" as response type' do
|
81
|
-
|
75
|
+
attributes[:response_type] = "token"
|
82
76
|
expect(subject).not_to be_authorizable
|
83
77
|
end
|
84
78
|
end
|
85
79
|
|
86
80
|
context "client application does not restrict valid scopes" do
|
87
81
|
it "accepts valid scopes" do
|
88
|
-
|
82
|
+
attributes[:scope] = "public"
|
89
83
|
expect(subject).to be_authorizable
|
90
84
|
end
|
91
85
|
|
92
86
|
it "rejects (globally) non-valid scopes" do
|
93
|
-
|
87
|
+
attributes[:scope] = "invalid"
|
94
88
|
expect(subject).not_to be_authorizable
|
95
89
|
end
|
96
90
|
|
97
91
|
it "accepts scopes which are permitted for grant_type" do
|
98
92
|
allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
|
99
|
-
|
93
|
+
attributes[:scope] = "public"
|
100
94
|
expect(subject).to be_authorizable
|
101
95
|
end
|
102
96
|
|
103
97
|
it "rejects scopes which are not permitted for grant_type" do
|
104
98
|
allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
|
105
|
-
|
99
|
+
attributes[:scope] = "public"
|
106
100
|
expect(subject).not_to be_authorizable
|
107
101
|
end
|
108
102
|
end
|
109
103
|
|
110
104
|
context "client application restricts valid scopes" do
|
111
105
|
let(:application) do
|
112
|
-
application
|
113
|
-
allow(application).to receive(:scopes).and_return(Scopes.from_string("public nonsense"))
|
114
|
-
application
|
106
|
+
FactoryBot.create(:application, scopes: Scopes.from_string("public nonsense"))
|
115
107
|
end
|
116
108
|
|
117
109
|
it "accepts valid scopes" do
|
118
|
-
|
110
|
+
attributes[:scope] = "public"
|
119
111
|
expect(subject).to be_authorizable
|
120
112
|
end
|
121
113
|
|
122
114
|
it "rejects (globally) non-valid scopes" do
|
123
|
-
|
115
|
+
attributes[:scope] = "invalid"
|
124
116
|
expect(subject).not_to be_authorizable
|
125
117
|
end
|
126
118
|
|
127
119
|
it "rejects (application level) non-valid scopes" do
|
128
|
-
|
120
|
+
attributes[:scope] = "profile"
|
129
121
|
expect(subject).to_not be_authorizable
|
130
122
|
end
|
131
123
|
|
132
124
|
it "accepts scopes which are permitted for grant_type" do
|
133
125
|
allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:public])
|
134
|
-
|
126
|
+
attributes[:scope] = "public"
|
135
127
|
expect(subject).to be_authorizable
|
136
128
|
end
|
137
129
|
|
138
130
|
it "rejects scopes which are not permitted for grant_type" do
|
139
131
|
allow(server).to receive(:scopes_by_grant_type).and_return(authorization_code: [:profile])
|
140
|
-
|
132
|
+
attributes[:scope] = "public"
|
141
133
|
expect(subject).not_to be_authorizable
|
142
134
|
end
|
143
135
|
end
|
144
136
|
|
145
|
-
|
146
|
-
|
147
|
-
subject.scope = nil
|
148
|
-
expect(subject.scope).to eq("default")
|
149
|
-
expect(subject.scopes).to eq(Scopes.from_string("default"))
|
150
|
-
end
|
151
|
-
|
152
|
-
context "with native redirect uri" do
|
153
|
-
let(:native_redirect_uri) { "urn:ietf:wg:oauth:2.0:oob" }
|
137
|
+
context "when scope is not provided to pre_authorization" do
|
138
|
+
before { attributes[:scope] = nil }
|
154
139
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
140
|
+
context "when default scopes is provided" do
|
141
|
+
it "uses default scopes" do
|
142
|
+
allow(server).to receive(:default_scopes).and_return(Scopes.from_string("default_scope"))
|
143
|
+
expect(subject).to be_authorizable
|
144
|
+
expect(subject.scope).to eq("default_scope")
|
145
|
+
expect(subject.scopes).to eq(Scopes.from_string("default_scope"))
|
146
|
+
end
|
159
147
|
end
|
160
148
|
|
161
|
-
|
162
|
-
|
163
|
-
|
149
|
+
context "when default scopes is none" do
|
150
|
+
it "not be authorizable when none default scope" do
|
151
|
+
allow(server).to receive(:default_scopes).and_return(Scopes.new)
|
152
|
+
expect(subject).not_to be_authorizable
|
153
|
+
end
|
164
154
|
end
|
165
155
|
end
|
166
156
|
|
167
157
|
it "matches the redirect uri against client's one" do
|
168
|
-
|
158
|
+
attributes[:redirect_uri] = "http://nothesame.com"
|
169
159
|
expect(subject).not_to be_authorizable
|
170
160
|
end
|
171
161
|
|
@@ -174,41 +164,61 @@ module Doorkeeper::OAuth
|
|
174
164
|
end
|
175
165
|
|
176
166
|
it "rejects if response type is not allowed" do
|
177
|
-
|
167
|
+
attributes[:response_type] = "whops"
|
178
168
|
expect(subject).not_to be_authorizable
|
179
169
|
end
|
180
170
|
|
181
171
|
it "requires an existing client" do
|
182
|
-
|
172
|
+
attributes[:client_id] = nil
|
183
173
|
expect(subject).not_to be_authorizable
|
184
174
|
end
|
185
175
|
|
186
176
|
it "requires a redirect uri" do
|
187
|
-
|
177
|
+
attributes[:redirect_uri] = nil
|
188
178
|
expect(subject).not_to be_authorizable
|
189
179
|
end
|
190
180
|
|
191
181
|
describe "as_json" do
|
192
|
-
|
193
|
-
let(:client_name) { "Acme Co." }
|
182
|
+
before { subject.authorizable? }
|
194
183
|
|
195
|
-
|
196
|
-
|
197
|
-
|
184
|
+
it { is_expected.to respond_to :as_json }
|
185
|
+
|
186
|
+
shared_examples "returns the pre authorization" do
|
187
|
+
it "returns the pre authorization" do
|
188
|
+
expect(json[:client_id]).to eq client.uid
|
189
|
+
expect(json[:redirect_uri]).to eq subject.redirect_uri
|
190
|
+
expect(json[:state]).to eq subject.state
|
191
|
+
expect(json[:response_type]).to eq subject.response_type
|
192
|
+
expect(json[:scope]).to eq subject.scope
|
193
|
+
expect(json[:client_name]).to eq client.name
|
194
|
+
expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
|
195
|
+
end
|
198
196
|
end
|
199
197
|
|
200
|
-
|
198
|
+
context "when attributes param is not passed" do
|
199
|
+
let(:json) { subject.as_json }
|
201
200
|
|
202
|
-
|
201
|
+
include_examples "returns the pre authorization"
|
202
|
+
end
|
203
|
+
|
204
|
+
context "when attributes param is passed" do
|
205
|
+
context "when attributes is a hash" do
|
206
|
+
let(:custom_attributes) { { custom_id: "1234", custom_name: "a pretty good name" } }
|
207
|
+
let(:json) { subject.as_json(custom_attributes) }
|
208
|
+
|
209
|
+
include_examples "returns the pre authorization"
|
210
|
+
|
211
|
+
it "merges the attributes in params" do
|
212
|
+
expect(json[:custom_id]).to eq custom_attributes[:custom_id]
|
213
|
+
expect(json[:custom_name]).to eq custom_attributes[:custom_name]
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context "when attributes is not a hash" do
|
218
|
+
let(:json) { subject.as_json(nil) }
|
203
219
|
|
204
|
-
|
205
|
-
|
206
|
-
expect(json[:redirect_uri]).to eq subject.redirect_uri
|
207
|
-
expect(json[:state]).to eq subject.state
|
208
|
-
expect(json[:response_type]).to eq subject.response_type
|
209
|
-
expect(json[:scope]).to eq subject.scope
|
210
|
-
expect(json[:client_name]).to eq client_name
|
211
|
-
expect(json[:status]).to eq I18n.t("doorkeeper.pre_authorization.status")
|
220
|
+
include_examples "returns the pre authorization"
|
221
|
+
end
|
212
222
|
end
|
213
223
|
end
|
214
224
|
end
|
@@ -9,15 +9,21 @@ module Doorkeeper::OAuth
|
|
9
9
|
end
|
10
10
|
|
11
11
|
let :pre_auth do
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
server = Doorkeeper.configuration
|
13
|
+
allow(server).to receive(:default_scopes).and_return(Scopes.from_string("public"))
|
14
|
+
allow(server).to receive(:grant_flows).and_return(Scopes.from_string("implicit"))
|
15
|
+
|
16
|
+
client = Doorkeeper::OAuth::Client.new(application)
|
17
|
+
|
18
|
+
attributes = {
|
19
|
+
client_id: client.uid,
|
20
|
+
response_type: "token",
|
21
|
+
redirect_uri: "https://app.com/callback",
|
22
|
+
}
|
23
|
+
|
24
|
+
pre_auth = PreAuthorization.new(server, attributes)
|
25
|
+
pre_auth.authorizable?
|
26
|
+
pre_auth
|
21
27
|
end
|
22
28
|
|
23
29
|
let :owner do
|
@@ -38,14 +44,11 @@ module Doorkeeper::OAuth
|
|
38
44
|
expect(subject.authorize).to be_a(CodeResponse)
|
39
45
|
end
|
40
46
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
it "returns a error response" do
|
47
|
-
allow(pre_auth).to receive(:authorizable?).and_return(false)
|
48
|
-
expect(subject.authorize).to be_a(ErrorResponse)
|
47
|
+
context "when pre_auth is denied" do
|
48
|
+
it "does not create token and returns a error response" do
|
49
|
+
expect { subject.deny }.not_to(change { Doorkeeper::AccessToken.count })
|
50
|
+
expect(subject.deny).to be_a(ErrorResponse)
|
51
|
+
end
|
49
52
|
end
|
50
53
|
|
51
54
|
describe "with custom expiration" do
|
data/spec/lib/server_spec.rb
CHANGED
@@ -10,12 +10,6 @@ describe Doorkeeper::Server do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
describe ".authorization_request" do
|
13
|
-
it "raises error when strategy does not exist" do
|
14
|
-
expect do
|
15
|
-
subject.authorization_request(:duh)
|
16
|
-
end.to raise_error(Doorkeeper::Errors::InvalidAuthorizationStrategy)
|
17
|
-
end
|
18
|
-
|
19
13
|
it "raises error when strategy does not match phase" do
|
20
14
|
expect do
|
21
15
|
subject.token_request(:code)
|
@@ -29,12 +23,6 @@ describe Doorkeeper::Server do
|
|
29
23
|
.and_return(["authorization_code"])
|
30
24
|
end
|
31
25
|
|
32
|
-
it "raises error when using the disabled Implicit strategy" do
|
33
|
-
expect do
|
34
|
-
subject.authorization_request(:token)
|
35
|
-
end.to raise_error(Doorkeeper::Errors::InvalidAuthorizationStrategy)
|
36
|
-
end
|
37
|
-
|
38
26
|
it "raises error when using the disabled Client Credentials strategy" do
|
39
27
|
expect do
|
40
28
|
subject.token_request(:client_credentials)
|
@@ -61,10 +61,29 @@ describe Doorkeeper::AccessGrant do
|
|
61
61
|
it "upgrades a plain token when falling back to it" do
|
62
62
|
# Side-effect: This will automatically upgrade the token
|
63
63
|
expect(clazz).to receive(:upgrade_fallback_value).and_call_original
|
64
|
-
expect(clazz.by_token(plain_text_token))
|
64
|
+
expect(clazz.by_token(plain_text_token))
|
65
|
+
.to have_attributes(
|
66
|
+
resource_owner_id: grant.resource_owner_id,
|
67
|
+
application_id: grant.application_id,
|
68
|
+
redirect_uri: grant.redirect_uri,
|
69
|
+
expires_in: grant.expires_in,
|
70
|
+
scopes: grant.scopes,
|
71
|
+
)
|
65
72
|
|
66
73
|
# Will find subsequently by hashing the token
|
67
|
-
expect(clazz.by_token(plain_text_token))
|
74
|
+
expect(clazz.by_token(plain_text_token))
|
75
|
+
.to have_attributes(
|
76
|
+
resource_owner_id: grant.resource_owner_id,
|
77
|
+
application_id: grant.application_id,
|
78
|
+
redirect_uri: grant.redirect_uri,
|
79
|
+
expires_in: grant.expires_in,
|
80
|
+
scopes: grant.scopes,
|
81
|
+
)
|
82
|
+
|
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
|
68
87
|
|
69
88
|
# And it modifies the token value
|
70
89
|
grant.reload
|
@@ -73,10 +73,25 @@ module Doorkeeper
|
|
73
73
|
it "upgrades a plain token when falling back to it" do
|
74
74
|
# Side-effect: This will automatically upgrade the token
|
75
75
|
expect(clazz).to receive(:upgrade_fallback_value).and_call_original
|
76
|
-
expect(clazz.by_token(plain_text_token))
|
76
|
+
expect(clazz.by_token(plain_text_token))
|
77
|
+
.to have_attributes(
|
78
|
+
resource_owner_id: access_token.resource_owner_id,
|
79
|
+
application_id: access_token.application_id,
|
80
|
+
scopes: access_token.scopes,
|
81
|
+
)
|
77
82
|
|
78
83
|
# Will find subsequently by hashing the token
|
79
|
-
expect(clazz.by_token(plain_text_token))
|
84
|
+
expect(clazz.by_token(plain_text_token))
|
85
|
+
.to have_attributes(
|
86
|
+
resource_owner_id: access_token.resource_owner_id,
|
87
|
+
application_id: access_token.application_id,
|
88
|
+
scopes: access_token.scopes,
|
89
|
+
)
|
90
|
+
|
91
|
+
# Not all the ORM support :id PK
|
92
|
+
if access_token.respond_to?(:id)
|
93
|
+
expect(clazz.by_token(plain_text_token).id).to eq(access_token.id)
|
94
|
+
end
|
80
95
|
|
81
96
|
# And it modifies the token value
|
82
97
|
access_token.reload
|
@@ -113,6 +128,7 @@ module Doorkeeper
|
|
113
128
|
eigenclass.class_eval do
|
114
129
|
remove_method :generate
|
115
130
|
end
|
131
|
+
|
116
132
|
module CustomGeneratorArgs
|
117
133
|
def self.generate(opts = {})
|
118
134
|
"custom_generator_token_#{opts[:application].name}"
|
@@ -307,10 +323,25 @@ module Doorkeeper
|
|
307
323
|
it "upgrades a plain token when falling back to it" do
|
308
324
|
# Side-effect: This will automatically upgrade the token
|
309
325
|
expect(clazz).to receive(:upgrade_fallback_value).and_call_original
|
310
|
-
expect(clazz.by_refresh_token(plain_refresh_token))
|
326
|
+
expect(clazz.by_refresh_token(plain_refresh_token))
|
327
|
+
.to have_attributes(
|
328
|
+
token: access_token.token,
|
329
|
+
resource_owner_id: access_token.resource_owner_id,
|
330
|
+
application_id: access_token.application_id,
|
331
|
+
)
|
311
332
|
|
312
333
|
# Will find subsequently by hashing the token
|
313
|
-
expect(clazz.by_refresh_token(plain_refresh_token))
|
334
|
+
expect(clazz.by_refresh_token(plain_refresh_token))
|
335
|
+
.to have_attributes(
|
336
|
+
token: access_token.token,
|
337
|
+
resource_owner_id: access_token.resource_owner_id,
|
338
|
+
application_id: access_token.application_id,
|
339
|
+
)
|
340
|
+
|
341
|
+
# Not all the ORM support :id PK
|
342
|
+
if access_token.respond_to?(:id)
|
343
|
+
expect(clazz.by_refresh_token(plain_refresh_token).id).to eq(access_token.id)
|
344
|
+
end
|
314
345
|
|
315
346
|
# And it modifies the token value
|
316
347
|
access_token.reload
|