@liminalfunctions/framework 1.0.52 → 1.0.54
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/dist/F_Collection.d.ts +2 -0
- package/dist/F_Collection.js +9 -0
- package/dist/F_Collection.js.map +1 -1
- package/dist/F_Compile.js +247 -0
- package/dist/F_Compile.js.map +1 -1
- package/dist/F_Security_Models/F_Security_Model.d.ts +1 -0
- package/dist/code_generation/generate_client_library.d.ts +1 -0
- package/dist/code_generation/generate_client_library.js +37 -16
- package/dist/code_generation/generate_client_library.js.map +1 -1
- package/dist/code_generation/templates/collection.mustache +79 -1
- package/dist/utils/array_children_from_zod.d.ts +3 -0
- package/dist/utils/array_children_from_zod.js +39 -0
- package/dist/utils/array_children_from_zod.js.map +1 -0
- package/dist/utils/mongoose_from_zod.js +6 -1
- package/dist/utils/mongoose_from_zod.js.map +1 -1
- package/package.json +1 -1
- package/src/F_Collection.ts +14 -3
- package/src/F_Compile.ts +294 -16
- package/src/F_Security_Models/F_Security_Model.ts +1 -0
- package/src/code_generation/generate_client_library.ts +35 -8
- package/src/code_generation/templates/collection.mustache +79 -1
- package/src/utils/array_children_from_zod.ts +44 -0
- package/src/utils/mongoose_from_zod.ts +7 -3
- package/test/0_1_mongoose_from_zod.test.ts +16 -10
- package/test/0_6_array_children.test.ts +127 -0
- package/test/1_0_basic_server.test.ts +107 -2
- package/test/1_1_security_ownership.test.ts +186 -6
- package/test/1_2_role_membership.test.ts +329 -9
- package/test/2_1_client_library_generation.test.ts +125 -1
- package/test/tmp/dist/Brief_News_Category.js.map +1 -1
- package/test/tmp/dist/Client.js.map +1 -1
- package/test/tmp/dist/Institution.js.map +1 -1
- package/test/tmp/dist/Project.d.ts +20 -0
- package/test/tmp/dist/Project.js +63 -0
- package/test/tmp/dist/Project.js.map +1 -1
- package/test/tmp/dist/types/project.d.ts +4 -0
- package/test/tmp/dist/types/project_post.d.ts +4 -0
- package/test/tmp/dist/types/project_put.d.ts +4 -0
- package/test/tmp/package-lock.json +114 -114
- package/test/tmp/src/Brief_News_Category.ts +3 -1
- package/test/tmp/src/Client.ts +3 -1
- package/test/tmp/src/Institution.ts +3 -1
- package/test/tmp/src/Project.ts +73 -1
- package/test/tmp/src/types/project.ts +4 -0
- package/test/tmp/src/types/project_post.ts +4 -0
- package/test/tmp/src/types/project_put.ts +4 -0
|
@@ -30,7 +30,12 @@ describe('Security Model Ownership', function () {
|
|
|
30
30
|
_id: z_mongodb_id,
|
|
31
31
|
user_id: z_mongodb_id,
|
|
32
32
|
name: z.string(),
|
|
33
|
-
email: z.string()
|
|
33
|
+
email: z.string(),
|
|
34
|
+
nicknames: z.array(z.object({
|
|
35
|
+
_id: z_mongodb_id,
|
|
36
|
+
server_key: z.string(),
|
|
37
|
+
name: z.string()
|
|
38
|
+
}))
|
|
34
39
|
})
|
|
35
40
|
|
|
36
41
|
// set up schema: user
|
|
@@ -99,7 +104,8 @@ describe('Security Model Ownership', function () {
|
|
|
99
104
|
let user_display = await collection_user_display.mongoose_model.create({
|
|
100
105
|
user_id: user._id,
|
|
101
106
|
name: 'steve',
|
|
102
|
-
email: 'steve@example.com'
|
|
107
|
+
email: 'steve@example.com',
|
|
108
|
+
nicknames: [],
|
|
103
109
|
})
|
|
104
110
|
|
|
105
111
|
return { user, user_display}
|
|
@@ -157,7 +163,8 @@ describe('Security Model Ownership', function () {
|
|
|
157
163
|
user_displays.push(await collection_user_display.mongoose_model.create({
|
|
158
164
|
user_id: user._id,
|
|
159
165
|
name: 'steve',
|
|
160
|
-
email: 'steve@example.com'
|
|
166
|
+
email: 'steve@example.com',
|
|
167
|
+
nicknames: [],
|
|
161
168
|
}))
|
|
162
169
|
}
|
|
163
170
|
|
|
@@ -185,7 +192,8 @@ describe('Security Model Ownership', function () {
|
|
|
185
192
|
user_displays.push(await collection_user_display.mongoose_model.create({
|
|
186
193
|
user_id: user._id,
|
|
187
194
|
name: 'steve',
|
|
188
|
-
email: 'steve@example.com'
|
|
195
|
+
email: 'steve@example.com',
|
|
196
|
+
nicknames: [],
|
|
189
197
|
}))
|
|
190
198
|
}
|
|
191
199
|
|
|
@@ -261,7 +269,8 @@ describe('Security Model Ownership', function () {
|
|
|
261
269
|
json: {
|
|
262
270
|
user_id: user._id,
|
|
263
271
|
name: 'grogfurd',
|
|
264
|
-
email: 'grogfurd@example.com'
|
|
272
|
+
email: 'grogfurd@example.com',
|
|
273
|
+
nicknames: [],
|
|
265
274
|
}
|
|
266
275
|
}).json();
|
|
267
276
|
|
|
@@ -284,7 +293,8 @@ describe('Security Model Ownership', function () {
|
|
|
284
293
|
json: {
|
|
285
294
|
user_id: user._id,
|
|
286
295
|
name: 'grogfurd',
|
|
287
|
-
email: 'grogfurd@example.com'
|
|
296
|
+
email: 'grogfurd@example.com',
|
|
297
|
+
nicknames: []
|
|
288
298
|
}
|
|
289
299
|
}).json();
|
|
290
300
|
}, {
|
|
@@ -330,4 +340,174 @@ describe('Security Model Ownership', function () {
|
|
|
330
340
|
message: 'Response code 403 (Forbidden)'
|
|
331
341
|
})
|
|
332
342
|
});
|
|
343
|
+
|
|
344
|
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
345
|
+
///////////////////////////////////////////////////////////// ARRAY OPERATIONS //////////////////////////////////////////////////////////////////////////
|
|
346
|
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
it(`should authorize a POST operation on a child array`, async function () {
|
|
350
|
+
let { user, user_display } = await generate_user_and_display();
|
|
351
|
+
|
|
352
|
+
let results = await got.post(`http://localhost:${port}/api/user_display/${user_display._id}/nicknames`, {
|
|
353
|
+
headers: {
|
|
354
|
+
authorization: 'steve'
|
|
355
|
+
},
|
|
356
|
+
json: {
|
|
357
|
+
server_key: 'best_server',
|
|
358
|
+
name: 'steve the mighty'
|
|
359
|
+
}
|
|
360
|
+
}).json();
|
|
361
|
+
|
|
362
|
+
//@ts-ignore
|
|
363
|
+
assert.deepEqual(JSON.parse(JSON.stringify(await collection_user_display.mongoose_model.findById(user_display._id))), results.data);
|
|
364
|
+
assert.deepEqual(JSON.parse(JSON.stringify((await collection_user_display.mongoose_model.findById(user_display._id)))).nicknames.length, 1);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it(`should reject a POST operation on a child array authenticated to the wrong user`, async function () {
|
|
368
|
+
let { user, user_display } = await generate_user_and_display();
|
|
369
|
+
|
|
370
|
+
let user_2 = await collection_user.mongoose_model.create({
|
|
371
|
+
auth_id: 'sharon'
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
await assert.rejects(async () => {
|
|
375
|
+
let results = await got.post(`http://localhost:${port}/api/user_display/${user_display._id}/nicknames`, {
|
|
376
|
+
headers: {
|
|
377
|
+
authorization: 'sharon'
|
|
378
|
+
},
|
|
379
|
+
json: {
|
|
380
|
+
server_key: 'best_server',
|
|
381
|
+
name: 'steve the mighty'
|
|
382
|
+
}
|
|
383
|
+
}).json();
|
|
384
|
+
}, {
|
|
385
|
+
message: 'Response code 403 (Forbidden)'
|
|
386
|
+
})
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
it(`should authorize a PUT operation on a child array`, async function () {
|
|
390
|
+
let { user, user_display } = await generate_user_and_display();
|
|
391
|
+
await collection_user_display.mongoose_model.findByIdAndUpdate(user_display._id, {
|
|
392
|
+
$push: {
|
|
393
|
+
nicknames: {
|
|
394
|
+
server_key: 'best_server',
|
|
395
|
+
name: 'steve the mighty'
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
//@ts-ignore
|
|
400
|
+
user_display = await collection_user_display.mongoose_model.findById(user_display._id);
|
|
401
|
+
|
|
402
|
+
let nickname_id = user_display.nicknames[0]._id + '';
|
|
403
|
+
|
|
404
|
+
let results = await got.put(`http://localhost:${port}/api/user_display/${user_display._id}/nicknames/${nickname_id}`, {
|
|
405
|
+
headers: {
|
|
406
|
+
authorization: 'steve'
|
|
407
|
+
},
|
|
408
|
+
json: {
|
|
409
|
+
_id: nickname_id,
|
|
410
|
+
server_key: 'best_server',
|
|
411
|
+
name: 'ubersteve'
|
|
412
|
+
}
|
|
413
|
+
}).json();
|
|
414
|
+
|
|
415
|
+
//@ts-ignore
|
|
416
|
+
assert.deepEqual('ubersteve', results.data.nicknames[0].name);
|
|
417
|
+
//@ts-ignore
|
|
418
|
+
assert.deepEqual(JSON.parse(JSON.stringify(await collection_user_display.mongoose_model.findById(user_display._id))), JSON.parse(JSON.stringify(results.data)));
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
it(`should reject a PUT operation on a child array authenticated to the wrong user`, async function () {
|
|
422
|
+
let { user, user_display } = await generate_user_and_display();
|
|
423
|
+
await collection_user_display.mongoose_model.findByIdAndUpdate(user_display._id, {
|
|
424
|
+
$push: {
|
|
425
|
+
nicknames: {
|
|
426
|
+
server_key: 'best_server',
|
|
427
|
+
name: 'steve the mighty'
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
let user_2 = await collection_user.mongoose_model.create({
|
|
433
|
+
auth_id: 'sharon'
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
//@ts-ignore
|
|
438
|
+
user_display = await collection_user_display.mongoose_model.findById(user_display._id);
|
|
439
|
+
|
|
440
|
+
let nickname_id = user_display.nicknames[0]._id + '';
|
|
441
|
+
|
|
442
|
+
await assert.rejects(async () => {
|
|
443
|
+
let results = await got.put(`http://localhost:${port}/api/user_display/${user_display._id}/nicknames/${nickname_id}`, {
|
|
444
|
+
headers: {
|
|
445
|
+
authorization: 'sharon'
|
|
446
|
+
},
|
|
447
|
+
json: {
|
|
448
|
+
_id: nickname_id,
|
|
449
|
+
server_key: 'best_server',
|
|
450
|
+
name: 'ubersteve'
|
|
451
|
+
}
|
|
452
|
+
}).json();
|
|
453
|
+
}, {
|
|
454
|
+
message: 'Response code 403 (Forbidden)'
|
|
455
|
+
})
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
it(`should authorize a DELETE operation on a child array`, async function () {
|
|
459
|
+
let { user, user_display } = await generate_user_and_display();
|
|
460
|
+
await collection_user_display.mongoose_model.findByIdAndUpdate(user_display._id, {
|
|
461
|
+
$push: {
|
|
462
|
+
nicknames: {
|
|
463
|
+
server_key: 'best_server',
|
|
464
|
+
name: 'steve the mighty'
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
//@ts-ignore
|
|
469
|
+
user_display = await collection_user_display.mongoose_model.findById(user_display._id);
|
|
470
|
+
let nickname_id = user_display.nicknames[0]._id + '';
|
|
471
|
+
|
|
472
|
+
let results = await got.delete(`http://localhost:${port}/api/user_display/${user_display._id}/nicknames/${nickname_id}`, {
|
|
473
|
+
headers: {
|
|
474
|
+
authorization: 'steve'
|
|
475
|
+
},
|
|
476
|
+
}).json();
|
|
477
|
+
|
|
478
|
+
//@ts-ignore
|
|
479
|
+
assert.deepEqual(0, results.data.nicknames.length);
|
|
480
|
+
//@ts-ignore
|
|
481
|
+
assert.deepEqual(JSON.parse(JSON.stringify(await collection_user_display.mongoose_model.findById(user_display._id))), JSON.parse(JSON.stringify(results.data)));
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
it(`should reject a DELETE operation authenticated to the wrong user`, async function () {
|
|
485
|
+
let { user, user_display } = await generate_user_and_display();
|
|
486
|
+
|
|
487
|
+
let user_2 = await collection_user.mongoose_model.create({
|
|
488
|
+
auth_id: 'sharon'
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
await collection_user_display.mongoose_model.findByIdAndUpdate(user_display._id, {
|
|
492
|
+
$push: {
|
|
493
|
+
nicknames: {
|
|
494
|
+
server_key: 'best_server',
|
|
495
|
+
name: 'steve the mighty'
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
//@ts-ignore
|
|
500
|
+
user_display = await collection_user_display.mongoose_model.findById(user_display._id);
|
|
501
|
+
let nickname_id = user_display.nicknames[0]._id + '';
|
|
502
|
+
|
|
503
|
+
await assert.rejects(async () => {
|
|
504
|
+
let results = await got.delete(`http://localhost:${port}/api/user_display/${user_display._id}/nicknames/${nickname_id}`, {
|
|
505
|
+
headers: {
|
|
506
|
+
authorization: 'sharon'
|
|
507
|
+
},
|
|
508
|
+
}).json();
|
|
509
|
+
}, {
|
|
510
|
+
message: 'Response code 403 (Forbidden)'
|
|
511
|
+
})
|
|
512
|
+
});
|
|
333
513
|
});
|
|
@@ -8,7 +8,7 @@ import { F_SM_Open_Access } from '../dist/F_Security_Models/F_SM_Open_Access.js'
|
|
|
8
8
|
import { F_SM_Role_Membership } from '../dist/F_Security_Models/F_SM_Role_Membership.js'
|
|
9
9
|
import { F_Security_Model } from '../dist/F_Security_Models/F_Security_Model.js'
|
|
10
10
|
import { Cache } from '../dist/utils/cache.js'
|
|
11
|
-
import { z, ZodBoolean, ZodDate, ZodNumber, ZodString } from 'zod'
|
|
11
|
+
import { z, ZodAny, ZodBoolean, ZodDate, ZodNumber, ZodString } from 'zod'
|
|
12
12
|
|
|
13
13
|
import got from 'got'
|
|
14
14
|
import express, { Express, Request, Response, NextFunction } from 'express'
|
|
@@ -38,6 +38,10 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
38
38
|
institution_id: z_mongodb_id,
|
|
39
39
|
client_id: z_mongodb_id,
|
|
40
40
|
name: z.string(),
|
|
41
|
+
steps: z.array(z.object({
|
|
42
|
+
_id: z_mongodb_id,
|
|
43
|
+
name: z.string()
|
|
44
|
+
}))
|
|
41
45
|
});
|
|
42
46
|
let validate_user = z.object({
|
|
43
47
|
_id: z_mongodb_id,
|
|
@@ -255,25 +259,29 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
255
259
|
let steve_project = await collection_project.mongoose_model.create({
|
|
256
260
|
institution_id: steve_institution._id,
|
|
257
261
|
client_id: steve_client,
|
|
258
|
-
name: 'steve project'
|
|
262
|
+
name: 'steve project',
|
|
263
|
+
steps: [],
|
|
259
264
|
})
|
|
260
265
|
|
|
261
266
|
let joe_project = await collection_project.mongoose_model.create({
|
|
262
267
|
institution_id: steve_institution._id,
|
|
263
268
|
client_id: joe_client,
|
|
264
|
-
name: 'joe project'
|
|
269
|
+
name: 'joe project',
|
|
270
|
+
steps: [],
|
|
265
271
|
})
|
|
266
272
|
|
|
267
273
|
let nathan_project = await collection_project.mongoose_model.create({
|
|
268
274
|
institution_id: edwin_institution._id,
|
|
269
275
|
client_id: nathan_client,
|
|
270
|
-
name: 'nathan project'
|
|
276
|
+
name: 'nathan project',
|
|
277
|
+
steps: [],
|
|
271
278
|
})
|
|
272
279
|
|
|
273
280
|
let edna_project = await collection_project.mongoose_model.create({
|
|
274
281
|
institution_id: edwin_institution._id,
|
|
275
282
|
client_id: edna_client,
|
|
276
|
-
name: 'edna project'
|
|
283
|
+
name: 'edna project',
|
|
284
|
+
steps: [],
|
|
277
285
|
})
|
|
278
286
|
|
|
279
287
|
let access_role_steve_institution_grants_project = await collection_role.mongoose_model.create({
|
|
@@ -460,7 +468,8 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
460
468
|
projects.push(await collection_project.mongoose_model.create({
|
|
461
469
|
institution_id: steve_institution._id,
|
|
462
470
|
client_id: steve_client,
|
|
463
|
-
name: `additional project ${q}
|
|
471
|
+
name: `additional project ${q}`,
|
|
472
|
+
steps: [],
|
|
464
473
|
}))
|
|
465
474
|
}
|
|
466
475
|
|
|
@@ -482,7 +491,8 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
482
491
|
projects.push(await collection_project.mongoose_model.create({
|
|
483
492
|
institution_id: edwin_institution._id,
|
|
484
493
|
client_id: nathan_client,
|
|
485
|
-
name: `additional project ${q}
|
|
494
|
+
name: `additional project ${q}`,
|
|
495
|
+
steps: [],
|
|
486
496
|
}))
|
|
487
497
|
}
|
|
488
498
|
|
|
@@ -504,7 +514,8 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
504
514
|
projects.push(await collection_project.mongoose_model.create({
|
|
505
515
|
institution_id: edwin_institution._id,
|
|
506
516
|
client_id: edna_client,
|
|
507
|
-
name: `additional project ${q}
|
|
517
|
+
name: `additional project ${q}`,
|
|
518
|
+
steps: [],
|
|
508
519
|
}))
|
|
509
520
|
}
|
|
510
521
|
|
|
@@ -526,7 +537,8 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
526
537
|
projects.push(await collection_project.mongoose_model.create({
|
|
527
538
|
institution_id: steve_institution._id,
|
|
528
539
|
client_id: steve_client,
|
|
529
|
-
name: `additional project ${q}
|
|
540
|
+
name: `additional project ${q}`,
|
|
541
|
+
steps: [],
|
|
530
542
|
}))
|
|
531
543
|
}
|
|
532
544
|
|
|
@@ -631,6 +643,7 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
631
643
|
name: 'Flammable Project',
|
|
632
644
|
institution_id: steve_institution._id,
|
|
633
645
|
client_id: steve_client._id,
|
|
646
|
+
steps: [],
|
|
634
647
|
}
|
|
635
648
|
}).json();
|
|
636
649
|
|
|
@@ -649,6 +662,7 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
649
662
|
name: 'Flammable Project',
|
|
650
663
|
institution_id: edwin_institution._id,
|
|
651
664
|
client_id: nathan_client._id,
|
|
665
|
+
steps: [],
|
|
652
666
|
}
|
|
653
667
|
}).json();
|
|
654
668
|
|
|
@@ -668,6 +682,7 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
668
682
|
name: 'Flammable Project',
|
|
669
683
|
institution_id: edwin_institution._id,
|
|
670
684
|
client_id: edna_client._id,
|
|
685
|
+
steps: [],
|
|
671
686
|
}
|
|
672
687
|
}).json();
|
|
673
688
|
},
|
|
@@ -752,4 +767,309 @@ describe.skip('Security Model Role Membership', function () {
|
|
|
752
767
|
},
|
|
753
768
|
{ message: 'Response code 403 (Forbidden)' })
|
|
754
769
|
});
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
773
|
+
///////////////////////////////////////////////////////////// ARRAY OPERATIONS //////////////////////////////////////////////////////////////////////////
|
|
774
|
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
775
|
+
|
|
776
|
+
it(`should authorize a basic POST operation on a document's array children where the user has a T1 role membership`, async function () {
|
|
777
|
+
let { steve_institution, steve_client, steve_project } = await generate_test_setup();
|
|
778
|
+
|
|
779
|
+
let results = await got.post(`http://localhost:${port}/api/institution/${steve_institution._id}/client/${steve_client._id}/project/${steve_project._id}/steps`, {
|
|
780
|
+
headers: {
|
|
781
|
+
authorization: 'steve'
|
|
782
|
+
},
|
|
783
|
+
json: {
|
|
784
|
+
name: 'Fancy Step'
|
|
785
|
+
}
|
|
786
|
+
}).json();
|
|
787
|
+
|
|
788
|
+
//@ts-ignore
|
|
789
|
+
assert.deepEqual(JSON.parse(JSON.stringify(await collection_project.mongoose_model.findById(steve_project._id))), results.data);
|
|
790
|
+
assert.equal((await collection_project.mongoose_model.findById(steve_project._id))?.steps.length, 1)
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
it(`should authorize a basic PUT operation on a document's array children where the user has a T1 role membership`, async function () {
|
|
794
|
+
let { steve_institution, steve_client, steve_project } = await generate_test_setup();
|
|
795
|
+
|
|
796
|
+
//@ts-ignore
|
|
797
|
+
steve_project = await collection_project.mongoose_model.findByIdAndUpdate(steve_project._id, {
|
|
798
|
+
$push: {
|
|
799
|
+
steps: {
|
|
800
|
+
name: 'Fancy Step'
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
}, {new: true}).lean();
|
|
804
|
+
let step_id = steve_project.steps[0]._id;
|
|
805
|
+
|
|
806
|
+
let results = await got.put(`http://localhost:${port}/api/institution/${steve_institution._id}/client/${steve_client._id}/project/${steve_project._id}/steps/${step_id}`, {
|
|
807
|
+
headers: {
|
|
808
|
+
authorization: 'steve'
|
|
809
|
+
},
|
|
810
|
+
json: {
|
|
811
|
+
_id: step_id,
|
|
812
|
+
name: 'Somber Step'
|
|
813
|
+
}
|
|
814
|
+
}).json();
|
|
815
|
+
|
|
816
|
+
//@ts-ignore
|
|
817
|
+
assert.deepEqual(JSON.parse(JSON.stringify(await collection_project.mongoose_model.findById(steve_project._id))), results.data);
|
|
818
|
+
assert.equal((await collection_project.mongoose_model.findById(steve_project._id))?.steps[0].name, 'Somber Step')
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
it(`should authorize a basic DELETE operation on a document's array children where the user has a T1 role membership`, async function () {
|
|
822
|
+
let { steve_institution, steve_client, steve_project } = await generate_test_setup();
|
|
823
|
+
|
|
824
|
+
//@ts-ignore
|
|
825
|
+
steve_project = await collection_project.mongoose_model.findByIdAndUpdate(steve_project._id, {
|
|
826
|
+
$push: {
|
|
827
|
+
steps: {
|
|
828
|
+
name: 'Fancy Step'
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}, {new: true}).lean();
|
|
832
|
+
let step_id = steve_project.steps[0]._id;
|
|
833
|
+
|
|
834
|
+
let results = await got.delete(`http://localhost:${port}/api/institution/${steve_institution._id}/client/${steve_client._id}/project/${steve_project._id}/steps/${step_id}`, {
|
|
835
|
+
headers: {
|
|
836
|
+
authorization: 'steve'
|
|
837
|
+
}
|
|
838
|
+
}).json();
|
|
839
|
+
|
|
840
|
+
//@ts-ignore
|
|
841
|
+
assert.deepEqual(JSON.parse(JSON.stringify(await collection_project.mongoose_model.findById(steve_project._id))), results.data);
|
|
842
|
+
assert.equal((await collection_project.mongoose_model.findById(steve_project._id))?.steps.length, 0)
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
it(`should authorize a basic POST operation on a document's array children where the user has a T2 role membership`, async function () {
|
|
846
|
+
let { edwin_institution, nathan_client, nathan_project } = await generate_test_setup();
|
|
847
|
+
|
|
848
|
+
let results = await got.post(`http://localhost:${port}/api/institution/${edwin_institution._id}/client/${nathan_client._id}/project/${nathan_project._id}/steps`, {
|
|
849
|
+
headers: {
|
|
850
|
+
authorization: 'steve'
|
|
851
|
+
},
|
|
852
|
+
json: {
|
|
853
|
+
name: 'Fancy Step'
|
|
854
|
+
}
|
|
855
|
+
}).json();
|
|
856
|
+
|
|
857
|
+
//@ts-ignore
|
|
858
|
+
assert.deepEqual(JSON.parse(JSON.stringify(await collection_project.mongoose_model.findById(nathan_project._id))), results.data);
|
|
859
|
+
assert.equal((await collection_project.mongoose_model.findById(nathan_project._id))?.steps.length, 1)
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
it(`should authorize a basic PUT operation on a document's array children where the user has a T2 role membership`, async function () {
|
|
863
|
+
let { edwin_institution, nathan_client, nathan_project } = await generate_test_setup();
|
|
864
|
+
|
|
865
|
+
//@ts-ignore
|
|
866
|
+
nathan_project = await collection_project.mongoose_model.findByIdAndUpdate(nathan_project._id, {
|
|
867
|
+
$push: {
|
|
868
|
+
steps: {
|
|
869
|
+
name: 'Fancy Step'
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}, {new: true}).lean();
|
|
873
|
+
let step_id = nathan_project.steps[0]._id;
|
|
874
|
+
|
|
875
|
+
let results = await got.put(`http://localhost:${port}/api/institution/${edwin_institution._id}/client/${nathan_client._id}/project/${nathan_project._id}/steps/${step_id}`, {
|
|
876
|
+
headers: {
|
|
877
|
+
authorization: 'steve'
|
|
878
|
+
},
|
|
879
|
+
json: {
|
|
880
|
+
_id: step_id,
|
|
881
|
+
name: 'Somber Step'
|
|
882
|
+
}
|
|
883
|
+
}).json();
|
|
884
|
+
|
|
885
|
+
//@ts-ignore
|
|
886
|
+
assert.deepEqual(JSON.parse(JSON.stringify(await collection_project.mongoose_model.findById(nathan_project._id))), results.data);
|
|
887
|
+
assert.equal((await collection_project.mongoose_model.findById(nathan_project._id))?.steps[0].name, 'Somber Step')
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
it(`should authorize a basic DELETE operation on a document's array children where the user has a T2 role membership`, async function () {
|
|
891
|
+
let { edwin_institution, nathan_client, nathan_project } = await generate_test_setup();
|
|
892
|
+
|
|
893
|
+
//@ts-ignore
|
|
894
|
+
nathan_project = await collection_project.mongoose_model.findByIdAndUpdate(nathan_project._id, {
|
|
895
|
+
$push: {
|
|
896
|
+
steps: {
|
|
897
|
+
name: 'Fancy Step'
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}, {new: true}).lean();
|
|
901
|
+
let step_id = nathan_project.steps[0]._id;
|
|
902
|
+
|
|
903
|
+
let results = await got.delete(`http://localhost:${port}/api/institution/${edwin_institution._id}/client/${nathan_client._id}/project/${nathan_project._id}/steps/${step_id}`, {
|
|
904
|
+
headers: {
|
|
905
|
+
authorization: 'steve'
|
|
906
|
+
}
|
|
907
|
+
}).json();
|
|
908
|
+
|
|
909
|
+
//@ts-ignore
|
|
910
|
+
assert.deepEqual(JSON.parse(JSON.stringify(await collection_project.mongoose_model.findById(nathan_project._id))), results.data);
|
|
911
|
+
assert.equal((await collection_project.mongoose_model.findById(nathan_project._id))?.steps.length, 0)
|
|
912
|
+
});
|
|
913
|
+
|
|
914
|
+
it(`should reject a basic POST operation on a document's array children where the user has a role membership without permission`, async function () {
|
|
915
|
+
let { edwin_institution, edna_client, edna_project } = await generate_test_setup();
|
|
916
|
+
|
|
917
|
+
await assert.rejects(async () => {
|
|
918
|
+
let results = await got.post(`http://localhost:${port}/api/institution/${edwin_institution._id}/client/${edna_client._id}/project/${edna_project._id}/steps`, {
|
|
919
|
+
headers: {
|
|
920
|
+
authorization: 'steve'
|
|
921
|
+
},
|
|
922
|
+
json: {
|
|
923
|
+
name: 'Fancy Step'
|
|
924
|
+
}
|
|
925
|
+
}).json();
|
|
926
|
+
},
|
|
927
|
+
{ message: 'Response code 403 (Forbidden)' })
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
it(`should reject a basic PUT operation on a document's array children where the user has a role membership without permission`, async function () {
|
|
931
|
+
let { edwin_institution, edna_client, edna_project } = await generate_test_setup();
|
|
932
|
+
|
|
933
|
+
//@ts-ignore
|
|
934
|
+
edna_project = await collection_project.mongoose_model.findByIdAndUpdate(edna_project._id, {
|
|
935
|
+
$push: {
|
|
936
|
+
steps: {
|
|
937
|
+
name: 'Fancy Step'
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}, {new: true}).lean();
|
|
941
|
+
let step_id = edna_project.steps[0]._id;
|
|
942
|
+
|
|
943
|
+
await assert.rejects(async () => {
|
|
944
|
+
let results = await got.put(`http://localhost:${port}/api/institution/${edwin_institution._id}/client/${edna_client._id}/project/${edna_project._id}/steps/${step_id}`, {
|
|
945
|
+
headers: {
|
|
946
|
+
authorization: 'steve'
|
|
947
|
+
},
|
|
948
|
+
json: {
|
|
949
|
+
_id: step_id,
|
|
950
|
+
name: 'Somber Step'
|
|
951
|
+
}
|
|
952
|
+
}).json();
|
|
953
|
+
},
|
|
954
|
+
{ message: 'Response code 403 (Forbidden)' })
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
it(`should reject a basic DELETE operation on a document's array children where the user has a role membership without permission`, async function () {
|
|
958
|
+
let { edwin_institution, edna_client, edna_project } = await generate_test_setup();
|
|
959
|
+
|
|
960
|
+
//@ts-ignore
|
|
961
|
+
edna_project = await collection_project.mongoose_model.findByIdAndUpdate(edna_project._id, {
|
|
962
|
+
$push: {
|
|
963
|
+
steps: {
|
|
964
|
+
name: 'Fancy Step'
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
}, {new: true}).lean();
|
|
968
|
+
let step_id = edna_project.steps[0]._id;
|
|
969
|
+
|
|
970
|
+
await assert.rejects(async () => {
|
|
971
|
+
let results = await got.delete(`http://localhost:${port}/api/institution/${edwin_institution._id}/client/${edna_client._id}/project/${edna_project._id}/steps/${step_id}`, {
|
|
972
|
+
headers: {
|
|
973
|
+
authorization: 'steve'
|
|
974
|
+
}
|
|
975
|
+
}).json();
|
|
976
|
+
},
|
|
977
|
+
{ message: 'Response code 403 (Forbidden)' })
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
it(`should reject a basic POST operation on a document's array children where the user has POST permission but not PUT permission`, async function () {
|
|
981
|
+
let { steve_institution, steve_client, steve_project } = await generate_test_setup();
|
|
982
|
+
|
|
983
|
+
let user_barnabus = await collection_user.mongoose_model.create({
|
|
984
|
+
auth_id: 'barnabus'
|
|
985
|
+
});
|
|
986
|
+
|
|
987
|
+
let access_role_steve_institution_grants_project_no_update = await collection_role.mongoose_model.create({
|
|
988
|
+
name: 'steve full access',
|
|
989
|
+
institution_id: steve_institution._id,
|
|
990
|
+
permissions: {
|
|
991
|
+
institutions: ['read', 'create', 'update', 'delete'],
|
|
992
|
+
clients: ['read', 'create', 'update', 'delete'],
|
|
993
|
+
projects: ['read', 'create', 'delete'],
|
|
994
|
+
roles: ['read', 'create', 'update', 'delete'],
|
|
995
|
+
}
|
|
996
|
+
});
|
|
997
|
+
|
|
998
|
+
let barnabus_institution_role_membership = await collection_institution_role_membership.mongoose_model.create({
|
|
999
|
+
role_id: access_role_steve_institution_grants_project_no_update._id,
|
|
1000
|
+
user_id: user_barnabus._id,
|
|
1001
|
+
institution_id: steve_institution._id,
|
|
1002
|
+
})
|
|
1003
|
+
|
|
1004
|
+
await assert.rejects(async () => {
|
|
1005
|
+
let results = await got.post(`http://localhost:${port}/api/institution/${steve_institution._id}/client/${steve_client._id}/project/${steve_project._id}/steps`, {
|
|
1006
|
+
headers: {
|
|
1007
|
+
authorization: 'barnabus'
|
|
1008
|
+
},
|
|
1009
|
+
json: {
|
|
1010
|
+
name: 'Fancy Step'
|
|
1011
|
+
}
|
|
1012
|
+
}).json();
|
|
1013
|
+
},
|
|
1014
|
+
{ message: 'Response code 403 (Forbidden)' })
|
|
1015
|
+
});
|
|
1016
|
+
|
|
1017
|
+
it(`should reject a basic DELETE operation on a document's array children where the user has DELETE permission but not PUT permission`, async function () {
|
|
1018
|
+
let { steve_institution, steve_client, steve_project, steve_steve_institution_role_membership } = await generate_test_setup();
|
|
1019
|
+
|
|
1020
|
+
let user_barnabus = await collection_user.mongoose_model.create({
|
|
1021
|
+
auth_id: 'barnabus'
|
|
1022
|
+
});
|
|
1023
|
+
|
|
1024
|
+
let access_role_steve_institution_grants_project_no_update = await collection_role.mongoose_model.create({
|
|
1025
|
+
name: 'steve full access',
|
|
1026
|
+
institution_id: steve_institution._id,
|
|
1027
|
+
permissions: {
|
|
1028
|
+
institutions: ['read', 'create', 'update', 'delete'],
|
|
1029
|
+
clients: ['read', 'create', 'update', 'delete'],
|
|
1030
|
+
projects: ['read', 'create', 'delete'],
|
|
1031
|
+
roles: ['read', 'create', 'update', 'delete'],
|
|
1032
|
+
}
|
|
1033
|
+
});
|
|
1034
|
+
|
|
1035
|
+
let barnabus_institution_role_membership = await collection_institution_role_membership.mongoose_model.create({
|
|
1036
|
+
role_id: access_role_steve_institution_grants_project_no_update._id,
|
|
1037
|
+
user_id: user_barnabus._id,
|
|
1038
|
+
institution_id: steve_institution._id,
|
|
1039
|
+
})
|
|
1040
|
+
|
|
1041
|
+
let steve_new_access_role = await collection_role.mongoose_model.create({
|
|
1042
|
+
name: 'steve no project update',
|
|
1043
|
+
institution_id: steve_institution._id,
|
|
1044
|
+
permissions: {
|
|
1045
|
+
institutions: ['read', 'create', 'update', 'delete'],
|
|
1046
|
+
clients: ['read', 'create', 'update', 'delete'],
|
|
1047
|
+
projects: ['read', 'create', 'delete'],
|
|
1048
|
+
roles: ['read', 'create', 'update', 'delete'],
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
|
|
1052
|
+
await collection_client_role_membership.mongoose_model.findByIdAndUpdate(steve_steve_institution_role_membership._id, {
|
|
1053
|
+
role_id: steve_new_access_role._id
|
|
1054
|
+
})
|
|
1055
|
+
|
|
1056
|
+
//@ts-ignore
|
|
1057
|
+
steve_project = await collection_project.mongoose_model.findByIdAndUpdate(steve_project._id, {
|
|
1058
|
+
$push: {
|
|
1059
|
+
steps: {
|
|
1060
|
+
name: 'Fancy Step'
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}, {new: true}).lean();
|
|
1064
|
+
let step_id = steve_project.steps[0]._id;
|
|
1065
|
+
|
|
1066
|
+
await assert.rejects(async () => {
|
|
1067
|
+
let results = await got.delete(`http://localhost:${port}/api/institution/${steve_institution._id}/client/${steve_client._id}/project/${steve_project._id}/steps/${step_id}`, {
|
|
1068
|
+
headers: {
|
|
1069
|
+
authorization: 'barnabus'
|
|
1070
|
+
}
|
|
1071
|
+
}).json();
|
|
1072
|
+
},
|
|
1073
|
+
{ message: 'Response code 403 (Forbidden)' })
|
|
1074
|
+
});
|
|
755
1075
|
});
|