mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
a1a84d99c0
Summary: This particular combination of features is not built out - data will be censored but changes to data will not. So the user will now get an error if they try to do it. Existing rules of this kind will continue to operate as before, and can be set via the api. Test Plan: added test Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2751
97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
import { PartialPermissionSet } from 'app/common/ACLPermissions';
|
|
import { CellValue, RowRecord } from 'app/common/DocActions';
|
|
|
|
export interface RuleSet {
|
|
tableId: '*' | string;
|
|
colIds: '*' | string[];
|
|
// The default permissions for this resource, if set, are represented by a RulePart with
|
|
// aclFormula of "", which must be the last element of body.
|
|
body: RulePart[];
|
|
}
|
|
|
|
export interface RulePart {
|
|
origRecord?: RowRecord; // Original record used to create this RulePart.
|
|
aclFormula: string;
|
|
permissions: PartialPermissionSet;
|
|
permissionsText: string; // The text version of PermissionSet, as stored.
|
|
|
|
// Compiled version of aclFormula.
|
|
matchFunc?: AclMatchFunc;
|
|
|
|
// Optional memo, currently extracted from comment in formula.
|
|
memo?: string;
|
|
}
|
|
|
|
// Light wrapper for reading records or user attributes.
|
|
export interface InfoView {
|
|
get(key: string): CellValue;
|
|
toJSON(): {[key: string]: any};
|
|
}
|
|
|
|
// As InfoView, but also supporting writing.
|
|
export interface InfoEditor {
|
|
get(key: string): CellValue;
|
|
set(key: string, val: CellValue): this;
|
|
toJSON(): {[key: string]: any};
|
|
}
|
|
|
|
// Represents user info, which may include properties which are themselves RowRecords.
|
|
export type UserInfo = Record<string, CellValue|InfoView|Record<string, string>>;
|
|
|
|
/**
|
|
* Input into the AclMatchFunc. Compiled formulas evaluate AclMatchInput to produce a boolean.
|
|
*/
|
|
export interface AclMatchInput {
|
|
user: UserInfo;
|
|
rec?: InfoView;
|
|
newRec?: InfoView;
|
|
}
|
|
|
|
/**
|
|
* The actual boolean function that can evaluate a request. The result of compiling ParsedAclFormula.
|
|
*/
|
|
export type AclMatchFunc = (input: AclMatchInput) => boolean;
|
|
|
|
/**
|
|
* Representation of a parsed ACL formula.
|
|
*/
|
|
export type ParsedAclFormula = [string, ...Array<ParsedAclFormula|CellValue>];
|
|
|
|
/**
|
|
* Observations about a formula.
|
|
*/
|
|
export interface FormulaProperties {
|
|
hasRecOrNewRec?: boolean;
|
|
}
|
|
|
|
export interface UserAttributeRule {
|
|
origRecord?: RowRecord; // Original record used to create this UserAttributeRule.
|
|
name: string; // Should be unique among UserAttributeRules.
|
|
tableId: string; // Table in which to look up an existing attribute.
|
|
lookupColId: string; // Column in tableId in which to do the lookup.
|
|
charId: string; // Attribute to look up, possibly a path. E.g. 'Email' or 'office.city'.
|
|
}
|
|
|
|
/**
|
|
* Check some key facts about the formula.
|
|
*/
|
|
export function getFormulaProperties(formula: ParsedAclFormula) {
|
|
const result: FormulaProperties = {}
|
|
if (usesRec(formula)) { result.hasRecOrNewRec = true; }
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check whether a formula mentions `rec` or `newRec`.
|
|
*/
|
|
export function usesRec(formula: ParsedAclFormula): boolean {
|
|
if (!Array.isArray(formula)) { throw new Error('expected a list'); }
|
|
if (formula[0] === 'Name' && (formula[1] === 'rec' || formula[1] === 'newRec')) {
|
|
return true;
|
|
}
|
|
return formula.some(el => {
|
|
if (!Array.isArray(el)) { return false; }
|
|
return usesRec(el as any);
|
|
});
|
|
}
|