(core) Add getAclResources method for making all tables/columns available when editing ACL rules

Summary:
The goal is that those who can edit ACL rules can create or change rules for
any resource, even if the rules block their own ability to see the resource.

Test Plan: Added a browser test, and a server test for who can call the new method.

Reviewers: paulfitz

Reviewed By: paulfitz

Differential Revision: https://phab.getgrist.com/D2703
This commit is contained in:
Dmitry S
2021-01-14 11:10:42 -05:00
parent ffe4a34335
commit d8e742aa0d
6 changed files with 50 additions and 19 deletions

View File

@@ -932,7 +932,7 @@ export class ActiveDoc extends EventEmitter {
*/
public async checkAclFormula(docSession: DocSession, text: string): Promise<void> {
// Checks can leak names of tables and columns.
if (!await this._granularAccess.canReadEverything(docSession)) { return; }
if (await this._granularAccess.hasNuancedAccess(docSession)) { return; }
await this.waitForInitialization();
try {
const parsedAclFormula = await this._pyCall('parse_acl_formula', text);
@@ -945,6 +945,28 @@ export class ActiveDoc extends EventEmitter {
}
}
/**
* Returns the full set of tableIds, with the list of colIds for each table. This is intended
* for editing ACLs. It is only available to users who can edit ACLs, and lists all resources
* regardless of rules that may block access to them.
*/
public async getAclResources(docSession: DocSession): Promise<{[tableId: string]: string[]}> {
if (await this._granularAccess.hasNuancedAccess(docSession) || !this.docData) {
throw new Error('Cannot list ACL resources');
}
const result: {[tableId: string]: string[]} = {};
const tables = this.docData.getTable('_grist_Tables')!;
for (const tableId of tables.getColValues('tableId')!) {
result[tableId as string] = ['id'];
}
const columns = this.docData.getTable('_grist_Tables_column')!;
for (const col of columns.getRecords()) {
const tableId = tables.getValue(col.parentId as number, 'tableId');
result[tableId as string].push(col.colId as string);
}
return result;
}
public getGristDocAPI(): GristDocAPI {
return this.docPluginManager.gristDocAPI;
}
@@ -1023,7 +1045,7 @@ export class ActiveDoc extends EventEmitter {
if (!this.isOwner(docSession)) {
throw new Error('cannot delete actions, access denied');
}
this._actionHistory.deleteActions(keepN);
await this._actionHistory.deleteActions(keepN);
}
/**

View File

@@ -111,6 +111,7 @@ export class DocWorker {
reloadDoc: activeDocMethod.bind(null, 'editors', 'reloadDoc'),
fork: activeDocMethod.bind(null, 'viewers', 'fork'),
checkAclFormula: activeDocMethod.bind(null, 'viewers', 'checkAclFormula'),
getAclResources: activeDocMethod.bind(null, 'viewers', 'getAclResources'),
});
}