@nocobase/plugin-acl 0.8.1-alpha.4 → 0.9.0-alpha.2

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.
Files changed (41) hide show
  1. package/LICENSE +661 -201
  2. package/lib/actions/role-check.js +2 -0
  3. package/lib/actions/role-collections.js +39 -12
  4. package/lib/collections/roles.js +4 -0
  5. package/lib/collections/rolesResourcesActions.js +2 -1
  6. package/lib/collections/users.js +1 -0
  7. package/lib/migrations/20221214072638-set-role-snippets.d.ts +5 -0
  8. package/lib/migrations/20221214072638-set-role-snippets.js +49 -0
  9. package/lib/model/RoleModel.js +1 -0
  10. package/lib/model/RoleResourceActionModel.js +9 -3
  11. package/lib/server.js +393 -28
  12. package/package.json +7 -13
  13. package/src/__tests__/acl.test.ts +0 -548
  14. package/src/__tests__/association-field.test.ts +0 -308
  15. package/src/__tests__/configuration.test.ts +0 -74
  16. package/src/__tests__/middleware.test.ts +0 -228
  17. package/src/__tests__/own.test.ts +0 -133
  18. package/src/__tests__/prepare.ts +0 -20
  19. package/src/__tests__/role-check.test.ts +0 -41
  20. package/src/__tests__/role-resource.test.ts +0 -189
  21. package/src/__tests__/role-user.test.ts +0 -123
  22. package/src/__tests__/role.test.ts +0 -99
  23. package/src/__tests__/scope.test.ts +0 -59
  24. package/src/__tests__/setCurrentRole.test.ts +0 -83
  25. package/src/__tests__/users.test.ts +0 -52
  26. package/src/actions/available-actions.ts +0 -18
  27. package/src/actions/role-check.ts +0 -41
  28. package/src/actions/role-collections.ts +0 -65
  29. package/src/actions/user-setDefaultRole.ts +0 -45
  30. package/src/collections/roles-users.ts +0 -6
  31. package/src/collections/roles.ts +0 -79
  32. package/src/collections/rolesResources.ts +0 -31
  33. package/src/collections/rolesResourcesActions.ts +0 -28
  34. package/src/collections/rolesResourcesScopes.ts +0 -23
  35. package/src/collections/users.ts +0 -30
  36. package/src/index.ts +0 -2
  37. package/src/middlewares/setCurrentRole.ts +0 -32
  38. package/src/model/RoleModel.ts +0 -21
  39. package/src/model/RoleResourceActionModel.ts +0 -88
  40. package/src/model/RoleResourceModel.ts +0 -74
  41. package/src/server.ts +0 -463
@@ -1,548 +0,0 @@
1
- import { ACL } from '@nocobase/acl';
2
- import { Database } from '@nocobase/database';
3
- import { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
4
- import UsersPlugin from '@nocobase/plugin-users';
5
- import { MockServer } from '@nocobase/test';
6
- import { prepareApp } from './prepare';
7
-
8
- describe('acl', () => {
9
- let app: MockServer;
10
- let db: Database;
11
- let acl: ACL;
12
- let admin;
13
- let adminAgent;
14
-
15
- let uiSchemaRepository: UiSchemaRepository;
16
-
17
- afterEach(async () => {
18
- await app.destroy();
19
- });
20
-
21
- beforeEach(async () => {
22
- app = await prepareApp();
23
- db = app.db;
24
- acl = app.acl;
25
-
26
- const UserRepo = db.getCollection('users').repository;
27
- admin = await UserRepo.create({
28
- values: {
29
- roles: ['admin'],
30
- },
31
- });
32
-
33
- const userPlugin = app.getPlugin('users') as UsersPlugin;
34
-
35
- adminAgent = app.agent().auth(
36
- userPlugin.jwtService.sign({
37
- userId: admin.get('id'),
38
- }),
39
- { type: 'bearer' },
40
- );
41
-
42
- uiSchemaRepository = db.getRepository('uiSchemas');
43
- });
44
-
45
- it('should works with universal actions', async () => {
46
- await db.getRepository('roles').create({
47
- values: {
48
- name: 'new',
49
- },
50
- });
51
-
52
- expect(
53
- acl.can({
54
- role: 'new',
55
- resource: 'posts',
56
- action: 'create',
57
- }),
58
- ).toBeNull();
59
-
60
- // grant universal action
61
- await adminAgent.resource('roles').update({
62
- resourceIndex: 'new',
63
- values: {
64
- strategy: {
65
- actions: ['create'],
66
- },
67
- },
68
- forceUpdate: true,
69
- });
70
-
71
- expect(
72
- acl.can({
73
- role: 'new',
74
- resource: 'posts',
75
- action: 'create',
76
- }),
77
- ).toMatchObject({
78
- role: 'new',
79
- resource: 'posts',
80
- action: 'create',
81
- });
82
- });
83
-
84
- it('should deny when resource action has no resource', async () => {
85
- await db.getRepository('roles').create({
86
- values: {
87
- name: 'new',
88
- strategy: {
89
- actions: ['update:own', 'destroy:own', 'create', 'view'],
90
- },
91
- },
92
- });
93
-
94
- // create c1 collection
95
- await db.getRepository('collections').create({
96
- values: {
97
- name: 'c1',
98
- title: 'table1',
99
- },
100
- });
101
-
102
- // create c2 collection
103
- await db.getRepository('collections').create({
104
- values: {
105
- name: 'c2',
106
- title: 'table2',
107
- },
108
- });
109
-
110
- await adminAgent.resource('roles.resources', 'new').create({
111
- values: {
112
- name: 'c1',
113
- usingActionsConfig: true,
114
- actions: [],
115
- },
116
- });
117
-
118
- expect(
119
- acl.can({
120
- role: 'new',
121
- resource: 'c1',
122
- action: 'list',
123
- }),
124
- ).toBeNull();
125
- });
126
-
127
- it('should works with resources actions', async () => {
128
- const role = await db.getRepository('roles').create({
129
- values: {
130
- name: 'new',
131
- strategy: {
132
- actions: ['list'],
133
- },
134
- },
135
- });
136
-
137
- // create c1 collection
138
- await db.getRepository('collections').create({
139
- values: {
140
- name: 'c1',
141
- title: 'table1',
142
- },
143
- });
144
-
145
- // create c2 collection
146
- await db.getRepository('collections').create({
147
- values: {
148
- name: 'c2',
149
- title: 'table2',
150
- },
151
- });
152
-
153
- // create c1 published scope
154
- const {
155
- body: { data: publishedScope },
156
- } = await adminAgent.resource('rolesResourcesScopes').create({
157
- values: {
158
- resourceName: 'c1',
159
- name: 'published',
160
- scope: {
161
- published: true,
162
- },
163
- },
164
- });
165
-
166
- // await db.getRepository('rolesResourcesScopes').findOne();
167
-
168
- // set admin resources
169
- await adminAgent.resource('roles.resources', 'new').create({
170
- values: {
171
- name: 'c1',
172
- usingActionsConfig: true,
173
- actions: [
174
- {
175
- name: 'create',
176
- scope: publishedScope.id,
177
- },
178
- {
179
- name: 'view',
180
- fields: ['title', 'age'],
181
- },
182
- ],
183
- },
184
- });
185
-
186
- expect(
187
- acl.can({
188
- role: 'new',
189
- resource: 'c1',
190
- action: 'create',
191
- }),
192
- ).toMatchObject({
193
- role: 'new',
194
- resource: 'c1',
195
- action: 'create',
196
- params: {
197
- filter: { published: true },
198
- },
199
- });
200
-
201
- expect(
202
- acl.can({
203
- role: 'new',
204
- resource: 'c1',
205
- action: 'view',
206
- }),
207
- ).toMatchObject({
208
- role: 'new',
209
- resource: 'c1',
210
- action: 'view',
211
- params: {
212
- fields: ['age', 'title', 'id', 'createdAt', 'updatedAt'],
213
- },
214
- });
215
-
216
- // revoke action
217
- const response = await adminAgent.resource('roles.resources', role.get('name')).list({
218
- appends: ['actions'],
219
- });
220
-
221
- expect(response.statusCode).toEqual(200);
222
-
223
- const actions = response.body.data[0].actions;
224
- const collectionName = response.body.data[0].name;
225
-
226
- await adminAgent.resource('roles.resources', role.get('name')).update({
227
- filterByTk: collectionName,
228
- values: {
229
- name: 'c1',
230
- usingActionsConfig: true,
231
- actions: [
232
- {
233
- name: 'view',
234
- fields: ['title', 'age'],
235
- },
236
- ],
237
- },
238
- });
239
-
240
- expect(
241
- acl.can({
242
- role: 'new',
243
- resource: 'c1',
244
- action: 'create',
245
- }),
246
- ).toBeNull();
247
- });
248
-
249
- it('should revoke resource when collection destroy', async () => {
250
- await db.getRepository('roles').create({
251
- values: {
252
- name: 'new',
253
- },
254
- });
255
-
256
- await db.getRepository('collections').create({
257
- values: {
258
- name: 'posts',
259
- },
260
- });
261
-
262
- await db.getRepository('fields').create({
263
- values: {
264
- collectionName: 'posts',
265
- type: 'string',
266
- name: 'title',
267
- },
268
- });
269
-
270
- await adminAgent.resource('roles.resources').create({
271
- associatedIndex: 'new',
272
- values: {
273
- name: 'posts',
274
- usingActionsConfig: true,
275
- actions: [
276
- {
277
- name: 'view',
278
- fields: ['title'],
279
- },
280
- ],
281
- },
282
- });
283
-
284
- expect(
285
- acl.can({
286
- role: 'new',
287
- resource: 'posts',
288
- action: 'view',
289
- }),
290
- ).not.toBeNull();
291
-
292
- await db.getRepository('collections').destroy({
293
- filter: {
294
- name: 'posts',
295
- },
296
- });
297
-
298
- expect(
299
- acl.can({
300
- role: 'new',
301
- resource: 'posts',
302
- action: 'view',
303
- }),
304
- ).toBeNull();
305
- });
306
-
307
- it('should revoke actions when not using actions config', async () => {
308
- await db.getRepository('roles').create({
309
- values: {
310
- name: 'new',
311
- },
312
- });
313
-
314
- await db.getRepository('collections').create({
315
- values: {
316
- name: 'posts',
317
- title: 'posts',
318
- },
319
- });
320
-
321
- await adminAgent.resource('roles.resources').create({
322
- associatedIndex: 'new',
323
- values: {
324
- name: 'posts',
325
- usingActionsConfig: true,
326
- actions: [
327
- {
328
- name: 'create',
329
- },
330
- ],
331
- },
332
- });
333
-
334
- expect(
335
- acl.can({
336
- role: 'new',
337
- resource: 'posts',
338
- action: 'create',
339
- }),
340
- ).toMatchObject({
341
- role: 'new',
342
- resource: 'posts',
343
- action: 'create',
344
- });
345
-
346
- await adminAgent.resource('roles.resources', 'new').update({
347
- filterByTk: (
348
- await db.getRepository('rolesResources').findOne({
349
- filter: {
350
- name: 'posts',
351
- roleName: 'new',
352
- },
353
- })
354
- ).get('name') as string,
355
- values: {
356
- usingActionsConfig: false,
357
- },
358
- });
359
-
360
- expect(
361
- acl.can({
362
- role: 'new',
363
- resource: 'posts',
364
- action: 'create',
365
- }),
366
- ).toBeNull();
367
-
368
- await adminAgent.resource('roles.resources', 'new').update({
369
- filterByTk: (
370
- await db.getRepository('rolesResources').findOne({
371
- filter: {
372
- name: 'posts',
373
- roleName: 'new',
374
- },
375
- })
376
- ).get('name') as string,
377
- values: {
378
- usingActionsConfig: true,
379
- },
380
- });
381
-
382
- expect(
383
- acl.can({
384
- role: 'new',
385
- resource: 'posts',
386
- action: 'create',
387
- }),
388
- ).toMatchObject({
389
- role: 'new',
390
- resource: 'posts',
391
- action: 'create',
392
- });
393
- });
394
-
395
- it('should add fields when field created', async () => {
396
- await db.getRepository('roles').create({
397
- values: {
398
- name: 'new',
399
- },
400
- });
401
-
402
- await db.getRepository('collections').create({
403
- values: {
404
- name: 'posts',
405
- },
406
- });
407
-
408
- await db.getRepository('fields').create({
409
- values: {
410
- collectionName: 'posts',
411
- type: 'string',
412
- name: 'title',
413
- },
414
- });
415
-
416
- await adminAgent.resource('roles.resources').create({
417
- associatedIndex: 'new',
418
- values: {
419
- name: 'posts',
420
- usingActionsConfig: true,
421
- actions: [
422
- {
423
- name: 'view',
424
- fields: ['title'],
425
- },
426
- ],
427
- },
428
- });
429
-
430
- const allowFields = acl.can({
431
- role: 'new',
432
- resource: 'posts',
433
- action: 'view',
434
- })['params']['fields'];
435
-
436
- expect(allowFields.includes('title')).toBeTruthy();
437
-
438
- await db.getRepository('fields').create({
439
- values: {
440
- collectionName: 'posts',
441
- type: 'string',
442
- name: 'description',
443
- },
444
- });
445
-
446
- const newAllowFields = acl.can({
447
- role: 'new',
448
- resource: 'posts',
449
- action: 'view',
450
- })['params']['fields'];
451
-
452
- expect(newAllowFields.includes('description')).toBeTruthy();
453
- });
454
-
455
- it('should get role menus', async () => {
456
- const role = await db.getRepository('roles').create({
457
- values: {
458
- name: 'new',
459
- strategy: {
460
- actions: ['view'],
461
- },
462
- },
463
- });
464
-
465
- const menuResponse = await adminAgent.resource('roles.menuUiSchemas', 'new').list();
466
-
467
- expect(menuResponse.statusCode).toEqual(200);
468
- });
469
-
470
- it('should toggle role menus', async () => {
471
- const role = await db.getRepository('roles').create({
472
- values: {
473
- name: 'new',
474
- strategy: {
475
- actions: ['*'],
476
- },
477
- },
478
- });
479
- const UserRepo = db.getCollection('users').repository;
480
- const user = await UserRepo.create({
481
- values: {
482
- roles: ['new'],
483
- },
484
- });
485
-
486
- const userPlugin = app.getPlugin('users') as UsersPlugin;
487
- const userAgent = app.agent().auth(
488
- userPlugin.jwtService.sign({
489
- userId: user.get('id'),
490
- }),
491
- { type: 'bearer' },
492
- );
493
-
494
- const schema = {
495
- 'x-uid': 'test',
496
- };
497
-
498
- await uiSchemaRepository.insert(schema);
499
-
500
- const response = await userAgent
501
- // @ts-ignore
502
- .resource('roles.menuUiSchemas', 'new')
503
- .toggle({
504
- values: { tk: 'test' },
505
- });
506
-
507
- expect(response.statusCode).toEqual(200);
508
- });
509
-
510
- it('should sync data to acl after app reload', async () => {
511
- const role = await db.getRepository('roles').create({
512
- values: {
513
- name: 'new',
514
- resources: [
515
- {
516
- name: 'posts',
517
- usingActionsConfig: true,
518
- actions: [
519
- {
520
- name: 'view',
521
- fields: ['title'],
522
- },
523
- ],
524
- },
525
- ],
526
- },
527
- hooks: false,
528
- });
529
-
530
- expect(app.acl.getRole('new')).toBeUndefined();
531
-
532
- await app.reload();
533
-
534
- expect(app.acl.getRole('new')).toBeDefined();
535
-
536
- expect(
537
- app.acl.can({
538
- role: 'new',
539
- resource: 'posts',
540
- action: 'view',
541
- }),
542
- ).toMatchObject({
543
- role: 'new',
544
- resource: 'posts',
545
- action: 'view',
546
- });
547
- });
548
- });