diff --git a/app/client/aclui/ACLFormulaEditor.ts b/app/client/aclui/ACLFormulaEditor.ts index 4fe6a5e5..b000c2ea 100644 --- a/app/client/aclui/ACLFormulaEditor.ts +++ b/app/client/aclui/ACLFormulaEditor.ts @@ -42,6 +42,8 @@ export function aclFormulaEditor(options: ACLFormulaOptions) { return [ // The few Python keywords and constants we support. 'and', 'or', 'not', 'in', 'is', 'True', 'False', 'None', + // Some grist-specific constants: + 'OWNER', 'EDITOR', 'VIEWER', // The common variables. 'user', 'rec', // Other completions that depend on doc schema or other rules. diff --git a/app/common/ACLRuleCollection.ts b/app/common/ACLRuleCollection.ts index b94a4070..41d7a91b 100644 --- a/app/common/ACLRuleCollection.ts +++ b/app/common/ACLRuleCollection.ts @@ -13,12 +13,12 @@ const DEFAULT_RULE_SET: RuleSet = { tableId: '*', colIds: '*', body: [{ - aclFormula: "user.Access in ['editors', 'owners']", + aclFormula: "user.Access in [EDITOR, OWNER]", matchFunc: (input) => ['editors', 'owners'].includes(String(input.user.Access)), permissions: parsePermissions('all'), permissionsText: 'all', }, { - aclFormula: "user.Access in ['viewers']", + aclFormula: "user.Access in [VIEWER]", matchFunc: (input) => ['viewers'].includes(String(input.user.Access)), permissions: parsePermissions('+R-CUDS'), permissionsText: '+R', @@ -36,7 +36,7 @@ const EMERGENCY_RULE_SET: RuleSet = { tableId: '*', colIds: '*', body: [{ - aclFormula: "user.Access in ['owners']", + aclFormula: "user.Access in [OWNER]", matchFunc: (input) => ['owners'].includes(String(input.user.Access)), permissions: parsePermissions('all'), permissionsText: 'all', diff --git a/app/server/lib/ACLFormula.ts b/app/server/lib/ACLFormula.ts index d170df81..e6f824d0 100644 --- a/app/server/lib/ACLFormula.ts +++ b/app/server/lib/ACLFormula.ts @@ -13,6 +13,12 @@ import {ErrorWithCode} from 'app/common/ErrorWithCode'; import {AclMatchFunc, AclMatchInput, ParsedAclFormula} from 'app/common/GranularAccessClause'; import constant = require('lodash/constant'); +const GRIST_CONSTANTS: Record = { + EDITOR: 'editors', + OWNER: 'owners', + VIEWER: 'viewers', +}; + /** * Compile a parsed ACL formula into an actual function that can evaluate a request. */ @@ -55,6 +61,7 @@ function _compileNode(parsedAclFormula: ParsedAclFormula): AclEvalFunc { case 'Const': return constant(parsedAclFormula[1] as CellValue); case 'Name': { const name = rawArgs[0] as keyof AclMatchInput; + if (GRIST_CONSTANTS[name]) { return constant(GRIST_CONSTANTS[name]); } if (!['user', 'rec', 'newRec'].includes(name)) { throw new Error(`Unknown variable '${name}'`); }