From 6061b67fd9d6941686e948715c6a78f935a19d2f Mon Sep 17 00:00:00 2001 From: Paul Fitzpatrick Date: Thu, 17 Nov 2022 15:49:06 -0500 Subject: [PATCH] (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 --- app/server/lib/GranularAccess.ts | 39 +++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/app/server/lib/GranularAccess.ts b/app/server/lib/GranularAccess.ts index 1f437733..25f6723e 100644 --- a/app/server/lib/GranularAccess.ts +++ b/app/server/lib/GranularAccess.ts @@ -2149,23 +2149,30 @@ export class GranularAccess implements GranularAccessForBundle { private async _filterOutgoingDocAction(cursor: ActionCursor): Promise { 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[] = [];