mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) give more detailed reasons for access denied when memos are present
Summary: With this change, if a comment is added to an ACL formula, then that comment will be offered to the user if access is denied and that rule could potentially have granted access. The code is factored so that when access is permitted, or when partially visible tables are being filtered, there is little overhead. Comments are gathered only when an explicit denial of access. Test Plan: added tests, updated tests Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2730
This commit is contained in:
@@ -272,7 +272,6 @@ function readAclRules(docData: DocData, {log, compile}: ReadAclOptions): ReadAcl
|
||||
if (rule.userAttributes) {
|
||||
if (tableId !== '*' || colIds !== '*') {
|
||||
throw new Error(`ACLRule ${rule.id} invalid; user attributes must be on the default resource`);
|
||||
continue;
|
||||
}
|
||||
const parsed = JSON.parse(String(rule.userAttributes));
|
||||
// TODO: could perhaps use ts-interface-checker here.
|
||||
@@ -280,7 +279,6 @@ function readAclRules(docData: DocData, {log, compile}: ReadAclOptions): ReadAcl
|
||||
[parsed.name, parsed.tableId, parsed.lookupColId, parsed.charId]
|
||||
.every(p => p && typeof p === 'string'))) {
|
||||
throw new Error(`User attribute rule ${rule.id} is invalid`);
|
||||
continue;
|
||||
}
|
||||
parsed.origRecord = rule;
|
||||
userAttributes.push(parsed as UserAttributeRule);
|
||||
@@ -289,10 +287,12 @@ function readAclRules(docData: DocData, {log, compile}: ReadAclOptions): ReadAcl
|
||||
} else if (rule.aclFormula && !rule.aclFormulaParsed) {
|
||||
throw new Error(`ACLRule ${rule.id} invalid because missing its parsed formula`);
|
||||
} else {
|
||||
const aclFormulaParsed = rule.aclFormula && JSON.parse(String(rule.aclFormulaParsed));
|
||||
body.push({
|
||||
origRecord: rule,
|
||||
aclFormula: String(rule.aclFormula),
|
||||
matchFunc: rule.aclFormula ? compile?.(JSON.parse(String(rule.aclFormulaParsed))) : defaultMatchFunc,
|
||||
matchFunc: rule.aclFormula ? compile?.(aclFormulaParsed) : defaultMatchFunc,
|
||||
memo: aclFormulaParsed && aclFormulaParsed[0] === 'Comment' && aclFormulaParsed[2],
|
||||
permissions: parsePermissions(String(rule.permissionsText)),
|
||||
permissionsText: String(rule.permissionsText),
|
||||
});
|
||||
|
||||
@@ -28,6 +28,8 @@ export interface ApiErrorDetails {
|
||||
|
||||
// If set, contains suggestions for fixing a problem.
|
||||
tips?: ApiTip[];
|
||||
|
||||
memos?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -136,6 +136,9 @@ function throwApiError(url: string, resp: Response | AxiosResponse, body: any) {
|
||||
if (body.error) {
|
||||
details.userError = body.error;
|
||||
}
|
||||
if (body.memos) {
|
||||
details.memos = body.memos;
|
||||
}
|
||||
throw new ApiError(`Request to ${url} failed with status ${resp.status}: ` +
|
||||
`${resp.statusText} (${body.error || 'unknown cause'})`, resp.status, details);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {OpenDocMode} from 'app/common/DocListAPI';
|
||||
interface ErrorDetails {
|
||||
status?: number;
|
||||
accessMode?: OpenDocMode;
|
||||
memos?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -13,11 +14,9 @@ interface ErrorDetails {
|
||||
*
|
||||
*/
|
||||
export class ErrorWithCode extends Error {
|
||||
public accessMode?: OpenDocMode;
|
||||
public status?: number;
|
||||
constructor(public code: string, message: string, details: ErrorDetails = {}) {
|
||||
constructor(public code: string, message: string, public details: ErrorDetails = {}) {
|
||||
super(message);
|
||||
this.status = details.status;
|
||||
this.accessMode = details.accessMode;
|
||||
}
|
||||
public get accessMode() { return this.details?.accessMode; }
|
||||
public get status() { return this.details?.status; }
|
||||
}
|
||||
|
||||
@@ -17,6 +17,9 @@ export interface RulePart {
|
||||
|
||||
// Compiled version of aclFormula.
|
||||
matchFunc?: AclMatchFunc;
|
||||
|
||||
// Optional memo, currently extracted from comment in formula.
|
||||
memo?: string;
|
||||
}
|
||||
|
||||
// Light wrapper around characteristics or records.
|
||||
|
||||
Reference in New Issue
Block a user