(core) allow multiple rule sets for overlapping columns if they are all allows or all denies

Summary:
Previously, it was forbidden to have two rule sets with overlapping columns,
since that could introduce an dependency on order of evaluation without
the user having a way to control that order.  This diff permits such rule sets
if the are compatible in a very simple way -- all allows or all denies.
Anything more complicated (even if actually order independent) remains forbidden.

Test Plan: added tests

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2745
This commit is contained in:
Paul Fitzpatrick
2021-03-03 22:40:54 -05:00
parent c37a04c578
commit 7bd3b2499f
2 changed files with 76 additions and 6 deletions

View File

@@ -161,3 +161,32 @@ export function mergePermissions<T, U>(psets: Array<PermissionSet<T>>, combine:
export function toMixed(pset: PartialPermissionSet): MixedPermissionSet {
return mergePermissions([pset], ([bit]) => (bit === 'allow' || bit === 'mixed' ? bit : 'deny'));
}
/**
* Check if PermissionSet may only add permissions, only remove permissions, or may do either.
* A rule that neither adds nor removes permissions is treated as mixed.
*/
export function summarizePermissionSet(pset: PartialPermissionSet): MixedPermissionValue {
let sign = '';
for (const key of Object.keys(pset) as Array<keyof PartialPermissionSet>) {
const pWithSome = pset[key];
// "Some" postfix is not significant for summarization.
const p = pWithSome === 'allowSome' ? 'allow' : (pWithSome === 'denySome' ? 'deny' : pWithSome)
if (!p || p === sign) { continue; }
if (!sign) {
sign = p;
continue;
}
sign = 'mixed';
}
return (sign === 'allow' || sign === 'deny') ? sign : 'mixed';
}
/**
* Summarize whether a set of permissions are all 'allow', all 'deny', or other ('mixed').
*/
export function summarizePermissions(perms: MixedPermissionValue[]): MixedPermissionValue {
if (perms.length === 0) { return 'mixed'; }
const perm = perms[0];
return perms.some(p => p !== perm) ? 'mixed' : perm;
}