@nocobase/acl 2.0.0-alpha.7 → 2.0.0-alpha.71
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 +3 -2
- package/lib/acl.js +19 -3
- package/lib/allow-manager.d.ts +2 -0
- package/lib/allow-manager.js +13 -3
- package/lib/fixed-params-manager.d.ts +3 -0
- package/lib/fixed-params-manager.js +7 -0
- package/lib/snippet-manager.js +6 -1
- package/package.json +4 -4
package/lib/acl.d.ts
CHANGED
|
@@ -13,9 +13,9 @@ import { ACLAvailableAction, AvailableActionOptions } from './acl-available-acti
|
|
|
13
13
|
import { ACLAvailableStrategy, AvailableStrategyOptions } from './acl-available-strategy';
|
|
14
14
|
import { ACLRole, ResourceActionsOptions, RoleActionParams } from './acl-role';
|
|
15
15
|
import { AllowManager, ConditionFunc } from './allow-manager';
|
|
16
|
-
import FixedParamsManager, { Merger } from './fixed-params-manager';
|
|
16
|
+
import FixedParamsManager, { Merger, GeneralMerger } from './fixed-params-manager';
|
|
17
17
|
import SnippetManager, { SnippetOptions } from './snippet-manager';
|
|
18
|
-
interface CanResult {
|
|
18
|
+
export interface CanResult {
|
|
19
19
|
role: string;
|
|
20
20
|
resource: string;
|
|
21
21
|
action: string;
|
|
@@ -113,6 +113,7 @@ export declare class ACL extends EventEmitter {
|
|
|
113
113
|
* @internal
|
|
114
114
|
*/
|
|
115
115
|
getActionParams(ctx: any): Promise<void>;
|
|
116
|
+
addGeneralFixedParams(merger: GeneralMerger): void;
|
|
116
117
|
addFixedParams(resource: string, action: string, merger: Merger): void;
|
|
117
118
|
registerSnippet(snippet: SnippetOptions): void;
|
|
118
119
|
/**
|
package/lib/acl.js
CHANGED
|
@@ -48,9 +48,9 @@ var import_acl_available_action = require("./acl-available-action");
|
|
|
48
48
|
var import_acl_available_strategy = require("./acl-available-strategy");
|
|
49
49
|
var import_acl_role = require("./acl-role");
|
|
50
50
|
var import_allow_manager = require("./allow-manager");
|
|
51
|
+
var import_no_permission_error = require("./errors/no-permission-error");
|
|
51
52
|
var import_fixed_params_manager = __toESM(require("./fixed-params-manager"));
|
|
52
53
|
var import_snippet_manager = __toESM(require("./snippet-manager"));
|
|
53
|
-
var import_no_permission_error = require("./errors/no-permission-error");
|
|
54
54
|
var import_utils2 = require("./utils");
|
|
55
55
|
const _ACL = class _ACL extends import_events.default {
|
|
56
56
|
/**
|
|
@@ -196,6 +196,13 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
196
196
|
if (!aclRole) {
|
|
197
197
|
return null;
|
|
198
198
|
}
|
|
199
|
+
if (role === "root") {
|
|
200
|
+
return {
|
|
201
|
+
resource,
|
|
202
|
+
action,
|
|
203
|
+
role
|
|
204
|
+
};
|
|
205
|
+
}
|
|
199
206
|
const actionPath = `${rawResourceName ? rawResourceName : resource}:${action}`;
|
|
200
207
|
const snippetAllowed = aclRole.snippetAllowed(actionPath);
|
|
201
208
|
const fixedParams = this.fixedParamsManager.getParams(rawResourceName ? rawResourceName : resource, action);
|
|
@@ -262,6 +269,9 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
262
269
|
* @deprecated
|
|
263
270
|
*/
|
|
264
271
|
skip(resourceName, actionNames, condition) {
|
|
272
|
+
if (!condition) {
|
|
273
|
+
condition = "public";
|
|
274
|
+
}
|
|
265
275
|
if (!Array.isArray(actionNames)) {
|
|
266
276
|
actionNames = [actionNames];
|
|
267
277
|
}
|
|
@@ -297,6 +307,7 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
297
307
|
middleware() {
|
|
298
308
|
const acl = this;
|
|
299
309
|
return /* @__PURE__ */ __name(async function ACLMiddleware(ctx, next) {
|
|
310
|
+
ctx.acl = acl;
|
|
300
311
|
const roleName = ctx.state.currentRole || "anonymous";
|
|
301
312
|
const { resourceName: rawResourceName, actionName } = ctx.action;
|
|
302
313
|
let resourceName = rawResourceName;
|
|
@@ -357,6 +368,9 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
357
368
|
await (0, import_koa_compose.default)(this.middlewares.nodes)(ctx, async () => {
|
|
358
369
|
});
|
|
359
370
|
}
|
|
371
|
+
addGeneralFixedParams(merger) {
|
|
372
|
+
this.fixedParamsManager.addGeneralParams(merger);
|
|
373
|
+
}
|
|
360
374
|
addFixedParams(resource, action, merger) {
|
|
361
375
|
this.fixedParamsManager.addParams(resource, action, merger);
|
|
362
376
|
}
|
|
@@ -464,9 +478,11 @@ const _ACL = class _ACL extends import_events.default {
|
|
|
464
478
|
__name(_ACL, "ACL");
|
|
465
479
|
let ACL = _ACL;
|
|
466
480
|
function getUser(ctx) {
|
|
481
|
+
const dataSource = ctx.app.dataSourceManager.dataSources.get("main");
|
|
482
|
+
const db = dataSource.collectionManager.db;
|
|
467
483
|
return async ({ fields }) => {
|
|
468
484
|
var _a, _b;
|
|
469
|
-
const userFields = fields.filter((f) => f &&
|
|
485
|
+
const userFields = fields.filter((f) => f && db.getFieldByPath("users." + f));
|
|
470
486
|
(_a = ctx.logger) == null ? void 0 : _a.info("filter-parse: ", { userFields });
|
|
471
487
|
if (!ctx.state.currentUser) {
|
|
472
488
|
return;
|
|
@@ -474,7 +490,7 @@ function getUser(ctx) {
|
|
|
474
490
|
if (!userFields.length) {
|
|
475
491
|
return;
|
|
476
492
|
}
|
|
477
|
-
const user = await
|
|
493
|
+
const user = await db.getRepository("users").findOne({
|
|
478
494
|
filterByTk: ctx.state.currentUser.id,
|
|
479
495
|
fields: userFields
|
|
480
496
|
});
|
package/lib/allow-manager.d.ts
CHANGED
|
@@ -12,10 +12,12 @@ export declare class AllowManager {
|
|
|
12
12
|
acl: ACL;
|
|
13
13
|
protected skipActions: Map<string, Map<string, string | true | ConditionFunc>>;
|
|
14
14
|
protected registeredCondition: Map<string, ConditionFunc>;
|
|
15
|
+
isPublicCondition: () => boolean;
|
|
15
16
|
constructor(acl: ACL);
|
|
16
17
|
allow(resourceName: string, actionName: string, condition?: string | ConditionFunc): void;
|
|
17
18
|
getAllowedConditions(resourceName: string, actionName: string): Array<ConditionFunc | true>;
|
|
18
19
|
registerAllowCondition(name: string, condition: ConditionFunc): void;
|
|
20
|
+
isPublic(resourceName: string, actionName: string, ctx: any): Promise<boolean>;
|
|
19
21
|
isAllowed(resourceName: string, actionName: string, ctx: any): Promise<boolean>;
|
|
20
22
|
aclMiddleware(): (ctx: any, next: any) => Promise<void>;
|
|
21
23
|
}
|
package/lib/allow-manager.js
CHANGED
|
@@ -36,9 +36,7 @@ const _AllowManager = class _AllowManager {
|
|
|
36
36
|
this.registerAllowCondition("loggedIn", (ctx) => {
|
|
37
37
|
return ctx.state.currentUser;
|
|
38
38
|
});
|
|
39
|
-
this.registerAllowCondition("public",
|
|
40
|
-
return true;
|
|
41
|
-
});
|
|
39
|
+
this.registerAllowCondition("public", this.isPublicCondition);
|
|
42
40
|
this.registerAllowCondition("allowConfigure", async (ctx) => {
|
|
43
41
|
var _a;
|
|
44
42
|
const roleName = ctx.state.currentRole;
|
|
@@ -54,6 +52,9 @@ const _AllowManager = class _AllowManager {
|
|
|
54
52
|
}
|
|
55
53
|
skipActions = /* @__PURE__ */ new Map();
|
|
56
54
|
registeredCondition = /* @__PURE__ */ new Map();
|
|
55
|
+
isPublicCondition = /* @__PURE__ */ __name(() => {
|
|
56
|
+
return true;
|
|
57
|
+
}, "isPublicCondition");
|
|
57
58
|
allow(resourceName, actionName, condition) {
|
|
58
59
|
const actionMap = this.skipActions.get(resourceName) || /* @__PURE__ */ new Map();
|
|
59
60
|
actionMap.set(actionName, condition || true);
|
|
@@ -78,6 +79,15 @@ const _AllowManager = class _AllowManager {
|
|
|
78
79
|
registerAllowCondition(name, condition) {
|
|
79
80
|
this.registeredCondition.set(name, condition);
|
|
80
81
|
}
|
|
82
|
+
async isPublic(resourceName, actionName, ctx) {
|
|
83
|
+
const skippedConditions = this.getAllowedConditions(resourceName, actionName);
|
|
84
|
+
for (const skippedCondition of skippedConditions) {
|
|
85
|
+
if (skippedCondition === this.isPublicCondition) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
81
91
|
async isAllowed(resourceName, actionName, ctx) {
|
|
82
92
|
const skippedConditions = this.getAllowedConditions(resourceName, actionName);
|
|
83
93
|
for (const skippedCondition of skippedConditions) {
|
|
@@ -7,10 +7,13 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
export type Merger = () => object;
|
|
10
|
+
export type GeneralMerger = (resource: string, action: string) => object;
|
|
10
11
|
export type ActionPath = string;
|
|
11
12
|
export default class FixedParamsManager {
|
|
12
13
|
merger: Map<string, Merger[]>;
|
|
14
|
+
generalMergers: Array<GeneralMerger>;
|
|
13
15
|
addParams(resource: string, action: string, merger: Merger): void;
|
|
16
|
+
addGeneralParams(merger: GeneralMerger): void;
|
|
14
17
|
getParamsMerger(resource: string, action: string): Merger[];
|
|
15
18
|
protected getActionPath(resource: string, action: string): string;
|
|
16
19
|
getParams(resource: string, action: string, extraParams?: any): {};
|
|
@@ -34,10 +34,14 @@ var import_utils = require("@nocobase/utils");
|
|
|
34
34
|
const SPLIT = ":";
|
|
35
35
|
const _FixedParamsManager = class _FixedParamsManager {
|
|
36
36
|
merger = /* @__PURE__ */ new Map();
|
|
37
|
+
generalMergers = [];
|
|
37
38
|
addParams(resource, action, merger) {
|
|
38
39
|
const path = this.getActionPath(resource, action);
|
|
39
40
|
this.merger.set(path, [...this.getParamsMerger(resource, action), merger]);
|
|
40
41
|
}
|
|
42
|
+
addGeneralParams(merger) {
|
|
43
|
+
this.generalMergers.push(merger);
|
|
44
|
+
}
|
|
41
45
|
getParamsMerger(resource, action) {
|
|
42
46
|
const path = this.getActionPath(resource, action);
|
|
43
47
|
return this.merger.get(path) || [];
|
|
@@ -47,6 +51,9 @@ const _FixedParamsManager = class _FixedParamsManager {
|
|
|
47
51
|
}
|
|
48
52
|
getParams(resource, action, extraParams = {}) {
|
|
49
53
|
const results = {};
|
|
54
|
+
for (const merger of this.generalMergers) {
|
|
55
|
+
_FixedParamsManager.mergeParams(results, merger(resource, action));
|
|
56
|
+
}
|
|
50
57
|
for (const merger of this.getParamsMerger(resource, action)) {
|
|
51
58
|
_FixedParamsManager.mergeParams(results, merger());
|
|
52
59
|
}
|
package/lib/snippet-manager.js
CHANGED
|
@@ -56,7 +56,12 @@ const _SnippetManager = class _SnippetManager {
|
|
|
56
56
|
if (snippet.name.includes("*") || snippet.name.endsWith(".")) {
|
|
57
57
|
throw new Error(`Invalid snippet name: ${snippet.name}, name should not include * or end with dot.`);
|
|
58
58
|
}
|
|
59
|
-
this.snippets.
|
|
59
|
+
const existed = this.snippets.get(snippet.name);
|
|
60
|
+
if (existed) {
|
|
61
|
+
existed.actions = Array.from(/* @__PURE__ */ new Set([...existed.actions, ...snippet.actions]));
|
|
62
|
+
} else {
|
|
63
|
+
this.snippets.set(snippet.name, snippet);
|
|
64
|
+
}
|
|
60
65
|
}
|
|
61
66
|
allow(actionPath, snippetName) {
|
|
62
67
|
const negated = snippetName.startsWith("!");
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/acl",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.71",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"main": "./lib/index.js",
|
|
7
7
|
"types": "./lib/index.d.ts",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@nocobase/resourcer": "2.0.0-alpha.
|
|
10
|
-
"@nocobase/utils": "2.0.0-alpha.
|
|
9
|
+
"@nocobase/resourcer": "2.0.0-alpha.71",
|
|
10
|
+
"@nocobase/utils": "2.0.0-alpha.71",
|
|
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": "b6fc484eb698fa12fba02dd468a04e39079b1e79"
|
|
19
19
|
}
|