(core) lock down modification of the _grist_Attachments table

Summary:
Rows in the _grist_Attachments table have a special lifecycle,
being created by a special method, and deleted via a special
process. All other modifications are now rejected, for simplicity.

Test Plan: added test

Reviewers: dsagal, jarek

Reviewed By: dsagal, jarek

Differential Revision: https://phab.getgrist.com/D3712
This commit is contained in:
Paul Fitzpatrick 2022-11-22 09:15:18 -05:00
parent 94a7b750a8
commit 312d2331a8
4 changed files with 27 additions and 4 deletions

View File

@ -22,6 +22,7 @@ export interface ApplyUAExtendedOptions extends ApplyUAOptions {
oldestSource?: number; // If set, gives the timestamp of the oldest source the undo/redo
// action was built from, expressed as number of milliseconds
// elapsed since January 1, 1970 00:00:00 UTC
attachment?: boolean; // If set, allow actions on attachments.
}
export interface ApplyUAResult {

View File

@ -844,7 +844,9 @@ export class ActiveDoc extends EventEmitter {
);
const userActions: UserAction[] = await Promise.all(
upload.files.map(file => this._prepAttachment(docSession, file)));
const result = await this.applyUserActions(docSession, userActions);
const result = await this._applyUserActionsWithExtendedOptions(docSession, userActions, {
attachment: true,
});
this._updateAttachmentsSize().catch(e => {
this._log.warn(docSession, 'failed to update attachments size', e);
});

View File

@ -2346,9 +2346,24 @@ export class GranularAccess implements GranularAccessForBundle {
return dummyAccessCheck;
}
const tableId = getTableId(a);
if (tableId.startsWith('_grist') && tableId !== '_grist_Attachments' && tableId !== '_grist_Cells') {
if (tableId.startsWith('_grist') && tableId !== '_grist_Cells') {
if (tableId === '_grist_Attachments') {
// If the back end is adding/removing an attachment, all
// necessary authentication has happened, and we can go ahead
// and do it. Perhaps the back end should just use an
// exceptional session for this, rather than a special
// flag. That would change attribution of the action in the
// log, so I stuck with a flag, but I'm not sure if
// attribution is particularly useful in this case.
if (this._activeBundle?.options?.attachment) {
return dummyAccessCheck;
}
// Users cannot take actions on _grist_Attachments through the regular
// action interface.
throw new Error('_grist_Attachments modification is not allowed');
}
// Actions on any metadata table currently require the schemaEdit flag.
// Exception: the attachments table and cell info table, which needs to be reworked to be compatible
// Exception: the cell info table, which needs to be reworked to be compatible
// with granular access.
// Another exception: ensure owners always have full access to ACL tables, so they

View File

@ -81,8 +81,13 @@ settings = {
"ociVersion": "1.0.0",
"process": {
"terminal": include_bash,
# Match current user id, for convenience with mounts. For some versions of
# gvisor, default behavior may be better - if you see "access denied" problems
# during imports, try commenting this section out. We could make imports work
# for any version of gvisor by setting mode when using tmp.dir to allow
# others to list directory contents.
"user": {
"uid": os.getuid(), # match current user id, for convenience with mounts
"uid": os.getuid(),
"gid": 0
},
"args": cmd_args,