@nocobase/plugin-acl 0.7.0-alpha.8 → 0.7.0-alpha.82

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 (69) hide show
  1. package/lib/actions/available-actions.js +35 -25
  2. package/lib/actions/role-check.js +85 -38
  3. package/lib/actions/role-collections.js +78 -53
  4. package/lib/collections/roles.js +70 -78
  5. package/lib/collections/rolesResources.js +27 -30
  6. package/lib/collections/rolesResourcesActions.js +26 -27
  7. package/lib/collections/rolesResourcesScopes.js +21 -22
  8. package/lib/index.js +14 -8
  9. package/lib/model/RoleModel.js +39 -15
  10. package/lib/model/RoleResourceActionModel.js +103 -66
  11. package/lib/model/RoleResourceModel.js +125 -56
  12. package/lib/server.js +609 -351
  13. package/package.json +5 -10
  14. package/src/__tests__/acl.test.ts +50 -0
  15. package/src/__tests__/own.test.ts +5 -6
  16. package/src/actions/role-collections.ts +15 -5
  17. package/src/model/RoleResourceActionModel.ts +4 -2
  18. package/src/model/RoleResourceModel.ts +12 -4
  19. package/src/server.ts +5 -0
  20. package/esm/actions/available-actions.d.ts +0 -7
  21. package/esm/actions/available-actions.js +0 -26
  22. package/esm/actions/available-actions.js.map +0 -1
  23. package/esm/actions/role-check.d.ts +0 -1
  24. package/esm/actions/role-check.js +0 -38
  25. package/esm/actions/role-check.js.map +0 -1
  26. package/esm/actions/role-collections.d.ts +0 -7
  27. package/esm/actions/role-collections.js +0 -54
  28. package/esm/actions/role-collections.js.map +0 -1
  29. package/esm/collections/roles.d.ts +0 -3
  30. package/esm/collections/roles.js +0 -78
  31. package/esm/collections/roles.js.map +0 -1
  32. package/esm/collections/rolesResources.d.ts +0 -3
  33. package/esm/collections/rolesResources.js +0 -30
  34. package/esm/collections/rolesResources.js.map +0 -1
  35. package/esm/collections/rolesResourcesActions.d.ts +0 -3
  36. package/esm/collections/rolesResourcesActions.js +0 -27
  37. package/esm/collections/rolesResourcesActions.js.map +0 -1
  38. package/esm/collections/rolesResourcesScopes.d.ts +0 -3
  39. package/esm/collections/rolesResourcesScopes.js +0 -22
  40. package/esm/collections/rolesResourcesScopes.js.map +0 -1
  41. package/esm/index.d.ts +0 -1
  42. package/esm/index.js +0 -2
  43. package/esm/index.js.map +0 -1
  44. package/esm/model/RoleModel.d.ts +0 -7
  45. package/esm/model/RoleModel.js +0 -15
  46. package/esm/model/RoleModel.js.map +0 -1
  47. package/esm/model/RoleResourceActionModel.d.ts +0 -12
  48. package/esm/model/RoleResourceActionModel.js +0 -65
  49. package/esm/model/RoleResourceActionModel.js.map +0 -1
  50. package/esm/model/RoleResourceModel.d.ts +0 -16
  51. package/esm/model/RoleResourceModel.js +0 -55
  52. package/esm/model/RoleResourceModel.js.map +0 -1
  53. package/esm/server.d.ts +0 -33
  54. package/esm/server.js +0 -366
  55. package/esm/server.js.map +0 -1
  56. package/lib/actions/available-actions.js.map +0 -1
  57. package/lib/actions/role-check.js.map +0 -1
  58. package/lib/actions/role-collections.js.map +0 -1
  59. package/lib/collections/roles.js.map +0 -1
  60. package/lib/collections/rolesResources.js.map +0 -1
  61. package/lib/collections/rolesResourcesActions.js.map +0 -1
  62. package/lib/collections/rolesResourcesScopes.js.map +0 -1
  63. package/lib/index.js.map +0 -1
  64. package/lib/model/RoleModel.js.map +0 -1
  65. package/lib/model/RoleResourceActionModel.js.map +0 -1
  66. package/lib/model/RoleResourceModel.js.map +0 -1
  67. package/lib/server.js.map +0 -1
  68. package/tsconfig.build.json +0 -9
  69. package/tsconfig.json +0 -5
@@ -1,7 +0,0 @@
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
- }
@@ -1,15 +0,0 @@
1
- import { Model } from '@nocobase/database';
2
- export class RoleModel extends Model {
3
- writeToAcl(options) {
4
- const { acl } = options;
5
- const roleName = this.get('name');
6
- let role = acl.getRole(roleName);
7
- if (!role) {
8
- role = acl.define({
9
- role: roleName,
10
- });
11
- }
12
- role.setStrategy(Object.assign(Object.assign({}, (this.get('strategy') || {})), { allowConfigure: this.get('allowConfigure') }));
13
- }
14
- }
15
- //# sourceMappingURL=RoleModel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RoleModel.js","sourceRoot":"","sources":["../../src/model/RoleModel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,MAAM,OAAO,SAAU,SAAQ,KAAK;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","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"]}
@@ -1,12 +0,0 @@
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
- }
@@ -1,65 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { Model } from '@nocobase/database';
11
- export class RoleResourceActionModel extends Model {
12
- writeToACL(options) {
13
- var _a;
14
- return __awaiter(this, void 0, void 0, function* () {
15
- // @ts-ignore
16
- const db = this.constructor.database;
17
- const { resourceName, role, acl, associationFieldsActions, grantHelper } = options;
18
- const actionName = this.get('name');
19
- const fields = this.get('fields');
20
- const actionPath = `${resourceName}:${actionName}`;
21
- const actionParams = {
22
- fields,
23
- };
24
- // @ts-ignore
25
- const scope = yield this.getScope();
26
- if (scope) {
27
- actionParams['own'] = scope.get('key') === 'own';
28
- actionParams['filter'] = scope.get('scope');
29
- }
30
- role.grantAction(actionPath, actionParams);
31
- const collection = db.getCollection(resourceName);
32
- if (!collection) {
33
- return;
34
- }
35
- const availableAction = acl.resolveActionAlias(actionName);
36
- for (const field of fields) {
37
- const collectionField = collection.getField(field);
38
- const fieldType = collectionField.get('interface');
39
- const fieldActions = (_a = associationFieldsActions === null || associationFieldsActions === void 0 ? void 0 : associationFieldsActions[fieldType]) === null || _a === void 0 ? void 0 : _a[availableAction];
40
- const fieldTarget = collectionField.get('target');
41
- if (fieldActions) {
42
- const associationActions = fieldActions.associationActions || [];
43
- associationActions.forEach((associationAction) => {
44
- const actionName = `${resourceName}.${fieldTarget}:${associationAction}`;
45
- role.grantAction(actionName);
46
- });
47
- const targetActions = fieldActions.targetActions || [];
48
- targetActions.forEach((targetAction) => {
49
- const targetActionPath = `${fieldTarget}:${targetAction}`;
50
- grantHelper.resourceTargetActionMap.set(resourceName, [
51
- ...(grantHelper.resourceTargetActionMap.get(resourceName) || []),
52
- targetActionPath,
53
- ]);
54
- grantHelper.targetActionResourceMap.set(targetActionPath, [
55
- ...(grantHelper.targetActionResourceMap.get(targetActionPath) || []),
56
- resourceName,
57
- ]);
58
- role.grantAction(targetActionPath);
59
- });
60
- }
61
- }
62
- });
63
- }
64
- }
65
- //# sourceMappingURL=RoleResourceActionModel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RoleResourceActionModel.js","sourceRoot":"","sources":["../../src/model/RoleResourceActionModel.ts"],"names":[],"mappings":"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","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"]}
@@ -1,16 +0,0 @@
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
- }
@@ -1,55 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { Model } from '@nocobase/database';
11
- export class RoleResourceModel extends Model {
12
- revoke(options) {
13
- return __awaiter(this, void 0, void 0, function* () {
14
- const { role, resourceName, grantHelper } = options;
15
- role.revokeResource(resourceName);
16
- const targetActions = grantHelper.resourceTargetActionMap.get(resourceName) || [];
17
- for (const targetAction of targetActions) {
18
- const targetActionResource = (grantHelper.targetActionResourceMap.get(targetAction) || []).filter((item) => resourceName !== item);
19
- grantHelper.targetActionResourceMap.set(targetAction, targetActionResource);
20
- if (targetActionResource.length == 0) {
21
- role.revokeAction(targetAction);
22
- }
23
- }
24
- grantHelper.resourceTargetActionMap.set(resourceName, []);
25
- });
26
- }
27
- writeToACL(options) {
28
- return __awaiter(this, void 0, void 0, function* () {
29
- const { acl, associationFieldsActions, grantHelper } = options;
30
- const resourceName = this.get('name');
31
- const roleName = this.get('roleName');
32
- const role = acl.getRole(roleName);
33
- // revoke resource of role
34
- yield this.revoke({ role, resourceName, grantHelper });
35
- // @ts-ignore
36
- if (this.usingActionsConfig === false) {
37
- return;
38
- }
39
- // @ts-ignore
40
- const actions = yield this.getActions({
41
- transaction: options.transaction,
42
- });
43
- for (const action of actions) {
44
- yield action.writeToACL({
45
- acl,
46
- role,
47
- resourceName,
48
- associationFieldsActions,
49
- grantHelper: options.grantHelper,
50
- });
51
- }
52
- });
53
- }
54
- }
55
- //# sourceMappingURL=RoleResourceModel.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"RoleResourceModel.js","sourceRoot":"","sources":["../../src/model/RoleResourceModel.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAY,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAKrD,MAAM,OAAO,iBAAkB,SAAQ,KAAK;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","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"]}
package/esm/server.d.ts DELETED
@@ -1,33 +0,0 @@
1
- import { Plugin } from '@nocobase/server';
2
- import { RoleResourceActionModel } from './model/RoleResourceActionModel';
3
- import { RoleResourceModel } from './model/RoleResourceModel';
4
- export interface AssociationFieldAction {
5
- associationActions: string[];
6
- targetActions?: string[];
7
- }
8
- interface AssociationFieldActions {
9
- [availableActionName: string]: AssociationFieldAction;
10
- }
11
- export interface AssociationFieldsActions {
12
- [associationType: string]: AssociationFieldActions;
13
- }
14
- export declare class GrantHelper {
15
- resourceTargetActionMap: Map<string, string[]>;
16
- targetActionResourceMap: Map<string, string[]>;
17
- constructor();
18
- }
19
- export declare class PluginACL extends Plugin {
20
- associationFieldsActions: AssociationFieldsActions;
21
- grantHelper: GrantHelper;
22
- get acl(): import("@nocobase/acl").ACL;
23
- registerAssociationFieldAction(associationType: string, value: AssociationFieldActions): void;
24
- registerAssociationFieldsActions(): void;
25
- writeResourceToACL(resourceModel: RoleResourceModel, transaction: any): Promise<void>;
26
- writeActionToACL(actionModel: RoleResourceActionModel, transaction: any): Promise<void>;
27
- writeRolesToACL(): Promise<void>;
28
- beforeLoad(): Promise<void>;
29
- install(): Promise<void>;
30
- load(): Promise<void>;
31
- getName(): string;
32
- }
33
- export default PluginACL;
package/esm/server.js DELETED
@@ -1,366 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { Plugin } from '@nocobase/server';
11
- import { resolve } from 'path';
12
- import { availableActionResource } from './actions/available-actions';
13
- import { checkAction } from './actions/role-check';
14
- import { roleCollectionsResource } from './actions/role-collections';
15
- import { RoleModel } from './model/RoleModel';
16
- import { RoleResourceActionModel } from './model/RoleResourceActionModel';
17
- import { RoleResourceModel } from './model/RoleResourceModel';
18
- export class GrantHelper {
19
- constructor() {
20
- this.resourceTargetActionMap = new Map();
21
- this.targetActionResourceMap = new Map();
22
- }
23
- }
24
- export class PluginACL extends Plugin {
25
- constructor() {
26
- super(...arguments);
27
- this.associationFieldsActions = {};
28
- this.grantHelper = new GrantHelper();
29
- }
30
- get acl() {
31
- return this.app.acl;
32
- }
33
- registerAssociationFieldAction(associationType, value) {
34
- this.associationFieldsActions[associationType] = value;
35
- }
36
- registerAssociationFieldsActions() {
37
- this.registerAssociationFieldAction('linkTo', {
38
- view: {
39
- associationActions: ['list', 'get'],
40
- },
41
- create: {
42
- associationActions: ['add'],
43
- targetActions: ['view'],
44
- },
45
- update: {
46
- associationActions: ['add', 'remove', 'toggle'],
47
- targetActions: ['view'],
48
- },
49
- });
50
- this.registerAssociationFieldAction('attachments', {
51
- view: {
52
- associationActions: ['list', 'get'],
53
- },
54
- add: {
55
- associationActions: ['upload', 'add'],
56
- },
57
- update: {
58
- associationActions: ['update', 'add', 'remove', 'toggle'],
59
- },
60
- });
61
- this.registerAssociationFieldAction('subTable', {
62
- view: {
63
- associationActions: ['list', 'get'],
64
- },
65
- create: {
66
- associationActions: ['create'],
67
- },
68
- update: {
69
- associationActions: ['update', 'destroy'],
70
- },
71
- });
72
- }
73
- writeResourceToACL(resourceModel, transaction) {
74
- return __awaiter(this, void 0, void 0, function* () {
75
- yield resourceModel.writeToACL({
76
- acl: this.acl,
77
- associationFieldsActions: this.associationFieldsActions,
78
- transaction: transaction,
79
- grantHelper: this.grantHelper,
80
- });
81
- });
82
- }
83
- writeActionToACL(actionModel, transaction) {
84
- return __awaiter(this, void 0, void 0, function* () {
85
- const resource = actionModel.get('resource');
86
- const role = this.acl.getRole(resource.get('roleName'));
87
- yield actionModel.writeToACL({
88
- acl: this.acl,
89
- role,
90
- resourceName: resource.get('name'),
91
- associationFieldsActions: this.associationFieldsActions,
92
- grantHelper: this.grantHelper,
93
- });
94
- });
95
- }
96
- writeRolesToACL() {
97
- return __awaiter(this, void 0, void 0, function* () {
98
- const roles = (yield this.app.db.getRepository('roles').find({
99
- appends: ['resources', 'resources.actions'],
100
- }));
101
- for (const role of roles) {
102
- role.writeToAcl({ acl: this.acl });
103
- for (const resource of role.get('resources')) {
104
- yield this.writeResourceToACL(resource, null);
105
- }
106
- }
107
- });
108
- }
109
- beforeLoad() {
110
- return __awaiter(this, void 0, void 0, function* () {
111
- this.app.db.registerModels({
112
- RoleResourceActionModel,
113
- RoleResourceModel,
114
- RoleModel,
115
- });
116
- this.registerAssociationFieldsActions();
117
- this.app.resourcer.define(availableActionResource);
118
- this.app.resourcer.define(roleCollectionsResource);
119
- this.app.resourcer.registerActionHandler('roles:check', checkAction);
120
- this.app.db.on('roles.afterSaveWithAssociations', (model, options) => __awaiter(this, void 0, void 0, function* () {
121
- const { transaction } = options;
122
- model.writeToAcl({
123
- acl: this.acl,
124
- });
125
- for (const resource of (yield model.getResources({ transaction }))) {
126
- yield this.writeResourceToACL(resource, transaction);
127
- }
128
- // model is default
129
- if (model.get('default')) {
130
- yield this.app.db.getRepository('roles').update({
131
- values: {
132
- default: false,
133
- },
134
- filter: {
135
- 'name.$ne': model.get('name'),
136
- },
137
- hooks: false,
138
- transaction,
139
- });
140
- }
141
- }));
142
- this.app.db.on('roles.afterDestroy', (model) => {
143
- const roleName = model.get('name');
144
- this.acl.removeRole(roleName);
145
- });
146
- this.app.db.on('rolesResources.afterSaveWithAssociations', (model, options) => __awaiter(this, void 0, void 0, function* () {
147
- yield this.writeResourceToACL(model, options.transaction);
148
- }));
149
- this.app.db.on('rolesResourcesActions.afterUpdateWithAssociations', (model, options) => __awaiter(this, void 0, void 0, function* () {
150
- const { transaction } = options;
151
- const resource = yield model.getResource({
152
- transaction,
153
- });
154
- yield this.writeResourceToACL(resource, transaction);
155
- }));
156
- this.app.db.on('rolesResources.afterDestroy', (model, options) => __awaiter(this, void 0, void 0, function* () {
157
- const role = this.acl.getRole(model.get('roleName'));
158
- role.revokeResource(model.get('name'));
159
- }));
160
- this.app.db.on('collections.afterDestroy', (model, options) => __awaiter(this, void 0, void 0, function* () {
161
- const { transaction } = options;
162
- yield this.app.db.getRepository('rolesResources').destroy({
163
- filter: {
164
- name: model.get('name'),
165
- },
166
- transaction,
167
- });
168
- }));
169
- this.app.db.on('fields.afterCreate', (model, options) => __awaiter(this, void 0, void 0, function* () {
170
- const { transaction } = options;
171
- const collectionName = model.get('collectionName');
172
- const fieldName = model.get('name');
173
- const resourceActions = (yield this.app.db.getRepository('rolesResourcesActions').find({
174
- filter: {
175
- 'resource.name': collectionName,
176
- },
177
- transaction,
178
- appends: ['resource'],
179
- }));
180
- for (const resourceAction of resourceActions) {
181
- const fields = resourceAction.get('fields');
182
- const newFields = [...fields, fieldName];
183
- yield this.app.db.getRepository('rolesResourcesActions').update({
184
- filterByTk: resourceAction.get('id'),
185
- values: {
186
- fields: newFields,
187
- },
188
- transaction,
189
- });
190
- }
191
- }));
192
- this.app.db.on('fields.afterDestroy', (model, options) => __awaiter(this, void 0, void 0, function* () {
193
- const collectionName = model.get('collectionName');
194
- const fieldName = model.get('name');
195
- const resourceActions = yield this.app.db.getRepository('rolesResourcesActions').find({
196
- filter: {
197
- 'resource.name': collectionName,
198
- 'fields.$anyOf': [fieldName],
199
- },
200
- transaction: options.transaction,
201
- });
202
- for (const resourceAction of resourceActions) {
203
- const fields = resourceAction.get('fields');
204
- const newFields = fields.filter((field) => field != fieldName);
205
- yield this.app.db.getRepository('rolesResourcesActions').update({
206
- filterByTk: resourceAction.get('id'),
207
- values: {
208
- fields: newFields,
209
- },
210
- transaction: options.transaction,
211
- });
212
- }
213
- }));
214
- // sync database role data to acl
215
- this.app.on('beforeStart', () => __awaiter(this, void 0, void 0, function* () {
216
- yield this.writeRolesToACL();
217
- }));
218
- this.app.on('beforeInstallPlugin', (plugin) => __awaiter(this, void 0, void 0, function* () {
219
- if (plugin.constructor.name !== 'UsersPlugin') {
220
- return;
221
- }
222
- const roles = this.app.db.getRepository('roles');
223
- yield roles.createMany({
224
- records: [
225
- {
226
- name: 'root',
227
- title: '{{t("Root")}}',
228
- hidden: true,
229
- },
230
- {
231
- name: 'admin',
232
- title: '{{t("Admin")}}',
233
- allowConfigure: true,
234
- allowNewMenu: true,
235
- strategy: { actions: ['create', 'export', 'view', 'update', 'destroy'] },
236
- },
237
- {
238
- name: 'member',
239
- title: '{{t("Member")}}',
240
- allowNewMenu: true,
241
- strategy: { actions: ['view', 'update:own', 'destroy:own', 'create'] },
242
- default: true,
243
- },
244
- ],
245
- });
246
- const rolesResourcesScopes = this.app.db.getRepository('rolesResourcesScopes');
247
- yield rolesResourcesScopes.createMany({
248
- records: [
249
- {
250
- key: 'all',
251
- name: '{{t("All records")}}',
252
- scope: {},
253
- },
254
- {
255
- key: 'own',
256
- name: '{{t("Own records")}}',
257
- scope: {
258
- createdById: '{{ ctx.state.currentUser.id }}',
259
- },
260
- },
261
- ],
262
- });
263
- }));
264
- this.app.acl.allow('roles', 'check', 'loggedIn');
265
- this.app.acl.allow('roles', ['create', 'update', 'destroy'], 'allowConfigure');
266
- this.app.acl.allow('roles.menuUiSchemas', ['set', 'toggle', 'list'], 'allowConfigure');
267
- this.app.acl.allow('*', '*', (ctx) => {
268
- return ctx.state.currentRole === 'root';
269
- });
270
- this.app.resourcer.use((ctx, next) => __awaiter(this, void 0, void 0, function* () {
271
- const { actionName, resourceName, params } = ctx.action;
272
- const { showAnonymous } = params || {};
273
- if (actionName === 'list' && resourceName === 'roles') {
274
- if (!showAnonymous) {
275
- ctx.action.mergeParams({
276
- filter: {
277
- 'name.$ne': 'anonymous',
278
- },
279
- });
280
- }
281
- }
282
- yield next();
283
- }));
284
- this.app.acl.use((ctx, next) => __awaiter(this, void 0, void 0, function* () {
285
- var _a, _b, _c, _d, _e;
286
- const { actionName, resourceName } = ctx.action;
287
- if (actionName === 'get' || actionName === 'list') {
288
- if (!Array.isArray((_c = (_b = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.permission) === null || _a === void 0 ? void 0 : _a.can) === null || _b === void 0 ? void 0 : _b.params) === null || _c === void 0 ? void 0 : _c.fields)) {
289
- return next();
290
- }
291
- let collection;
292
- if (resourceName.includes('.')) {
293
- const [collectionName, associationName] = resourceName.split('.');
294
- const field = (_e = (_d = ctx.db.getCollection(collectionName)) === null || _d === void 0 ? void 0 : _d.getField) === null || _e === void 0 ? void 0 : _e.call(_d, associationName);
295
- if (field.target) {
296
- collection = ctx.db.getCollection(field.target);
297
- }
298
- }
299
- else {
300
- collection = ctx.db.getCollection(resourceName);
301
- }
302
- if (collection && collection.hasField('createdById')) {
303
- ctx.permission.can.params.fields.push('createdById');
304
- }
305
- }
306
- return next();
307
- }));
308
- const parseJsonTemplate = this.app.acl.parseJsonTemplate;
309
- this.app.acl.use((ctx, next) => __awaiter(this, void 0, void 0, function* () {
310
- var _f, _g, _h, _j;
311
- const { actionName, resourceName, resourceOf } = ctx.action;
312
- if (resourceName.includes('.') && resourceOf) {
313
- if (!((_g = (_f = ctx === null || ctx === void 0 ? void 0 : ctx.permission) === null || _f === void 0 ? void 0 : _f.can) === null || _g === void 0 ? void 0 : _g.params)) {
314
- return next();
315
- }
316
- // 关联数据去掉 filter
317
- delete ctx.permission.can.params.filter;
318
- // 关联数据能不能处理取决于 source 是否有权限
319
- const [collectionName] = resourceName.split('.');
320
- const action = ctx.can({ resource: collectionName, action: actionName });
321
- const availableAction = this.app.acl.getAvailableAction(actionName);
322
- if ((_h = availableAction === null || availableAction === void 0 ? void 0 : availableAction.options) === null || _h === void 0 ? void 0 : _h.onNewRecord) {
323
- if (action) {
324
- ctx.permission.skip = true;
325
- }
326
- else {
327
- ctx.permission.can = false;
328
- }
329
- }
330
- else {
331
- const filter = parseJsonTemplate(((_j = action === null || action === void 0 ? void 0 : action.params) === null || _j === void 0 ? void 0 : _j.filter) || {}, ctx);
332
- const sourceInstance = yield ctx.db.getRepository(collectionName).findOne({
333
- filterByTk: resourceOf,
334
- filter,
335
- });
336
- if (!sourceInstance) {
337
- ctx.permission.can = false;
338
- }
339
- }
340
- }
341
- yield next();
342
- }));
343
- });
344
- }
345
- install() {
346
- return __awaiter(this, void 0, void 0, function* () {
347
- const repo = this.db.getRepository('collections');
348
- if (repo) {
349
- yield repo.db2cm('roles');
350
- }
351
- });
352
- }
353
- load() {
354
- return __awaiter(this, void 0, void 0, function* () {
355
- yield this.app.db.import({
356
- directory: resolve(__dirname, 'collections'),
357
- });
358
- this.app.resourcer.use(this.acl.middleware());
359
- });
360
- }
361
- getName() {
362
- return this.getPackageName(__dirname);
363
- }
364
- }
365
- export default PluginACL;
366
- //# sourceMappingURL=server.js.map