expressa 2.0.4 → 2.0.5
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.
- package/controllers/collections.js +22 -7
- package/package.json +1 -1
- package/test/testutils.js +1 -0
- package/test/users.js +114 -0
|
@@ -167,22 +167,37 @@ exports.getById = async function (req) {
|
|
|
167
167
|
exports.replaceById = async function (req) {
|
|
168
168
|
assertValidCollection(req)
|
|
169
169
|
req.customResponseData = req.customResponseData || {}
|
|
170
|
+
const data = req.body
|
|
170
171
|
let oldDoc = {}
|
|
171
172
|
try {
|
|
172
173
|
oldDoc = await req.db[req.params.collection].get(req.params.id)
|
|
173
174
|
} catch (error) {
|
|
174
175
|
// happens when new documents are created via a PUT
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
oldDoc = { meta: { owner: req.user._id, owner_collection: 'users' } }
|
|
177
|
+
data._id = req.params.id.trim()
|
|
178
|
+
await setDocumentOwner(req, data)
|
|
179
|
+
}
|
|
180
|
+
if (data._id) {
|
|
181
|
+
data._id = data._id.trim()
|
|
182
|
+
} else {
|
|
183
|
+
data._id = req.params.id.trim()
|
|
177
184
|
}
|
|
178
|
-
const data = req.body
|
|
179
|
-
data._id = req.params.id
|
|
180
185
|
data.meta = data.meta || {}
|
|
181
186
|
data.meta.created = (oldDoc.meta || {}).created
|
|
182
|
-
data.meta.owner
|
|
187
|
+
if (data.meta.owner !== oldDoc.meta.owner || data.meta.owner_collection !== oldDoc.meta.owner_ollection) {
|
|
188
|
+
if (req.hasPermission(`${req.params.collection}: modify owner`)) {
|
|
189
|
+
if (oldDoc.meta.owner) {
|
|
190
|
+
await validateDocumentOwner(req, data)
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
debug('attempting to change document owner.')
|
|
194
|
+
data.meta.owner = oldDoc.meta.owner
|
|
195
|
+
data.meta.owner_collection = oldDoc.meta.owner_collection
|
|
196
|
+
}
|
|
197
|
+
}
|
|
183
198
|
await util.notify('put', req, req.params.collection, data)
|
|
184
|
-
await req.db[req.params.collection].update(req.params.id,
|
|
185
|
-
await util.notify('changed', req, req.params.collection,
|
|
199
|
+
await req.db[req.params.collection].update(req.params.id, data)
|
|
200
|
+
await util.notify('changed', req, req.params.collection, data)
|
|
186
201
|
return {
|
|
187
202
|
status: 'OK',
|
|
188
203
|
id: data._id,
|
package/package.json
CHANGED
package/test/testutils.js
CHANGED
package/test/users.js
CHANGED
|
@@ -232,6 +232,50 @@ describe('user functionality', function () {
|
|
|
232
232
|
expect(res2.body.meta.owner).to.equal(user._id)
|
|
233
233
|
})
|
|
234
234
|
|
|
235
|
+
it('cannot change owner with a PUT by default', async function () {
|
|
236
|
+
const token = await testutils.getUserWithPermissions(api, ['users: view', 'users: edit', 'users: view hashed passwords'])
|
|
237
|
+
|
|
238
|
+
const res = await request(app)
|
|
239
|
+
.get(`/users/me`)
|
|
240
|
+
.set('x-access-token', token)
|
|
241
|
+
const newUser = JSON.parse(JSON.stringify(res.body))
|
|
242
|
+
|
|
243
|
+
res.body.meta.owner = user._id
|
|
244
|
+
await request(app)
|
|
245
|
+
.put(`/users/${newUser._id}`)
|
|
246
|
+
.set('x-access-token', token)
|
|
247
|
+
.send(res.body)
|
|
248
|
+
.expect(200)
|
|
249
|
+
|
|
250
|
+
const res2 = await request(app)
|
|
251
|
+
.get(`/users/${newUser._id}`)
|
|
252
|
+
.set('x-access-token', token)
|
|
253
|
+
expect(res2.body.meta.owner).to.not.equal(user._id)
|
|
254
|
+
expect(res2.body.meta.owner).to.equal(newUser._id)
|
|
255
|
+
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('can change owner with a PUT with correct permission', async function () {
|
|
259
|
+
const token = await testutils.getUserWithPermissions(api, ['users: view', 'users: edit', 'users: view hashed passwords', 'users: modify owner'])
|
|
260
|
+
|
|
261
|
+
const res = await request(app)
|
|
262
|
+
.get(`/users/me`)
|
|
263
|
+
.set('x-access-token', token)
|
|
264
|
+
const newUser = JSON.parse(JSON.stringify(res.body))
|
|
265
|
+
|
|
266
|
+
res.body.meta.owner = user._id
|
|
267
|
+
await request(app)
|
|
268
|
+
.put(`/users/${newUser._id}`)
|
|
269
|
+
.set('x-access-token', token)
|
|
270
|
+
.send(res.body) // try change owner to another user
|
|
271
|
+
.expect(200)
|
|
272
|
+
|
|
273
|
+
const res2 = await request(app)
|
|
274
|
+
.get(`/users/${newUser._id}`)
|
|
275
|
+
.set('x-access-token', token)
|
|
276
|
+
expect(res2.body.meta.owner).to.equal(user._id)
|
|
277
|
+
})
|
|
278
|
+
|
|
235
279
|
it('changing to bogus owner fails', async function () {
|
|
236
280
|
const token = await testutils.getUserWithPermissions(api, ['users: view', 'users: edit', 'users: modify owner'])
|
|
237
281
|
|
|
@@ -308,4 +352,74 @@ describe('user functionality', function () {
|
|
|
308
352
|
expect(res3.body.meta.owner).to.not.equal(newUser._id)
|
|
309
353
|
expect(res3.body.meta.owner).to.equal(user._id)
|
|
310
354
|
})
|
|
355
|
+
|
|
356
|
+
it('cannot set owner with a PUT on creation by default', async function () {
|
|
357
|
+
const token = await testutils.getUserWithPermissions(api, ['users: view', 'users: edit', 'testdoc: edit', 'testdoc: view own'])
|
|
358
|
+
|
|
359
|
+
const res = await request(app)
|
|
360
|
+
.get(`/users/me`)
|
|
361
|
+
.set('x-access-token', token)
|
|
362
|
+
const newUser = res.body
|
|
363
|
+
|
|
364
|
+
const doc = {
|
|
365
|
+
title: 'Test Title',
|
|
366
|
+
meta: {
|
|
367
|
+
owner: user._id,
|
|
368
|
+
owner_collection: 'users',
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const docId = testutils.generateDocumentId()
|
|
373
|
+
|
|
374
|
+
const res2 = await request(app)
|
|
375
|
+
.put(`/testdoc/${docId}`)
|
|
376
|
+
.set('x-access-token', token)
|
|
377
|
+
.send(doc)
|
|
378
|
+
.expect(200) // will succeed but owner will not change
|
|
379
|
+
|
|
380
|
+
expect(res2.body.id).to.equal(docId)
|
|
381
|
+
doc._id = docId
|
|
382
|
+
|
|
383
|
+
const res3 = await request(app)
|
|
384
|
+
.get(`/testdoc/${doc._id}`)
|
|
385
|
+
.set('x-access-token', token)
|
|
386
|
+
.expect(200)
|
|
387
|
+
expect(res3.body.meta.owner).to.not.equal(user._id)
|
|
388
|
+
expect(res3.body.meta.owner).to.equal(newUser._id)
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
it('can set owner with a PUT on creation with correct permission', async function () {
|
|
392
|
+
const token = await testutils.getUserWithPermissions(api, ['users: view', 'users: edit', 'testdoc: edit', 'testdoc: view', 'testdoc: modify owner'])
|
|
393
|
+
|
|
394
|
+
const res = await request(app)
|
|
395
|
+
.get(`/users/me`)
|
|
396
|
+
.set('x-access-token', token)
|
|
397
|
+
const newUser = res.body
|
|
398
|
+
|
|
399
|
+
const doc = {
|
|
400
|
+
title: 'Test Title',
|
|
401
|
+
meta: {
|
|
402
|
+
owner: user._id,
|
|
403
|
+
owner_collection: 'users',
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
const docId = testutils.generateDocumentId()
|
|
408
|
+
|
|
409
|
+
const res2 = await request(app)
|
|
410
|
+
.put(`/testdoc/${docId}`)
|
|
411
|
+
.set('x-access-token', token)
|
|
412
|
+
.send(doc)
|
|
413
|
+
.expect(200) // will succeed but owner will not change
|
|
414
|
+
|
|
415
|
+
expect(res2.body.id).to.equal(docId)
|
|
416
|
+
doc._id = docId
|
|
417
|
+
|
|
418
|
+
const res3 = await request(app)
|
|
419
|
+
.get(`/testdoc/${doc._id}`)
|
|
420
|
+
.set('x-access-token', token)
|
|
421
|
+
.expect(200)
|
|
422
|
+
expect(res3.body.meta.owner).to.not.equal(newUser._id)
|
|
423
|
+
expect(res3.body.meta.owner).to.equal(user._id)
|
|
424
|
+
})
|
|
311
425
|
})
|