(core) make filtering of metadata consistent in presence of default access rules

Summary:
This brings the treatment of metadata updates being broadcast to a user
into line with how it is treated when they first open the document.
Specifically, this fixes a bug where, for a document with a default access
rule denying access to everything, a user would not receive any
metadata updates.

Test Plan: added test; existing tests pass

Reviewers: jarek, dsagal

Reviewed By: jarek, dsagal

Differential Revision: https://phab.getgrist.com/D3711
This commit is contained in:
Paul Fitzpatrick 2022-11-17 15:49:06 -05:00
parent 1a6d427339
commit 6061b67fd9

View File

@ -2149,23 +2149,30 @@ export class GranularAccess implements GranularAccessForBundle {
private async _filterOutgoingDocAction(cursor: ActionCursor): Promise<DocAction[]> {
const {action} = cursor;
const tableId = getTableId(action);
const permInfo = await this._getStepAccess(cursor);
const tableAccess = permInfo.getTableAccess(tableId);
const access = this.getReadPermission(tableAccess);
const readAccessCheck = this._readAccessCheck(cursor.docSession);
const results: DocAction[] = [];
if (access === 'deny') {
// filter out this data.
} else if (access === 'allow') {
results.push(action);
} else if (access === 'mixedColumns') {
const act = this._pruneColumns(action, permInfo, tableId, readAccessCheck);
if (act) { results.push(act); }
let results: DocAction[] = [];
if (tableId.startsWith('_grist')) {
// Granular access rules don't apply to metadata directly, instead there
// is a process of censorship (see later in this method).
results = [action];
} else {
// The remainder is the mixed condition.
for (const act of await this._pruneRows(cursor)) {
const prunedAct = this._pruneColumns(act, permInfo, tableId, readAccessCheck);
if (prunedAct) { results.push(prunedAct); }
const permInfo = await this._getStepAccess(cursor);
const tableAccess = permInfo.getTableAccess(tableId);
const access = this.getReadPermission(tableAccess);
const readAccessCheck = this._readAccessCheck(cursor.docSession);
if (access === 'deny') {
// filter out this data.
} else if (access === 'allow') {
results.push(action);
} else if (access === 'mixedColumns') {
const act = this._pruneColumns(action, permInfo, tableId, readAccessCheck);
if (act) { results.push(act); }
} else {
// The remainder is the mixed condition.
for (const act of await this._pruneRows(cursor)) {
const prunedAct = this._pruneColumns(act, permInfo, tableId, readAccessCheck);
if (prunedAct) { results.push(prunedAct); }
}
}
}
const secondPass: DocAction[] = [];