(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[]> { private async _filterOutgoingDocAction(cursor: ActionCursor): Promise<DocAction[]> {
const {action} = cursor; const {action} = cursor;
const tableId = getTableId(action); const tableId = getTableId(action);
const permInfo = await this._getStepAccess(cursor);
const tableAccess = permInfo.getTableAccess(tableId); let results: DocAction[] = [];
const access = this.getReadPermission(tableAccess); if (tableId.startsWith('_grist')) {
const readAccessCheck = this._readAccessCheck(cursor.docSession); // Granular access rules don't apply to metadata directly, instead there
const results: DocAction[] = []; // is a process of censorship (see later in this method).
if (access === 'deny') { results = [action];
// 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 { } else {
// The remainder is the mixed condition. const permInfo = await this._getStepAccess(cursor);
for (const act of await this._pruneRows(cursor)) { const tableAccess = permInfo.getTableAccess(tableId);
const prunedAct = this._pruneColumns(act, permInfo, tableId, readAccessCheck); const access = this.getReadPermission(tableAccess);
if (prunedAct) { results.push(prunedAct); } 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[] = []; const secondPass: DocAction[] = [];