mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
refactor: optimze merge role snippets
This commit is contained in:
parent
ee05e2dd22
commit
ad74362e18
@ -7,7 +7,6 @@
|
|||||||
* For more information, please refer to: https://www.nocobase.com/agreement.
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ACLRole } from '@nocobase/acl';
|
|
||||||
import { mergeRole } from '../utils';
|
import { mergeRole } from '../utils';
|
||||||
|
|
||||||
const map2obj = (map: Map<string, string>) => {
|
const map2obj = (map: Map<string, string>) => {
|
||||||
|
@ -17,14 +17,18 @@ export function mergeRole(roles) {
|
|||||||
snippets: [],
|
snippets: [],
|
||||||
resources: null,
|
resources: null,
|
||||||
};
|
};
|
||||||
|
const allSnippets: string[][] = [];
|
||||||
for (const role of roles) {
|
for (const role of roles) {
|
||||||
const jsonRole = role.toJSON();
|
const jsonRole = role.toJSON();
|
||||||
result.roles = mergeRoleNames(result.roles, jsonRole.role);
|
result.roles = mergeRoleNames(result.roles, jsonRole.role);
|
||||||
result.strategy = mergeRoleStrategy(result.strategy, jsonRole.strategy);
|
result.strategy = mergeRoleStrategy(result.strategy, jsonRole.strategy);
|
||||||
result.actions = mergeRoleActions(result.actions, jsonRole.actions);
|
result.actions = mergeRoleActions(result.actions, jsonRole.actions);
|
||||||
result.snippets = mergeRoleSnippets(result.snippets, jsonRole.snippets);
|
|
||||||
result.resources = mergeRoleResources(result.resources, [...role.resources.keys()]);
|
result.resources = mergeRoleResources(result.resources, [...role.resources.keys()]);
|
||||||
|
if (_.isArray(jsonRole.snippets)) {
|
||||||
|
allSnippets.push(jsonRole.snippets);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
result.snippets = mergeRoleSnippets(allSnippets);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,22 +59,31 @@ function mergeRoleActions(sourceActions, newActions) {
|
|||||||
return _.merge(sourceActions, newActions);
|
return _.merge(sourceActions, newActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeRoleSnippets(sourceSnippets, newSnippets = []) {
|
function mergeRoleSnippets(allRoleSnippets: string[][]): string[] {
|
||||||
const allSnippets = [...sourceSnippets, ...newSnippets];
|
if (!allRoleSnippets.length) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const result = allSnippets.reduce((acc, snippet) => {
|
const allSnippets = allRoleSnippets.flat();
|
||||||
// 去重
|
const isExclusion = (value) => value.startsWith('!');
|
||||||
if (acc.includes(snippet)) {
|
const includes = new Set(allSnippets.filter((x) => !isExclusion(x)));
|
||||||
return acc;
|
const excludes = new Set(allSnippets.filter((x) => isExclusion(x)));
|
||||||
|
|
||||||
|
// 处理黑名单的交集:比如 ['a.*', '!a.b.*'] 和 ['a.*', '!a.b.*', '!a.c.*'],最终取 ['a.*', '!a.b.*']
|
||||||
|
const excludesSet = new Set<string>();
|
||||||
|
excludes.forEach((snippet) => {
|
||||||
|
// 取交集:所有角色都有这个黑名单
|
||||||
|
const allHas = allRoleSnippets.every((x) => x.includes(snippet));
|
||||||
|
if (allHas) {
|
||||||
|
excludesSet.add(snippet);
|
||||||
}
|
}
|
||||||
// 当前是 !xxx 并且已经有 xxx,!xxx 则不需要生效
|
});
|
||||||
const isExclusion = snippet.startsWith('!');
|
|
||||||
if (isExclusion && acc.includes(snippet.slice(1))) {
|
// 处理冲突项,比如 ['a'] 和 ['!a'],最终取 ['a']
|
||||||
return acc;
|
excludesSet.forEach((x) => includes.has(x.slice(1)) && excludesSet.delete(x));
|
||||||
}
|
|
||||||
acc.push(snippet);
|
const result = [...includes];
|
||||||
return acc;
|
excludesSet.forEach((x) => result.push(x));
|
||||||
}, []);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user