@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,308 +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 field acl', () => {
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
- await db.getRepository('roles').create({
27
- values: {
28
- name: 'new',
29
- allowConfigure: true,
30
- },
31
- });
32
-
33
- await db.getRepository('roles').create({
34
- values: {
35
- name: 'testAdmin',
36
- allowConfigure: true,
37
- },
38
- });
39
- const UserRepo = db.getCollection('users').repository;
40
- user = await UserRepo.create({
41
- values: {
42
- roles: ['new'],
43
- },
44
- });
45
- admin = await UserRepo.create({
46
- values: {
47
- roles: ['testAdmin'],
48
- },
49
- });
50
-
51
- const userPlugin = app.getPlugin('users') as UsersPlugin;
52
- userAgent = app.agent().auth(
53
- userPlugin.jwtService.sign({
54
- userId: user.get('id'),
55
- }),
56
- { type: 'bearer' },
57
- );
58
- adminAgent = app.agent().auth(
59
- userPlugin.jwtService.sign({
60
- userId: admin.get('id'),
61
- }),
62
- { type: 'bearer' },
63
- );
64
-
65
- await db.getRepository('collections').create({
66
- values: {
67
- name: 'orders',
68
- },
69
- context: {},
70
- });
71
-
72
- await db.getRepository('collections.fields', 'users').create({
73
- values: {
74
- name: 'name',
75
- type: 'string',
76
- },
77
- context: {},
78
- });
79
-
80
- await db.getRepository('collections.fields', 'users').create({
81
- values: {
82
- name: 'age',
83
- type: 'integer',
84
- },
85
- context: {},
86
- });
87
-
88
- await db.getRepository('collections.fields', 'users').create({
89
- values: {
90
- interface: 'linkTo',
91
- name: 'orders',
92
- type: 'hasMany',
93
- target: 'orders',
94
- },
95
- context: {},
96
- });
97
-
98
- await db.getRepository('collections.fields', 'orders').create({
99
- values: {
100
- name: 'content',
101
- type: 'string',
102
- },
103
- context: {},
104
- });
105
-
106
- await adminAgent.resource('roles.resources', 'new').create({
107
- values: {
108
- name: 'users',
109
- usingActionsConfig: true,
110
- actions: [
111
- {
112
- name: 'create',
113
- fields: ['orders'],
114
- },
115
- {
116
- name: 'view',
117
- fields: ['orders'],
118
- },
119
- ],
120
- },
121
- });
122
- });
123
-
124
- it('should revoke target action on association action revoke', async () => {
125
- expect(
126
- acl.can({
127
- role: 'new',
128
- resource: 'orders',
129
- action: 'list',
130
- }),
131
- ).toMatchObject({
132
- role: 'new',
133
- resource: 'orders',
134
- action: 'list',
135
- });
136
-
137
- await adminAgent.resource('roles.resources', 'new').update({
138
- values: {
139
- name: 'users',
140
- usingActionsConfig: true,
141
- actions: [],
142
- },
143
- });
144
-
145
- expect(
146
- acl.can({
147
- role: 'new',
148
- resource: 'orders',
149
- action: 'list',
150
- }),
151
- ).toBeNull();
152
- });
153
-
154
- it('should revoke association action on action revoke', async () => {
155
- expect(
156
- acl.can({
157
- role: 'new',
158
- resource: 'users.orders',
159
- action: 'add',
160
- }),
161
- ).toMatchObject({
162
- role: 'new',
163
- resource: 'users.orders',
164
- action: 'add',
165
- });
166
-
167
- const viewAction = await db.getRepository('rolesResourcesActions').findOne({
168
- filter: {
169
- name: 'view',
170
- },
171
- });
172
-
173
- const actionId = viewAction.get('id') as number;
174
-
175
- const response = await adminAgent.resource('roles.resources', 'new').update({
176
- values: {
177
- name: 'users',
178
- usingActionsConfig: true,
179
- actions: [
180
- {
181
- id: actionId,
182
- },
183
- ],
184
- },
185
- });
186
-
187
- expect(response.statusCode).toEqual(200);
188
-
189
- expect(
190
- acl.can({
191
- role: 'new',
192
- resource: 'users.orders',
193
- action: 'add',
194
- }),
195
- ).toBeNull();
196
- });
197
-
198
- it('should revoke association action on field deleted', async () => {
199
- await adminAgent.resource('roles.resources', 'new').update({
200
- values: {
201
- name: 'users',
202
- usingActionsConfig: true,
203
- actions: [
204
- {
205
- name: 'create',
206
- fields: ['name', 'age'],
207
- },
208
- ],
209
- },
210
- });
211
- expect(
212
- acl.can({
213
- role: 'new',
214
- resource: 'users',
215
- action: 'create',
216
- }),
217
- ).toMatchObject({
218
- role: 'new',
219
- resource: 'users',
220
- action: 'create',
221
- params: {
222
- whitelist: ['age', 'name'],
223
- },
224
- });
225
- const roleResource = await db.getRepository('rolesResources').findOne({
226
- filter: {
227
- name: 'users',
228
- },
229
- });
230
-
231
- const action = await db
232
- .getRepository<HasManyRepository>('rolesResources.actions', roleResource.get('id') as string)
233
- .findOne({
234
- filter: {
235
- name: 'create',
236
- },
237
- });
238
-
239
- expect(action.get('fields').includes('name')).toBeTruthy();
240
-
241
- // remove field
242
- await db.getRepository<HasManyRepository>('collections.fields', 'users').destroy({
243
- filter: {
244
- name: 'name',
245
- },
246
- context: {},
247
- });
248
-
249
- expect(
250
- acl.can({
251
- role: 'new',
252
- resource: 'users',
253
- action: 'create',
254
- }),
255
- ).toMatchObject({
256
- role: 'new',
257
- resource: 'users',
258
- action: 'create',
259
- params: {
260
- whitelist: ['age'],
261
- },
262
- });
263
- });
264
-
265
- it('should allow association fields access', async () => {
266
- const createResponse = await userAgent.resource('users').create({
267
- values: {
268
- orders: [
269
- {
270
- content: 'apple',
271
- },
272
- ],
273
- },
274
- });
275
-
276
- expect(createResponse.statusCode).toEqual(200);
277
-
278
- const user = await db.getRepository('users').findOne({
279
- filterByTk: createResponse.body.data.id,
280
- });
281
- // @ts-ignore
282
- expect(await user.countOrders()).toEqual(1);
283
-
284
- expect(
285
- acl.can({
286
- role: 'new',
287
- resource: 'users.orders',
288
- action: 'list',
289
- }),
290
- ).toMatchObject({
291
- role: 'new',
292
- resource: 'users.orders',
293
- action: 'list',
294
- });
295
-
296
- expect(
297
- acl.can({
298
- role: 'new',
299
- resource: 'orders',
300
- action: 'list',
301
- }),
302
- ).toMatchObject({
303
- role: 'new',
304
- resource: 'orders',
305
- action: 'list',
306
- });
307
- });
308
- });
@@ -1,74 +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
- allowConfigure: true,
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().auth(userPlugin.jwtService.sign({
50
- userId: admin.get('id'),
51
- }), { type: 'bearer' });
52
-
53
- userAgent = app.agent().auth(userPlugin.jwtService.sign({
54
- userId: user.get('id'),
55
- }), { type: 'bearer' });
56
-
57
- guestAgent = app.agent();
58
- });
59
-
60
- it('should list collections', async () => {
61
- expect((await userAgent.resource('collections').create()).statusCode).toEqual(403);
62
- expect((await userAgent.resource('collections').list()).statusCode).toEqual(200);
63
- });
64
-
65
- it('should not create/list collections', async () => {
66
- expect((await guestAgent.resource('collections').create()).statusCode).toEqual(403);
67
- expect((await guestAgent.resource('collections').list()).statusCode).toEqual(403);
68
- });
69
-
70
- it('should allow when role has allowConfigure with true value', async () => {
71
- expect((await adminAgent.resource('collections').create()).statusCode).toEqual(200);
72
- expect((await adminAgent.resource('collections').list()).statusCode).toEqual(200);
73
- });
74
- });
@@ -1,228 +0,0 @@
1
- import { ACL } from '@nocobase/acl';
2
- import { Database, Model } from '@nocobase/database';
3
- import UsersPlugin from '@nocobase/plugin-users';
4
- import { MockServer } from '@nocobase/test';
5
- import { prepareApp } from './prepare';
6
-
7
- describe('middleware', () => {
8
- let app: MockServer;
9
- let role: Model;
10
- let db: Database;
11
- let acl: ACL;
12
- let admin;
13
- let adminAgent;
14
-
15
- beforeEach(async () => {
16
- app = await prepareApp();
17
- db = app.db;
18
- acl = app.acl;
19
-
20
- role = await db.getRepository('roles').findOne({
21
- filter: {
22
- name: 'admin',
23
- },
24
- });
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
- adminAgent = app.agent().auth(userPlugin.jwtService.sign({
35
- userId: admin.get('id'),
36
- }), { type: 'bearer' });
37
-
38
- await db.getRepository('collections').create({
39
- values: {
40
- name: 'posts',
41
- },
42
- context: {},
43
- });
44
-
45
- await db.getRepository('collections.fields', 'posts').create({
46
- values: {
47
- name: 'title',
48
- type: 'string',
49
- },
50
- context: {},
51
- });
52
-
53
- await db.getRepository('collections.fields', 'posts').create({
54
- values: {
55
- name: 'description',
56
- type: 'string',
57
- },
58
- context: {},
59
- });
60
-
61
- await db.getRepository('collections.fields', 'posts').create({
62
- values: {
63
- name: 'createdById',
64
- type: 'integer',
65
- },
66
- context: {},
67
- });
68
- });
69
-
70
- afterEach(async () => {
71
- await app.destroy();
72
- });
73
-
74
- it('should throw 403 when no permission', async () => {
75
- const response = await app.agent().resource('posts').create({
76
- values: {},
77
- });
78
-
79
- expect(response.statusCode).toEqual(403);
80
- });
81
-
82
- it('should return 200 when role has permission', async () => {
83
- await db.getRepository('roles').update({
84
- filterByTk: 'admin',
85
- values: {
86
- strategy: {
87
- actions: ['create:all'],
88
- },
89
- },
90
- });
91
-
92
- const response = await adminAgent.resource('posts').create({
93
- values: {},
94
- });
95
-
96
- expect(response.statusCode).toEqual(200);
97
- });
98
-
99
- it('should limit fields on view actions', async () => {
100
- await adminAgent
101
- .resource('roles.resources', role.get('name'))
102
- .create({
103
- values: {
104
- name: 'posts',
105
- usingActionsConfig: true,
106
- actions: [
107
- {
108
- name: 'create',
109
- fields: ['title', 'description'],
110
- },
111
- {
112
- name: 'view',
113
- fields: ['title'],
114
- },
115
- ],
116
- },
117
- });
118
-
119
- await adminAgent
120
- .resource('posts')
121
- .create({
122
- values: {
123
- title: 'post-title',
124
- description: 'post-description',
125
- },
126
- });
127
-
128
- const post = await db.getRepository('posts').findOne();
129
- expect(post.get('title')).toEqual('post-title');
130
- expect(post.get('description')).toEqual('post-description');
131
-
132
- const response = await adminAgent.resource('posts').list({});
133
- expect(response.statusCode).toEqual(200);
134
-
135
- const [data] = response.body.data;
136
-
137
- expect(data['id']).not.toBeUndefined();
138
- expect(data['title']).toEqual('post-title');
139
- expect(data['description']).toBeUndefined();
140
- });
141
-
142
- it('should parse template value on action params', async () => {
143
- const res = await adminAgent
144
- .resource('rolesResourcesScopes')
145
- .create({
146
- values: {
147
- name: 'own',
148
- scope: {
149
- createdById: '{{ ctx.state.currentUser.id }}',
150
- },
151
- },
152
- });
153
-
154
- await adminAgent
155
- .resource('roles.resources', role.get('name'))
156
- .create({
157
- values: {
158
- name: 'posts',
159
- usingActionsConfig: true,
160
- actions: [
161
- {
162
- name: 'create',
163
- fields: ['title', 'description', 'createdById'],
164
- },
165
- {
166
- name: 'view',
167
- fields: ['title'],
168
- scope: res.body.data.id,
169
- },
170
- ],
171
- },
172
- });
173
-
174
- await adminAgent
175
- .resource('posts')
176
- .create({
177
- values: {
178
- title: 't1',
179
- description: 'd1',
180
- createdById: 1,
181
- },
182
- });
183
-
184
- await adminAgent
185
- .resource('posts')
186
- .create({
187
- values: {
188
- title: 't2',
189
- description: 'p2',
190
- createdById: 2,
191
- },
192
- });
193
-
194
- const response = await adminAgent.resource('posts').list();
195
- const data = response.body.data;
196
- expect(data.length).toEqual(1);
197
- });
198
-
199
- it('should change fields params to whitelist in create action', async () => {
200
- await adminAgent
201
- .resource('roles.resources', role.get('name'))
202
- .create({
203
- values: {
204
- name: 'posts',
205
- usingActionsConfig: true,
206
- actions: [
207
- {
208
- name: 'create',
209
- fields: ['title'],
210
- },
211
- ],
212
- },
213
- });
214
-
215
- await adminAgent
216
- .resource('posts')
217
- .create({
218
- values: {
219
- title: 'post-title',
220
- description: 'post-description',
221
- },
222
- });
223
-
224
- const post = await db.getRepository('posts').findOne();
225
- expect(post.get('title')).toEqual('post-title');
226
- expect(post.get('description')).toBeNull();
227
- });
228
- });