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