mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) update read access for exceptional sessions
Summary: Exceptional sessions had lost full read access to documents; this restores it. Exceptional sessions are used for system actions or while creating documents. Test Plan: added test Reviewers: alexmojaki Reviewed By: alexmojaki Differential Revision: https://phab.getgrist.com/D2966
This commit is contained in:
parent
4ca47878ca
commit
4a23b964ed
@ -653,6 +653,13 @@ export class GranularAccess implements GranularAccessForBundle {
|
||||
* access level and any row-level access functions needed.
|
||||
*/
|
||||
public async getTableAccess(docSession: OptDocSession, tableId: string): Promise<TablePermissionSetWithContext> {
|
||||
if (this._hasExceptionalFullAccess(docSession)) {
|
||||
return {
|
||||
perms: {read: 'allow', create: 'allow', delete: 'allow', update: 'allow', schemaEdit: 'allow'},
|
||||
ruleType: 'table',
|
||||
getMemos() { throw new Error('never needed'); }
|
||||
};
|
||||
}
|
||||
return (await this._getAccess(docSession)).getTableAccess(tableId);
|
||||
}
|
||||
|
||||
@ -665,6 +672,7 @@ export class GranularAccess implements GranularAccessForBundle {
|
||||
const cursor: ActionCursor = {docSession, action: data, actionIdx: null};
|
||||
const tableId = getTableId(data);
|
||||
if (this.getReadPermission(permInfo.getTableAccess(tableId)) === 'mixed') {
|
||||
const readAccessCheck = this._readAccessCheck(docSession);
|
||||
await this._filterRowsAndCells(cursor, data, data, readAccessCheck, true);
|
||||
}
|
||||
|
||||
@ -684,7 +692,7 @@ export class GranularAccess implements GranularAccessForBundle {
|
||||
}
|
||||
|
||||
public assertCanRead(ps: PermissionSetWithContext) {
|
||||
readAccessCheck.throwIfDenied(ps);
|
||||
accessChecks.fatal.read.get(ps);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -734,6 +742,18 @@ export class GranularAccess implements GranularAccessForBundle {
|
||||
}
|
||||
}
|
||||
|
||||
// The AccessCheck for the "read" permission is used enough to merit a shortcut.
|
||||
// We just need to be careful to retain unfettered access for exceptional sessions.
|
||||
private _readAccessCheck(docSession: OptDocSession): IAccessCheck {
|
||||
return this._hasExceptionalFullAccess(docSession) ? dummyAccessCheck : accessChecks.check.read;
|
||||
}
|
||||
|
||||
// Return true for special system sessions or document-creation sessions, where
|
||||
// unfettered access is appropriate.
|
||||
private _hasExceptionalFullAccess(docSession: OptDocSession): Boolean {
|
||||
return docSession.mode === 'system' || docSession.mode === 'nascent';
|
||||
}
|
||||
|
||||
/**
|
||||
* This filters a message being broadcast to all clients to be appropriate for one
|
||||
* particular client, if that client may need some material filtered out.
|
||||
@ -909,6 +929,7 @@ export class GranularAccess implements GranularAccessForBundle {
|
||||
}
|
||||
|
||||
// Return the results, also applying any cell-level access control.
|
||||
const readAccessCheck = this._readAccessCheck(cursor.docSession);
|
||||
for (const a of revisedDocActions) {
|
||||
await this._filterRowsAndCells({...cursor, action: a}, rowsAfter, rowsAfter, readAccessCheck, false);
|
||||
}
|
||||
@ -1518,6 +1539,7 @@ export class GranularAccess implements GranularAccessForBundle {
|
||||
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.
|
||||
@ -1636,7 +1658,7 @@ export class GranularAccess implements GranularAccessForBundle {
|
||||
// TODO: deal with ReplaceTableData, which both deletes and creates rows.
|
||||
private async _getAccessForActionType(docSession: OptDocSession, a: DocAction,
|
||||
severity: 'check'|'fatal'): Promise<IAccessCheck> {
|
||||
if (docSession.mode === 'system' || docSession.mode === 'nascent') {
|
||||
if (this._hasExceptionalFullAccess(docSession)) {
|
||||
return dummyAccessCheck;
|
||||
}
|
||||
const tableId = getTableId(a);
|
||||
@ -1821,6 +1843,7 @@ class UserAttributes {
|
||||
|
||||
interface IAccessCheck {
|
||||
get(ps: PermissionSetWithContext): string;
|
||||
throwIfDenied(ps: PermissionSetWithContext): void;
|
||||
}
|
||||
|
||||
class AccessCheck implements IAccessCheck {
|
||||
@ -1852,11 +1875,11 @@ export const accessChecks = {
|
||||
};
|
||||
|
||||
|
||||
// The AccessCheck for the "read" permission is used enough to merit a shortcut.
|
||||
const readAccessCheck = accessChecks.check.read;
|
||||
|
||||
// This AccessCheck allows everything.
|
||||
const dummyAccessCheck = { get() { return 'allow'; } };
|
||||
const dummyAccessCheck: IAccessCheck = {
|
||||
get() { return 'allow'; },
|
||||
throwIfDenied() {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user