(core) deal with write access for attachments

Summary:
Attachments are a special case for granular access control. A user is now allowed to read a given attachment if they have read access to a cell containing its id. So when a user writes to a cell in an attachment column, it is important that they can only write the ids of cells to which they have access. This diff allows a user to add an attachment id in a cell if:

  * The user already has access to that a attachment via some existing cell, or
  * The user recently updated the attachment, or
  * The attachment change is from an undo/redo of a previous action attributed to that user

Test Plan: Updated tests

Reviewers: georgegevoian, dsagal

Reviewed By: georgegevoian, dsagal

Differential Revision: https://phab.getgrist.com/D3681
This commit is contained in:
Paul Fitzpatrick
2022-11-15 09:37:48 -05:00
parent 955fdf4ae7
commit ea71312d0e
11 changed files with 344 additions and 86 deletions

View File

@@ -3,6 +3,7 @@
* See also EncActionBundle for how these are packaged for encryption.
*/
import {ApplyUAOptions} from 'app/common/ActiveDocAPI';
import {DocAction, UserAction} from 'app/common/DocActions';
import {RowCounts} from 'app/common/DocUsage';
@@ -50,6 +51,7 @@ export function getEnvContent<Content>(items: Array<EnvContent<Content>>): Conte
export interface UserActionBundle {
info: ActionInfo;
userActions: UserAction[];
options?: ApplyUAOptions;
}
// ActionBundle as received from the sandbox. It does not have some action metadata, but does have

View File

@@ -12,10 +12,18 @@ export interface ApplyUAOptions {
desc?: string; // Overrides the description of the action.
otherId?: number; // For undo/redo; the actionNum of the original action to which it applies.
linkId?: number; // For bundled actions, actionNum of the previous action in the bundle.
bestEffort?: boolean; // If set, action may be applied in part if it cannot be applied completely.
parseStrings?: boolean; // If true, parses string values in some actions based on the column
}
export interface ApplyUAExtendedOptions extends ApplyUAOptions {
bestEffort?: boolean; // If set, action may be applied in part if it cannot be applied completely.
fromOwnHistory?: boolean; // If set, action is confirmed to be a redo/undo taken from history, from
// an action marked as being by the current user.
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
}
export interface ApplyUAResult {
actionNum: number; // number of the action that got recorded.
retValues: any[]; // array of return values, one for each of the passed-in user actions.

View File

@@ -46,6 +46,7 @@ export interface UserInfo {
LinkKey: Record<string, string | undefined>;
UserID: number | null;
UserRef: string | null;
SessionID: string | null;
[attributes: string]: unknown;
toJSON(): {[key: string]: any};
}