@tachybase/acl 0.23.58 → 1.0.18
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.d.ts +6 -0
- package/lib/acl.js +51 -9
- package/package.json +3 -3
package/lib/acl.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ interface CanArgs {
|
|
|
33
33
|
role: string;
|
|
34
34
|
resource: string;
|
|
35
35
|
action: string;
|
|
36
|
+
rawResourceName?: string;
|
|
36
37
|
ctx?: any;
|
|
37
38
|
}
|
|
38
39
|
export declare class ACL extends EventEmitter {
|
|
@@ -64,7 +65,12 @@ export declare class ACL extends EventEmitter {
|
|
|
64
65
|
protected fixedParamsManager: FixedParamsManager;
|
|
65
66
|
protected middlewares: Toposort<any>;
|
|
66
67
|
middlewareSourceMap: WeakMap<Function, string>;
|
|
68
|
+
protected strategyResources: Set<string> | null;
|
|
67
69
|
constructor();
|
|
70
|
+
setStrategyResources(resources: Array<string> | null): void;
|
|
71
|
+
getStrategyResources(): string[];
|
|
72
|
+
appendStrategyResource(resource: string): void;
|
|
73
|
+
removeStrategyResource(resource: string): void;
|
|
68
74
|
define(options: DefineOptions): ACLRole;
|
|
69
75
|
getRole(name: string): ACLRole;
|
|
70
76
|
removeRole(name: string): boolean;
|
package/lib/acl.js
CHANGED
|
@@ -71,6 +71,7 @@ const _ACL = class _ACL extends import_node_events.default {
|
|
|
71
71
|
this.availableActions = /* @__PURE__ */ new Map();
|
|
72
72
|
this.fixedParamsManager = new import_fixed_params_manager.default();
|
|
73
73
|
this.middlewareSourceMap = /* @__PURE__ */ new WeakMap();
|
|
74
|
+
this.strategyResources = null;
|
|
74
75
|
this.middlewares = new import_utils.Toposort();
|
|
75
76
|
this.beforeGrantAction((ctx) => {
|
|
76
77
|
if (import_lodash.default.isPlainObject(ctx.params) && ctx.params.own) {
|
|
@@ -94,6 +95,21 @@ const _ACL = class _ACL extends import_node_events.default {
|
|
|
94
95
|
});
|
|
95
96
|
this.addCoreMiddleware();
|
|
96
97
|
}
|
|
98
|
+
setStrategyResources(resources) {
|
|
99
|
+
this.strategyResources = new Set(resources);
|
|
100
|
+
}
|
|
101
|
+
getStrategyResources() {
|
|
102
|
+
return this.strategyResources ? [...this.strategyResources] : null;
|
|
103
|
+
}
|
|
104
|
+
appendStrategyResource(resource) {
|
|
105
|
+
if (!this.strategyResources) {
|
|
106
|
+
this.strategyResources = /* @__PURE__ */ new Set();
|
|
107
|
+
}
|
|
108
|
+
this.strategyResources.add(resource);
|
|
109
|
+
}
|
|
110
|
+
removeStrategyResource(resource) {
|
|
111
|
+
this.strategyResources.delete(resource);
|
|
112
|
+
}
|
|
97
113
|
define(options) {
|
|
98
114
|
const roleName = options.role;
|
|
99
115
|
const role = new import_acl_role.ACLRole(this, roleName);
|
|
@@ -154,13 +170,14 @@ const _ACL = class _ACL extends import_node_events.default {
|
|
|
154
170
|
this.addListener("beforeGrantAction", listener);
|
|
155
171
|
}
|
|
156
172
|
can(options) {
|
|
157
|
-
const { role, resource, action } = options;
|
|
173
|
+
const { role, resource, action, rawResourceName, ctx } = options;
|
|
158
174
|
const aclRole = this.roles.get(role);
|
|
159
175
|
if (!aclRole) {
|
|
160
176
|
return null;
|
|
161
177
|
}
|
|
162
|
-
const
|
|
163
|
-
const
|
|
178
|
+
const actionPath = `${rawResourceName ? rawResourceName : resource}:${action}`;
|
|
179
|
+
const snippetAllowed = aclRole.snippetAllowed(actionPath);
|
|
180
|
+
const fixedParams = this.fixedParamsManager.getParams(rawResourceName ? rawResourceName : resource, action);
|
|
164
181
|
const mergeParams = /* @__PURE__ */ __name((result) => {
|
|
165
182
|
const params = result["params"] || {};
|
|
166
183
|
const mergedParams = (0, import_utils.assign)(params, fixedParams);
|
|
@@ -189,7 +206,10 @@ const _ACL = class _ACL extends import_node_events.default {
|
|
|
189
206
|
if (!roleStrategy && !snippetAllowed) {
|
|
190
207
|
return null;
|
|
191
208
|
}
|
|
192
|
-
let roleStrategyParams
|
|
209
|
+
let roleStrategyParams;
|
|
210
|
+
if (this.strategyResources === null || this.strategyResources.has(resource)) {
|
|
211
|
+
roleStrategyParams = roleStrategy == null ? void 0 : roleStrategy.allow(resource, this.resolveActionAlias(action));
|
|
212
|
+
}
|
|
193
213
|
if (!roleStrategyParams && snippetAllowed) {
|
|
194
214
|
roleStrategyParams = {};
|
|
195
215
|
}
|
|
@@ -258,13 +278,25 @@ const _ACL = class _ACL extends import_node_events.default {
|
|
|
258
278
|
const acl = this;
|
|
259
279
|
return /* @__PURE__ */ __name(async function ACLMiddleware(ctx, next) {
|
|
260
280
|
const roleName = ctx.state.currentRole || "anonymous";
|
|
261
|
-
const { resourceName, actionName } = ctx.action;
|
|
281
|
+
const { resourceName: rawResourceName, actionName } = ctx.action;
|
|
282
|
+
let resourceName = rawResourceName;
|
|
283
|
+
if (rawResourceName.includes(".")) {
|
|
284
|
+
resourceName = rawResourceName.split(".").pop();
|
|
285
|
+
}
|
|
286
|
+
if (ctx.getCurrentRepository) {
|
|
287
|
+
const currentRepository = ctx.getCurrentRepository();
|
|
288
|
+
if (currentRepository && currentRepository.targetCollection) {
|
|
289
|
+
resourceName = ctx.getCurrentRepository().targetCollection.name;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
262
292
|
ctx.can = (options) => {
|
|
263
|
-
const canResult = acl.can({ role: roleName, ...options });
|
|
293
|
+
const canResult = acl.can({ role: roleName, ...options, ctx });
|
|
264
294
|
return canResult;
|
|
265
295
|
};
|
|
266
296
|
ctx.permission = {
|
|
267
|
-
can: ctx.can({ resource: resourceName, action: actionName })
|
|
297
|
+
can: ctx.can({ resource: resourceName, action: actionName, rawResourceName }),
|
|
298
|
+
resourceName,
|
|
299
|
+
actionName
|
|
268
300
|
};
|
|
269
301
|
return (0, import_koa_compose.default)(acl.middlewares.nodes)(ctx, next);
|
|
270
302
|
}, "ACLMiddleware");
|
|
@@ -274,7 +306,17 @@ const _ACL = class _ACL extends import_node_events.default {
|
|
|
274
306
|
*/
|
|
275
307
|
async getActionParams(ctx) {
|
|
276
308
|
const roleName = ctx.state.currentRole || "anonymous";
|
|
277
|
-
const { resourceName, actionName } = ctx.action;
|
|
309
|
+
const { resourceName: rawResourceName, actionName } = ctx.action;
|
|
310
|
+
let resourceName = rawResourceName;
|
|
311
|
+
if (rawResourceName.includes(".")) {
|
|
312
|
+
resourceName = rawResourceName.split(".").pop();
|
|
313
|
+
}
|
|
314
|
+
if (ctx.getCurrentRepository) {
|
|
315
|
+
const currentRepository = ctx.getCurrentRepository();
|
|
316
|
+
if (currentRepository && currentRepository.targetCollection) {
|
|
317
|
+
resourceName = ctx.getCurrentRepository().targetCollection.name;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
278
320
|
ctx.can = (options) => {
|
|
279
321
|
const can = this.can({ role: roleName, ...options });
|
|
280
322
|
if (!can) {
|
|
@@ -313,7 +355,7 @@ const _ACL = class _ACL extends import_node_events.default {
|
|
|
313
355
|
async (ctx, next) => {
|
|
314
356
|
var _a, _b, _c, _d;
|
|
315
357
|
const resourcerAction = ctx.action;
|
|
316
|
-
const { resourceName, actionName } = ctx.
|
|
358
|
+
const { resourceName, actionName } = ctx.permission;
|
|
317
359
|
const permission = ctx.permission;
|
|
318
360
|
((_a = ctx.log) == null ? void 0 : _a.info) && ctx.log.info("ctx permission", permission);
|
|
319
361
|
if ((!permission.can || typeof permission.can !== "object") && !permission.skip) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tachybase/acl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.18",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"koa-compose": "^4.1.0",
|
|
10
10
|
"lodash": "4.17.21",
|
|
11
11
|
"minimatch": "^5.1.6",
|
|
12
|
-
"@tachybase/resourcer": "0.
|
|
13
|
-
"@tachybase/utils": "0.
|
|
12
|
+
"@tachybase/resourcer": "1.0.18",
|
|
13
|
+
"@tachybase/utils": "1.0.18"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@types/lodash": "4.17.13",
|