doorkeeper 5.0.2 → 5.0.3
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 +5 -5
- data/NEWS.md +3 -2
- data/app/controllers/doorkeeper/applications_controller.rb +3 -3
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +1 -1
- data/lib/doorkeeper/orm/active_record/application.rb +55 -0
- data/lib/doorkeeper/version.rb +1 -1
- data/spec/models/doorkeeper/application_spec.rb +299 -194
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 897eb14bd6b334b3b9f69f5cd54bfe524baddc09b3f96159f29a3c0b32b89d9b
|
4
|
+
data.tar.gz: b7bdd3e4d3cef46cb68fca0ac0bc854b5fa28c170c70a244b331b223d035d16f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ff4eb6145d1a432a2cb31055ccf4fcbbaa0d91f3cb8c59ad061ede4d25b6ca345e1b5404c7180816524b5e0c650e359189d42790be61d025eeb940781accac52
|
7
|
+
data.tar.gz: 30463a001c175d07cecda2f760ed669c5c460c6fd0e3ed802b9988c8ca3b15e80fd335022f61b9cec9954d7906c53e160a3462df8988f9f0a756dff2a7452cb1
|
data/NEWS.md
CHANGED
@@ -5,9 +5,10 @@ upgrade guides.
|
|
5
5
|
|
6
6
|
User-visible changes worth mentioning.
|
7
7
|
|
8
|
-
##
|
8
|
+
## 5.0.3
|
9
9
|
|
10
|
-
|
10
|
+
[#1371] Backport: Add #as_json method and attributes serialization restriction for Application model.
|
11
|
+
Fixes information disclosure vulnerability (CVE-2020-10187).
|
11
12
|
|
12
13
|
## 5.0.2
|
13
14
|
|
@@ -19,7 +19,7 @@ module Doorkeeper
|
|
19
19
|
def show
|
20
20
|
respond_to do |format|
|
21
21
|
format.html
|
22
|
-
format.json { render json: @application }
|
22
|
+
format.json { render json: @application, as_owner: true }
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -35,7 +35,7 @@ module Doorkeeper
|
|
35
35
|
|
36
36
|
respond_to do |format|
|
37
37
|
format.html { redirect_to oauth_application_url(@application) }
|
38
|
-
format.json { render json: @application }
|
38
|
+
format.json { render json: @application, as_owner: true }
|
39
39
|
end
|
40
40
|
else
|
41
41
|
respond_to do |format|
|
@@ -53,7 +53,7 @@ module Doorkeeper
|
|
53
53
|
|
54
54
|
respond_to do |format|
|
55
55
|
format.html { redirect_to oauth_application_url(@application) }
|
56
|
-
format.json { render json: @application }
|
56
|
+
format.json { render json: @application, as_owner: true }
|
57
57
|
end
|
58
58
|
else
|
59
59
|
respond_to do |format|
|
@@ -45,6 +45,29 @@ module Doorkeeper
|
|
45
45
|
AccessGrant.revoke_all_for(id, resource_owner)
|
46
46
|
end
|
47
47
|
|
48
|
+
# Represents client as set of it's attributes in JSON format.
|
49
|
+
# This is the right way how we want to override ActiveRecord #to_json.
|
50
|
+
#
|
51
|
+
# Respects privacy settings and serializes minimum set of attributes
|
52
|
+
# for public/private clients and full set for authorized owners.
|
53
|
+
#
|
54
|
+
# @return [Hash] entity attributes for JSON
|
55
|
+
#
|
56
|
+
def as_json(options = {})
|
57
|
+
# if application belongs to some owner we need to check if it's the same as
|
58
|
+
# the one passed in the options or check if we render the client as an owner
|
59
|
+
if (respond_to?(:owner) && owner && owner == options[:current_resource_owner]) ||
|
60
|
+
options[:as_owner]
|
61
|
+
# Owners can see all the client attributes, fallback to ActiveModel serialization
|
62
|
+
super
|
63
|
+
else
|
64
|
+
# if application has no owner or it's owner doesn't match one from the options
|
65
|
+
# we render only minimum set of attributes that could be exposed to a public
|
66
|
+
only = extract_serializable_attributes(options)
|
67
|
+
super(options.merge(only: only))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
48
71
|
private
|
49
72
|
|
50
73
|
def generate_uid
|
@@ -65,5 +88,37 @@ module Doorkeeper
|
|
65
88
|
def enforce_scopes?
|
66
89
|
Doorkeeper.configuration.enforce_configured_scopes?
|
67
90
|
end
|
91
|
+
|
92
|
+
# Helper method to extract collection of serializable attribute names
|
93
|
+
# considering serialization options (like `only`, `except` and so on).
|
94
|
+
#
|
95
|
+
# @param options [Hash] serialization options
|
96
|
+
#
|
97
|
+
# @return [Array<String>]
|
98
|
+
# collection of attributes to be serialized using #as_json
|
99
|
+
#
|
100
|
+
def extract_serializable_attributes(options = {})
|
101
|
+
opts = options.try(:dup) || {}
|
102
|
+
only = Array.wrap(opts[:only]).map(&:to_s)
|
103
|
+
|
104
|
+
only = if only.blank?
|
105
|
+
serializable_attributes
|
106
|
+
else
|
107
|
+
only & serializable_attributes
|
108
|
+
end
|
109
|
+
|
110
|
+
only -= Array.wrap(opts[:except]).map(&:to_s) if opts.key?(:except)
|
111
|
+
only.uniq
|
112
|
+
end
|
113
|
+
|
114
|
+
# Collection of attributes that could be serialized for public.
|
115
|
+
# Override this method if you need additional attributes to be serialized.
|
116
|
+
#
|
117
|
+
# @return [Array<String>] collection of serializable attributes
|
118
|
+
def serializable_attributes
|
119
|
+
attributes = %w[id name created_at]
|
120
|
+
attributes << "uid" unless confidential?
|
121
|
+
attributes
|
122
|
+
end
|
68
123
|
end
|
69
124
|
end
|
data/lib/doorkeeper/version.rb
CHANGED
@@ -1,269 +1,374 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
describe Application do
|
5
|
-
let(:require_owner) { Doorkeeper.configuration.instance_variable_set('@confirm_application_owner', true) }
|
6
|
-
let(:unset_require_owner) { Doorkeeper.configuration.instance_variable_set('@confirm_application_owner', false) }
|
7
|
-
let(:new_application) { FactoryBot.build(:application) }
|
3
|
+
require "spec_helper"
|
8
4
|
|
9
|
-
|
10
|
-
|
5
|
+
describe Doorkeeper::Application do
|
6
|
+
let(:require_owner) { Doorkeeper.configuration.instance_variable_set("@confirm_application_owner", true) }
|
7
|
+
let(:unset_require_owner) { Doorkeeper.configuration.instance_variable_set("@confirm_application_owner", false) }
|
8
|
+
let(:new_application) { FactoryBot.build(:application) }
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
Doorkeeper.configure do
|
15
|
-
orm DOORKEEPER_ORM
|
16
|
-
enable_application_owner
|
17
|
-
end
|
18
|
-
end
|
10
|
+
let(:uid) { SecureRandom.hex(8) }
|
11
|
+
let(:secret) { SecureRandom.hex(8) }
|
19
12
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
13
|
+
it "is invalid without a name" do
|
14
|
+
new_application.name = nil
|
15
|
+
expect(new_application).not_to be_valid
|
16
|
+
end
|
24
17
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
18
|
+
it "is invalid without determining confidentiality" do
|
19
|
+
new_application.confidential = nil
|
20
|
+
expect(new_application).not_to be_valid
|
21
|
+
end
|
29
22
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
23
|
+
it "generates uid on create" do
|
24
|
+
expect(new_application.uid).to be_nil
|
25
|
+
new_application.save
|
26
|
+
expect(new_application.uid).not_to be_nil
|
27
|
+
end
|
35
28
|
|
36
|
-
|
37
|
-
|
38
|
-
|
29
|
+
it "generates uid on create if an empty string" do
|
30
|
+
new_application.uid = ""
|
31
|
+
new_application.save
|
32
|
+
expect(new_application.uid).not_to be_blank
|
33
|
+
end
|
39
34
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
35
|
+
it "generates uid on create unless one is set" do
|
36
|
+
new_application.uid = uid
|
37
|
+
new_application.save
|
38
|
+
expect(new_application.uid).to eq(uid)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "is invalid without uid" do
|
42
|
+
new_application.save
|
43
|
+
new_application.uid = nil
|
44
|
+
expect(new_application).not_to be_valid
|
45
|
+
end
|
46
|
+
|
47
|
+
it "checks uniqueness of uid" do
|
48
|
+
app1 = FactoryBot.create(:application)
|
49
|
+
app2 = FactoryBot.create(:application)
|
50
|
+
app2.uid = app1.uid
|
51
|
+
expect(app2).not_to be_valid
|
52
|
+
end
|
53
|
+
|
54
|
+
it "expects database to throw an error when uids are the same" do
|
55
|
+
app1 = FactoryBot.create(:application)
|
56
|
+
app2 = FactoryBot.create(:application)
|
57
|
+
app2.uid = app1.uid
|
58
|
+
expect { app2.save!(validate: false) }.to raise_error(uniqueness_error)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "generate secret on create" do
|
62
|
+
expect(new_application.secret).to be_nil
|
63
|
+
new_application.save
|
64
|
+
expect(new_application.secret).not_to be_nil
|
65
|
+
end
|
66
|
+
|
67
|
+
it "generate secret on create if is blank string" do
|
68
|
+
new_application.secret = ""
|
69
|
+
new_application.save
|
70
|
+
expect(new_application.secret).not_to be_blank
|
71
|
+
end
|
72
|
+
|
73
|
+
it "generate secret on create unless one is set" do
|
74
|
+
new_application.secret = secret
|
75
|
+
new_application.save
|
76
|
+
expect(new_application.secret).to eq(secret)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "is invalid without secret" do
|
80
|
+
new_application.save
|
81
|
+
new_application.secret = nil
|
82
|
+
expect(new_application).not_to be_valid
|
83
|
+
end
|
84
|
+
|
85
|
+
context "application_owner is enabled" do
|
86
|
+
before do
|
87
|
+
Doorkeeper.configure do
|
88
|
+
orm DOORKEEPER_ORM
|
89
|
+
enable_application_owner
|
44
90
|
end
|
45
91
|
end
|
46
92
|
|
47
|
-
|
48
|
-
|
49
|
-
|
93
|
+
context "application owner is not required" do
|
94
|
+
before(:each) do
|
95
|
+
unset_require_owner
|
96
|
+
end
|
97
|
+
|
98
|
+
it "is valid given valid attributes" do
|
99
|
+
expect(new_application).to be_valid
|
100
|
+
end
|
50
101
|
end
|
51
102
|
|
52
|
-
|
53
|
-
|
54
|
-
|
103
|
+
context "application owner is required" do
|
104
|
+
before do
|
105
|
+
require_owner
|
106
|
+
@owner = FactoryBot.build_stubbed(:doorkeeper_testing_user)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "is invalid without an owner" do
|
110
|
+
expect(new_application).not_to be_valid
|
111
|
+
end
|
112
|
+
|
113
|
+
it "is valid with an owner" do
|
114
|
+
new_application.owner = @owner
|
115
|
+
expect(new_application).to be_valid
|
116
|
+
end
|
55
117
|
end
|
118
|
+
end
|
56
119
|
|
57
|
-
|
58
|
-
|
120
|
+
context "redirect URI" do
|
121
|
+
it "is invalid without redirect_uri" do
|
59
122
|
new_application.save
|
60
|
-
|
123
|
+
new_application.redirect_uri = nil
|
124
|
+
expect(new_application).not_to be_valid
|
61
125
|
end
|
126
|
+
end
|
62
127
|
|
63
|
-
|
64
|
-
|
128
|
+
describe "destroy related models on cascade" do
|
129
|
+
before(:each) do
|
65
130
|
new_application.save
|
66
|
-
expect(new_application.uid).not_to be_blank
|
67
131
|
end
|
68
132
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
133
|
+
let(:resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
|
134
|
+
|
135
|
+
it "should destroy its access grants" do
|
136
|
+
FactoryBot.create(
|
137
|
+
:access_grant,
|
138
|
+
application: new_application,
|
139
|
+
resource_owner_id: resource_owner.id,
|
140
|
+
)
|
141
|
+
|
142
|
+
expect { new_application.destroy }.to change { Doorkeeper::AccessGrant.count }.by(-1)
|
73
143
|
end
|
74
144
|
|
75
|
-
it
|
76
|
-
new_application
|
77
|
-
|
78
|
-
expect
|
145
|
+
it "should destroy its access tokens" do
|
146
|
+
FactoryBot.create(:access_token, application: new_application)
|
147
|
+
FactoryBot.create(:access_token, application: new_application, revoked_at: Time.now.utc)
|
148
|
+
expect do
|
149
|
+
new_application.destroy
|
150
|
+
end.to change { Doorkeeper::AccessToken.count }.by(-2)
|
79
151
|
end
|
152
|
+
end
|
80
153
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
154
|
+
describe "#ordered_by" do
|
155
|
+
let(:applications) { FactoryBot.create_list(:application, 5) }
|
156
|
+
|
157
|
+
context "when a direction is not specified" do
|
158
|
+
it "calls order with a default order of asc" do
|
159
|
+
names = applications.map(&:name).sort
|
160
|
+
expect(described_class.ordered_by(:name).map(&:name)).to eq(names)
|
161
|
+
end
|
85
162
|
end
|
86
163
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
164
|
+
context "when a direction is specified" do
|
165
|
+
it "calls order with specified direction" do
|
166
|
+
names = applications.map(&:name).sort.reverse
|
167
|
+
expect(described_class.ordered_by(:name, :desc).map(&:name)).to eq(names)
|
168
|
+
end
|
92
169
|
end
|
170
|
+
end
|
93
171
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
172
|
+
describe "#redirect_uri=" do
|
173
|
+
context "when array of valid redirect_uris" do
|
174
|
+
it "should join by newline" do
|
175
|
+
new_application.redirect_uri = ["http://localhost/callback1", "http://localhost/callback2"]
|
176
|
+
expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
|
177
|
+
end
|
178
|
+
end
|
179
|
+
context "when string of valid redirect_uris" do
|
180
|
+
it "should store as-is" do
|
181
|
+
new_application.redirect_uri = "http://localhost/callback1\nhttp://localhost/callback2"
|
182
|
+
expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
|
183
|
+
end
|
99
184
|
end
|
185
|
+
end
|
100
186
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
187
|
+
describe "#authorized_for" do
|
188
|
+
let(:resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
|
189
|
+
let(:other_resource_owner) { FactoryBot.create(:doorkeeper_testing_user) }
|
190
|
+
|
191
|
+
it "is empty if the application is not authorized for anyone" do
|
192
|
+
expect(described_class.authorized_for(resource_owner)).to be_empty
|
105
193
|
end
|
106
194
|
|
107
|
-
it
|
108
|
-
|
109
|
-
|
110
|
-
|
195
|
+
it "returns only application for a specific resource owner" do
|
196
|
+
FactoryBot.create(
|
197
|
+
:access_token,
|
198
|
+
resource_owner_id: other_resource_owner.id,
|
199
|
+
)
|
200
|
+
token = FactoryBot.create(
|
201
|
+
:access_token,
|
202
|
+
resource_owner_id: resource_owner.id,
|
203
|
+
)
|
204
|
+
expect(described_class.authorized_for(resource_owner)).to eq([token.application])
|
111
205
|
end
|
112
206
|
|
113
|
-
it
|
114
|
-
|
115
|
-
|
116
|
-
|
207
|
+
it "excludes revoked tokens" do
|
208
|
+
FactoryBot.create(
|
209
|
+
:access_token,
|
210
|
+
resource_owner_id: resource_owner.id,
|
211
|
+
revoked_at: 2.days.ago,
|
212
|
+
)
|
213
|
+
expect(described_class.authorized_for(resource_owner)).to be_empty
|
117
214
|
end
|
118
215
|
|
119
|
-
it
|
120
|
-
|
121
|
-
|
122
|
-
|
216
|
+
it "returns all applications that have been authorized" do
|
217
|
+
token1 = FactoryBot.create(
|
218
|
+
:access_token,
|
219
|
+
resource_owner_id: resource_owner.id,
|
220
|
+
)
|
221
|
+
token2 = FactoryBot.create(
|
222
|
+
:access_token,
|
223
|
+
resource_owner_id: resource_owner.id,
|
224
|
+
)
|
225
|
+
expect(described_class.authorized_for(resource_owner))
|
226
|
+
.to eq([token1.application, token2.application])
|
123
227
|
end
|
124
228
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
229
|
+
it "returns only one application even if it has been authorized twice" do
|
230
|
+
application = FactoryBot.create(:application)
|
231
|
+
FactoryBot.create(
|
232
|
+
:access_token,
|
233
|
+
resource_owner_id: resource_owner.id,
|
234
|
+
application: application,
|
235
|
+
)
|
236
|
+
FactoryBot.create(
|
237
|
+
:access_token,
|
238
|
+
resource_owner_id: resource_owner.id,
|
239
|
+
application: application,
|
240
|
+
)
|
241
|
+
expect(described_class.authorized_for(resource_owner)).to eq([application])
|
242
|
+
end
|
243
|
+
end
|
129
244
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
245
|
+
describe "#revoke_tokens_and_grants_for" do
|
246
|
+
it "revokes all access tokens and access grants" do
|
247
|
+
application_id = 42
|
248
|
+
resource_owner = double
|
249
|
+
expect(Doorkeeper::AccessToken)
|
250
|
+
.to receive(:revoke_all_for).with(application_id, resource_owner)
|
251
|
+
expect(Doorkeeper::AccessGrant)
|
252
|
+
.to receive(:revoke_all_for).with(application_id, resource_owner)
|
134
253
|
|
135
|
-
|
136
|
-
FactoryBot.create(:access_token, application: new_application)
|
137
|
-
FactoryBot.create(:access_token, application: new_application, revoked_at: Time.now.utc)
|
138
|
-
expect do
|
139
|
-
new_application.destroy
|
140
|
-
end.to change { Doorkeeper::AccessToken.count }.by(-2)
|
141
|
-
end
|
254
|
+
described_class.revoke_tokens_and_grants_for(application_id, resource_owner)
|
142
255
|
end
|
256
|
+
end
|
143
257
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
expect(Application.ordered_by(:name).map(&:name)).to eq(names)
|
151
|
-
end
|
258
|
+
describe "#by_uid_and_secret" do
|
259
|
+
context "when application is private/confidential" do
|
260
|
+
it "finds the application via uid/secret" do
|
261
|
+
app = FactoryBot.create :application
|
262
|
+
authenticated = described_class.by_uid_and_secret(app.uid, app.secret)
|
263
|
+
expect(authenticated).to eq(app)
|
152
264
|
end
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
expect(
|
265
|
+
context "when secret is wrong" do
|
266
|
+
it "should not find the application" do
|
267
|
+
app = FactoryBot.create :application
|
268
|
+
authenticated = described_class.by_uid_and_secret(app.uid, "bad")
|
269
|
+
expect(authenticated).to eq(nil)
|
158
270
|
end
|
159
271
|
end
|
160
272
|
end
|
161
273
|
|
162
|
-
|
163
|
-
context "when
|
164
|
-
it "should
|
165
|
-
|
166
|
-
|
274
|
+
context "when application is public/non-confidential" do
|
275
|
+
context "when secret is blank" do
|
276
|
+
it "should find the application" do
|
277
|
+
app = FactoryBot.create :application, confidential: false
|
278
|
+
authenticated = described_class.by_uid_and_secret(app.uid, nil)
|
279
|
+
expect(authenticated).to eq(app)
|
167
280
|
end
|
168
281
|
end
|
169
|
-
context "when
|
170
|
-
it "should
|
171
|
-
|
172
|
-
|
282
|
+
context "when secret is wrong" do
|
283
|
+
it "should not find the application" do
|
284
|
+
app = FactoryBot.create :application, confidential: false
|
285
|
+
authenticated = described_class.by_uid_and_secret(app.uid, "bad")
|
286
|
+
expect(authenticated).to eq(nil)
|
173
287
|
end
|
174
288
|
end
|
175
289
|
end
|
290
|
+
end
|
176
291
|
|
177
|
-
|
178
|
-
|
292
|
+
describe "#confidential?" do
|
293
|
+
subject { FactoryBot.create(:application, confidential: confidential).confidential? }
|
179
294
|
|
180
|
-
|
181
|
-
|
182
|
-
|
295
|
+
context "when application is private/confidential" do
|
296
|
+
let(:confidential) { true }
|
297
|
+
it { expect(subject).to eq(true) }
|
298
|
+
end
|
183
299
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
300
|
+
context "when application is public/non-confidential" do
|
301
|
+
let(:confidential) { false }
|
302
|
+
it { expect(subject).to eq(false) }
|
303
|
+
end
|
304
|
+
end
|
189
305
|
|
190
|
-
|
191
|
-
|
192
|
-
expect(Application.authorized_for(resource_owner)).to be_empty
|
193
|
-
end
|
306
|
+
describe "#as_json" do
|
307
|
+
let(:app) { FactoryBot.create :application, secret: "123123123" }
|
194
308
|
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
309
|
+
# AR specific feature
|
310
|
+
if DOORKEEPER_ORM == :active_record
|
311
|
+
it "correctly works with #to_json" do
|
312
|
+
ActiveRecord::Base.include_root_in_json = true
|
313
|
+
expect(app.to_json(include_root_in_json: true)).to match(/application.+?:\{/)
|
314
|
+
ActiveRecord::Base.include_root_in_json = false
|
199
315
|
end
|
316
|
+
end
|
200
317
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
318
|
+
context "when called without authorized resource owner" do
|
319
|
+
it "includes minimal set of attributes" do
|
320
|
+
expect(app.as_json).to match(
|
321
|
+
"id" => app.id,
|
322
|
+
"name" => app.name,
|
323
|
+
"created_at" => anything,
|
324
|
+
)
|
206
325
|
end
|
207
|
-
end
|
208
326
|
|
209
|
-
|
210
|
-
|
211
|
-
application_id = 42
|
212
|
-
resource_owner = double
|
213
|
-
expect(Doorkeeper::AccessToken)
|
214
|
-
.to receive(:revoke_all_for).with(application_id, resource_owner)
|
215
|
-
expect(Doorkeeper::AccessGrant)
|
216
|
-
.to receive(:revoke_all_for).with(application_id, resource_owner)
|
327
|
+
it "includes application UID if it's public" do
|
328
|
+
app = FactoryBot.create :application, secret: "123123123", confidential: false
|
217
329
|
|
218
|
-
|
330
|
+
expect(app.as_json).to match(
|
331
|
+
"id" => app.id,
|
332
|
+
"name" => app.name,
|
333
|
+
"created_at" => anything,
|
334
|
+
"uid" => app.uid,
|
335
|
+
)
|
219
336
|
end
|
220
|
-
end
|
221
337
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
context "when secret is wrong" do
|
230
|
-
it "should not find the application" do
|
231
|
-
app = FactoryBot.create :application
|
232
|
-
authenticated = Application.by_uid_and_secret(app.uid, 'bad')
|
233
|
-
expect(authenticated).to eq(nil)
|
234
|
-
end
|
235
|
-
end
|
338
|
+
it "respects custom options" do
|
339
|
+
expect(app.as_json(except: :id)).not_to include("id")
|
340
|
+
expect(app.as_json(only: %i[name created_at secret]))
|
341
|
+
.to match(
|
342
|
+
"name" => app.name,
|
343
|
+
"created_at" => anything,
|
344
|
+
)
|
236
345
|
end
|
346
|
+
end
|
237
347
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
it "should not find the application" do
|
248
|
-
app = FactoryBot.create :application, confidential: false
|
249
|
-
authenticated = Application.by_uid_and_secret(app.uid, 'bad')
|
250
|
-
expect(authenticated).to eq(nil)
|
251
|
-
end
|
348
|
+
context "when called with authorized resource owner" do
|
349
|
+
let(:owner) { FactoryBot.create(:doorkeeper_testing_user) }
|
350
|
+
let(:other_owner) { FactoryBot.create(:doorkeeper_testing_user) }
|
351
|
+
let(:app) { FactoryBot.create(:application, secret: "123123123", owner: owner) }
|
352
|
+
|
353
|
+
before do
|
354
|
+
Doorkeeper.configure do
|
355
|
+
orm DOORKEEPER_ORM
|
356
|
+
enable_application_owner confirmation: false
|
252
357
|
end
|
253
358
|
end
|
254
|
-
end
|
255
|
-
|
256
|
-
describe :confidential? do
|
257
|
-
subject { FactoryBot.create(:application, confidential: confidential).confidential? }
|
258
359
|
|
259
|
-
|
260
|
-
|
261
|
-
|
360
|
+
it "includes all the attributes" do
|
361
|
+
expect(app.as_json(current_resource_owner: owner))
|
362
|
+
.to include(
|
363
|
+
"secret" => "123123123",
|
364
|
+
"redirect_uri" => app.redirect_uri,
|
365
|
+
"uid" => app.uid,
|
366
|
+
)
|
262
367
|
end
|
263
368
|
|
264
|
-
|
265
|
-
|
266
|
-
|
369
|
+
it "doesn't include unsafe attributes if current owner isn't the same as owner" do
|
370
|
+
expect(app.as_json(current_resource_owner: other_owner))
|
371
|
+
.not_to include("redirect_uri")
|
267
372
|
end
|
268
373
|
end
|
269
374
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doorkeeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.
|
4
|
+
version: 5.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felipe Elias Philipp
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2020-05-05 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: railties
|
@@ -447,8 +447,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
447
447
|
- !ruby/object:Gem::Version
|
448
448
|
version: '0'
|
449
449
|
requirements: []
|
450
|
-
|
451
|
-
rubygems_version: 2.6.11
|
450
|
+
rubygems_version: 3.0.2
|
452
451
|
signing_key:
|
453
452
|
specification_version: 4
|
454
453
|
summary: OAuth 2 provider for Rails and Grape
|