aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2020-10-12 17:22:26 -0400
committerbobzel <zzzman@gmail.com>2020-10-12 17:22:26 -0400
commit8ebf3cb0ac7a023aa47a5264d74c3edaebf28b1b (patch)
tree9e5f51fc81de6b3254c7ce398cd261f93114e296 /src
parent04bbff759710d58fa97ce2f0d685ec59b6beb60e (diff)
updated getEffectiveAcl to be a computedFn. got rid of OverrideAcl in favor of just using UpdatingFromServer
Diffstat (limited to 'src')
-rw-r--r--src/client/DocServer.ts2
-rw-r--r--src/client/util/SerializationHelper.ts2
-rw-r--r--src/client/views/collections/CollectionSubView.tsx2
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx8
-rw-r--r--src/fields/Doc.ts20
-rw-r--r--src/fields/util.ts36
6 files changed, 33 insertions, 37 deletions
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index d936f6e2a..00f9877c3 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,6 +1,6 @@
import * as io from 'socket.io-client';
import { MessageStore, YoutubeQueryTypes, GestureContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, MobileDocumentUploadContent } from "./../server/Message";
-import { Opt, Doc, fetchProto, FieldsSym, UpdatingFromServer } from '../fields/Doc';
+import { Opt, Doc, UpdatingFromServer } from '../fields/Doc';
import { Utils, emptyFunction } from '../Utils';
import { SerializationHelper } from './util/SerializationHelper';
import { RefField } from '../fields/RefField';
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index 19b217726..00ac6e521 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -43,7 +43,7 @@ export namespace SerializationHelper {
}
if (!obj.__type) {
- if (ClientUtils.RELEASE) {
+ if (true || ClientUtils.RELEASE) {
console.warn("No property 'type' found in JSON.");
return undefined;
} else {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index b282d1e27..f3e563422 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -134,7 +134,7 @@ export function CollectionSubView<T, X>(schemaCtor: (doc: Doc) => T, moreProps?:
rawdocs = rootDoc && !this.props.annotationsKey ? [Doc.GetProto(rootDoc)] : [];
}
- const docs = rawdocs.filter(d => !(d instanceof Promise) && GetEffectiveAcl(d) !== AclPrivate).map(d => d as Doc);
+ const docs = rawdocs.filter(d => !(d instanceof Promise) && GetEffectiveAcl(Doc.GetProto(d)) !== AclPrivate).map(d => d as Doc);
const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField);
const childDocs = viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index da797eda0..4f8f46111 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -11,7 +11,7 @@ import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from "
import { ReplaceStep } from 'prosemirror-transform';
import { EditorView } from "prosemirror-view";
import { DateField } from '../../../../fields/DateField';
-import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, AclEdit, AclAdmin } from "../../../../fields/Doc";
+import { DataSym, Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, AclEdit, AclAdmin, UpdatingFromServer } from "../../../../fields/Doc";
import { documentSchema } from '../../../../fields/documentSchemas';
import applyDevTools = require("prosemirror-dev-tools");
import { removeMarkWithAttrs } from "./prosemirrorPatches";
@@ -22,7 +22,7 @@ import { RichTextField } from "../../../../fields/RichTextField";
import { RichTextUtils } from '../../../../fields/RichTextUtils';
import { makeInterface } from "../../../../fields/Schema";
import { Cast, DateCast, NumCast, StrCast, ScriptCast, BoolCast } from "../../../../fields/Types";
-import { TraceMobx, OVERRIDE_acl, GetEffectiveAcl } from '../../../../fields/util';
+import { TraceMobx, GetEffectiveAcl } from '../../../../fields/util';
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, numberRange, returnOne, returnZero, Utils, setupMoveUpEvents, OmitKeys } from '../../../../Utils';
import { GoogleApiClientUtils, Pulls, Pushes } from '../../../apis/google_docs/GoogleApiClientUtils';
import { DocServer } from "../../../DocServer";
@@ -805,9 +805,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
tr = tr.addMark(pos, pos + node.nodeSize, link);
}
});
- OVERRIDE_acl(true);
+ this.dataDoc[UpdatingFromServer] = true; // need to allow permissions for adding links to readonly/augment only documents
this._editorView!.dispatch(tr.removeMark(sel.from, sel.to, splitter));
- OVERRIDE_acl(false);
+ this.dataDoc[UpdatingFromServer] = false;
}
}
componentDidMount() {
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 2452ab408..cea09b9c5 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -102,22 +102,28 @@ const AclMap = new Map<string, symbol>([
[SharingPermissions.Admin, AclAdmin]
]);
-export function fetchProto(doc: Doc) {
+// caches the document access permissions for the current user.
+// this recursively updates all protos as well.
+export function updateCachedAcls(doc: Doc) {
if (!doc) return;
const permissions: { [key: string]: symbol } = {};
+ doc[UpdatingFromServer] = true;
Object.keys(doc).filter(key => key.startsWith("acl") && (permissions[key] = AclMap.get(StrCast(doc[key]))!));
+ doc[UpdatingFromServer] = false;
- if (Object.keys(permissions).length) doc[AclSym] = permissions;
+ if (Object.keys(permissions).length) {
+ doc[AclSym] = permissions;
+ }
if (doc.proto instanceof Promise) {
- doc.proto.then(fetchProto);
+ doc.proto.then(updateCachedAcls);
return doc.proto;
}
}
@scriptingGlobal
-@Deserializable("Doc", fetchProto).withFields(["id"])
+@Deserializable("Doc", updateCachedAcls).withFields(["id"])
export class Doc extends RefField {
constructor(id?: FieldId, forceSave?: boolean) {
super(id);
@@ -233,17 +239,15 @@ export class Doc extends RefField {
const prev = GetEffectiveAcl(this);
this[UpdatingFromServer] = true;
this[fKey] = value;
+ this[UpdatingFromServer] = false;
if (fKey.startsWith("acl")) {
- fetchProto(this);
+ updateCachedAcls(this);
}
- this[UpdatingFromServer] = false;
if (prev === AclPrivate && GetEffectiveAcl(this) !== AclPrivate) {
DocServer.GetRefField(this[Id], true);
}
// if (prev !== AclPrivate && GetEffectiveAcl(this) === AclPrivate) {
- // this[UpdatingFromServer] = true;
// this[FieldsSym](true);
- // this[UpdatingFromServer] = false;
// }
};
if (sameAuthor || fKey.startsWith("acl") || DocServer.getFieldWriteMode(fKey) !== DocServer.WriteMode.Playground) {
diff --git a/src/fields/util.ts b/src/fields/util.ts
index dd0444d61..d48011194 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -1,14 +1,14 @@
import { UndoManager } from "../client/util/UndoManager";
-import { Doc, FieldResult, UpdatingFromServer, LayoutSym, AclPrivate, AclEdit, AclReadonly, AclAddonly, AclSym, CachedUpdates, DataSym, DocListCast, AclAdmin, FieldsSym, HeightSym, WidthSym, fetchProto, AclUnset, DocListCastAsync } from "./Doc";
+import { Doc, FieldResult, UpdatingFromServer, LayoutSym, AclPrivate, AclEdit, AclReadonly, AclAddonly, AclSym, DataSym, DocListCast, AclAdmin, HeightSym, WidthSym, updateCachedAcls, AclUnset, DocListCastAsync } from "./Doc";
import { SerializationHelper } from "../client/util/SerializationHelper";
import { ProxyField, PrefetchProxy } from "./Proxy";
import { RefField } from "./RefField";
import { ObjectField } from "./ObjectField";
-import { action, trace, observable, reaction, computed } from "mobx";
-import { Parent, OnUpdate, Update, Id, SelfProxy, Self, HandleUpdate, ToString, ToScriptString } from "./FieldSymbols";
+import { action, trace, } from "mobx";
+import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols";
import { DocServer } from "../client/DocServer";
import { ComputedField } from "./ScriptField";
-import { ScriptCast, StrCast, DateCast, Cast, NumCast } from "./Types";
+import { ScriptCast, StrCast } from "./Types";
import { returnZero } from "../Utils";
import CursorField from "./CursorField";
import { List } from "./List";
@@ -114,10 +114,6 @@ export function makeReadOnly() {
export function makeEditable() {
_setter = _setterImpl;
}
-var _overrideAcl = false;
-export function OVERRIDE_acl(val: boolean) {
- _overrideAcl = val;
-}
export function normalizeEmail(email: string) {
return email.replace(/\./g, '__');
@@ -154,18 +150,19 @@ export enum SharingPermissions {
None = "Not Shared"
}
-// return acl from cache or cache the acl and return. bcz: Argh! NOT WORKING ... nothing gets invalidated properly....
+// return acl from cache or cache the acl and return.
const getEffectiveAclCache = computedFn(function (target: any, user?: string) { return getEffectiveAcl(target, user); }, true);
/**
* Calculates the effective access right to a document for the current user.
*/
export function GetEffectiveAcl(target: any, user?: string): symbol {
- return target ? getEffectiveAcl(target, user) : AclPrivate;
+ return !target ? AclPrivate :
+ target[UpdatingFromServer] ? AclAdmin : getEffectiveAclCache(target, user);// all changes received from the server must be processed as Admin. return this directly so that the acls aren't cached (UpdatingFromServer is not observable)
}
function getPropAcl(target: any, prop: string | symbol | number) {
- if (prop === UpdatingFromServer) return AclAdmin; // requesting the UpdatingFromServer prop must always go through to keep the local DB consistent
+ if (prop === UpdatingFromServer || target[UpdatingFromServer] || prop == AclSym) return AclAdmin; // requesting the UpdatingFromServer prop or AclSym must always go through to keep the local DB consistent
if (prop && DocServer.PlaygroundFields?.includes(prop.toString())) return AclEdit; // playground props are always editable
return GetEffectiveAcl(target);
}
@@ -173,16 +170,12 @@ function getPropAcl(target: any, prop: string | symbol | number) {
let HierarchyMapping: Map<symbol, number> | undefined;
function getEffectiveAcl(target: any, user?: string): symbol {
- if (target[UpdatingFromServer]) return AclAdmin; // all changes received from the server must be processed as Admin
- // if the current user is the author of the document / the current user is a member of the admin group
- const userChecked = user || Doc.CurrentUserEmail;
+ const targetAcls = target[AclSym];
+ const userChecked = user || Doc.CurrentUserEmail; // if the current user is the author of the document / the current user is a member of the admin group
if (userChecked === (target.__fields?.author || target.author)) return AclAdmin; // target may be a Doc of Proxy, so check __fields.author and .author
if (SnappingManager.GetCachedGroupByName("Admin")) return AclAdmin;
- const targetAcls = target[AclSym];
if (targetAcls && Object.keys(targetAcls).length) {
- if (_overrideAcl) return AclEdit;
-
HierarchyMapping = HierarchyMapping || new Map<symbol, number>([
[AclPrivate, 0],
[AclReadonly, 1],
@@ -199,7 +192,6 @@ function getEffectiveAcl(target: any, user?: string): symbol {
if (HierarchyMapping.get(value as symbol)! > HierarchyMapping.get(effectiveAcl)!) {
if (SnappingManager.GetCachedGroupByName(entity) || userChecked === entity) {
effectiveAcl = value as symbol;
- if (effectiveAcl === AclAdmin) return effectiveAcl;
}
}
}
@@ -278,8 +270,8 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
});
}
- layoutDocChanged && fetchProto(target); // updates target[AclSym] when changes to acls have been made
- dataDocChanged && fetchProto(dataDoc);
+ layoutDocChanged && updateCachedAcls(target); // updates target[AclSym] when changes to acls have been made
+ dataDocChanged && updateCachedAcls(dataDoc);
}
const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox",
@@ -312,9 +304,9 @@ export function setter(target: any, in_prop: string | symbol | number, value: an
export function getter(target: any, in_prop: string | symbol | number, receiver: any): any {
let prop = in_prop;
- if (in_prop === AclSym) return _overrideAcl ? undefined : target[AclSym];
+ if (in_prop === AclSym) return target[AclSym];
if (in_prop === "toString" || (in_prop !== HeightSym && in_prop !== WidthSym && in_prop !== LayoutSym && typeof prop === "symbol")) return target.__fields[prop] || target[prop];
- if (GetEffectiveAcl(target) === AclPrivate && !_overrideAcl) return prop === HeightSym || prop === WidthSym ? returnZero : undefined;
+ if (GetEffectiveAcl(target) === AclPrivate) return prop === HeightSym || prop === WidthSym ? returnZero : undefined;
if (prop === LayoutSym) return target.__LAYOUT__;
if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) {
if (!prop.startsWith("_")) {