@nocobase/acl 0.20.0-alpha.9 → 0.21.0-alpha.10
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/lib/acl-available-strategy.d.ts +3 -0
- package/lib/acl-role.d.ts +3 -0
- package/lib/acl.d.ts +49 -0
- package/lib/acl.js +76 -9
- package/package.json +4 -4
package/lib/acl-role.d.ts
CHANGED
package/lib/acl.d.ts
CHANGED
|
@@ -15,9 +15,15 @@ interface CanResult {
|
|
|
15
15
|
}
|
|
16
16
|
export interface DefineOptions {
|
|
17
17
|
role: string;
|
|
18
|
+
/**
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
18
21
|
allowConfigure?: boolean;
|
|
19
22
|
strategy?: string | AvailableStrategyOptions;
|
|
20
23
|
actions?: ResourceActionsOptions;
|
|
24
|
+
/**
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
21
27
|
routes?: any;
|
|
22
28
|
snippets?: string[];
|
|
23
29
|
}
|
|
@@ -34,14 +40,33 @@ interface CanArgs {
|
|
|
34
40
|
role: string;
|
|
35
41
|
resource: string;
|
|
36
42
|
action: string;
|
|
43
|
+
rawResourceName?: string;
|
|
37
44
|
ctx?: any;
|
|
38
45
|
}
|
|
39
46
|
export declare class ACL extends EventEmitter {
|
|
47
|
+
/**
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
40
50
|
availableStrategy: Map<string, ACLAvailableStrategy>;
|
|
51
|
+
/**
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
41
54
|
allowManager: AllowManager;
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
42
58
|
snippetManager: SnippetManager;
|
|
59
|
+
/**
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
43
62
|
roles: Map<string, ACLRole>;
|
|
63
|
+
/**
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
44
66
|
actionAlias: Map<string, string>;
|
|
67
|
+
/**
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
45
70
|
configResources: string[];
|
|
46
71
|
protected availableActions: Map<string, ACLAvailableAction>;
|
|
47
72
|
protected fixedParamsManager: FixedParamsManager;
|
|
@@ -50,8 +75,17 @@ export declare class ACL extends EventEmitter {
|
|
|
50
75
|
define(options: DefineOptions): ACLRole;
|
|
51
76
|
getRole(name: string): ACLRole;
|
|
52
77
|
removeRole(name: string): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
53
81
|
registerConfigResources(names: string[]): void;
|
|
82
|
+
/**
|
|
83
|
+
* @internal
|
|
84
|
+
*/
|
|
54
85
|
registerConfigResource(name: string): void;
|
|
86
|
+
/**
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
55
89
|
isConfigResource(name: string): boolean;
|
|
56
90
|
setAvailableAction(name: string, options?: AvailableActionOptions): void;
|
|
57
91
|
getAvailableAction(name: string): ACLAvailableAction;
|
|
@@ -59,15 +93,30 @@ export declare class ACL extends EventEmitter {
|
|
|
59
93
|
setAvailableStrategy(name: string, options: AvailableStrategyOptions): void;
|
|
60
94
|
beforeGrantAction(listener?: Listener): void;
|
|
61
95
|
can(options: CanArgs): CanResult | null;
|
|
96
|
+
/**
|
|
97
|
+
* @internal
|
|
98
|
+
*/
|
|
62
99
|
resolveActionAlias(action: string): string;
|
|
63
100
|
use(fn: any, options?: ToposortOptions): void;
|
|
64
101
|
allow(resourceName: string, actionNames: string[] | string, condition?: string | ConditionFunc): void;
|
|
102
|
+
/**
|
|
103
|
+
* @deprecated
|
|
104
|
+
*/
|
|
65
105
|
skip(resourceName: string, actionNames: string[] | string, condition?: string | ConditionFunc): void;
|
|
106
|
+
/**
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
66
109
|
parseJsonTemplate(json: any, ctx: any): Promise<any>;
|
|
67
110
|
middleware(): (ctx: any, next: any) => Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
68
114
|
getActionParams(ctx: any): Promise<void>;
|
|
69
115
|
addFixedParams(resource: string, action: string, merger: Merger): void;
|
|
70
116
|
registerSnippet(snippet: SnippetOptions): void;
|
|
117
|
+
/**
|
|
118
|
+
* @internal
|
|
119
|
+
*/
|
|
71
120
|
filterParams(ctx: any, resourceName: any, params: any): any;
|
|
72
121
|
protected addCoreMiddleware(): void;
|
|
73
122
|
protected isAvailableAction(actionName: string): boolean;
|
package/lib/acl.js
CHANGED
|
@@ -42,11 +42,29 @@ var import_allow_manager = require("./allow-manager");
|
|
|
42
42
|
var import_fixed_params_manager = __toESM(require("./fixed-params-manager"));
|
|
43
43
|
var import_snippet_manager = __toESM(require("./snippet-manager"));
|
|
44
44
|
const _ACL = class _ACL extends import_events.default {
|
|
45
|
+
/**
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
45
48
|
availableStrategy = /* @__PURE__ */ new Map();
|
|
49
|
+
/**
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
46
52
|
allowManager = new import_allow_manager.AllowManager(this);
|
|
53
|
+
/**
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
47
56
|
snippetManager = new import_snippet_manager.default();
|
|
57
|
+
/**
|
|
58
|
+
* @internal
|
|
59
|
+
*/
|
|
48
60
|
roles = /* @__PURE__ */ new Map();
|
|
61
|
+
/**
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
49
64
|
actionAlias = /* @__PURE__ */ new Map();
|
|
65
|
+
/**
|
|
66
|
+
* @internal
|
|
67
|
+
*/
|
|
50
68
|
configResources = [];
|
|
51
69
|
availableActions = /* @__PURE__ */ new Map();
|
|
52
70
|
fixedParamsManager = new import_fixed_params_manager.default();
|
|
@@ -95,12 +113,21 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
95
113
|
removeRole(name) {
|
|
96
114
|
return this.roles.delete(name);
|
|
97
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* @internal
|
|
118
|
+
*/
|
|
98
119
|
registerConfigResources(names) {
|
|
99
120
|
names.forEach((name) => this.registerConfigResource(name));
|
|
100
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
101
125
|
registerConfigResource(name) {
|
|
102
126
|
this.configResources.push(name);
|
|
103
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
104
131
|
isConfigResource(name) {
|
|
105
132
|
return this.configResources.includes(name);
|
|
106
133
|
}
|
|
@@ -127,13 +154,14 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
127
154
|
this.addListener("beforeGrantAction", listener);
|
|
128
155
|
}
|
|
129
156
|
can(options) {
|
|
130
|
-
const { role, resource, action } = options;
|
|
157
|
+
const { role, resource, action, rawResourceName } = options;
|
|
131
158
|
const aclRole = this.roles.get(role);
|
|
132
159
|
if (!aclRole) {
|
|
133
160
|
return null;
|
|
134
161
|
}
|
|
135
|
-
const
|
|
136
|
-
const
|
|
162
|
+
const actionPath = `${rawResourceName ? rawResourceName : resource}:${action}`;
|
|
163
|
+
const snippetAllowed = aclRole.snippetAllowed(actionPath);
|
|
164
|
+
const fixedParams = this.fixedParamsManager.getParams(rawResourceName ? rawResourceName : resource, action);
|
|
137
165
|
const mergeParams = /* @__PURE__ */ __name((result) => {
|
|
138
166
|
const params = result["params"] || {};
|
|
139
167
|
const mergedParams = (0, import_utils.assign)(params, fixedParams);
|
|
@@ -175,6 +203,9 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
175
203
|
}
|
|
176
204
|
return null;
|
|
177
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* @internal
|
|
208
|
+
*/
|
|
178
209
|
resolveActionAlias(action) {
|
|
179
210
|
return this.actionAlias.get(action) ? this.actionAlias.get(action) : action;
|
|
180
211
|
}
|
|
@@ -187,6 +218,9 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
187
218
|
allow(resourceName, actionNames, condition) {
|
|
188
219
|
return this.skip(resourceName, actionNames, condition);
|
|
189
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* @deprecated
|
|
223
|
+
*/
|
|
190
224
|
skip(resourceName, actionNames, condition) {
|
|
191
225
|
if (!Array.isArray(actionNames)) {
|
|
192
226
|
actionNames = [actionNames];
|
|
@@ -195,6 +229,9 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
195
229
|
this.allowManager.allow(resourceName, actionName, condition);
|
|
196
230
|
}
|
|
197
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* @internal
|
|
234
|
+
*/
|
|
198
235
|
async parseJsonTemplate(json, ctx) {
|
|
199
236
|
var _a, _b, _c, _d, _e;
|
|
200
237
|
if (json.filter) {
|
|
@@ -221,20 +258,45 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
221
258
|
const acl = this;
|
|
222
259
|
return /* @__PURE__ */ __name(async function ACLMiddleware(ctx, next) {
|
|
223
260
|
const roleName = ctx.state.currentRole || "anonymous";
|
|
224
|
-
const { resourceName, actionName } = ctx.action;
|
|
261
|
+
const { resourceName: rawResourceName, actionName } = ctx.action;
|
|
262
|
+
let resourceName = rawResourceName;
|
|
263
|
+
if (rawResourceName.includes(".")) {
|
|
264
|
+
resourceName = rawResourceName.split(".").pop();
|
|
265
|
+
}
|
|
266
|
+
if (ctx.getCurrentRepository) {
|
|
267
|
+
const currentRepository = ctx.getCurrentRepository();
|
|
268
|
+
if (currentRepository && currentRepository.targetCollection) {
|
|
269
|
+
resourceName = ctx.getCurrentRepository().targetCollection.name;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
225
272
|
ctx.can = (options) => {
|
|
226
273
|
const canResult = acl.can({ role: roleName, ...options });
|
|
227
274
|
return canResult;
|
|
228
275
|
};
|
|
229
276
|
ctx.permission = {
|
|
230
|
-
can: ctx.can({ resource: resourceName, action: actionName })
|
|
277
|
+
can: ctx.can({ resource: resourceName, action: actionName, rawResourceName }),
|
|
278
|
+
resourceName,
|
|
279
|
+
actionName
|
|
231
280
|
};
|
|
232
|
-
return (0, import_koa_compose.default)(acl.middlewares.nodes)(ctx, next);
|
|
281
|
+
return await (0, import_koa_compose.default)(acl.middlewares.nodes)(ctx, next);
|
|
233
282
|
}, "ACLMiddleware");
|
|
234
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* @internal
|
|
286
|
+
*/
|
|
235
287
|
async getActionParams(ctx) {
|
|
236
288
|
const roleName = ctx.state.currentRole || "anonymous";
|
|
237
|
-
const { resourceName, actionName } = ctx.action;
|
|
289
|
+
const { resourceName: rawResourceName, actionName } = ctx.action;
|
|
290
|
+
let resourceName = rawResourceName;
|
|
291
|
+
if (rawResourceName.includes(".")) {
|
|
292
|
+
resourceName = rawResourceName.split(".").pop();
|
|
293
|
+
}
|
|
294
|
+
if (ctx.getCurrentRepository) {
|
|
295
|
+
const currentRepository = ctx.getCurrentRepository();
|
|
296
|
+
if (currentRepository && currentRepository.targetCollection) {
|
|
297
|
+
resourceName = ctx.getCurrentRepository().targetCollection.name;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
238
300
|
ctx.can = (options) => {
|
|
239
301
|
const can = this.can({ role: roleName, ...options });
|
|
240
302
|
if (!can) {
|
|
@@ -243,7 +305,9 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
243
305
|
return import_lodash.default.cloneDeep(can);
|
|
244
306
|
};
|
|
245
307
|
ctx.permission = {
|
|
246
|
-
can: ctx.can({ resource: resourceName, action: actionName })
|
|
308
|
+
can: ctx.can({ resource: resourceName, action: actionName, rawResourceName }),
|
|
309
|
+
resourceName,
|
|
310
|
+
actionName
|
|
247
311
|
};
|
|
248
312
|
await (0, import_koa_compose.default)(this.middlewares.nodes)(ctx, async () => {
|
|
249
313
|
});
|
|
@@ -254,6 +318,9 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
254
318
|
registerSnippet(snippet) {
|
|
255
319
|
this.snippetManager.register(snippet);
|
|
256
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* @internal
|
|
323
|
+
*/
|
|
257
324
|
filterParams(ctx, resourceName, params) {
|
|
258
325
|
var _a;
|
|
259
326
|
if ((_a = params == null ? void 0 : params.filter) == null ? void 0 : _a.createdById) {
|
|
@@ -270,7 +337,7 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
270
337
|
async (ctx, next) => {
|
|
271
338
|
var _a, _b, _c, _d;
|
|
272
339
|
const resourcerAction = ctx.action;
|
|
273
|
-
const { resourceName, actionName } = ctx.
|
|
340
|
+
const { resourceName, actionName } = ctx.permission;
|
|
274
341
|
const permission = ctx.permission;
|
|
275
342
|
((_a = ctx.log) == null ? void 0 : _a.info) && ctx.log.info("ctx permission", permission);
|
|
276
343
|
if ((!permission.can || typeof permission.can !== "object") && !permission.skip) {
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/acl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0-alpha.10",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./lib/index.js",
|
|
7
7
|
"types": "./lib/index.d.ts",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@nocobase/resourcer": "0.
|
|
10
|
-
"@nocobase/utils": "0.
|
|
9
|
+
"@nocobase/resourcer": "0.21.0-alpha.10",
|
|
10
|
+
"@nocobase/utils": "0.21.0-alpha.10",
|
|
11
11
|
"minimatch": "^5.1.1"
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
16
16
|
"directory": "packages/acl"
|
|
17
17
|
},
|
|
18
|
-
"gitHead": "
|
|
18
|
+
"gitHead": "98adf5ec996a4f359c6ca1c4a6ac837c43b6e268"
|
|
19
19
|
}
|