@nocobase/acl 0.7.0-alpha.0
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.
- package/LICENSE +201 -0
- package/esm/acl-available-action.d.ts +16 -0
- package/esm/acl-available-action.js +7 -0
- package/esm/acl-available-action.js.map +1 -0
- package/esm/acl-available-strategy.d.ts +29 -0
- package/esm/acl-available-strategy.js +60 -0
- package/esm/acl-available-strategy.js.map +1 -0
- package/esm/acl-resource.d.ts +25 -0
- package/esm/acl-resource.js +42 -0
- package/esm/acl-resource.js.map +1 -0
- package/esm/acl-role.d.ts +38 -0
- package/esm/acl-role.js +86 -0
- package/esm/acl-role.js.map +1 -0
- package/esm/acl.d.ts +64 -0
- package/esm/acl.js +202 -0
- package/esm/acl.js.map +1 -0
- package/esm/allow-manager.d.ts +13 -0
- package/esm/allow-manager.js +80 -0
- package/esm/allow-manager.js.map +1 -0
- package/esm/index.d.ts +6 -0
- package/esm/index.js +7 -0
- package/esm/index.js.map +1 -0
- package/esm/skip-middleware.d.ts +6 -0
- package/esm/skip-middleware.js +23 -0
- package/esm/skip-middleware.js.map +1 -0
- package/lib/acl-available-action.d.ts +16 -0
- package/lib/acl-available-action.js +11 -0
- package/lib/acl-available-action.js.map +1 -0
- package/lib/acl-available-strategy.d.ts +29 -0
- package/lib/acl-available-strategy.js +68 -0
- package/lib/acl-available-strategy.js.map +1 -0
- package/lib/acl-resource.d.ts +25 -0
- package/lib/acl-resource.js +46 -0
- package/lib/acl-resource.js.map +1 -0
- package/lib/acl-role.d.ts +38 -0
- package/lib/acl-role.js +90 -0
- package/lib/acl-role.js.map +1 -0
- package/lib/acl.d.ts +64 -0
- package/lib/acl.js +209 -0
- package/lib/acl.js.map +1 -0
- package/lib/allow-manager.d.ts +13 -0
- package/lib/allow-manager.js +84 -0
- package/lib/allow-manager.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.js +19 -0
- package/lib/index.js.map +1 -0
- package/lib/skip-middleware.d.ts +6 -0
- package/lib/skip-middleware.js +27 -0
- package/lib/skip-middleware.js.map +1 -0
- package/package.json +29 -0
- package/tsconfig.build.json +9 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ACL, DefineOptions } from './acl';
|
|
2
|
+
import { AvailableStrategyOptions } from './acl-available-strategy';
|
|
3
|
+
import { ACLResource } from './acl-resource';
|
|
4
|
+
export interface RoleActionParams {
|
|
5
|
+
fields?: string[];
|
|
6
|
+
filter?: any;
|
|
7
|
+
own?: boolean;
|
|
8
|
+
whitelist?: string[];
|
|
9
|
+
blacklist?: string[];
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
12
|
+
interface ResourceActionsOptions {
|
|
13
|
+
[actionName: string]: RoleActionParams;
|
|
14
|
+
}
|
|
15
|
+
export declare class ACLRole {
|
|
16
|
+
acl: ACL;
|
|
17
|
+
name: string;
|
|
18
|
+
strategy: string | AvailableStrategyOptions;
|
|
19
|
+
resources: Map<string, ACLResource>;
|
|
20
|
+
constructor(acl: ACL, name: string);
|
|
21
|
+
getResource(name: string): ACLResource | undefined;
|
|
22
|
+
setResource(name: string, resource: ACLResource): void;
|
|
23
|
+
setStrategy(value: string | AvailableStrategyOptions): void;
|
|
24
|
+
grantResource(resourceName: string, options: ResourceActionsOptions): void;
|
|
25
|
+
getResourceActionsParams(resourceName: string): {};
|
|
26
|
+
revokeResource(resourceName: any): void;
|
|
27
|
+
grantAction(path: string, options?: RoleActionParams): void;
|
|
28
|
+
getActionParams(path: string): RoleActionParams;
|
|
29
|
+
revokeAction(path: string): void;
|
|
30
|
+
toJSON(): DefineOptions;
|
|
31
|
+
protected getResourceActionFromPath(path: string): {
|
|
32
|
+
resourceName: string;
|
|
33
|
+
actionName: string;
|
|
34
|
+
resource: ACLResource;
|
|
35
|
+
action: any;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export {};
|
package/lib/acl-role.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ACLRole = void 0;
|
|
4
|
+
const acl_resource_1 = require("./acl-resource");
|
|
5
|
+
class ACLRole {
|
|
6
|
+
constructor(acl, name) {
|
|
7
|
+
this.acl = acl;
|
|
8
|
+
this.name = name;
|
|
9
|
+
this.resources = new Map();
|
|
10
|
+
}
|
|
11
|
+
getResource(name) {
|
|
12
|
+
return this.resources.get(name);
|
|
13
|
+
}
|
|
14
|
+
setResource(name, resource) {
|
|
15
|
+
this.resources.set(name, resource);
|
|
16
|
+
}
|
|
17
|
+
setStrategy(value) {
|
|
18
|
+
this.strategy = value;
|
|
19
|
+
}
|
|
20
|
+
grantResource(resourceName, options) {
|
|
21
|
+
const resource = new acl_resource_1.ACLResource({
|
|
22
|
+
role: this,
|
|
23
|
+
name: resourceName,
|
|
24
|
+
});
|
|
25
|
+
for (const [actionName, actionParams] of Object.entries(options)) {
|
|
26
|
+
resource.setAction(actionName, actionParams);
|
|
27
|
+
}
|
|
28
|
+
this.resources.set(resourceName, resource);
|
|
29
|
+
}
|
|
30
|
+
getResourceActionsParams(resourceName) {
|
|
31
|
+
const resource = this.getResource(resourceName);
|
|
32
|
+
return resource.getActions();
|
|
33
|
+
}
|
|
34
|
+
revokeResource(resourceName) {
|
|
35
|
+
for (const key of [...this.resources.keys()]) {
|
|
36
|
+
if (key === resourceName || key.includes(`${resourceName}.`)) {
|
|
37
|
+
this.resources.delete(key);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
grantAction(path, options) {
|
|
42
|
+
let { resource, resourceName, actionName } = this.getResourceActionFromPath(path);
|
|
43
|
+
if (!resource) {
|
|
44
|
+
resource = new acl_resource_1.ACLResource({
|
|
45
|
+
role: this,
|
|
46
|
+
name: resourceName,
|
|
47
|
+
});
|
|
48
|
+
this.resources.set(resourceName, resource);
|
|
49
|
+
}
|
|
50
|
+
resource.setAction(actionName, options);
|
|
51
|
+
}
|
|
52
|
+
getActionParams(path) {
|
|
53
|
+
const { action } = this.getResourceActionFromPath(path);
|
|
54
|
+
return action;
|
|
55
|
+
}
|
|
56
|
+
revokeAction(path) {
|
|
57
|
+
const { resource, actionName } = this.getResourceActionFromPath(path);
|
|
58
|
+
resource.removeAction(actionName);
|
|
59
|
+
}
|
|
60
|
+
toJSON() {
|
|
61
|
+
const actions = {};
|
|
62
|
+
for (const resourceName of this.resources.keys()) {
|
|
63
|
+
const resourceActions = this.getResourceActionsParams(resourceName);
|
|
64
|
+
for (const actionName of Object.keys(resourceActions)) {
|
|
65
|
+
actions[`${resourceName}:${actionName}`] = resourceActions[actionName];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
role: this.name,
|
|
70
|
+
strategy: this.strategy,
|
|
71
|
+
actions,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
getResourceActionFromPath(path) {
|
|
75
|
+
const [resourceName, actionName] = path.split(':');
|
|
76
|
+
const resource = this.resources.get(resourceName);
|
|
77
|
+
let action = null;
|
|
78
|
+
if (resource) {
|
|
79
|
+
action = resource.getAction(actionName);
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
resourceName,
|
|
83
|
+
actionName,
|
|
84
|
+
resource,
|
|
85
|
+
action,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.ACLRole = ACLRole;
|
|
90
|
+
//# sourceMappingURL=acl-role.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acl-role.js","sourceRoot":"","sources":["../src/acl-role.ts"],"names":[],"mappings":"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","sourcesContent":["import { ACL, DefineOptions } from './acl';\nimport { AvailableStrategyOptions } from './acl-available-strategy';\nimport { ACLResource } from './acl-resource';\n\nexport interface RoleActionParams {\n fields?: string[];\n filter?: any;\n own?: boolean;\n whitelist?: string[];\n blacklist?: string[];\n [key: string]: any;\n}\n\ninterface ResourceActionsOptions {\n [actionName: string]: RoleActionParams;\n}\n\nexport class ACLRole {\n strategy: string | AvailableStrategyOptions;\n resources = new Map<string, ACLResource>();\n\n constructor(public acl: ACL, public name: string) {}\n\n getResource(name: string): ACLResource | undefined {\n return this.resources.get(name);\n }\n\n setResource(name: string, resource: ACLResource) {\n this.resources.set(name, resource);\n }\n\n public setStrategy(value: string | AvailableStrategyOptions) {\n this.strategy = value;\n }\n\n public grantResource(resourceName: string, options: ResourceActionsOptions) {\n const resource = new ACLResource({\n role: this,\n name: resourceName,\n });\n\n for (const [actionName, actionParams] of Object.entries(options)) {\n resource.setAction(actionName, actionParams);\n }\n\n this.resources.set(resourceName, resource);\n }\n\n public getResourceActionsParams(resourceName: string) {\n const resource = this.getResource(resourceName);\n return resource.getActions();\n }\n\n public revokeResource(resourceName) {\n for (const key of [...this.resources.keys()]) {\n if (key === resourceName || key.includes(`${resourceName}.`)) {\n this.resources.delete(key);\n }\n }\n }\n\n public grantAction(path: string, options?: RoleActionParams) {\n let { resource, resourceName, actionName } = this.getResourceActionFromPath(path);\n\n if (!resource) {\n resource = new ACLResource({\n role: this,\n name: resourceName,\n });\n\n this.resources.set(resourceName, resource);\n }\n\n resource.setAction(actionName, options);\n }\n\n public getActionParams(path: string): RoleActionParams {\n const { action } = this.getResourceActionFromPath(path);\n return action;\n }\n\n public revokeAction(path: string) {\n const { resource, actionName } = this.getResourceActionFromPath(path);\n resource.removeAction(actionName);\n }\n\n public toJSON(): DefineOptions {\n const actions = {};\n\n for (const resourceName of this.resources.keys()) {\n const resourceActions = this.getResourceActionsParams(resourceName);\n for (const actionName of Object.keys(resourceActions)) {\n actions[`${resourceName}:${actionName}`] = resourceActions[actionName];\n }\n }\n\n return {\n role: this.name,\n strategy: this.strategy,\n actions,\n };\n }\n\n protected getResourceActionFromPath(path: string) {\n const [resourceName, actionName] = path.split(':');\n\n const resource = this.resources.get(resourceName);\n\n let action = null;\n if (resource) {\n action = resource.getAction(actionName);\n }\n\n return {\n resourceName,\n actionName,\n resource,\n action,\n };\n }\n}\n"]}
|
package/lib/acl.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import EventEmitter from 'events';
|
|
3
|
+
import { AclAvailableAction, AvailableActionOptions } from './acl-available-action';
|
|
4
|
+
import { ACLAvailableStrategy, AvailableStrategyOptions } from './acl-available-strategy';
|
|
5
|
+
import { ACLRole, RoleActionParams } from './acl-role';
|
|
6
|
+
import { AllowManager } from './allow-manager';
|
|
7
|
+
interface CanResult {
|
|
8
|
+
role: string;
|
|
9
|
+
resource: string;
|
|
10
|
+
action: string;
|
|
11
|
+
params?: any;
|
|
12
|
+
}
|
|
13
|
+
export interface DefineOptions {
|
|
14
|
+
role: string;
|
|
15
|
+
allowConfigure?: boolean;
|
|
16
|
+
strategy?: string | Omit<AvailableStrategyOptions, 'acl'>;
|
|
17
|
+
actions?: {
|
|
18
|
+
[key: string]: RoleActionParams;
|
|
19
|
+
};
|
|
20
|
+
routes?: any;
|
|
21
|
+
}
|
|
22
|
+
export interface ListenerContext {
|
|
23
|
+
acl: ACL;
|
|
24
|
+
role: ACLRole;
|
|
25
|
+
path: string;
|
|
26
|
+
actionName: string;
|
|
27
|
+
resourceName: string;
|
|
28
|
+
params: RoleActionParams;
|
|
29
|
+
}
|
|
30
|
+
declare type Listener = (ctx: ListenerContext) => void;
|
|
31
|
+
interface CanArgs {
|
|
32
|
+
role: string;
|
|
33
|
+
resource: string;
|
|
34
|
+
action: string;
|
|
35
|
+
}
|
|
36
|
+
export declare class ACL extends EventEmitter {
|
|
37
|
+
protected availableActions: Map<string, AclAvailableAction>;
|
|
38
|
+
protected availableStrategy: Map<string, ACLAvailableStrategy>;
|
|
39
|
+
protected middlewares: any[];
|
|
40
|
+
allowManager: AllowManager;
|
|
41
|
+
roles: Map<string, ACLRole>;
|
|
42
|
+
actionAlias: Map<string, string>;
|
|
43
|
+
configResources: string[];
|
|
44
|
+
constructor();
|
|
45
|
+
define(options: DefineOptions): ACLRole;
|
|
46
|
+
getRole(name: string): ACLRole;
|
|
47
|
+
removeRole(name: string): boolean;
|
|
48
|
+
registerConfigResources(names: string[]): void;
|
|
49
|
+
registerConfigResource(name: string): void;
|
|
50
|
+
isConfigResource(name: string): boolean;
|
|
51
|
+
setAvailableAction(name: string, options: AvailableActionOptions): void;
|
|
52
|
+
getAvailableAction(name: string): AclAvailableAction;
|
|
53
|
+
getAvailableActions(): Map<string, AclAvailableAction>;
|
|
54
|
+
setAvailableStrategy(name: string, options: Omit<AvailableStrategyOptions, 'acl'>): void;
|
|
55
|
+
beforeGrantAction(listener?: Listener): void;
|
|
56
|
+
can({ role, resource, action }: CanArgs): CanResult | null;
|
|
57
|
+
protected isAvailableAction(actionName: string): boolean;
|
|
58
|
+
resolveActionAlias(action: string): string;
|
|
59
|
+
use(fn: any): void;
|
|
60
|
+
allow(resourceName: string, actionNames: string[] | string, condition?: any): void;
|
|
61
|
+
parseJsonTemplate(json: any, ctx: any): any;
|
|
62
|
+
middleware(): (ctx: any, next: any) => Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
export {};
|
package/lib/acl.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ACL = void 0;
|
|
16
|
+
const events_1 = __importDefault(require("events"));
|
|
17
|
+
const koa_compose_1 = __importDefault(require("koa-compose"));
|
|
18
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
19
|
+
const acl_available_action_1 = require("./acl-available-action");
|
|
20
|
+
const acl_available_strategy_1 = require("./acl-available-strategy");
|
|
21
|
+
const acl_role_1 = require("./acl-role");
|
|
22
|
+
const allow_manager_1 = require("./allow-manager");
|
|
23
|
+
const parse = require('json-templates');
|
|
24
|
+
class ACL extends events_1.default {
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
this.availableActions = new Map();
|
|
28
|
+
this.availableStrategy = new Map();
|
|
29
|
+
this.middlewares = [];
|
|
30
|
+
this.allowManager = new allow_manager_1.AllowManager(this);
|
|
31
|
+
this.roles = new Map();
|
|
32
|
+
this.actionAlias = new Map();
|
|
33
|
+
this.configResources = [];
|
|
34
|
+
this.beforeGrantAction((ctx) => {
|
|
35
|
+
if (lodash_1.default.isPlainObject(ctx.params) && ctx.params.own) {
|
|
36
|
+
ctx.params = lodash_1.default.merge(ctx.params, acl_available_strategy_1.predicate.own);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
this.beforeGrantAction((ctx) => {
|
|
40
|
+
const actionName = this.resolveActionAlias(ctx.actionName);
|
|
41
|
+
if (lodash_1.default.isPlainObject(ctx.params)) {
|
|
42
|
+
if ((actionName === 'create' || actionName === 'update') && ctx.params.fields) {
|
|
43
|
+
ctx.params = Object.assign(Object.assign({}, lodash_1.default.omit(ctx.params, 'fields')), { whitelist: ctx.params.fields });
|
|
44
|
+
}
|
|
45
|
+
if (actionName === 'view' && ctx.params.fields) {
|
|
46
|
+
const appendFields = ['id', 'createdAt', 'updatedAt'];
|
|
47
|
+
ctx.params = Object.assign(Object.assign({}, lodash_1.default.omit(ctx.params, 'fields')), { fields: [...ctx.params.fields, ...appendFields] });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
this.middlewares.push(this.allowManager.aclMiddleware());
|
|
52
|
+
}
|
|
53
|
+
define(options) {
|
|
54
|
+
const roleName = options.role;
|
|
55
|
+
const role = new acl_role_1.ACLRole(this, roleName);
|
|
56
|
+
if (options.strategy) {
|
|
57
|
+
role.strategy = options.strategy;
|
|
58
|
+
}
|
|
59
|
+
const actions = options.actions || {};
|
|
60
|
+
for (const [actionName, actionParams] of Object.entries(actions)) {
|
|
61
|
+
role.grantAction(actionName, actionParams);
|
|
62
|
+
}
|
|
63
|
+
this.roles.set(roleName, role);
|
|
64
|
+
return role;
|
|
65
|
+
}
|
|
66
|
+
getRole(name) {
|
|
67
|
+
return this.roles.get(name);
|
|
68
|
+
}
|
|
69
|
+
removeRole(name) {
|
|
70
|
+
return this.roles.delete(name);
|
|
71
|
+
}
|
|
72
|
+
registerConfigResources(names) {
|
|
73
|
+
names.forEach((name) => this.registerConfigResource(name));
|
|
74
|
+
}
|
|
75
|
+
registerConfigResource(name) {
|
|
76
|
+
this.configResources.push(name);
|
|
77
|
+
}
|
|
78
|
+
isConfigResource(name) {
|
|
79
|
+
return this.configResources.includes(name);
|
|
80
|
+
}
|
|
81
|
+
setAvailableAction(name, options) {
|
|
82
|
+
this.availableActions.set(name, new acl_available_action_1.AclAvailableAction(name, options));
|
|
83
|
+
if (options.aliases) {
|
|
84
|
+
const aliases = lodash_1.default.isArray(options.aliases) ? options.aliases : [options.aliases];
|
|
85
|
+
for (const alias of aliases) {
|
|
86
|
+
this.actionAlias.set(alias, name);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
getAvailableAction(name) {
|
|
91
|
+
const actionName = this.actionAlias.get(name) || name;
|
|
92
|
+
return this.availableActions.get(actionName);
|
|
93
|
+
}
|
|
94
|
+
getAvailableActions() {
|
|
95
|
+
return this.availableActions;
|
|
96
|
+
}
|
|
97
|
+
setAvailableStrategy(name, options) {
|
|
98
|
+
this.availableStrategy.set(name, new acl_available_strategy_1.ACLAvailableStrategy(this, options));
|
|
99
|
+
}
|
|
100
|
+
beforeGrantAction(listener) {
|
|
101
|
+
this.addListener('beforeGrantAction', listener);
|
|
102
|
+
}
|
|
103
|
+
can({ role, resource, action }) {
|
|
104
|
+
const aclRole = this.roles.get(role);
|
|
105
|
+
if (!aclRole) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const aclResource = aclRole.getResource(resource);
|
|
109
|
+
if (aclResource) {
|
|
110
|
+
const actionParams = aclResource.getAction(action);
|
|
111
|
+
if (actionParams) {
|
|
112
|
+
// handle single action config
|
|
113
|
+
return {
|
|
114
|
+
role,
|
|
115
|
+
resource,
|
|
116
|
+
action,
|
|
117
|
+
params: actionParams,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (!aclRole.strategy) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const roleStrategy = lodash_1.default.isString(aclRole.strategy)
|
|
125
|
+
? this.availableStrategy.get(aclRole.strategy)
|
|
126
|
+
: new acl_available_strategy_1.ACLAvailableStrategy(this, aclRole.strategy);
|
|
127
|
+
if (!roleStrategy) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const roleStrategyParams = roleStrategy.allow(resource, this.resolveActionAlias(action));
|
|
131
|
+
if (roleStrategyParams) {
|
|
132
|
+
const result = { role, resource, action };
|
|
133
|
+
if (lodash_1.default.isPlainObject(roleStrategyParams)) {
|
|
134
|
+
result['params'] = roleStrategyParams;
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
isAvailableAction(actionName) {
|
|
141
|
+
return this.availableActions.has(this.resolveActionAlias(actionName));
|
|
142
|
+
}
|
|
143
|
+
resolveActionAlias(action) {
|
|
144
|
+
return this.actionAlias.get(action) ? this.actionAlias.get(action) : action;
|
|
145
|
+
}
|
|
146
|
+
use(fn) {
|
|
147
|
+
this.middlewares.push(fn);
|
|
148
|
+
}
|
|
149
|
+
allow(resourceName, actionNames, condition) {
|
|
150
|
+
if (!Array.isArray(actionNames)) {
|
|
151
|
+
actionNames = [actionNames];
|
|
152
|
+
}
|
|
153
|
+
for (const actionName of actionNames) {
|
|
154
|
+
this.allowManager.allow(resourceName, actionName, condition);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
parseJsonTemplate(json, ctx) {
|
|
158
|
+
return parse(json)({
|
|
159
|
+
ctx: {
|
|
160
|
+
state: JSON.parse(JSON.stringify(ctx.state)),
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
middleware() {
|
|
165
|
+
const acl = this;
|
|
166
|
+
const filterParams = (ctx, resourceName, params) => {
|
|
167
|
+
var _a;
|
|
168
|
+
if ((_a = params === null || params === void 0 ? void 0 : params.filter) === null || _a === void 0 ? void 0 : _a.createdById) {
|
|
169
|
+
const collection = ctx.db.getCollection(resourceName);
|
|
170
|
+
if (collection && !collection.getField('createdById')) {
|
|
171
|
+
return lodash_1.default.omit(params, 'filter.createdById');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return params;
|
|
175
|
+
};
|
|
176
|
+
return function ACLMiddleware(ctx, next) {
|
|
177
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
178
|
+
const roleName = ctx.state.currentRole || 'anonymous';
|
|
179
|
+
const { resourceName, actionName } = ctx.action;
|
|
180
|
+
const resourcerAction = ctx.action;
|
|
181
|
+
ctx.can = (options) => {
|
|
182
|
+
return acl.can(Object.assign({ role: roleName }, options));
|
|
183
|
+
};
|
|
184
|
+
ctx.permission = {
|
|
185
|
+
can: ctx.can({ resource: resourceName, action: actionName }),
|
|
186
|
+
};
|
|
187
|
+
return (0, koa_compose_1.default)(acl.middlewares)(ctx, () => __awaiter(this, void 0, void 0, function* () {
|
|
188
|
+
const permission = ctx.permission;
|
|
189
|
+
if (permission.skip) {
|
|
190
|
+
return next();
|
|
191
|
+
}
|
|
192
|
+
if (!permission.can || typeof permission.can !== 'object') {
|
|
193
|
+
ctx.throw(403, 'No permissions');
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
const { params } = permission.can;
|
|
197
|
+
if (params) {
|
|
198
|
+
const filteredParams = filterParams(ctx, resourceName, params);
|
|
199
|
+
const parsedParams = acl.parseJsonTemplate(filteredParams, ctx);
|
|
200
|
+
resourcerAction.mergeParams(parsedParams);
|
|
201
|
+
}
|
|
202
|
+
yield next();
|
|
203
|
+
}));
|
|
204
|
+
});
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
exports.ACL = ACL;
|
|
209
|
+
//# sourceMappingURL=acl.js.map
|
package/lib/acl.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acl.js","sourceRoot":"","sources":["../src/acl.ts"],"names":[],"mappings":"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","sourcesContent":["import { Action } from '@nocobase/resourcer';\nimport EventEmitter from 'events';\nimport compose from 'koa-compose';\nimport lodash from 'lodash';\nimport { AclAvailableAction, AvailableActionOptions } from './acl-available-action';\nimport { ACLAvailableStrategy, AvailableStrategyOptions, predicate } from './acl-available-strategy';\nimport { ACLRole, RoleActionParams } from './acl-role';\nimport { AllowManager } from './allow-manager';\nconst parse = require('json-templates');\n\ninterface CanResult {\n role: string;\n resource: string;\n action: string;\n params?: any;\n}\n\nexport interface DefineOptions {\n role: string;\n allowConfigure?: boolean;\n strategy?: string | Omit<AvailableStrategyOptions, 'acl'>;\n actions?: {\n [key: string]: RoleActionParams;\n };\n routes?: any;\n}\n\nexport interface ListenerContext {\n acl: ACL;\n role: ACLRole;\n path: string;\n actionName: string;\n resourceName: string;\n params: RoleActionParams;\n}\n\ntype Listener = (ctx: ListenerContext) => void;\n\ninterface CanArgs {\n role: string;\n resource: string;\n action: string;\n}\n\nexport class ACL extends EventEmitter {\n protected availableActions = new Map<string, AclAvailableAction>();\n protected availableStrategy = new Map<string, ACLAvailableStrategy>();\n protected middlewares = [];\n\n public allowManager = new AllowManager(this);\n\n roles = new Map<string, ACLRole>();\n\n actionAlias = new Map<string, string>();\n\n configResources: string[] = [];\n\n constructor() {\n super();\n\n this.beforeGrantAction((ctx) => {\n if (lodash.isPlainObject(ctx.params) && ctx.params.own) {\n ctx.params = lodash.merge(ctx.params, predicate.own);\n }\n });\n\n this.beforeGrantAction((ctx) => {\n const actionName = this.resolveActionAlias(ctx.actionName);\n\n if (lodash.isPlainObject(ctx.params)) {\n if ((actionName === 'create' || actionName === 'update') && ctx.params.fields) {\n ctx.params = {\n ...lodash.omit(ctx.params, 'fields'),\n whitelist: ctx.params.fields,\n };\n }\n\n if (actionName === 'view' && ctx.params.fields) {\n const appendFields = ['id', 'createdAt', 'updatedAt'];\n ctx.params = {\n ...lodash.omit(ctx.params, 'fields'),\n fields: [...ctx.params.fields, ...appendFields],\n };\n }\n }\n });\n\n this.middlewares.push(this.allowManager.aclMiddleware());\n }\n\n define(options: DefineOptions): ACLRole {\n const roleName = options.role;\n const role = new ACLRole(this, roleName);\n\n if (options.strategy) {\n role.strategy = options.strategy;\n }\n\n const actions = options.actions || {};\n\n for (const [actionName, actionParams] of Object.entries(actions)) {\n role.grantAction(actionName, actionParams);\n }\n\n this.roles.set(roleName, role);\n\n return role;\n }\n\n getRole(name: string): ACLRole {\n return this.roles.get(name);\n }\n\n removeRole(name: string) {\n return this.roles.delete(name);\n }\n\n registerConfigResources(names: string[]) {\n names.forEach((name) => this.registerConfigResource(name));\n }\n\n registerConfigResource(name: string) {\n this.configResources.push(name);\n }\n\n isConfigResource(name: string) {\n return this.configResources.includes(name);\n }\n\n setAvailableAction(name: string, options: AvailableActionOptions) {\n this.availableActions.set(name, new AclAvailableAction(name, options));\n\n if (options.aliases) {\n const aliases = lodash.isArray(options.aliases) ? options.aliases : [options.aliases];\n for (const alias of aliases) {\n this.actionAlias.set(alias, name);\n }\n }\n }\n\n getAvailableAction(name: string) {\n const actionName = this.actionAlias.get(name) || name;\n return this.availableActions.get(actionName);\n }\n\n getAvailableActions() {\n return this.availableActions;\n }\n\n setAvailableStrategy(name: string, options: Omit<AvailableStrategyOptions, 'acl'>) {\n this.availableStrategy.set(name, new ACLAvailableStrategy(this, options));\n }\n\n beforeGrantAction(listener?: Listener) {\n this.addListener('beforeGrantAction', listener);\n }\n\n can({ role, resource, action }: CanArgs): CanResult | null {\n const aclRole = this.roles.get(role);\n\n if (!aclRole) {\n return null;\n }\n\n const aclResource = aclRole.getResource(resource);\n\n if (aclResource) {\n const actionParams = aclResource.getAction(action);\n\n if (actionParams) {\n // handle single action config\n return {\n role,\n resource,\n action,\n params: actionParams,\n };\n }\n }\n\n if (!aclRole.strategy) {\n return null;\n }\n\n const roleStrategy = lodash.isString(aclRole.strategy)\n ? this.availableStrategy.get(aclRole.strategy)\n : new ACLAvailableStrategy(this, aclRole.strategy);\n\n if (!roleStrategy) {\n return null;\n }\n\n const roleStrategyParams = roleStrategy.allow(resource, this.resolveActionAlias(action));\n\n if (roleStrategyParams) {\n const result = { role, resource, action };\n\n if (lodash.isPlainObject(roleStrategyParams)) {\n result['params'] = roleStrategyParams;\n }\n\n return result;\n }\n\n return null;\n }\n\n protected isAvailableAction(actionName: string) {\n return this.availableActions.has(this.resolveActionAlias(actionName));\n }\n\n public resolveActionAlias(action: string) {\n return this.actionAlias.get(action) ? this.actionAlias.get(action) : action;\n }\n\n use(fn: any) {\n this.middlewares.push(fn);\n }\n\n allow(resourceName: string, actionNames: string[] | string, condition?: any) {\n if (!Array.isArray(actionNames)) {\n actionNames = [actionNames];\n }\n\n for (const actionName of actionNames) {\n this.allowManager.allow(resourceName, actionName, condition);\n }\n }\n\n parseJsonTemplate(json: any, ctx: any) {\n return parse(json)({\n ctx: {\n state: JSON.parse(JSON.stringify(ctx.state)),\n },\n });\n }\n\n middleware() {\n const acl = this;\n\n const filterParams = (ctx, resourceName, params) => {\n if (params?.filter?.createdById) {\n const collection = ctx.db.getCollection(resourceName);\n if (collection && !collection.getField('createdById')) {\n return lodash.omit(params, 'filter.createdById');\n }\n }\n\n return params;\n };\n\n return async function ACLMiddleware(ctx, next) {\n const roleName = ctx.state.currentRole || 'anonymous';\n const { resourceName, actionName } = ctx.action;\n\n const resourcerAction: Action = ctx.action;\n\n ctx.can = (options: Omit<CanArgs, 'role'>) => {\n return acl.can({ role: roleName, ...options });\n };\n\n ctx.permission = {\n can: ctx.can({ resource: resourceName, action: actionName }),\n };\n\n return compose(acl.middlewares)(ctx, async () => {\n const permission = ctx.permission;\n\n if (permission.skip) {\n return next();\n }\n\n if (!permission.can || typeof permission.can !== 'object') {\n ctx.throw(403, 'No permissions');\n return;\n }\n\n const { params } = permission.can;\n\n if (params) {\n const filteredParams = filterParams(ctx, resourceName, params);\n const parsedParams = acl.parseJsonTemplate(filteredParams, ctx);\n resourcerAction.mergeParams(parsedParams);\n }\n\n await next();\n });\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ACL } from './acl';
|
|
2
|
+
declare type ConditionFunc = (ctx: any) => Promise<boolean>;
|
|
3
|
+
export declare class AllowManager {
|
|
4
|
+
acl: ACL;
|
|
5
|
+
protected skipActions: Map<string, Map<string, string | true | ConditionFunc>>;
|
|
6
|
+
protected registeredCondition: Map<string, ConditionFunc>;
|
|
7
|
+
constructor(acl: ACL);
|
|
8
|
+
allow(resourceName: string, actionName: string, condition?: string | ConditionFunc): void;
|
|
9
|
+
getAllowedConditions(resourceName: string, actionName: string): Array<ConditionFunc | true>;
|
|
10
|
+
registerAllowCondition(name: string, condition: ConditionFunc): void;
|
|
11
|
+
aclMiddleware(): (ctx: any, next: any) => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
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.AllowManager = void 0;
|
|
13
|
+
class AllowManager {
|
|
14
|
+
constructor(acl) {
|
|
15
|
+
this.acl = acl;
|
|
16
|
+
this.skipActions = new Map();
|
|
17
|
+
this.registeredCondition = new Map();
|
|
18
|
+
this.registerAllowCondition('loggedIn', (ctx) => {
|
|
19
|
+
return ctx.state.currentUser;
|
|
20
|
+
});
|
|
21
|
+
this.registerAllowCondition('allowConfigure', (ctx) => __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const roleName = ctx.state.currentRole;
|
|
23
|
+
if (!roleName) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const roleInstance = yield ctx.db.getRepository('roles').findOne({
|
|
27
|
+
name: roleName,
|
|
28
|
+
});
|
|
29
|
+
return roleInstance === null || roleInstance === void 0 ? void 0 : roleInstance.get('allowConfigure');
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
allow(resourceName, actionName, condition) {
|
|
33
|
+
const actionMap = this.skipActions.get(resourceName) || new Map();
|
|
34
|
+
actionMap.set(actionName, condition || true);
|
|
35
|
+
this.skipActions.set(resourceName, actionMap);
|
|
36
|
+
}
|
|
37
|
+
getAllowedConditions(resourceName, actionName) {
|
|
38
|
+
const fetchActionSteps = ['*', resourceName];
|
|
39
|
+
const results = [];
|
|
40
|
+
for (const fetchActionStep of fetchActionSteps) {
|
|
41
|
+
const resource = this.skipActions.get(fetchActionStep);
|
|
42
|
+
if (resource) {
|
|
43
|
+
const condition = resource.get('*') || resource.get(actionName);
|
|
44
|
+
if (condition) {
|
|
45
|
+
results.push(typeof condition === 'string' ? this.registeredCondition.get(condition) : condition);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return results;
|
|
50
|
+
}
|
|
51
|
+
registerAllowCondition(name, condition) {
|
|
52
|
+
this.registeredCondition.set(name, condition);
|
|
53
|
+
}
|
|
54
|
+
aclMiddleware() {
|
|
55
|
+
return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const { resourceName, actionName } = ctx.action;
|
|
57
|
+
const skippedConditions = ctx.app.acl.allowManager.getAllowedConditions(resourceName, actionName);
|
|
58
|
+
let skip = false;
|
|
59
|
+
for (const skippedCondition of skippedConditions) {
|
|
60
|
+
if (skippedCondition) {
|
|
61
|
+
let skipResult = false;
|
|
62
|
+
if (typeof skippedCondition === 'function') {
|
|
63
|
+
skipResult = yield skippedCondition(ctx);
|
|
64
|
+
}
|
|
65
|
+
else if (skippedCondition) {
|
|
66
|
+
skipResult = true;
|
|
67
|
+
}
|
|
68
|
+
if (skipResult) {
|
|
69
|
+
skip = true;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (skip) {
|
|
75
|
+
ctx.permission = {
|
|
76
|
+
skip: true,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
yield next();
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.AllowManager = AllowManager;
|
|
84
|
+
//# sourceMappingURL=allow-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allow-manager.js","sourceRoot":"","sources":["../src/allow-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { ACL } from './acl';\n\ntype ConditionFunc = (ctx: any) => Promise<boolean>;\n\nexport class AllowManager {\n protected skipActions = new Map<string, Map<string, string | ConditionFunc | true>>();\n\n protected registeredCondition = new Map<string, ConditionFunc>();\n\n constructor(public acl: ACL) {\n this.registerAllowCondition('loggedIn', (ctx) => {\n return ctx.state.currentUser;\n });\n\n this.registerAllowCondition('allowConfigure', async (ctx) => {\n const roleName = ctx.state.currentRole;\n if (!roleName) {\n return false;\n }\n\n const roleInstance = await ctx.db.getRepository('roles').findOne({\n name: roleName,\n });\n\n return roleInstance?.get('allowConfigure');\n });\n }\n\n allow(resourceName: string, actionName: string, condition?: string | ConditionFunc) {\n const actionMap = this.skipActions.get(resourceName) || new Map<string, string | ConditionFunc>();\n actionMap.set(actionName, condition || true);\n\n this.skipActions.set(resourceName, actionMap);\n }\n\n getAllowedConditions(resourceName: string, actionName: string): Array<ConditionFunc | true> {\n const fetchActionSteps: string[] = ['*', resourceName];\n\n const results = [];\n\n for (const fetchActionStep of fetchActionSteps) {\n const resource = this.skipActions.get(fetchActionStep);\n if (resource) {\n const condition = resource.get('*') || resource.get(actionName);\n if (condition) {\n results.push(typeof condition === 'string' ? this.registeredCondition.get(condition) : condition);\n }\n }\n }\n\n return results;\n }\n\n registerAllowCondition(name: string, condition: ConditionFunc) {\n this.registeredCondition.set(name, condition);\n }\n\n aclMiddleware() {\n return async (ctx, next) => {\n const { resourceName, actionName } = ctx.action;\n const skippedConditions = ctx.app.acl.allowManager.getAllowedConditions(resourceName, actionName);\n let skip = false;\n\n for (const skippedCondition of skippedConditions) {\n if (skippedCondition) {\n let skipResult = false;\n\n if (typeof skippedCondition === 'function') {\n skipResult = await skippedCondition(ctx);\n } else if (skippedCondition) {\n skipResult = true;\n }\n\n if (skipResult) {\n skip = true;\n break;\n }\n }\n }\n\n if (skip) {\n ctx.permission = {\n skip: true,\n };\n }\n await next();\n };\n }\n}\n"]}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./acl"), exports);
|
|
14
|
+
__exportStar(require("./acl-available-action"), exports);
|
|
15
|
+
__exportStar(require("./acl-available-strategy"), exports);
|
|
16
|
+
__exportStar(require("./acl-resource"), exports);
|
|
17
|
+
__exportStar(require("./acl-role"), exports);
|
|
18
|
+
__exportStar(require("./skip-middleware"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,wCAAsB;AACtB,yDAAuC;AACvC,2DAAyC;AACzC,iDAA+B;AAC/B,6CAA2B;AAC3B,oDAAkC","sourcesContent":["export * from './acl';\nexport * from './acl-available-action';\nexport * from './acl-available-strategy';\nexport * from './acl-resource';\nexport * from './acl-role';\nexport * from './skip-middleware';\n\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
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.skip = void 0;
|
|
13
|
+
const skip = (options) => {
|
|
14
|
+
return function ACLSkipMiddleware(ctx, next) {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
const { resourceName, actionName } = ctx.action;
|
|
17
|
+
if (resourceName === options.resourceName && actionName === options.actionName) {
|
|
18
|
+
ctx.permission = {
|
|
19
|
+
skip: true,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
yield next();
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
exports.skip = skip;
|
|
27
|
+
//# sourceMappingURL=skip-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skip-middleware.js","sourceRoot":"","sources":["../src/skip-middleware.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAO,MAAM,IAAI,GAAG,CAAC,OAAuB,EAAE,EAAE;IAC9C,OAAO,SAAe,iBAAiB,CAAC,GAAG,EAAE,IAAI;;YAC/C,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;YAChD,IAAI,YAAY,KAAK,OAAO,CAAC,YAAY,IAAI,UAAU,KAAK,OAAO,CAAC,UAAU,EAAE;gBAC9E,GAAG,CAAC,UAAU,GAAG;oBACf,IAAI,EAAE,IAAI;iBACX,CAAC;aACH;YACD,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;KAAA,CAAC;AACJ,CAAC,CAAC;AAVW,QAAA,IAAI,QAUf","sourcesContent":["export const skip = (options: ACLSkipOptions) => {\n return async function ACLSkipMiddleware(ctx, next) {\n const { resourceName, actionName } = ctx.action;\n if (resourceName === options.resourceName && actionName === options.actionName) {\n ctx.permission = {\n skip: true,\n };\n }\n await next();\n };\n};\n\ninterface ACLSkipOptions {\n resourceName: string;\n actionName: string;\n}\n"]}
|