File size: 1,545 Bytes
fc93158 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | const OPERATOR_ROLE = "operator";
const OPERATOR_ADMIN_SCOPE = "operator.admin";
const OPERATOR_READ_SCOPE = "operator.read";
const OPERATOR_WRITE_SCOPE = "operator.write";
const OPERATOR_SCOPE_PREFIX = "operator.";
function normalizeScopeList(scopes: readonly string[]): string[] {
const out = new Set<string>();
for (const scope of scopes) {
const trimmed = scope.trim();
if (trimmed) {
out.add(trimmed);
}
}
return [...out];
}
function operatorScopeSatisfied(requestedScope: string, granted: Set<string>): boolean {
if (granted.has(OPERATOR_ADMIN_SCOPE) && requestedScope.startsWith(OPERATOR_SCOPE_PREFIX)) {
return true;
}
if (requestedScope === OPERATOR_READ_SCOPE) {
return granted.has(OPERATOR_READ_SCOPE) || granted.has(OPERATOR_WRITE_SCOPE);
}
if (requestedScope === OPERATOR_WRITE_SCOPE) {
return granted.has(OPERATOR_WRITE_SCOPE);
}
return granted.has(requestedScope);
}
export function roleScopesAllow(params: {
role: string;
requestedScopes: readonly string[];
allowedScopes: readonly string[];
}): boolean {
const requested = normalizeScopeList(params.requestedScopes);
if (requested.length === 0) {
return true;
}
const allowed = normalizeScopeList(params.allowedScopes);
if (allowed.length === 0) {
return false;
}
const allowedSet = new Set(allowed);
if (params.role.trim() !== OPERATOR_ROLE) {
return requested.every((scope) => allowedSet.has(scope));
}
return requested.every((scope) => operatorScopeSatisfied(scope, allowedSet));
}
|