@nocobase/plugin-acl 0.10.0-alpha.5 → 0.11.0-alpha.1

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 (78) hide show
  1. package/client.d.ts +3 -0
  2. package/client.js +1 -0
  3. package/lib/client/index.d.ts +5 -0
  4. package/lib/client/index.js +22 -0
  5. package/lib/{actions → server/actions}/role-check.js +0 -3
  6. package/lib/server/index.d.ts +1 -0
  7. package/lib/server/index.js +13 -0
  8. package/lib/server/middlewares/setCurrentRole.d.ts +2 -0
  9. package/lib/{middlewares → server/middlewares}/setCurrentRole.js +16 -15
  10. package/lib/{server.js → server/server.js} +15 -16
  11. package/package.json +26 -9
  12. package/server.d.ts +3 -0
  13. package/server.js +1 -0
  14. package/src/client/index.ts +8 -0
  15. package/src/index.ts +1 -0
  16. package/src/server/__tests__/acl.test.ts +835 -0
  17. package/src/server/__tests__/actions.test.ts +141 -0
  18. package/src/server/__tests__/association-field.test.ts +413 -0
  19. package/src/server/__tests__/configuration.test.ts +70 -0
  20. package/src/server/__tests__/list-action.test.ts +446 -0
  21. package/src/server/__tests__/middleware.test.ts +210 -0
  22. package/src/server/__tests__/own.test.ts +124 -0
  23. package/src/server/__tests__/prepare.ts +20 -0
  24. package/src/server/__tests__/role-check.test.ts +46 -0
  25. package/src/server/__tests__/role-resource.test.ts +177 -0
  26. package/src/server/__tests__/role-user.test.ts +127 -0
  27. package/src/server/__tests__/role.test.ts +118 -0
  28. package/src/server/__tests__/scope.test.ts +55 -0
  29. package/src/server/__tests__/setCurrentRole.test.ts +86 -0
  30. package/src/server/__tests__/snippets.test.ts +35 -0
  31. package/src/server/__tests__/users.test.ts +136 -0
  32. package/src/server/__tests__/write-role-to-acl.test.ts +41 -0
  33. package/src/server/actions/available-actions.ts +18 -0
  34. package/src/server/actions/role-check.ts +50 -0
  35. package/src/server/actions/role-collections.ts +95 -0
  36. package/src/server/actions/user-setDefaultRole.ts +47 -0
  37. package/src/server/collections/roles-users.ts +8 -0
  38. package/src/server/collections/roles.ts +89 -0
  39. package/src/server/collections/rolesResources.ts +33 -0
  40. package/src/server/collections/rolesResourcesActions.ts +31 -0
  41. package/src/server/collections/rolesResourcesScopes.ts +25 -0
  42. package/src/server/collections/users.ts +31 -0
  43. package/src/server/index.ts +1 -0
  44. package/src/server/middlewares/setCurrentRole.ts +35 -0
  45. package/src/server/migrations/20221214072638-set-role-snippets.ts +23 -0
  46. package/src/server/model/RoleModel.ts +23 -0
  47. package/src/server/model/RoleResourceActionModel.ts +95 -0
  48. package/src/server/model/RoleResourceModel.ts +74 -0
  49. package/src/server/server.ts +854 -0
  50. package/lib/middlewares/setCurrentRole.d.ts +0 -1
  51. /package/lib/{actions → server/actions}/available-actions.d.ts +0 -0
  52. /package/lib/{actions → server/actions}/available-actions.js +0 -0
  53. /package/lib/{actions → server/actions}/role-check.d.ts +0 -0
  54. /package/lib/{actions → server/actions}/role-collections.d.ts +0 -0
  55. /package/lib/{actions → server/actions}/role-collections.js +0 -0
  56. /package/lib/{actions → server/actions}/user-setDefaultRole.d.ts +0 -0
  57. /package/lib/{actions → server/actions}/user-setDefaultRole.js +0 -0
  58. /package/lib/{collections → server/collections}/roles-users.d.ts +0 -0
  59. /package/lib/{collections → server/collections}/roles-users.js +0 -0
  60. /package/lib/{collections → server/collections}/roles.d.ts +0 -0
  61. /package/lib/{collections → server/collections}/roles.js +0 -0
  62. /package/lib/{collections → server/collections}/rolesResources.d.ts +0 -0
  63. /package/lib/{collections → server/collections}/rolesResources.js +0 -0
  64. /package/lib/{collections → server/collections}/rolesResourcesActions.d.ts +0 -0
  65. /package/lib/{collections → server/collections}/rolesResourcesActions.js +0 -0
  66. /package/lib/{collections → server/collections}/rolesResourcesScopes.d.ts +0 -0
  67. /package/lib/{collections → server/collections}/rolesResourcesScopes.js +0 -0
  68. /package/lib/{collections → server/collections}/users.d.ts +0 -0
  69. /package/lib/{collections → server/collections}/users.js +0 -0
  70. /package/lib/{migrations → server/migrations}/20221214072638-set-role-snippets.d.ts +0 -0
  71. /package/lib/{migrations → server/migrations}/20221214072638-set-role-snippets.js +0 -0
  72. /package/lib/{model → server/model}/RoleModel.d.ts +0 -0
  73. /package/lib/{model → server/model}/RoleModel.js +0 -0
  74. /package/lib/{model → server/model}/RoleResourceActionModel.d.ts +0 -0
  75. /package/lib/{model → server/model}/RoleResourceActionModel.js +0 -0
  76. /package/lib/{model → server/model}/RoleResourceModel.d.ts +0 -0
  77. /package/lib/{model → server/model}/RoleResourceModel.js +0 -0
  78. /package/lib/{server.d.ts → server/server.d.ts} +0 -0
@@ -0,0 +1,86 @@
1
+ import Database from '@nocobase/database';
2
+ import UsersPlugin from '@nocobase/plugin-users';
3
+ import { MockServer } from '@nocobase/test';
4
+ import { setCurrentRole } from '../middlewares/setCurrentRole';
5
+ import { prepareApp } from './prepare';
6
+
7
+ describe('role', () => {
8
+ let api: MockServer;
9
+ let db: Database;
10
+
11
+ let usersPlugin: UsersPlugin;
12
+ let ctx;
13
+
14
+ beforeEach(async () => {
15
+ api = await prepareApp();
16
+
17
+ db = api.db;
18
+ usersPlugin = api.getPlugin('users');
19
+
20
+ ctx = {
21
+ db,
22
+ state: {
23
+ currentRole: '',
24
+ },
25
+ };
26
+ });
27
+
28
+ afterEach(async () => {
29
+ await api.destroy();
30
+ });
31
+
32
+ it('should set role with X-Role when exists', async () => {
33
+ ctx.state.currentUser = await db.getRepository('users').findOne({
34
+ appends: ['roles'],
35
+ });
36
+ ctx.get = function (name) {
37
+ if (name === 'X-Role') {
38
+ return 'admin';
39
+ }
40
+ };
41
+ await setCurrentRole(ctx, () => {});
42
+ expect(ctx.state.currentRole).toBe('admin');
43
+ });
44
+
45
+ it('should set role with default', async () => {
46
+ ctx.state.currentUser = await db.getRepository('users').findOne({
47
+ appends: ['roles'],
48
+ });
49
+ ctx.get = function (name) {
50
+ if (name === 'X-Role') {
51
+ return '';
52
+ }
53
+ };
54
+ await setCurrentRole(ctx, () => {});
55
+ expect(ctx.state.currentRole).toBe('root');
56
+ });
57
+
58
+ it('should throw 401', async () => {
59
+ ctx.state.currentUser = await db.getRepository('users').findOne({
60
+ appends: ['roles'],
61
+ });
62
+ ctx.get = function (name) {
63
+ if (name === 'X-Role') {
64
+ return 'abc';
65
+ }
66
+ };
67
+ const throwFn = jest.fn();
68
+ ctx.throw = throwFn;
69
+ await setCurrentRole(ctx, () => {});
70
+ expect(throwFn).lastCalledWith(401, 'User role not found');
71
+ expect(ctx.state.currentRole).not.toBeDefined();
72
+ });
73
+
74
+ it('should set role with anonymous', async () => {
75
+ ctx.state.currentUser = await db.getRepository('users').findOne({
76
+ appends: ['roles'],
77
+ });
78
+ ctx.get = function (name) {
79
+ if (name === 'X-Role') {
80
+ return 'anonymous';
81
+ }
82
+ };
83
+ await setCurrentRole(ctx, () => {});
84
+ expect(ctx.state.currentRole).toBe('anonymous');
85
+ });
86
+ });
@@ -0,0 +1,35 @@
1
+ import { MockServer } from '@nocobase/test';
2
+ import { prepareApp } from './prepare';
3
+
4
+ describe('snippet', () => {
5
+ let app: MockServer;
6
+
7
+ beforeEach(async () => {
8
+ app = await prepareApp();
9
+ });
10
+
11
+ afterEach(async () => {
12
+ await app.destroy();
13
+ });
14
+
15
+ it('should not allow to create collections when global allow create', async () => {
16
+ await app.db.getRepository('roles').create({
17
+ values: {
18
+ name: 'testRole',
19
+ strategy: { actions: ['view', 'update:own', 'destroy:own', 'create'] },
20
+ snippets: ['!ui.*', '!pm', '!pm.*'],
21
+ },
22
+ });
23
+ const user = await app.db.getRepository('users').create({
24
+ values: {
25
+ roles: ['testRole'],
26
+ },
27
+ });
28
+
29
+ const userPlugin: any = app.getPlugin('users');
30
+ const userAgent: any = app.agent().login(user);
31
+ const createCollectionResponse = await userAgent.resource('collections').create({});
32
+
33
+ expect(createCollectionResponse.statusCode).toEqual(403);
34
+ });
35
+ });
@@ -0,0 +1,136 @@
1
+ import Database from '@nocobase/database';
2
+ import { MockServer } from '@nocobase/test';
3
+ import { prepareApp } from './prepare';
4
+
5
+ describe('actions', () => {
6
+ let app: MockServer;
7
+ let db: Database;
8
+ let adminUser;
9
+ let agent;
10
+ let adminAgent;
11
+ let pluginUser;
12
+
13
+ beforeEach(async () => {
14
+ process.env.INIT_ROOT_EMAIL = 'test@nocobase.com';
15
+ process.env.INIT_ROOT_PASSWORD = '123456';
16
+ process.env.INIT_ROOT_NICKNAME = 'Test';
17
+
18
+ app = await prepareApp();
19
+ db = app.db;
20
+
21
+ pluginUser = app.getPlugin('users');
22
+ adminUser = await db.getRepository('users').findOne({
23
+ filter: {
24
+ email: process.env.INIT_ROOT_EMAIL,
25
+ },
26
+ appends: ['roles'],
27
+ });
28
+
29
+ agent = app.agent();
30
+ adminAgent = app.agent().login(adminUser);
31
+ });
32
+
33
+ afterEach(async () => {
34
+ await db.close();
35
+ });
36
+
37
+ it('update profile with roles', async () => {
38
+ const res2 = await adminAgent.resource('users').updateProfile({
39
+ filterByTk: adminUser.id,
40
+ values: {
41
+ nickname: 'a',
42
+ roles: adminUser.roles,
43
+ },
44
+ });
45
+ expect(res2.status).toBe(200);
46
+ });
47
+
48
+ it('can destroy users role', async () => {
49
+ const role2 = await db.getRepository('roles').create({
50
+ values: {
51
+ name: 'test',
52
+ },
53
+ });
54
+
55
+ const users2 = await db.getRepository('users').create({
56
+ values: {
57
+ email: 'test2@nocobase.com',
58
+ name: 'test2',
59
+ password: '123456',
60
+ roles: [
61
+ {
62
+ name: 'test',
63
+ },
64
+ ],
65
+ },
66
+ });
67
+
68
+ let response = await agent.post('/auth:signIn').send({
69
+ email: 'test2@nocobase.com',
70
+ password: '123456',
71
+ });
72
+
73
+ expect(response.statusCode).toEqual(200);
74
+
75
+ const token = response.body.data.token;
76
+
77
+ const loggedAgent = app.agent().auth(token, { type: 'bearer' });
78
+
79
+ const rolesCheckResponse = (await loggedAgent.set('Accept', 'application/json').get('/roles:check')) as any;
80
+
81
+ expect(rolesCheckResponse.statusCode).toEqual(200);
82
+
83
+ await db.getRepository('roles').destroy({
84
+ filterByTk: 'test',
85
+ });
86
+
87
+ response = await agent.post('/auth:signIn').send({
88
+ email: 'test2@nocobase.com',
89
+ password: '123456',
90
+ });
91
+
92
+ expect(response.statusCode).toEqual(200);
93
+
94
+ const rolesCheckResponse2 = (await loggedAgent.set('Accept', 'application/json').get('/roles:check')) as any;
95
+
96
+ expect(rolesCheckResponse2.status).toEqual(401);
97
+ expect(rolesCheckResponse2.body.errors[0].message).toEqual('User role not found');
98
+ });
99
+
100
+ it('should destroy through table record when destroy role', async () => {
101
+ await db.getRepository('roles').create({
102
+ values: {
103
+ name: 'test',
104
+ },
105
+ });
106
+
107
+ const users2 = await db.getRepository('users').create({
108
+ values: {
109
+ email: 'test2@nocobase.com',
110
+ name: 'test2',
111
+ password: '123456',
112
+ roles: [
113
+ {
114
+ name: 'test',
115
+ },
116
+ ],
117
+ },
118
+ });
119
+
120
+ expect(await users2.countRoles()).toEqual(1);
121
+
122
+ await db.getRepository('roles').destroy({
123
+ filterByTk: 'test',
124
+ });
125
+
126
+ expect(await users2.countRoles()).toEqual(0);
127
+
128
+ await db.getRepository('roles').create({
129
+ values: {
130
+ name: 'test',
131
+ },
132
+ });
133
+
134
+ expect(await users2.countRoles()).toEqual(0);
135
+ });
136
+ });
@@ -0,0 +1,41 @@
1
+ import { MockServer } from '@nocobase/test';
2
+ import { Database } from '@nocobase/database';
3
+ import { prepareApp } from './prepare';
4
+
5
+ describe('write role to acl', () => {
6
+ let app: MockServer;
7
+ let db: Database;
8
+
9
+ beforeEach(async () => {
10
+ app = await prepareApp();
11
+ db = app.db;
12
+ });
13
+
14
+ afterEach(async () => {
15
+ await app.destroy();
16
+ });
17
+
18
+ it('should write role to acl if role instance exists in db', async () => {
19
+ const role = await db.getRepository('roles').create({
20
+ values: {
21
+ name: 'test',
22
+ },
23
+ });
24
+
25
+ // remove role from acl
26
+ app.acl.removeRole('test');
27
+
28
+ const user = await db.getRepository('users').create({
29
+ values: {
30
+ roles: ['test'],
31
+ },
32
+ });
33
+
34
+ const agent = app.agent().login(user);
35
+
36
+ // @ts-ignore
37
+ const response = await agent.resource('roles').check();
38
+
39
+ expect(response.statusCode).toEqual(200);
40
+ });
41
+ });
@@ -0,0 +1,18 @@
1
+ const availableActionResource = {
2
+ name: 'availableActions',
3
+ actions: {
4
+ async list(ctx, next) {
5
+ const acl = ctx.app.acl;
6
+ const availableActions = acl.getAvailableActions();
7
+ ctx.body = Array.from(availableActions.entries()).map(([, { name, options }]) => {
8
+ return {
9
+ ...options,
10
+ name,
11
+ };
12
+ });
13
+ await next();
14
+ },
15
+ },
16
+ };
17
+
18
+ export { availableActionResource };
@@ -0,0 +1,50 @@
1
+ const map2obj = (map: Map<string, string>) => {
2
+ const obj = {};
3
+ for (const [key, value] of map) {
4
+ obj[key] = value;
5
+ }
6
+ return obj;
7
+ };
8
+
9
+ export async function checkAction(ctx, next) {
10
+ const currentRole = ctx.state.currentRole;
11
+
12
+ const roleInstance = await ctx.db.getRepository('roles').findOne({
13
+ filter: {
14
+ name: currentRole,
15
+ },
16
+ appends: ['menuUiSchemas'],
17
+ });
18
+
19
+ if (!roleInstance) {
20
+ throw new Error(`Role ${currentRole} not exists`);
21
+ }
22
+
23
+ const anonymous = await ctx.db.getRepository('roles').findOne({
24
+ filter: {
25
+ name: 'anonymous',
26
+ },
27
+ });
28
+
29
+ let role = ctx.app.acl.getRole(currentRole);
30
+
31
+ if (!role) {
32
+ await ctx.app.emitAsync('acl:writeRoleToACL', roleInstance);
33
+ role = ctx.app.acl.getRole(currentRole);
34
+ }
35
+
36
+ const availableActions = ctx.app.acl.getAvailableActions();
37
+
38
+ ctx.body = {
39
+ ...role.toJSON(),
40
+ availableActions: [...availableActions.keys()],
41
+ resources: [...role.resources.keys()],
42
+ actionAlias: map2obj(ctx.app.acl.actionAlias),
43
+ allowAll: currentRole === 'root',
44
+ allowConfigure: roleInstance.get('allowConfigure'),
45
+ allowMenuItemIds: roleInstance.get('menuUiSchemas').map((uiSchema) => uiSchema.get('x-uid')),
46
+ allowAnonymous: !!anonymous,
47
+ };
48
+
49
+ await next();
50
+ }
@@ -0,0 +1,95 @@
1
+ import { Database } from '@nocobase/database';
2
+
3
+ type UsingConfigType = 'strategy' | 'resourceAction';
4
+
5
+ function totalPage(total, pageSize): number {
6
+ return Math.ceil(total / pageSize);
7
+ }
8
+
9
+ const roleCollectionsResource = {
10
+ name: 'roles.collections',
11
+ actions: {
12
+ async list(ctx, next) {
13
+ const role = ctx.action.params.associatedIndex;
14
+ const { page = 1, pageSize = 20 } = ctx.action.params;
15
+
16
+ const db: Database = ctx.db;
17
+ const collectionRepository = db.getRepository('collections');
18
+ const fieldRepository = db.getRepository('fields');
19
+
20
+ // all collections
21
+ const [collections, count] = await collectionRepository.findAndCount({
22
+ filter: ctx.action.params.filter,
23
+ sort: 'sort',
24
+ });
25
+
26
+ // role collections
27
+ const roleResources = await db.getRepository('rolesResources').find({
28
+ filter: {
29
+ roleName: role,
30
+ },
31
+ });
32
+
33
+ // role collections
34
+ const roleResourcesNames = roleResources.map((roleResource) => roleResource.get('name'));
35
+ const roleResourceActionResourceNames = roleResources
36
+ .filter((roleResources) => roleResources.get('usingActionsConfig'))
37
+ .map((roleResources) => roleResources.get('name'));
38
+
39
+ const items = collections.map((collection, i) => {
40
+ const exists = roleResourcesNames.includes(collection.get('name'));
41
+
42
+ const usingConfig: UsingConfigType = roleResourceActionResourceNames.includes(collection.get('name'))
43
+ ? 'resourceAction'
44
+ : 'strategy';
45
+
46
+ const c = db.getCollection(collection.get('name'));
47
+
48
+ // const children = [...c.fields.values()]
49
+ // .filter(
50
+ // (f) => f.options.interface && ['hasOne', 'hasMany', 'belongsTo', 'belongsToMany'].includes(f.options.type),
51
+ // )
52
+ // .map((f, j) => {
53
+ // const name = `${collection.get('name')}.${f.options.name}`;
54
+ // const usingConfig: UsingConfigType = roleResourceActionResourceNames.includes(name)
55
+ // ? 'resourceAction'
56
+ // : 'strategy';
57
+ // const exists = roleResourcesNames.includes(name);
58
+ // return {
59
+ // type: 'association',
60
+ // __index: `${i}.children.${j}`,
61
+ // name,
62
+ // collectionName: f.options.target,
63
+ // title: f.options?.uiSchema?.title,
64
+ // roleName: role,
65
+ // usingConfig,
66
+ // exists,
67
+ // };
68
+ // });
69
+
70
+ return {
71
+ type: 'collection',
72
+ name: collection.get('name') as string,
73
+ collectionName: collection.get('name'),
74
+ title: collection.get('title') as string,
75
+ roleName: role,
76
+ usingConfig,
77
+ exists,
78
+ // children: children.length > 0 ? children : null,
79
+ };
80
+ });
81
+
82
+ ctx.body = {
83
+ count,
84
+ rows: items,
85
+ page: Number(page),
86
+ pageSize: Number(pageSize),
87
+ totalPage: totalPage(count, pageSize),
88
+ };
89
+
90
+ await next();
91
+ },
92
+ },
93
+ };
94
+
95
+ export { roleCollectionsResource };
@@ -0,0 +1,47 @@
1
+ import { Context, Next } from '@nocobase/actions';
2
+
3
+ export async function setDefaultRole(ctx: Context, next: Next) {
4
+ const {
5
+ values: { roleName },
6
+ } = ctx.action.params;
7
+
8
+ const {
9
+ db,
10
+ state: { currentUser },
11
+ action: {
12
+ params: { values },
13
+ },
14
+ } = ctx;
15
+
16
+ if (values.roleName == 'anonymous') {
17
+ return next();
18
+ }
19
+
20
+ const repository = db.getRepository('rolesUsers');
21
+
22
+ await db.sequelize.transaction(async (transaction) => {
23
+ await repository.update({
24
+ filter: {
25
+ userId: currentUser.get('id'),
26
+ },
27
+ values: {
28
+ default: false,
29
+ },
30
+ transaction,
31
+ });
32
+ await repository.update({
33
+ filter: {
34
+ userId: currentUser.get('id'),
35
+ roleName,
36
+ },
37
+ values: {
38
+ default: true,
39
+ },
40
+ transaction,
41
+ });
42
+ });
43
+
44
+ ctx.body = 'ok';
45
+
46
+ await next();
47
+ }
@@ -0,0 +1,8 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+
3
+ export default {
4
+ name: 'rolesUsers',
5
+ duplicator: 'optional',
6
+ namespace: 'acl.acl',
7
+ fields: [{ type: 'boolean', name: 'default' }],
8
+ } as CollectionOptions;
@@ -0,0 +1,89 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+
3
+ export default {
4
+ namespace: 'acl.acl',
5
+ duplicator: {
6
+ dumpable: 'required',
7
+ with: 'uiSchemas',
8
+ },
9
+ name: 'roles',
10
+ title: '{{t("Roles")}}',
11
+ autoGenId: false,
12
+ model: 'RoleModel',
13
+ filterTargetKey: 'name',
14
+ // targetKey: 'name',
15
+ sortable: true,
16
+ fields: [
17
+ {
18
+ type: 'uid',
19
+ name: 'name',
20
+ prefix: 'r_',
21
+ primaryKey: true,
22
+ interface: 'input',
23
+ uiSchema: {
24
+ type: 'string',
25
+ title: '{{t("Role UID")}}',
26
+ 'x-component': 'Input',
27
+ },
28
+ },
29
+ {
30
+ type: 'string',
31
+ name: 'title',
32
+ unique: true,
33
+ interface: 'input',
34
+ uiSchema: {
35
+ type: 'string',
36
+ title: '{{t("Role name")}}',
37
+ 'x-component': 'Input',
38
+ },
39
+ },
40
+ {
41
+ type: 'boolean',
42
+ name: 'default',
43
+ },
44
+ {
45
+ type: 'string',
46
+ name: 'description',
47
+ },
48
+ {
49
+ type: 'json',
50
+ name: 'strategy',
51
+ },
52
+ {
53
+ type: 'boolean',
54
+ name: 'default',
55
+ defaultValue: false,
56
+ },
57
+ {
58
+ type: 'boolean',
59
+ name: 'hidden',
60
+ defaultValue: false,
61
+ },
62
+ {
63
+ type: 'boolean',
64
+ name: 'allowConfigure',
65
+ },
66
+ {
67
+ type: 'boolean',
68
+ name: 'allowNewMenu',
69
+ },
70
+ {
71
+ type: 'belongsToMany',
72
+ name: 'menuUiSchemas',
73
+ target: 'uiSchemas',
74
+ targetKey: 'x-uid',
75
+ },
76
+ {
77
+ type: 'hasMany',
78
+ name: 'resources',
79
+ target: 'rolesResources',
80
+ sourceKey: 'name',
81
+ targetKey: 'name',
82
+ },
83
+ {
84
+ type: 'set',
85
+ name: 'snippets',
86
+ defaultValue: ['!ui.*', '!pm', '!pm.*'],
87
+ },
88
+ ],
89
+ } as CollectionOptions;
@@ -0,0 +1,33 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+
3
+ export default {
4
+ namespace: 'acl.acl',
5
+ duplicator: 'required',
6
+ name: 'rolesResources',
7
+ model: 'RoleResourceModel',
8
+ indexes: [
9
+ {
10
+ unique: true,
11
+ fields: ['roleName', 'name'],
12
+ },
13
+ ],
14
+ fields: [
15
+ {
16
+ type: 'belongsTo',
17
+ name: 'role',
18
+ },
19
+ {
20
+ type: 'string',
21
+ name: 'name',
22
+ },
23
+ {
24
+ type: 'boolean',
25
+ name: 'usingActionsConfig',
26
+ },
27
+ {
28
+ type: 'hasMany',
29
+ name: 'actions',
30
+ target: 'rolesResourcesActions',
31
+ },
32
+ ],
33
+ } as CollectionOptions;
@@ -0,0 +1,31 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+
3
+ export default {
4
+ namespace: 'acl.acl',
5
+ duplicator: 'required',
6
+ name: 'rolesResourcesActions',
7
+ model: 'RoleResourceActionModel',
8
+ fields: [
9
+ {
10
+ type: 'belongsTo',
11
+ name: 'resource',
12
+ foreignKey: 'rolesResourceId',
13
+ target: 'rolesResources',
14
+ },
15
+ {
16
+ type: 'string',
17
+ name: 'name',
18
+ },
19
+ {
20
+ type: 'array',
21
+ name: 'fields',
22
+ defaultValue: [],
23
+ },
24
+ {
25
+ type: 'belongsTo',
26
+ name: 'scope',
27
+ target: 'rolesResourcesScopes',
28
+ onDelete: 'RESTRICT',
29
+ },
30
+ ],
31
+ } as CollectionOptions;
@@ -0,0 +1,25 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+
3
+ export default {
4
+ namespace: 'acl.acl',
5
+ duplicator: 'required',
6
+ name: 'rolesResourcesScopes',
7
+ fields: [
8
+ {
9
+ type: 'uid',
10
+ name: 'key',
11
+ },
12
+ {
13
+ type: 'string',
14
+ name: 'name',
15
+ },
16
+ {
17
+ type: 'string',
18
+ name: 'resourceName',
19
+ },
20
+ {
21
+ type: 'json',
22
+ name: 'scope',
23
+ },
24
+ ],
25
+ } as CollectionOptions;