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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3a0fa2d314b8aa479233379028c00d8107830f46
4
- data.tar.gz: c0bb3f5658cbbc4f7b640e08ae418afab36d7225
2
+ SHA256:
3
+ metadata.gz: 897eb14bd6b334b3b9f69f5cd54bfe524baddc09b3f96159f29a3c0b32b89d9b
4
+ data.tar.gz: b7bdd3e4d3cef46cb68fca0ac0bc854b5fa28c170c70a244b331b223d035d16f
5
5
  SHA512:
6
- metadata.gz: 45411b41e6ca7e5b3016b6831efa7cb6df93dcca172ac1902a8561ca004f6701ebaf4364d5e12d439bd0867533aa4b98133224482cd91ce015b835b26753dc64
7
- data.tar.gz: 89aaf99254db0422ce86ed21f6e604ce8ecac6eb6c58070170b88be0fa02c338b71e7683d95f557319d75936e53f464e47118fbc85c35ac8a97cfd1588202622
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
- ## master
8
+ ## 5.0.3
9
9
 
10
- - [#] Add your description here.
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|
@@ -9,7 +9,7 @@ module Doorkeeper
9
9
 
10
10
  respond_to do |format|
11
11
  format.html
12
- format.json { render json: @applications }
12
+ format.json { render json: @applications, current_resource_owner: current_resource_owner }
13
13
  end
14
14
  end
15
15
 
@@ -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
@@ -9,7 +9,7 @@ module Doorkeeper
9
9
  # Semantic versioning
10
10
  MAJOR = 5
11
11
  MINOR = 0
12
- TINY = 2
12
+ TINY = 3
13
13
  PRE = nil
14
14
 
15
15
  # Full version number
@@ -1,269 +1,374 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- module Doorkeeper
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
- let(:uid) { SecureRandom.hex(8) }
10
- let(:secret) { SecureRandom.hex(8) }
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
- context 'application_owner is enabled' do
13
- before do
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
- context 'application owner is not required' do
21
- before(:each) do
22
- unset_require_owner
23
- end
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
- it 'is valid given valid attributes' do
26
- expect(new_application).to be_valid
27
- end
28
- end
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
- context 'application owner is required' do
31
- before(:each) do
32
- require_owner
33
- @owner = FactoryBot.build_stubbed(:doorkeeper_testing_user)
34
- end
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
- it 'is invalid without an owner' do
37
- expect(new_application).not_to be_valid
38
- end
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
- it 'is valid with an owner' do
41
- new_application.owner = @owner
42
- expect(new_application).to be_valid
43
- end
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
- it 'is invalid without a name' do
48
- new_application.name = nil
49
- expect(new_application).not_to be_valid
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
- it 'is invalid without determining confidentiality' do
53
- new_application.confidential = nil
54
- expect(new_application).not_to be_valid
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
- it 'generates uid on create' do
58
- expect(new_application.uid).to be_nil
120
+ context "redirect URI" do
121
+ it "is invalid without redirect_uri" do
59
122
  new_application.save
60
- expect(new_application.uid).not_to be_nil
123
+ new_application.redirect_uri = nil
124
+ expect(new_application).not_to be_valid
61
125
  end
126
+ end
62
127
 
63
- it 'generates uid on create if an empty string' do
64
- new_application.uid = ''
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
- it 'generates uid on create unless one is set' do
70
- new_application.uid = uid
71
- new_application.save
72
- expect(new_application.uid).to eq(uid)
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 'is invalid without uid' do
76
- new_application.save
77
- new_application.uid = nil
78
- expect(new_application).not_to be_valid
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
- it 'is invalid without redirect_uri' do
82
- new_application.save
83
- new_application.redirect_uri = nil
84
- expect(new_application).not_to be_valid
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
- it 'checks uniqueness of uid' do
88
- app1 = FactoryBot.create(:application)
89
- app2 = FactoryBot.create(:application)
90
- app2.uid = app1.uid
91
- expect(app2).not_to be_valid
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
- it 'expects database to throw an error when uids are the same' do
95
- app1 = FactoryBot.create(:application)
96
- app2 = FactoryBot.create(:application)
97
- app2.uid = app1.uid
98
- expect { app2.save!(validate: false) }.to raise_error(uniqueness_error)
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
- it 'generate secret on create' do
102
- expect(new_application.secret).to be_nil
103
- new_application.save
104
- expect(new_application.secret).not_to be_nil
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 'generate secret on create if is blank string' do
108
- new_application.secret = ''
109
- new_application.save
110
- expect(new_application.secret).not_to be_blank
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 'generate secret on create unless one is set' do
114
- new_application.secret = secret
115
- new_application.save
116
- expect(new_application.secret).to eq(secret)
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 'is invalid without secret' do
120
- new_application.save
121
- new_application.secret = nil
122
- expect(new_application).not_to be_valid
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
- describe 'destroy related models on cascade' do
126
- before(:each) do
127
- new_application.save
128
- end
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
- it 'should destroy its access grants' do
131
- FactoryBot.create(:access_grant, application: new_application)
132
- expect { new_application.destroy }.to change { Doorkeeper::AccessGrant.count }.by(-1)
133
- end
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
- it 'should destroy its access tokens' do
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
- describe :ordered_by do
145
- let(:applications) { FactoryBot.create_list(:application, 5) }
146
-
147
- context 'when a direction is not specified' do
148
- it 'calls order with a default order of asc' do
149
- names = applications.map(&:name).sort
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
- context 'when a direction is specified' do
155
- it 'calls order with specified direction' do
156
- names = applications.map(&:name).sort.reverse
157
- expect(Application.ordered_by(:name, :desc).map(&:name)).to eq(names)
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
- describe "#redirect_uri=" do
163
- context "when array of valid redirect_uris" do
164
- it "should join by newline" do
165
- new_application.redirect_uri = ['http://localhost/callback1', 'http://localhost/callback2']
166
- expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
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 string of valid redirect_uris" do
170
- it "should store as-is" do
171
- new_application.redirect_uri = "http://localhost/callback1\nhttp://localhost/callback2"
172
- expect(new_application.redirect_uri).to eq("http://localhost/callback1\nhttp://localhost/callback2")
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
- describe :authorized_for do
178
- let(:resource_owner) { double(:resource_owner, id: 10) }
292
+ describe "#confidential?" do
293
+ subject { FactoryBot.create(:application, confidential: confidential).confidential? }
179
294
 
180
- it 'is empty if the application is not authorized for anyone' do
181
- expect(Application.authorized_for(resource_owner)).to be_empty
182
- end
295
+ context "when application is private/confidential" do
296
+ let(:confidential) { true }
297
+ it { expect(subject).to eq(true) }
298
+ end
183
299
 
184
- it 'returns only application for a specific resource owner' do
185
- FactoryBot.create(:access_token, resource_owner_id: resource_owner.id + 1)
186
- token = FactoryBot.create(:access_token, resource_owner_id: resource_owner.id)
187
- expect(Application.authorized_for(resource_owner)).to eq([token.application])
188
- end
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
- it 'excludes revoked tokens' do
191
- FactoryBot.create(:access_token, resource_owner_id: resource_owner.id, revoked_at: 2.days.ago)
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
- it 'returns all applications that have been authorized' do
196
- token1 = FactoryBot.create(:access_token, resource_owner_id: resource_owner.id)
197
- token2 = FactoryBot.create(:access_token, resource_owner_id: resource_owner.id)
198
- expect(Application.authorized_for(resource_owner)).to eq([token1.application, token2.application])
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
- it 'returns only one application even if it has been authorized twice' do
202
- application = FactoryBot.create(:application)
203
- FactoryBot.create(:access_token, resource_owner_id: resource_owner.id, application: application)
204
- FactoryBot.create(:access_token, resource_owner_id: resource_owner.id, application: application)
205
- expect(Application.authorized_for(resource_owner)).to eq([application])
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
- describe :revoke_tokens_and_grants_for do
210
- it 'revokes all access tokens and access grants' do
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
- Application.revoke_tokens_and_grants_for(application_id, resource_owner)
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
- describe :by_uid_and_secret do
223
- context "when application is private/confidential" do
224
- it "finds the application via uid/secret" do
225
- app = FactoryBot.create :application
226
- authenticated = Application.by_uid_and_secret(app.uid, app.secret)
227
- expect(authenticated).to eq(app)
228
- end
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
- context "when application is public/non-confidential" do
239
- context "when secret is blank" do
240
- it "should find the application" do
241
- app = FactoryBot.create :application, confidential: false
242
- authenticated = Application.by_uid_and_secret(app.uid, nil)
243
- expect(authenticated).to eq(app)
244
- end
245
- end
246
- context "when secret is wrong" do
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
- context 'when application is private/confidential' do
260
- let(:confidential) { true }
261
- it { expect(subject).to eq(true) }
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
- context 'when application is public/non-confidential' do
265
- let(:confidential) { false }
266
- it { expect(subject).to eq(false) }
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.2
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: 2018-10-25 00:00:00.000000000 Z
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
- rubyforge_project:
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