mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-03 00:13:57 +00:00
better permission compiler
This commit is contained in:
@@ -1,10 +1,14 @@
|
|||||||
import _escapeRegExp from 'lodash/escapeRegExp';
|
import _escapeRegExp from 'lodash/escapeRegExp';
|
||||||
import _isString from 'lodash/isString';
|
import _isString from 'lodash/isString';
|
||||||
import _compact from 'lodash/compact';
|
import _compact from 'lodash/compact';
|
||||||
|
import _flatten from 'lodash/flatten';
|
||||||
|
|
||||||
|
interface CompiledPermissionLevel {
|
||||||
|
re: RegExp;
|
||||||
|
type: 'allow' | 'deny';
|
||||||
|
}
|
||||||
interface CompiledPermissions {
|
interface CompiledPermissions {
|
||||||
revoke: RegExp;
|
levels: CompiledPermissionLevel[];
|
||||||
allow: RegExp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function compileRegexp(permissions) {
|
function compileRegexp(permissions) {
|
||||||
@@ -14,25 +18,58 @@ function compileRegexp(permissions) {
|
|||||||
|
|
||||||
export function compilePermissions(permissions: string[] | string): CompiledPermissions {
|
export function compilePermissions(permissions: string[] | string): CompiledPermissions {
|
||||||
if (!permissions) return null;
|
if (!permissions) return null;
|
||||||
if (_isString(permissions)) permissions = permissions.split(',');
|
|
||||||
|
if (_isString(permissions)) permissions = permissions.split(/,|;|\||\s/);
|
||||||
|
else permissions = _flatten(permissions.map(x => x.split(/,|;|\||\s/)));
|
||||||
|
|
||||||
permissions = _compact(permissions.map(x => x.trim()));
|
permissions = _compact(permissions.map(x => x.trim()));
|
||||||
const revoke = permissions.filter(x => x.startsWith('~')).map(x => x.substring(1));
|
|
||||||
const allow = permissions.filter(x => !x.startsWith('~'));
|
let lastType = null;
|
||||||
return {
|
let lastItems = [];
|
||||||
revoke: compileRegexp(revoke),
|
|
||||||
allow: compileRegexp(allow),
|
const res: CompiledPermissions = {
|
||||||
|
levels: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
for (const item of permissions) {
|
||||||
|
const type = item.startsWith('~') ? 'deny' : 'allow';
|
||||||
|
const perm = item.startsWith('~') ? item.substring(1) : item;
|
||||||
|
|
||||||
|
if (lastType != null && type != lastType) {
|
||||||
|
res.levels.push({
|
||||||
|
re: compileRegexp(lastItems),
|
||||||
|
type: lastType,
|
||||||
|
});
|
||||||
|
lastItems = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
lastItems.push(perm);
|
||||||
|
lastType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastItems.length > 0) {
|
||||||
|
res.levels.push({
|
||||||
|
re: compileRegexp(lastItems),
|
||||||
|
type: lastType,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function testPermission(tested: string, permissions: CompiledPermissions) {
|
export function testPermission(tested: string, permissions: CompiledPermissions) {
|
||||||
if (!permissions) return true;
|
let allow = true;
|
||||||
if (!permissions.revoke) return true;
|
|
||||||
|
|
||||||
if (tested.match(permissions.revoke)) {
|
if (!permissions) {
|
||||||
if (!tested.match(permissions.allow)) {
|
return true;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
for (const level of permissions.levels) {
|
||||||
|
if (tested.match(level.re)) {
|
||||||
|
if (level.type == 'allow') allow = true;
|
||||||
|
if (level.type == 'deny') allow = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return allow;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user