@nocobase/plugin-acl 0.11.1-alpha.5 → 0.12.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 (96) hide show
  1. package/client.d.ts +2 -3
  2. package/client.js +1 -1
  3. package/dist/client/index.js +11 -0
  4. package/{lib/server → dist}/index.d.ts +1 -0
  5. package/dist/index.js +18 -0
  6. package/{src/server/actions/available-actions.ts → dist/server/actions/available-actions.js} +7 -5
  7. package/{src/server/actions/role-check.ts → dist/server/actions/role-check.js} +17 -22
  8. package/dist/server/actions/role-collections.js +53 -0
  9. package/dist/server/actions/user-setDefaultRole.js +43 -0
  10. package/dist/server/collections/roles-users.js +10 -0
  11. package/dist/server/collections/roles.js +103 -0
  12. package/dist/server/collections/rolesResources.js +35 -0
  13. package/dist/server/collections/rolesResourcesActions.js +33 -0
  14. package/dist/server/collections/rolesResourcesScopes.js +27 -0
  15. package/dist/server/collections/users.js +35 -0
  16. package/dist/server/index.js +11 -0
  17. package/dist/server/middlewares/setCurrentRole.js +31 -0
  18. package/dist/server/migrations/20221214072638-set-role-snippets.js +25 -0
  19. package/dist/server/model/RoleModel.js +23 -0
  20. package/dist/server/model/RoleResourceActionModel.js +64 -0
  21. package/dist/server/model/RoleResourceModel.js +55 -0
  22. package/dist/server/server.js +709 -0
  23. package/package.json +12 -21
  24. package/server.d.ts +3 -3
  25. package/server.js +1 -1
  26. package/lib/client/index.js +0 -22
  27. package/lib/index.js +0 -13
  28. package/lib/server/actions/available-actions.js +0 -34
  29. package/lib/server/actions/role-check.js +0 -77
  30. package/lib/server/actions/role-collections.js +0 -98
  31. package/lib/server/actions/user-setDefaultRole.js +0 -52
  32. package/lib/server/collections/roles-users.js +0 -16
  33. package/lib/server/collections/roles.js +0 -92
  34. package/lib/server/collections/rolesResources.js +0 -31
  35. package/lib/server/collections/rolesResourcesActions.js +0 -31
  36. package/lib/server/collections/rolesResourcesScopes.js +0 -25
  37. package/lib/server/collections/users.js +0 -41
  38. package/lib/server/index.js +0 -13
  39. package/lib/server/middlewares/setCurrentRole.js +0 -45
  40. package/lib/server/migrations/20221214072638-set-role-snippets.js +0 -43
  41. package/lib/server/model/RoleModel.js +0 -35
  42. package/lib/server/model/RoleResourceActionModel.js +0 -91
  43. package/lib/server/model/RoleResourceModel.js +0 -106
  44. package/lib/server/server.js +0 -947
  45. package/src/client/index.ts +0 -8
  46. package/src/index.ts +0 -1
  47. package/src/server/__tests__/acl.test.ts +0 -835
  48. package/src/server/__tests__/actions.test.ts +0 -141
  49. package/src/server/__tests__/association-field.test.ts +0 -413
  50. package/src/server/__tests__/configuration.test.ts +0 -70
  51. package/src/server/__tests__/list-action.test.ts +0 -446
  52. package/src/server/__tests__/middleware.test.ts +0 -210
  53. package/src/server/__tests__/own.test.ts +0 -124
  54. package/src/server/__tests__/prepare.ts +0 -20
  55. package/src/server/__tests__/role-check.test.ts +0 -46
  56. package/src/server/__tests__/role-resource.test.ts +0 -177
  57. package/src/server/__tests__/role-user.test.ts +0 -127
  58. package/src/server/__tests__/role.test.ts +0 -118
  59. package/src/server/__tests__/scope.test.ts +0 -55
  60. package/src/server/__tests__/setCurrentRole.test.ts +0 -86
  61. package/src/server/__tests__/snippets.test.ts +0 -35
  62. package/src/server/__tests__/users.test.ts +0 -136
  63. package/src/server/__tests__/write-role-to-acl.test.ts +0 -41
  64. package/src/server/actions/role-collections.ts +0 -95
  65. package/src/server/actions/user-setDefaultRole.ts +0 -47
  66. package/src/server/collections/roles-users.ts +0 -8
  67. package/src/server/collections/roles.ts +0 -101
  68. package/src/server/collections/rolesResources.ts +0 -33
  69. package/src/server/collections/rolesResourcesActions.ts +0 -31
  70. package/src/server/collections/rolesResourcesScopes.ts +0 -25
  71. package/src/server/collections/users.ts +0 -31
  72. package/src/server/index.ts +0 -1
  73. package/src/server/middlewares/setCurrentRole.ts +0 -35
  74. package/src/server/migrations/20221214072638-set-role-snippets.ts +0 -23
  75. package/src/server/model/RoleModel.ts +0 -23
  76. package/src/server/model/RoleResourceActionModel.ts +0 -95
  77. package/src/server/model/RoleResourceModel.ts +0 -74
  78. package/src/server/server.ts +0 -854
  79. /package/{lib → dist}/client/index.d.ts +0 -0
  80. /package/{lib → dist}/server/actions/available-actions.d.ts +0 -0
  81. /package/{lib → dist}/server/actions/role-check.d.ts +0 -0
  82. /package/{lib → dist}/server/actions/role-collections.d.ts +0 -0
  83. /package/{lib → dist}/server/actions/user-setDefaultRole.d.ts +0 -0
  84. /package/{lib → dist}/server/collections/roles-users.d.ts +0 -0
  85. /package/{lib → dist}/server/collections/roles.d.ts +0 -0
  86. /package/{lib → dist}/server/collections/rolesResources.d.ts +0 -0
  87. /package/{lib → dist}/server/collections/rolesResourcesActions.d.ts +0 -0
  88. /package/{lib → dist}/server/collections/rolesResourcesScopes.d.ts +0 -0
  89. /package/{lib → dist}/server/collections/users.d.ts +0 -0
  90. /package/{lib → dist/server}/index.d.ts +0 -0
  91. /package/{lib → dist}/server/middlewares/setCurrentRole.d.ts +0 -0
  92. /package/{lib → dist}/server/migrations/20221214072638-set-role-snippets.d.ts +0 -0
  93. /package/{lib → dist}/server/model/RoleModel.d.ts +0 -0
  94. /package/{lib → dist}/server/model/RoleResourceActionModel.d.ts +0 -0
  95. /package/{lib → dist}/server/model/RoleResourceModel.d.ts +0 -0
  96. /package/{lib → dist}/server/server.d.ts +0 -0
@@ -1,141 +0,0 @@
1
- import { MockServer } from '@nocobase/test';
2
- import { prepareApp } from './prepare';
3
-
4
- describe('destroy action with acl', () => {
5
- let app: MockServer;
6
- let Post;
7
-
8
- beforeEach(async () => {
9
- app = await prepareApp();
10
-
11
- Post = app.collection({
12
- name: 'posts',
13
- fields: [
14
- { type: 'string', name: 'title' },
15
- {
16
- type: 'bigInt',
17
- name: 'createdById',
18
- },
19
- ],
20
- });
21
-
22
- await app.db.sync();
23
- });
24
-
25
- afterEach(async () => {
26
- await app.destroy();
27
- });
28
-
29
- it('should throw error when user has no permission to destroy record', async () => {
30
- const userRole = app.acl.define({
31
- role: 'user',
32
- });
33
-
34
- // user can destroy post which created by himself
35
- userRole.grantAction('posts:destroy', {
36
- own: true,
37
- });
38
-
39
- const p1 = await Post.repository.create({
40
- values: {
41
- title: 'p1',
42
- createById: 2,
43
- },
44
- });
45
-
46
- app.resourcer.use(
47
- (ctx, next) => {
48
- ctx.state.currentRole = 'user';
49
- ctx.state.currentUser = {
50
- id: 1,
51
- };
52
- return next();
53
- },
54
- {
55
- before: 'acl',
56
- },
57
- );
58
-
59
- const response = await app
60
- .agent()
61
- .resource('posts')
62
- .destroy({
63
- filterByTk: p1.get('id'),
64
- });
65
-
66
- // should throw errors
67
- expect(response.statusCode).toEqual(403);
68
- });
69
-
70
- it('should throw error when user has no permissions with array query', async () => {
71
- const userRole = app.acl.define({
72
- role: 'user',
73
- });
74
-
75
- userRole.grantAction('posts:destroy', {
76
- filter: {
77
- 'title.$in': ['p1', 'p2', 'p3'],
78
- },
79
- });
80
-
81
- await Post.repository.create({
82
- values: [
83
- {
84
- title: 'p1',
85
- },
86
- {
87
- title: 'p2',
88
- },
89
- {
90
- title: 'p3',
91
- },
92
- {
93
- title: 'p4',
94
- },
95
- {
96
- title: 'p5',
97
- },
98
- {
99
- title: 'p6',
100
- },
101
- ],
102
- });
103
-
104
- app.resourcer.use(
105
- (ctx, next) => {
106
- ctx.state.currentRole = 'user';
107
- ctx.state.currentUser = {
108
- id: 1,
109
- };
110
- return next();
111
- },
112
- {
113
- before: 'acl',
114
- },
115
- );
116
-
117
- const response = await app
118
- .agent()
119
- .resource('posts')
120
- .destroy({
121
- filter: {
122
- 'title.$in': ['p4', 'p5', 'p6'],
123
- },
124
- });
125
-
126
- // should throw error
127
- expect(response.statusCode).toEqual(403);
128
-
129
- const response2 = await app
130
- .agent()
131
- .resource('posts')
132
- .destroy({
133
- filter: {
134
- 'title.$in': ['p1'],
135
- },
136
- });
137
-
138
- // should throw error
139
- expect(response2.statusCode).toEqual(200);
140
- });
141
- });
@@ -1,413 +0,0 @@
1
- import { ACL } from '@nocobase/acl';
2
- import { Database, HasManyRepository } from '@nocobase/database';
3
- import UsersPlugin from '@nocobase/plugin-users';
4
- import { MockServer } from '@nocobase/test';
5
- import { prepareApp } from './prepare';
6
-
7
- describe('association test', () => {
8
- let app: MockServer;
9
- let db: Database;
10
- let acl: ACL;
11
-
12
- let user;
13
- let userAgent;
14
- let admin;
15
- let adminAgent;
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
-
27
- it('should set association actions', async () => {
28
- await db.getRepository('collections').create({
29
- values: {
30
- name: 'posts',
31
- fields: [
32
- { name: 'title', type: 'string' },
33
- { name: 'userComments', type: 'hasMany', target: 'comments', interface: 'linkTo' },
34
- ],
35
- },
36
- context: {},
37
- });
38
-
39
- await db.getRepository('collections').create({
40
- values: {
41
- name: 'comments',
42
- fields: [{ name: 'content', type: 'string' }],
43
- },
44
- context: {},
45
- });
46
-
47
- await db.getRepository('roles').create({
48
- values: {
49
- name: 'test-role',
50
- },
51
- context: {},
52
- });
53
-
54
- await db.getRepository('roles.resources', 'test-role').create({
55
- values: {
56
- name: 'posts',
57
- usingActionsConfig: true,
58
- actions: [
59
- {
60
- name: 'view',
61
- fields: ['userComments'],
62
- },
63
- ],
64
- },
65
- context: {},
66
- });
67
-
68
- const role = acl.getRole('test-role');
69
-
70
- expect(
71
- acl.can({
72
- role: 'test-role',
73
- action: 'list',
74
- resource: 'posts.userComments',
75
- }),
76
- ).not.toBeNull();
77
-
78
- const post = await db.getRepository('posts').create({
79
- values: {
80
- title: 'hello world',
81
- userComments: [{ content: 'comment 1' }],
82
- },
83
- });
84
-
85
- const UserRepo = db.getCollection('users').repository;
86
- const user = await UserRepo.create({
87
- values: {
88
- roles: ['test-role'],
89
- },
90
- });
91
-
92
- const userAgent = app.agent().login(user);
93
-
94
- //@ts-ignore
95
- const response = await userAgent.resource('posts').list({});
96
- expect(response.statusCode).toEqual(200);
97
- const post1 = response.body.data[0];
98
- expect(post1.userComments).not.toBeDefined();
99
- });
100
- });
101
-
102
- describe('association field acl', () => {
103
- let app: MockServer;
104
- let db: Database;
105
- let acl: ACL;
106
-
107
- let user;
108
- let userAgent;
109
- let admin;
110
- let adminAgent;
111
-
112
- afterEach(async () => {
113
- await app.destroy();
114
- });
115
-
116
- beforeEach(async () => {
117
- app = await prepareApp();
118
- db = app.db;
119
- acl = app.acl;
120
-
121
- await db.getRepository('roles').create({
122
- values: {
123
- name: 'new',
124
- },
125
- });
126
-
127
- await db.getRepository('roles').create({
128
- values: {
129
- name: 'testAdmin',
130
- snippets: ['pm.*'],
131
- },
132
- });
133
-
134
- const UserRepo = db.getCollection('users').repository;
135
-
136
- user = await UserRepo.create({
137
- values: {
138
- roles: ['new'],
139
- },
140
- });
141
-
142
- admin = await UserRepo.create({
143
- values: {
144
- roles: ['testAdmin'],
145
- },
146
- });
147
-
148
- const userPlugin = app.getPlugin('users') as UsersPlugin;
149
- userAgent = app.agent().login(user);
150
-
151
- adminAgent = app.agent().login(admin);
152
-
153
- await db.getRepository('collections').create({
154
- values: {
155
- name: 'orders',
156
- },
157
- context: {},
158
- });
159
-
160
- await db.getRepository('collections.fields', 'users').create({
161
- values: {
162
- name: 'name',
163
- type: 'string',
164
- },
165
- context: {},
166
- });
167
-
168
- await db.getRepository('collections.fields', 'users').create({
169
- values: {
170
- name: 'age',
171
- type: 'integer',
172
- },
173
- context: {},
174
- });
175
-
176
- await db.getRepository('collections.fields', 'users').create({
177
- values: {
178
- interface: 'linkTo',
179
- name: 'orders',
180
- type: 'hasMany',
181
- target: 'orders',
182
- },
183
- context: {},
184
- });
185
-
186
- await db.getRepository('collections.fields', 'orders').create({
187
- values: {
188
- name: 'content',
189
- type: 'string',
190
- },
191
- context: {},
192
- });
193
-
194
- await adminAgent.resource('roles.resources', 'new').create({
195
- values: {
196
- name: 'users',
197
- usingActionsConfig: true,
198
- actions: [
199
- {
200
- name: 'create',
201
- fields: ['orders'],
202
- },
203
- {
204
- name: 'view',
205
- fields: ['orders'],
206
- },
207
- ],
208
- },
209
- });
210
-
211
- await adminAgent.resource('roles.resources', 'new').create({
212
- values: {
213
- name: 'orders',
214
- usingActionsConfig: true,
215
- actions: [
216
- {
217
- name: 'view',
218
- },
219
- ],
220
- },
221
- });
222
- });
223
-
224
- // skip because of disable grant associations target action
225
- it.skip('should revoke target action on association action revoke', async () => {
226
- expect(
227
- acl.can({
228
- role: 'new',
229
- resource: 'orders',
230
- action: 'list',
231
- }),
232
- ).toMatchObject({
233
- role: 'new',
234
- resource: 'orders',
235
- action: 'list',
236
- });
237
-
238
- await adminAgent.resource('roles.resources', 'new').update({
239
- values: {
240
- name: 'users',
241
- usingActionsConfig: true,
242
- actions: [],
243
- },
244
- });
245
-
246
- expect(
247
- acl.can({
248
- role: 'new',
249
- resource: 'orders',
250
- action: 'list',
251
- }),
252
- ).toBeNull();
253
- });
254
-
255
- it('should revoke association action on action revoke', async () => {
256
- expect(
257
- acl.can({
258
- role: 'new',
259
- resource: 'users.orders',
260
- action: 'add',
261
- }),
262
- ).toMatchObject({
263
- role: 'new',
264
- resource: 'users.orders',
265
- action: 'add',
266
- });
267
-
268
- const viewAction = await db.getRepository('rolesResourcesActions').findOne({
269
- filter: {
270
- name: 'view',
271
- },
272
- });
273
-
274
- const actionId = viewAction.get('id') as number;
275
-
276
- const response = await adminAgent.resource('roles.resources', 'new').update({
277
- filterByTk: 'users',
278
- values: {
279
- name: 'users',
280
- usingActionsConfig: true,
281
- actions: [
282
- {
283
- id: actionId,
284
- },
285
- ],
286
- },
287
- });
288
-
289
- expect(response.statusCode).toEqual(200);
290
-
291
- expect(
292
- acl.can({
293
- role: 'new',
294
- resource: 'users.orders',
295
- action: 'add',
296
- }),
297
- ).toBeNull();
298
- });
299
-
300
- it('should revoke association action on field deleted', async () => {
301
- await adminAgent.resource('roles.resources', 'new').update({
302
- filterByTk: 'users',
303
- values: {
304
- name: 'users',
305
- usingActionsConfig: true,
306
- actions: [
307
- {
308
- name: 'create',
309
- fields: ['name', 'age'],
310
- },
311
- ],
312
- },
313
- });
314
-
315
- expect(
316
- acl.can({
317
- role: 'new',
318
- resource: 'users',
319
- action: 'create',
320
- }),
321
- ).toMatchObject({
322
- role: 'new',
323
- resource: 'users',
324
- action: 'create',
325
- params: {
326
- whitelist: ['age', 'name'],
327
- },
328
- });
329
-
330
- const roleResource = await db.getRepository('rolesResources').findOne({
331
- filter: {
332
- name: 'users',
333
- },
334
- });
335
-
336
- const action = await db
337
- .getRepository<HasManyRepository>('rolesResources.actions', roleResource.get('id') as string)
338
- .findOne({
339
- filter: {
340
- name: 'create',
341
- },
342
- });
343
-
344
- expect(action.get('fields').includes('name')).toBeTruthy();
345
-
346
- // remove field
347
- await db.getRepository<HasManyRepository>('collections.fields', 'users').destroy({
348
- filter: {
349
- name: 'name',
350
- },
351
- context: {},
352
- });
353
-
354
- expect(
355
- acl.can({
356
- role: 'new',
357
- resource: 'users',
358
- action: 'create',
359
- }),
360
- ).toMatchObject({
361
- role: 'new',
362
- resource: 'users',
363
- action: 'create',
364
- params: {
365
- whitelist: ['age'],
366
- },
367
- });
368
- });
369
-
370
- it('should allow association fields access', async () => {
371
- const createResponse = await userAgent.resource('users').create({
372
- values: {
373
- orders: [
374
- {
375
- content: 'apple',
376
- },
377
- ],
378
- },
379
- });
380
-
381
- expect(createResponse.statusCode).toEqual(200);
382
-
383
- const user = await db.getRepository('users').findOne({
384
- filterByTk: createResponse.body.data.id,
385
- });
386
- // @ts-ignore
387
- expect(await user.countOrders()).toEqual(1);
388
-
389
- expect(
390
- acl.can({
391
- role: 'new',
392
- resource: 'users.orders',
393
- action: 'list',
394
- }),
395
- ).toMatchObject({
396
- role: 'new',
397
- resource: 'users.orders',
398
- action: 'list',
399
- });
400
-
401
- expect(
402
- acl.can({
403
- role: 'new',
404
- resource: 'orders',
405
- action: 'list',
406
- }),
407
- ).toMatchObject({
408
- role: 'new',
409
- resource: 'orders',
410
- action: 'list',
411
- });
412
- });
413
- });
@@ -1,70 +0,0 @@
1
- import { Database } from '@nocobase/database';
2
- import UsersPlugin from '@nocobase/plugin-users';
3
- import { MockServer } from '@nocobase/test';
4
- import { prepareApp } from './prepare';
5
-
6
- describe('configuration', () => {
7
- let app: MockServer;
8
- let db: Database;
9
- let admin;
10
- let adminAgent;
11
- let user;
12
- let userAgent;
13
- let guestAgent;
14
-
15
- afterEach(async () => {
16
- await app.destroy();
17
- });
18
-
19
- beforeEach(async () => {
20
- app = await prepareApp();
21
- db = app.db;
22
-
23
- await db.getRepository('roles').create({
24
- values: {
25
- name: 'test1',
26
- snippets: ['pm.*'],
27
- },
28
- });
29
-
30
- await db.getRepository('roles').create({
31
- values: {
32
- name: 'test2',
33
- },
34
- });
35
-
36
- const UserRepo = db.getCollection('users').repository;
37
- admin = await UserRepo.create({
38
- values: {
39
- roles: ['test1'],
40
- },
41
- });
42
- user = await UserRepo.create({
43
- values: {
44
- roles: ['test2'],
45
- },
46
- });
47
-
48
- const userPlugin = app.getPlugin('users') as UsersPlugin;
49
- adminAgent = app.agent().login(admin);
50
-
51
- userAgent = app.agent().login(user);
52
-
53
- guestAgent = app.agent();
54
- });
55
-
56
- it('should list collections', async () => {
57
- expect((await userAgent.resource('collections').create()).statusCode).toEqual(403);
58
- expect((await userAgent.resource('collections').list()).statusCode).toEqual(200);
59
- });
60
-
61
- it('should not create/list collections', async () => {
62
- expect((await guestAgent.resource('collections').create()).statusCode).toEqual(403);
63
- expect((await guestAgent.resource('collections').list()).statusCode).toEqual(403);
64
- });
65
-
66
- it('should allow when role has allowConfigure with true value', async () => {
67
- expect((await adminAgent.resource('collections').create()).statusCode).toEqual(200);
68
- expect((await adminAgent.resource('collections').list()).statusCode).toEqual(200);
69
- });
70
- });