@nocobase/plugin-acl 0.7.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 (98) hide show
  1. package/LICENSE +201 -0
  2. package/esm/actions/available-actions.d.ts +7 -0
  3. package/esm/actions/available-actions.js +26 -0
  4. package/esm/actions/available-actions.js.map +1 -0
  5. package/esm/actions/role-check.d.ts +1 -0
  6. package/esm/actions/role-check.js +38 -0
  7. package/esm/actions/role-check.js.map +1 -0
  8. package/esm/actions/role-collections.d.ts +7 -0
  9. package/esm/actions/role-collections.js +54 -0
  10. package/esm/actions/role-collections.js.map +1 -0
  11. package/esm/collections/roles.d.ts +3 -0
  12. package/esm/collections/roles.js +78 -0
  13. package/esm/collections/roles.js.map +1 -0
  14. package/esm/collections/rolesResources.d.ts +3 -0
  15. package/esm/collections/rolesResources.js +30 -0
  16. package/esm/collections/rolesResources.js.map +1 -0
  17. package/esm/collections/rolesResourcesActions.d.ts +3 -0
  18. package/esm/collections/rolesResourcesActions.js +27 -0
  19. package/esm/collections/rolesResourcesActions.js.map +1 -0
  20. package/esm/collections/rolesResourcesScopes.d.ts +3 -0
  21. package/esm/collections/rolesResourcesScopes.js +22 -0
  22. package/esm/collections/rolesResourcesScopes.js.map +1 -0
  23. package/esm/index.d.ts +1 -0
  24. package/esm/index.js +2 -0
  25. package/esm/index.js.map +1 -0
  26. package/esm/model/RoleModel.d.ts +7 -0
  27. package/esm/model/RoleModel.js +15 -0
  28. package/esm/model/RoleModel.js.map +1 -0
  29. package/esm/model/RoleResourceActionModel.d.ts +12 -0
  30. package/esm/model/RoleResourceActionModel.js +65 -0
  31. package/esm/model/RoleResourceActionModel.js.map +1 -0
  32. package/esm/model/RoleResourceModel.d.ts +16 -0
  33. package/esm/model/RoleResourceModel.js +55 -0
  34. package/esm/model/RoleResourceModel.js.map +1 -0
  35. package/esm/server.d.ts +33 -0
  36. package/esm/server.js +366 -0
  37. package/esm/server.js.map +1 -0
  38. package/lib/actions/available-actions.d.ts +7 -0
  39. package/lib/actions/available-actions.js +29 -0
  40. package/lib/actions/available-actions.js.map +1 -0
  41. package/lib/actions/role-check.d.ts +1 -0
  42. package/lib/actions/role-check.js +42 -0
  43. package/lib/actions/role-check.js.map +1 -0
  44. package/lib/actions/role-collections.d.ts +7 -0
  45. package/lib/actions/role-collections.js +57 -0
  46. package/lib/actions/role-collections.js.map +1 -0
  47. package/lib/collections/roles.d.ts +3 -0
  48. package/lib/collections/roles.js +80 -0
  49. package/lib/collections/roles.js.map +1 -0
  50. package/lib/collections/rolesResources.d.ts +3 -0
  51. package/lib/collections/rolesResources.js +32 -0
  52. package/lib/collections/rolesResources.js.map +1 -0
  53. package/lib/collections/rolesResourcesActions.d.ts +3 -0
  54. package/lib/collections/rolesResourcesActions.js +29 -0
  55. package/lib/collections/rolesResourcesActions.js.map +1 -0
  56. package/lib/collections/rolesResourcesScopes.d.ts +3 -0
  57. package/lib/collections/rolesResourcesScopes.js +24 -0
  58. package/lib/collections/rolesResourcesScopes.js.map +1 -0
  59. package/lib/index.d.ts +1 -0
  60. package/lib/index.js +9 -0
  61. package/lib/index.js.map +1 -0
  62. package/lib/model/RoleModel.d.ts +7 -0
  63. package/lib/model/RoleModel.js +19 -0
  64. package/lib/model/RoleModel.js.map +1 -0
  65. package/lib/model/RoleResourceActionModel.d.ts +12 -0
  66. package/lib/model/RoleResourceActionModel.js +69 -0
  67. package/lib/model/RoleResourceActionModel.js.map +1 -0
  68. package/lib/model/RoleResourceModel.d.ts +16 -0
  69. package/lib/model/RoleResourceModel.js +59 -0
  70. package/lib/model/RoleResourceModel.js.map +1 -0
  71. package/lib/server.d.ts +33 -0
  72. package/lib/server.js +371 -0
  73. package/lib/server.js.map +1 -0
  74. package/package.json +30 -0
  75. package/src/__tests__/acl.test.ts +533 -0
  76. package/src/__tests__/association-field.test.ts +297 -0
  77. package/src/__tests__/configuration.test.ts +45 -0
  78. package/src/__tests__/middleware.test.ts +233 -0
  79. package/src/__tests__/own.test.ts +140 -0
  80. package/src/__tests__/prepare.ts +39 -0
  81. package/src/__tests__/role-check.test.ts +35 -0
  82. package/src/__tests__/role-resource.test.ts +187 -0
  83. package/src/__tests__/role.test.ts +92 -0
  84. package/src/__tests__/scope.test.ts +51 -0
  85. package/src/actions/available-actions.ts +18 -0
  86. package/src/actions/role-check.ts +39 -0
  87. package/src/actions/role-collections.ts +55 -0
  88. package/src/collections/roles.ts +79 -0
  89. package/src/collections/rolesResources.ts +31 -0
  90. package/src/collections/rolesResourcesActions.ts +28 -0
  91. package/src/collections/rolesResourcesScopes.ts +23 -0
  92. package/src/index.ts +2 -0
  93. package/src/model/RoleModel.ts +21 -0
  94. package/src/model/RoleResourceActionModel.ts +80 -0
  95. package/src/model/RoleResourceModel.ts +61 -0
  96. package/src/server.ts +398 -0
  97. package/tsconfig.build.json +9 -0
  98. package/tsconfig.json +5 -0
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.availableActionResource = void 0;
13
+ const availableActionResource = {
14
+ name: 'availableActions',
15
+ actions: {
16
+ list(ctx, next) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ const acl = ctx.app.acl;
19
+ const availableActions = acl.getAvailableActions();
20
+ ctx.body = Array.from(availableActions.entries()).map(([, { name, options }]) => {
21
+ return Object.assign(Object.assign({}, options), { name });
22
+ });
23
+ yield next();
24
+ });
25
+ },
26
+ },
27
+ };
28
+ exports.availableActionResource = availableActionResource;
29
+ //# sourceMappingURL=available-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"available-actions.js","sourceRoot":"","sources":["../../src/actions/available-actions.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,MAAM,uBAAuB,GAAG;IAC9B,IAAI,EAAE,kBAAkB;IACxB,OAAO,EAAE;QACD,IAAI,CAAC,GAAG,EAAE,IAAI;;gBAClB,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;gBACxB,MAAM,gBAAgB,GAAG,GAAG,CAAC,mBAAmB,EAAE,CAAC;gBACnD,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE;oBAC9E,uCACK,OAAO,KACV,IAAI,IACJ;gBACJ,CAAC,CAAC,CAAC;gBACH,MAAM,IAAI,EAAE,CAAC;YACf,CAAC;SAAA;KACF;CACF,CAAC;AAEO,0DAAuB","sourcesContent":["const availableActionResource = {\n name: 'availableActions',\n actions: {\n async list(ctx, next) {\n const acl = ctx.app.acl;\n const availableActions = acl.getAvailableActions();\n ctx.body = Array.from(availableActions.entries()).map(([, { name, options }]) => {\n return {\n ...options,\n name,\n };\n });\n await next();\n },\n },\n};\n\nexport { availableActionResource };\n"]}
@@ -0,0 +1 @@
1
+ export declare function checkAction(ctx: any, next: any): Promise<void>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.checkAction = void 0;
13
+ const map2obj = (map) => {
14
+ const obj = {};
15
+ for (let [key, value] of map) {
16
+ obj[key] = value;
17
+ }
18
+ return obj;
19
+ };
20
+ function checkAction(ctx, next) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const currentRole = ctx.state.currentRole;
23
+ if (currentRole) {
24
+ const roleInstance = yield ctx.db.getRepository('roles').findOne({
25
+ filter: {
26
+ name: currentRole,
27
+ },
28
+ appends: ['menuUiSchemas'],
29
+ });
30
+ const anonymous = yield ctx.db.getRepository('roles').findOne({
31
+ filter: {
32
+ name: 'anonymous',
33
+ },
34
+ });
35
+ const role = ctx.app.acl.getRole(currentRole);
36
+ ctx.body = Object.assign(Object.assign({}, role.toJSON()), { resources: [...role.resources.keys()], actionAlias: map2obj(ctx.app.acl.actionAlias), allowAll: currentRole === 'root', allowConfigure: roleInstance.get('allowConfigure'), allowMenuItemIds: roleInstance.get('menuUiSchemas').map((uiSchema) => uiSchema.get('x-uid')), allowAnonymous: !!anonymous });
37
+ }
38
+ yield next();
39
+ });
40
+ }
41
+ exports.checkAction = checkAction;
42
+ //# sourceMappingURL=role-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role-check.js","sourceRoot":"","sources":["../../src/actions/role-check.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,MAAM,OAAO,GAAG,CAAC,GAAwB,EAAE,EAAE;IAC3C,MAAM,GAAG,GAAG,EAAE,CAAC;IACf,KAAI,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,GAAG,EAAC;QAC1B,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;KAClB;IACF,OAAO,GAAG,CAAC;AACZ,CAAC,CAAA;AAED,SAAsB,WAAW,CAAC,GAAG,EAAE,IAAI;;QACzC,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC;QAC1C,IAAI,WAAW,EAAE;YACf,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;gBAC/D,MAAM,EAAE;oBACN,IAAI,EAAE,WAAW;iBAClB;gBACD,OAAO,EAAE,CAAC,eAAe,CAAC;aAC3B,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC;gBAC5D,MAAM,EAAE;oBACN,IAAI,EAAE,WAAW;iBAClB;aACF,CAAC,CAAC;YAEH,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAE9C,GAAG,CAAC,IAAI,mCACH,IAAI,CAAC,MAAM,EAAE,KAChB,SAAS,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,EACrC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,EAC7C,QAAQ,EAAE,WAAW,KAAK,MAAM,EAChC,cAAc,EAAE,YAAY,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAClD,gBAAgB,EAAE,YAAY,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,EAC5F,cAAc,EAAE,CAAC,CAAC,SAAS,GAC5B,CAAC;SACH;QAED,MAAM,IAAI,EAAE,CAAC;IACf,CAAC;CAAA;AA9BD,kCA8BC","sourcesContent":["const map2obj = (map: Map<string, string>) => {\n const obj = {};\n for(let [key, value] of map){\n obj[key] = value;\n }\n return obj;\n}\n\nexport async function checkAction(ctx, next) {\n const currentRole = ctx.state.currentRole;\n if (currentRole) {\n const roleInstance = await ctx.db.getRepository('roles').findOne({\n filter: {\n name: currentRole,\n },\n appends: ['menuUiSchemas'],\n });\n\n const anonymous = await ctx.db.getRepository('roles').findOne({\n filter: {\n name: 'anonymous',\n },\n });\n\n const role = ctx.app.acl.getRole(currentRole);\n\n ctx.body = {\n ...role.toJSON(),\n resources: [...role.resources.keys()],\n actionAlias: map2obj(ctx.app.acl.actionAlias),\n allowAll: currentRole === 'root',\n allowConfigure: roleInstance.get('allowConfigure'),\n allowMenuItemIds: roleInstance.get('menuUiSchemas').map((uiSchema) => uiSchema.get('x-uid')),\n allowAnonymous: !!anonymous,\n };\n }\n\n await next();\n}\n"]}
@@ -0,0 +1,7 @@
1
+ declare const roleCollectionsResource: {
2
+ name: string;
3
+ actions: {
4
+ list(ctx: any, next: any): Promise<void>;
5
+ };
6
+ };
7
+ export { roleCollectionsResource };
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.roleCollectionsResource = void 0;
13
+ const roleCollectionsResource = {
14
+ name: 'roles.collections',
15
+ actions: {
16
+ list(ctx, next) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ const role = ctx.action.params.associatedIndex;
19
+ const db = ctx.db;
20
+ const collectionRepository = db.getRepository('collections');
21
+ // all collections
22
+ const collections = yield collectionRepository.find({
23
+ filter: ctx.action.params.filter,
24
+ });
25
+ // role collections
26
+ const roleResources = yield db.getRepository('rolesResources').find({
27
+ filter: {
28
+ roleName: role,
29
+ },
30
+ });
31
+ // role collections
32
+ const roleResourcesNames = roleResources.map((roleResource) => roleResource.get('name'));
33
+ const roleResourceActionResourceNames = roleResources
34
+ .filter((roleResources) => roleResources.get('usingActionsConfig'))
35
+ .map((roleResources) => roleResources.get('name'));
36
+ ctx.body = collections
37
+ .map((collection) => {
38
+ const exists = roleResourcesNames.includes(collection.get('name'));
39
+ const usingConfig = roleResourceActionResourceNames.includes(collection.get('name'))
40
+ ? 'resourceAction'
41
+ : 'strategy';
42
+ return {
43
+ name: collection.get('name'),
44
+ title: collection.get('title'),
45
+ roleName: role,
46
+ usingConfig,
47
+ exists,
48
+ };
49
+ })
50
+ .sort((a, b) => (a.name > b.name ? 1 : -1));
51
+ yield next();
52
+ });
53
+ },
54
+ },
55
+ };
56
+ exports.roleCollectionsResource = roleCollectionsResource;
57
+ //# sourceMappingURL=role-collections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role-collections.js","sourceRoot":"","sources":["../../src/actions/role-collections.ts"],"names":[],"mappings":";;;;;;;;;;;;AAIA,MAAM,uBAAuB,GAAG;IAC9B,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE;QACD,IAAI,CAAC,GAAG,EAAE,IAAI;;gBAClB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC;gBAE/C,MAAM,EAAE,GAAa,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,oBAAoB,GAAG,EAAE,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;gBAE7D,kBAAkB;gBAClB,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC;oBAClD,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM;iBACjC,CAAC,CAAC;gBAEH,mBAAmB;gBACnB,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC;oBAClE,MAAM,EAAE;wBACN,QAAQ,EAAE,IAAI;qBACf;iBACF,CAAC,CAAC;gBAEH,mBAAmB;gBACnB,MAAM,kBAAkB,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;gBACzF,MAAM,+BAA+B,GAAG,aAAa;qBAClD,MAAM,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;qBAClE,GAAG,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;gBAErD,GAAG,CAAC,IAAI,GAAG,WAAW;qBACnB,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;oBAClB,MAAM,MAAM,GAAG,kBAAkB,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;oBAEnE,MAAM,WAAW,GAAoB,+BAA+B,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;wBACnG,CAAC,CAAC,gBAAgB;wBAClB,CAAC,CAAC,UAAU,CAAC;oBAEf,OAAO;wBACL,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAW;wBACtC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,OAAO,CAAW;wBACxC,QAAQ,EAAE,IAAI;wBACd,WAAW;wBACX,MAAM;qBACP,CAAC;gBACJ,CAAC,CAAC;qBACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAE9C,MAAM,IAAI,EAAE,CAAC;YACf,CAAC;SAAA;KACF;CACF,CAAC;AAEO,0DAAuB","sourcesContent":["import { Database } from '@nocobase/database';\n\ntype UsingConfigType = 'strategy' | 'resourceAction';\n\nconst roleCollectionsResource = {\n name: 'roles.collections',\n actions: {\n async list(ctx, next) {\n const role = ctx.action.params.associatedIndex;\n\n const db: Database = ctx.db;\n const collectionRepository = db.getRepository('collections');\n\n // all collections\n const collections = await collectionRepository.find({\n filter: ctx.action.params.filter,\n });\n\n // role collections\n const roleResources = await db.getRepository('rolesResources').find({\n filter: {\n roleName: role,\n },\n });\n\n // role collections\n const roleResourcesNames = roleResources.map((roleResource) => roleResource.get('name'));\n const roleResourceActionResourceNames = roleResources\n .filter((roleResources) => roleResources.get('usingActionsConfig'))\n .map((roleResources) => roleResources.get('name'));\n\n ctx.body = collections\n .map((collection) => {\n const exists = roleResourcesNames.includes(collection.get('name'));\n\n const usingConfig: UsingConfigType = roleResourceActionResourceNames.includes(collection.get('name'))\n ? 'resourceAction'\n : 'strategy';\n\n return {\n name: collection.get('name') as string,\n title: collection.get('title') as string,\n roleName: role,\n usingConfig,\n exists,\n };\n })\n .sort((a, b) => (a.name > b.name ? 1 : -1));\n\n await next();\n },\n },\n};\n\nexport { roleCollectionsResource };\n"]}
@@ -0,0 +1,3 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+ declare const _default: CollectionOptions;
3
+ export default _default;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ name: 'roles',
5
+ title: '{{t("Roles")}}',
6
+ autoGenId: false,
7
+ model: 'RoleModel',
8
+ filterTargetKey: 'name',
9
+ // targetKey: 'name',
10
+ sortable: true,
11
+ fields: [
12
+ {
13
+ type: 'uid',
14
+ name: 'name',
15
+ prefix: 'r_',
16
+ primaryKey: true,
17
+ interface: 'input',
18
+ uiSchema: {
19
+ type: 'string',
20
+ title: '{{t("Role UID")}}',
21
+ 'x-component': 'Input',
22
+ },
23
+ },
24
+ {
25
+ type: 'string',
26
+ name: 'title',
27
+ unique: true,
28
+ interface: 'input',
29
+ uiSchema: {
30
+ type: 'string',
31
+ title: '{{t("Role name")}}',
32
+ 'x-component': 'Input',
33
+ },
34
+ },
35
+ {
36
+ type: 'boolean',
37
+ name: 'default',
38
+ },
39
+ {
40
+ type: 'string',
41
+ name: 'description',
42
+ },
43
+ {
44
+ type: 'json',
45
+ name: 'strategy',
46
+ },
47
+ {
48
+ type: 'boolean',
49
+ name: 'default',
50
+ defaultValue: false,
51
+ },
52
+ {
53
+ type: 'boolean',
54
+ name: 'hidden',
55
+ defaultValue: false,
56
+ },
57
+ {
58
+ type: 'boolean',
59
+ name: 'allowConfigure',
60
+ },
61
+ {
62
+ type: 'boolean',
63
+ name: 'allowNewMenu',
64
+ },
65
+ {
66
+ type: 'belongsToMany',
67
+ name: 'menuUiSchemas',
68
+ target: 'uiSchemas',
69
+ targetKey: 'x-uid',
70
+ },
71
+ {
72
+ type: 'hasMany',
73
+ name: 'resources',
74
+ target: 'rolesResources',
75
+ sourceKey: 'name',
76
+ targetKey: 'name',
77
+ },
78
+ ],
79
+ };
80
+ //# sourceMappingURL=roles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles.js","sourceRoot":"","sources":["../../src/collections/roles.ts"],"names":[],"mappings":";;AAEA,kBAAe;IACb,IAAI,EAAE,OAAO;IACb,KAAK,EAAE,gBAAgB;IACvB,SAAS,EAAE,KAAK;IAChB,KAAK,EAAE,WAAW;IAClB,eAAe,EAAE,MAAM;IACvB,qBAAqB;IACrB,QAAQ,EAAE,IAAI;IACd,MAAM,EAAE;QACN;YACE,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,IAAI;YACZ,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,mBAAmB;gBAC1B,aAAa,EAAE,OAAO;aACvB;SACF;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,OAAO;YAClB,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,oBAAoB;gBAC3B,aAAa,EAAE,OAAO;aACvB;SACF;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;SAChB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,aAAa;SACpB;QACD;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,UAAU;SACjB;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,YAAY,EAAE,KAAK;SACpB;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,QAAQ;YACd,YAAY,EAAE,KAAK;SACpB;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,gBAAgB;SACvB;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,cAAc;SACrB;QACD;YACE,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,eAAe;YACrB,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,OAAO;SACnB;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,gBAAgB;YACxB,SAAS,EAAE,MAAM;YACjB,SAAS,EAAE,MAAM;SAClB;KACF;CACmB,CAAC","sourcesContent":["import { CollectionOptions } from '@nocobase/database';\n\nexport default {\n name: 'roles',\n title: '{{t(\"Roles\")}}',\n autoGenId: false,\n model: 'RoleModel',\n filterTargetKey: 'name',\n // targetKey: 'name',\n sortable: true,\n fields: [\n {\n type: 'uid',\n name: 'name',\n prefix: 'r_',\n primaryKey: true,\n interface: 'input',\n uiSchema: {\n type: 'string',\n title: '{{t(\"Role UID\")}}',\n 'x-component': 'Input',\n },\n },\n {\n type: 'string',\n name: 'title',\n unique: true,\n interface: 'input',\n uiSchema: {\n type: 'string',\n title: '{{t(\"Role name\")}}',\n 'x-component': 'Input',\n },\n },\n {\n type: 'boolean',\n name: 'default',\n },\n {\n type: 'string',\n name: 'description',\n },\n {\n type: 'json',\n name: 'strategy',\n },\n {\n type: 'boolean',\n name: 'default',\n defaultValue: false,\n },\n {\n type: 'boolean',\n name: 'hidden',\n defaultValue: false,\n },\n {\n type: 'boolean',\n name: 'allowConfigure',\n },\n {\n type: 'boolean',\n name: 'allowNewMenu',\n },\n {\n type: 'belongsToMany',\n name: 'menuUiSchemas',\n target: 'uiSchemas',\n targetKey: 'x-uid',\n },\n {\n type: 'hasMany',\n name: 'resources',\n target: 'rolesResources',\n sourceKey: 'name',\n targetKey: 'name',\n },\n ],\n} as CollectionOptions;\n"]}
@@ -0,0 +1,3 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+ declare const _default: CollectionOptions;
3
+ export default _default;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ name: 'rolesResources',
5
+ model: 'RoleResourceModel',
6
+ indexes: [
7
+ {
8
+ unique: true,
9
+ fields: ['roleName', 'name'],
10
+ },
11
+ ],
12
+ fields: [
13
+ {
14
+ type: 'belongsTo',
15
+ name: 'role',
16
+ },
17
+ {
18
+ type: 'string',
19
+ name: 'name',
20
+ },
21
+ {
22
+ type: 'boolean',
23
+ name: 'usingActionsConfig',
24
+ },
25
+ {
26
+ type: 'hasMany',
27
+ name: 'actions',
28
+ target: 'rolesResourcesActions',
29
+ },
30
+ ],
31
+ };
32
+ //# sourceMappingURL=rolesResources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rolesResources.js","sourceRoot":"","sources":["../../src/collections/rolesResources.ts"],"names":[],"mappings":";;AAEA,kBAAe;IACb,IAAI,EAAE,gBAAgB;IACtB,KAAK,EAAE,mBAAmB;IAC1B,OAAO,EAAE;QACP;YACE,MAAM,EAAE,IAAI;YACZ,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC;SAC7B;KACF;IACD,MAAM,EAAE;QACN;YACE,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,MAAM;SACb;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,MAAM;SACb;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,oBAAoB;SAC3B;QACD;YACE,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,uBAAuB;SAChC;KACF;CACmB,CAAC","sourcesContent":["import { CollectionOptions } from '@nocobase/database';\n\nexport default {\n name: 'rolesResources',\n model: 'RoleResourceModel',\n indexes: [\n {\n unique: true,\n fields: ['roleName', 'name'],\n },\n ],\n fields: [\n {\n type: 'belongsTo',\n name: 'role',\n },\n {\n type: 'string',\n name: 'name',\n },\n {\n type: 'boolean',\n name: 'usingActionsConfig',\n },\n {\n type: 'hasMany',\n name: 'actions',\n target: 'rolesResourcesActions',\n },\n ],\n} as CollectionOptions;\n"]}
@@ -0,0 +1,3 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+ declare const _default: CollectionOptions;
3
+ export default _default;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ name: 'rolesResourcesActions',
5
+ model: 'RoleResourceActionModel',
6
+ fields: [
7
+ {
8
+ type: 'belongsTo',
9
+ name: 'resource',
10
+ foreignKey: 'rolesResourceId',
11
+ target: 'rolesResources',
12
+ },
13
+ {
14
+ type: 'string',
15
+ name: 'name',
16
+ },
17
+ {
18
+ type: 'array',
19
+ name: 'fields',
20
+ defaultValue: [],
21
+ },
22
+ {
23
+ type: 'belongsTo',
24
+ name: 'scope',
25
+ target: 'rolesResourcesScopes',
26
+ },
27
+ ],
28
+ };
29
+ //# sourceMappingURL=rolesResourcesActions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rolesResourcesActions.js","sourceRoot":"","sources":["../../src/collections/rolesResourcesActions.ts"],"names":[],"mappings":";;AAEA,kBAAe;IACb,IAAI,EAAE,uBAAuB;IAC7B,KAAK,EAAE,yBAAyB;IAChC,MAAM,EAAE;QACN;YACE,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,UAAU;YAChB,UAAU,EAAE,iBAAiB;YAC7B,MAAM,EAAE,gBAAgB;SACzB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,MAAM;SACb;QACD;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,QAAQ;YACd,YAAY,EAAE,EAAE;SACjB;QACD;YACE,IAAI,EAAE,WAAW;YACjB,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,sBAAsB;SAC/B;KACF;CACmB,CAAC","sourcesContent":["import { CollectionOptions } from '@nocobase/database';\n\nexport default {\n name: 'rolesResourcesActions',\n model: 'RoleResourceActionModel',\n fields: [\n {\n type: 'belongsTo',\n name: 'resource',\n foreignKey: 'rolesResourceId',\n target: 'rolesResources',\n },\n {\n type: 'string',\n name: 'name',\n },\n {\n type: 'array',\n name: 'fields',\n defaultValue: [],\n },\n {\n type: 'belongsTo',\n name: 'scope',\n target: 'rolesResourcesScopes',\n },\n ],\n} as CollectionOptions;\n"]}
@@ -0,0 +1,3 @@
1
+ import { CollectionOptions } from '@nocobase/database';
2
+ declare const _default: CollectionOptions;
3
+ export default _default;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = {
4
+ name: 'rolesResourcesScopes',
5
+ fields: [
6
+ {
7
+ type: 'uid',
8
+ name: 'key',
9
+ },
10
+ {
11
+ type: 'string',
12
+ name: 'name',
13
+ },
14
+ {
15
+ type: 'string',
16
+ name: 'resourceName',
17
+ },
18
+ {
19
+ type: 'json',
20
+ name: 'scope',
21
+ },
22
+ ],
23
+ };
24
+ //# sourceMappingURL=rolesResourcesScopes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rolesResourcesScopes.js","sourceRoot":"","sources":["../../src/collections/rolesResourcesScopes.ts"],"names":[],"mappings":";;AAEA,kBAAe;IACb,IAAI,EAAE,sBAAsB;IAC5B,MAAM,EAAE;QACN;YACE,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,KAAK;SACZ;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,MAAM;SACb;QACD;YACE,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,cAAc;SACrB;QACD;YACE,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,OAAO;SACd;KACF;CACmB,CAAC","sourcesContent":["import { CollectionOptions } from '@nocobase/database';\n\nexport default {\n name: 'rolesResourcesScopes',\n fields: [\n {\n type: 'uid',\n name: 'key',\n },\n {\n type: 'string',\n name: 'name',\n },\n {\n type: 'string',\n name: 'resourceName',\n },\n {\n type: 'json',\n name: 'scope',\n },\n ],\n} as CollectionOptions;\n"]}
package/lib/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { default } from './server';
package/lib/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = void 0;
7
+ var server_1 = require("./server");
8
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(server_1).default; } });
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,mCAAmC;AAA1B,kHAAA,OAAO,OAAA","sourcesContent":["export { default } from './server';\n\n"]}
@@ -0,0 +1,7 @@
1
+ import { Model } from '@nocobase/database';
2
+ import { ACL } from '@nocobase/acl';
3
+ export declare class RoleModel extends Model {
4
+ writeToAcl(options: {
5
+ acl: ACL;
6
+ }): void;
7
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RoleModel = void 0;
4
+ const database_1 = require("@nocobase/database");
5
+ class RoleModel extends database_1.Model {
6
+ writeToAcl(options) {
7
+ const { acl } = options;
8
+ const roleName = this.get('name');
9
+ let role = acl.getRole(roleName);
10
+ if (!role) {
11
+ role = acl.define({
12
+ role: roleName,
13
+ });
14
+ }
15
+ role.setStrategy(Object.assign(Object.assign({}, (this.get('strategy') || {})), { allowConfigure: this.get('allowConfigure') }));
16
+ }
17
+ }
18
+ exports.RoleModel = RoleModel;
19
+ //# sourceMappingURL=RoleModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoleModel.js","sourceRoot":"","sources":["../../src/model/RoleModel.ts"],"names":[],"mappings":";;;AAAA,iDAA2C;AAG3C,MAAa,SAAU,SAAQ,gBAAK;IAClC,UAAU,CAAC,OAAqB;QAC9B,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAW,CAAC;QAC5C,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAEjC,IAAI,CAAC,IAAI,EAAE;YACT,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC;gBAChB,IAAI,EAAE,QAAQ;aACf,CAAC,CAAC;SACJ;QAED,IAAI,CAAC,WAAW,iCACX,CAAE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAY,IAAI,EAAE,CAAC,KAC3C,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAY,IACrD,CAAC;IACL,CAAC;CACF;AAjBD,8BAiBC","sourcesContent":["import { Model } from '@nocobase/database';\nimport { ACL } from '@nocobase/acl';\n\nexport class RoleModel extends Model {\n writeToAcl(options: { acl: ACL }) {\n const { acl } = options;\n const roleName = this.get('name') as string;\n let role = acl.getRole(roleName);\n\n if (!role) {\n role = acl.define({\n role: roleName,\n });\n }\n\n role.setStrategy({\n ...((this.get('strategy') as object) || {}),\n allowConfigure: this.get('allowConfigure') as boolean,\n });\n }\n}\n"]}
@@ -0,0 +1,12 @@
1
+ import { ACL, ACLRole } from '@nocobase/acl';
2
+ import { Model } from '@nocobase/database';
3
+ import { AssociationFieldsActions, GrantHelper } from '../server';
4
+ export declare class RoleResourceActionModel extends Model {
5
+ writeToACL(options: {
6
+ acl: ACL;
7
+ role: ACLRole;
8
+ resourceName: string;
9
+ associationFieldsActions: AssociationFieldsActions;
10
+ grantHelper: GrantHelper;
11
+ }): Promise<void>;
12
+ }
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RoleResourceActionModel = void 0;
13
+ const database_1 = require("@nocobase/database");
14
+ class RoleResourceActionModel extends database_1.Model {
15
+ writeToACL(options) {
16
+ var _a;
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ // @ts-ignore
19
+ const db = this.constructor.database;
20
+ const { resourceName, role, acl, associationFieldsActions, grantHelper } = options;
21
+ const actionName = this.get('name');
22
+ const fields = this.get('fields');
23
+ const actionPath = `${resourceName}:${actionName}`;
24
+ const actionParams = {
25
+ fields,
26
+ };
27
+ // @ts-ignore
28
+ const scope = yield this.getScope();
29
+ if (scope) {
30
+ actionParams['own'] = scope.get('key') === 'own';
31
+ actionParams['filter'] = scope.get('scope');
32
+ }
33
+ role.grantAction(actionPath, actionParams);
34
+ const collection = db.getCollection(resourceName);
35
+ if (!collection) {
36
+ return;
37
+ }
38
+ const availableAction = acl.resolveActionAlias(actionName);
39
+ for (const field of fields) {
40
+ const collectionField = collection.getField(field);
41
+ const fieldType = collectionField.get('interface');
42
+ const fieldActions = (_a = associationFieldsActions === null || associationFieldsActions === void 0 ? void 0 : associationFieldsActions[fieldType]) === null || _a === void 0 ? void 0 : _a[availableAction];
43
+ const fieldTarget = collectionField.get('target');
44
+ if (fieldActions) {
45
+ const associationActions = fieldActions.associationActions || [];
46
+ associationActions.forEach((associationAction) => {
47
+ const actionName = `${resourceName}.${fieldTarget}:${associationAction}`;
48
+ role.grantAction(actionName);
49
+ });
50
+ const targetActions = fieldActions.targetActions || [];
51
+ targetActions.forEach((targetAction) => {
52
+ const targetActionPath = `${fieldTarget}:${targetAction}`;
53
+ grantHelper.resourceTargetActionMap.set(resourceName, [
54
+ ...(grantHelper.resourceTargetActionMap.get(resourceName) || []),
55
+ targetActionPath,
56
+ ]);
57
+ grantHelper.targetActionResourceMap.set(targetActionPath, [
58
+ ...(grantHelper.targetActionResourceMap.get(targetActionPath) || []),
59
+ resourceName,
60
+ ]);
61
+ role.grantAction(targetActionPath);
62
+ });
63
+ }
64
+ }
65
+ });
66
+ }
67
+ }
68
+ exports.RoleResourceActionModel = RoleResourceActionModel;
69
+ //# sourceMappingURL=RoleResourceActionModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoleResourceActionModel.js","sourceRoot":"","sources":["../../src/model/RoleResourceActionModel.ts"],"names":[],"mappings":";;;;;;;;;;;;AACA,iDAAqD;AAGrD,MAAa,uBAAwB,SAAQ,gBAAK;IAC1C,UAAU,CAAC,OAMhB;;;YACC,aAAa;YACb,MAAM,EAAE,GAAa,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;YAE/C,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,GAAG,EAAE,wBAAwB,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;YAEnF,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAW,CAAC;YAE9C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAQ,CAAC;YAEzC,MAAM,UAAU,GAAG,GAAG,YAAY,IAAI,UAAU,EAAE,CAAC;YACnD,MAAM,YAAY,GAAG;gBACnB,MAAM;aACP,CAAC;YAEF,aAAa;YACb,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YAEpC,IAAI,KAAK,EAAE;gBACT,YAAY,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC;gBACjD,YAAY,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aAC7C;YAED,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;YAE3C,MAAM,UAAU,GAAG,EAAE,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;YAElD,IAAI,CAAC,UAAU,EAAE;gBACf,OAAO;aACR;YAED,MAAM,eAAe,GAAG,GAAG,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;YAE3D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;gBAC1B,MAAM,eAAe,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACnD,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,WAAW,CAAW,CAAC;gBAE7D,MAAM,YAAY,GAA2B,MAAA,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAG,SAAS,CAAC,0CAAG,eAAe,CAAC,CAAC;gBAEtG,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAElD,IAAI,YAAY,EAAE;oBAChB,MAAM,kBAAkB,GAAG,YAAY,CAAC,kBAAkB,IAAI,EAAE,CAAC;oBACjE,kBAAkB,CAAC,OAAO,CAAC,CAAC,iBAAiB,EAAE,EAAE;wBAC/C,MAAM,UAAU,GAAG,GAAG,YAAY,IAAI,WAAW,IAAI,iBAAiB,EAAE,CAAC;wBACzE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;oBAC/B,CAAC,CAAC,CAAC;oBAEH,MAAM,aAAa,GAAG,YAAY,CAAC,aAAa,IAAI,EAAE,CAAC;oBAEvD,aAAa,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;wBACrC,MAAM,gBAAgB,GAAG,GAAG,WAAW,IAAI,YAAY,EAAE,CAAC;wBAE1D,WAAW,CAAC,uBAAuB,CAAC,GAAG,CAAC,YAAY,EAAE;4BACpD,GAAG,CAAC,WAAW,CAAC,uBAAuB,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;4BAChE,gBAAgB;yBACjB,CAAC,CAAC;wBAEH,WAAW,CAAC,uBAAuB,CAAC,GAAG,CAAC,gBAAgB,EAAE;4BACxD,GAAG,CAAC,WAAW,CAAC,uBAAuB,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;4BACpE,YAAY;yBACb,CAAC,CAAC;wBAEH,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;oBACrC,CAAC,CAAC,CAAC;iBACJ;aACF;;KACF;CACF;AA3ED,0DA2EC","sourcesContent":["import { ACL, ACLRole } from '@nocobase/acl';\nimport { Database, Model } from '@nocobase/database';\nimport { AssociationFieldAction, AssociationFieldsActions, GrantHelper } from '../server';\n\nexport class RoleResourceActionModel extends Model {\n async writeToACL(options: {\n acl: ACL;\n role: ACLRole;\n resourceName: string;\n associationFieldsActions: AssociationFieldsActions;\n grantHelper: GrantHelper;\n }) {\n // @ts-ignore\n const db: Database = this.constructor.database;\n\n const { resourceName, role, acl, associationFieldsActions, grantHelper } = options;\n\n const actionName = this.get('name') as string;\n\n const fields = this.get('fields') as any;\n\n const actionPath = `${resourceName}:${actionName}`;\n const actionParams = {\n fields,\n };\n\n // @ts-ignore\n const scope = await this.getScope();\n\n if (scope) {\n actionParams['own'] = scope.get('key') === 'own';\n actionParams['filter'] = scope.get('scope');\n }\n\n role.grantAction(actionPath, actionParams);\n\n const collection = db.getCollection(resourceName);\n\n if (!collection) {\n return;\n }\n\n const availableAction = acl.resolveActionAlias(actionName);\n\n for (const field of fields) {\n const collectionField = collection.getField(field);\n const fieldType = collectionField.get('interface') as string;\n\n const fieldActions: AssociationFieldAction = associationFieldsActions?.[fieldType]?.[availableAction];\n\n const fieldTarget = collectionField.get('target');\n\n if (fieldActions) {\n const associationActions = fieldActions.associationActions || [];\n associationActions.forEach((associationAction) => {\n const actionName = `${resourceName}.${fieldTarget}:${associationAction}`;\n role.grantAction(actionName);\n });\n\n const targetActions = fieldActions.targetActions || [];\n\n targetActions.forEach((targetAction) => {\n const targetActionPath = `${fieldTarget}:${targetAction}`;\n\n grantHelper.resourceTargetActionMap.set(resourceName, [\n ...(grantHelper.resourceTargetActionMap.get(resourceName) || []),\n targetActionPath,\n ]);\n\n grantHelper.targetActionResourceMap.set(targetActionPath, [\n ...(grantHelper.targetActionResourceMap.get(targetActionPath) || []),\n resourceName,\n ]);\n\n role.grantAction(targetActionPath);\n });\n }\n }\n }\n}\n"]}
@@ -0,0 +1,16 @@
1
+ import { Model } from '@nocobase/database';
2
+ import { ACL, ACLRole } from '@nocobase/acl';
3
+ import { AssociationFieldsActions, GrantHelper } from '../server';
4
+ export declare class RoleResourceModel extends Model {
5
+ revoke(options: {
6
+ role: ACLRole;
7
+ resourceName: string;
8
+ grantHelper: GrantHelper;
9
+ }): Promise<void>;
10
+ writeToACL(options: {
11
+ acl: ACL;
12
+ associationFieldsActions: AssociationFieldsActions;
13
+ grantHelper: GrantHelper;
14
+ transaction: any;
15
+ }): Promise<void>;
16
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RoleResourceModel = void 0;
13
+ const database_1 = require("@nocobase/database");
14
+ class RoleResourceModel extends database_1.Model {
15
+ revoke(options) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const { role, resourceName, grantHelper } = options;
18
+ role.revokeResource(resourceName);
19
+ const targetActions = grantHelper.resourceTargetActionMap.get(resourceName) || [];
20
+ for (const targetAction of targetActions) {
21
+ const targetActionResource = (grantHelper.targetActionResourceMap.get(targetAction) || []).filter((item) => resourceName !== item);
22
+ grantHelper.targetActionResourceMap.set(targetAction, targetActionResource);
23
+ if (targetActionResource.length == 0) {
24
+ role.revokeAction(targetAction);
25
+ }
26
+ }
27
+ grantHelper.resourceTargetActionMap.set(resourceName, []);
28
+ });
29
+ }
30
+ writeToACL(options) {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ const { acl, associationFieldsActions, grantHelper } = options;
33
+ const resourceName = this.get('name');
34
+ const roleName = this.get('roleName');
35
+ const role = acl.getRole(roleName);
36
+ // revoke resource of role
37
+ yield this.revoke({ role, resourceName, grantHelper });
38
+ // @ts-ignore
39
+ if (this.usingActionsConfig === false) {
40
+ return;
41
+ }
42
+ // @ts-ignore
43
+ const actions = yield this.getActions({
44
+ transaction: options.transaction,
45
+ });
46
+ for (const action of actions) {
47
+ yield action.writeToACL({
48
+ acl,
49
+ role,
50
+ resourceName,
51
+ associationFieldsActions,
52
+ grantHelper: options.grantHelper,
53
+ });
54
+ }
55
+ });
56
+ }
57
+ }
58
+ exports.RoleResourceModel = RoleResourceModel;
59
+ //# sourceMappingURL=RoleResourceModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoleResourceModel.js","sourceRoot":"","sources":["../../src/model/RoleResourceModel.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,iDAAqD;AAKrD,MAAa,iBAAkB,SAAQ,gBAAK;IACpC,MAAM,CAAC,OAA0E;;YACrF,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;YACpD,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YAElC,MAAM,aAAa,GAAG,WAAW,CAAC,uBAAuB,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YAElF,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE;gBACxC,MAAM,oBAAoB,GAAG,CAAC,WAAW,CAAC,uBAAuB,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAC/F,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,KAAK,IAAI,CAChC,CAAC;gBAEF,WAAW,CAAC,uBAAuB,CAAC,GAAG,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;gBAC5E,IAAI,oBAAoB,CAAC,MAAM,IAAI,CAAC,EAAE;oBACpC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;iBACjC;aACF;YAED,WAAW,CAAC,uBAAuB,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC;KAAA;IAEK,UAAU,CAAC,OAKhB;;YACC,MAAM,EAAE,GAAG,EAAE,wBAAwB,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;YAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAW,CAAC;YAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAW,CAAC;YAChD,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAEnC,0BAA0B;YAC1B,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;YAEvD,aAAa;YACb,IAAI,IAAI,CAAC,kBAAkB,KAAK,KAAK,EAAE;gBACrC,OAAO;aACR;YAED,aAAa;YACb,MAAM,OAAO,GAA8B,MAAM,IAAI,CAAC,UAAU,CAAC;gBAC/D,WAAW,EAAE,OAAO,CAAC,WAAW;aACjC,CAAC,CAAC;YAEH,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;gBAC5B,MAAM,MAAM,CAAC,UAAU,CAAC;oBACtB,GAAG;oBACH,IAAI;oBACJ,YAAY;oBACZ,wBAAwB;oBACxB,WAAW,EAAE,OAAO,CAAC,WAAW;iBACjC,CAAC,CAAC;aACJ;QACH,CAAC;KAAA;CACF;AAvDD,8CAuDC","sourcesContent":["import { Database, Model } from '@nocobase/database';\nimport { ACL, ACLRole } from '@nocobase/acl';\nimport { RoleResourceActionModel } from './RoleResourceActionModel';\nimport { AssociationFieldsActions, GrantHelper } from '../server';\n\nexport class RoleResourceModel extends Model {\n async revoke(options: { role: ACLRole; resourceName: string; grantHelper: GrantHelper }) {\n const { role, resourceName, grantHelper } = options;\n role.revokeResource(resourceName);\n\n const targetActions = grantHelper.resourceTargetActionMap.get(resourceName) || [];\n\n for (const targetAction of targetActions) {\n const targetActionResource = (grantHelper.targetActionResourceMap.get(targetAction) || []).filter(\n (item) => resourceName !== item,\n );\n\n grantHelper.targetActionResourceMap.set(targetAction, targetActionResource);\n if (targetActionResource.length == 0) {\n role.revokeAction(targetAction);\n }\n }\n\n grantHelper.resourceTargetActionMap.set(resourceName, []);\n }\n\n async writeToACL(options: {\n acl: ACL;\n associationFieldsActions: AssociationFieldsActions;\n grantHelper: GrantHelper;\n transaction: any;\n }) {\n const { acl, associationFieldsActions, grantHelper } = options;\n const resourceName = this.get('name') as string;\n const roleName = this.get('roleName') as string;\n const role = acl.getRole(roleName);\n\n // revoke resource of role\n await this.revoke({ role, resourceName, grantHelper });\n\n // @ts-ignore\n if (this.usingActionsConfig === false) {\n return;\n }\n\n // @ts-ignore\n const actions: RoleResourceActionModel[] = await this.getActions({\n transaction: options.transaction,\n });\n\n for (const action of actions) {\n await action.writeToACL({\n acl,\n role,\n resourceName,\n associationFieldsActions,\n grantHelper: options.grantHelper,\n });\n }\n }\n}\n"]}