(core) granular access control in the presence of schema changes

Summary:
 - Support schema changes in the presence of non-trivial ACL rules.
 - Fix update of `aclFormulaParsed` when updating formulas automatically after schema change.
 - Filter private metadata in broadcasts, not just fetches.  Censorship method is unchanged, just refactored.
 - Allow only owners to change ACL rules.
 - Force reloads if rules are changed.
 - Track rule changes within bundle, for clarity during schema changes - tableId and colId changes create a muddle otherwise.
 - Show or forbid pages dynamically depending on user's access to its sections. Logic unchanged, just no longer requires reload.
 - Fix calculation of pre-existing rows touched by a bundle, in the presence of schema changes.
 - Gray out acl page for non-owners.

Test Plan: added tests

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2734
This commit is contained in:
Paul Fitzpatrick
2021-03-01 11:51:30 -05:00
parent aae4a58300
commit 4ab096d179
18 changed files with 930 additions and 454 deletions

View File

@@ -18,16 +18,30 @@ class RowIdTracker {
*/
export function getRelatedRows(docActions: DocAction[]): ReadonlyArray<readonly [string, Set<number>]> {
// Relate tableIds for tables with what they were before the actions, if renamed.
const tableIds = new Map<string, string>();
const rowIds = new Map<string, RowIdTracker>();
const tableIds = new Map<string, string>(); // key is current tableId
const rowIds = new Map<string, RowIdTracker>(); // key is pre-existing tableId
const addedTables = new Set<string>(); // track newly added tables to ignore; key is current tableId
for (const docAction of docActions) {
const currentTableId = getTableId(docAction);
const tableId = tableIds.get(currentTableId) || currentTableId;
if (docAction[0] === 'RenameTable') {
if (addedTables.has(currentTableId)) {
addedTables.delete(currentTableId);
addedTables.add(docAction[2])
continue;
}
tableIds.delete(currentTableId);
tableIds.set(docAction[2], tableId);
continue;
}
if (docAction[0] === 'AddTable') {
addedTables.add(currentTableId);
}
if (docAction[0] === 'RemoveTable') {
addedTables.delete(currentTableId);
continue;
}
if (addedTables.has(currentTableId)) { continue; }
// tableId will now be that prior to docActions, regardless of renames.
const tracker = getSetMapValue(rowIds, tableId, () => new RowIdTracker());