diff options
Diffstat (limited to 'src/fields')
-rw-r--r-- | src/fields/Doc.ts | 24 | ||||
-rw-r--r-- | src/fields/util.ts | 84 |
2 files changed, 47 insertions, 61 deletions
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index c965dc282..27eabf451 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -109,7 +109,6 @@ const AclMap = new Map<string, symbol>([ ]); export function fetchProto(doc: Doc) { - console.log("in fetchproto"); if (doc.author !== Doc.CurrentUserEmail) { // storing acls for groups needs to be extended here - AclSym should store a datastructure that stores information about permissions const permissions: { [key: string]: symbol } = {}; @@ -118,22 +117,8 @@ export function fetchProto(doc: Doc) { if (key.startsWith("ACL")) permissions[key] = AclMap.get(StrCast(doc[key]))!; }); - doc[AclSym] = permissions; - // const acl = Doc.Get(doc, "ACL", true); - // switch (acl) { - // case "ownerOnly": - // doc[AclSym] = AclPrivate; - // return undefined; - // case "readOnly": - // doc[AclSym] = AclReadonly; - // break; - // case "addOnly": - // doc[AclSym] = AclAddonly; - // break; - // // case "edit": - // // doc[AclSym] = AclEdit; - // } + if (Object.keys(permissions).length) doc[AclSym] = permissions; } if (doc.proto instanceof Promise) { @@ -208,7 +193,7 @@ export class Doc extends RefField { private [Self] = this; private [SelfProxy]: any; - public [AclSym]: any; + public [AclSym]: { [key: string]: symbol }; public [WidthSym] = () => NumCast(this[SelfProxy]._width); public [HeightSym] = () => NumCast(this[SelfProxy]._height); public [ToScriptString]() { return `DOC-"${this[Self][Id]}"-`; } @@ -232,8 +217,8 @@ export class Doc extends RefField { return Cast(this[SelfProxy][renderFieldKey + "-layout[" + templateLayoutDoc[Id] + "]"], Doc, null) || templateLayoutDoc; } return undefined; - } + } private [CachedUpdates]: { [key: string]: () => void | Promise<any> } = {}; public static CurrentUserEmail: string = ""; @@ -840,7 +825,6 @@ export namespace Doc { } // don't bother memoizing (caching) the result if called from a non-reactive context. (plus this avoids a warning message) export function IsBrushedDegreeUnmemoized(doc: Doc) { - console.log("here"); if (!doc || getEffectiveAcl(doc) === AclPrivate || getEffectiveAcl(Doc.GetProto(doc)) === AclPrivate) return 0; return brushManager.BrushedDoc.has(doc) ? 2 : brushManager.BrushedDoc.has(Doc.GetProto(doc)) ? 1 : 0; } @@ -850,7 +834,6 @@ export namespace Doc { })(doc); } export function BrushDoc(doc: Doc) { - console.log("here"); if (!doc || getEffectiveAcl(doc) === AclPrivate || getEffectiveAcl(Doc.GetProto(doc)) === AclPrivate) return doc; brushManager.BrushedDoc.set(doc, true); brushManager.BrushedDoc.set(Doc.GetProto(doc), true); @@ -888,7 +871,6 @@ export namespace Doc { } const highlightManager = new HighlightBrush(); export function IsHighlighted(doc: Doc) { - console.log("here"); if (!doc || getEffectiveAcl(doc) === AclPrivate || getEffectiveAcl(Doc.GetProto(doc)) === AclPrivate) return false; return highlightManager.HighlightedDoc.get(doc) || highlightManager.HighlightedDoc.get(Doc.GetProto(doc)); } diff --git a/src/fields/util.ts b/src/fields/util.ts index a3e7a36f8..a1af1d3c5 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -1,5 +1,5 @@ import { UndoManager } from "../client/util/UndoManager"; -import { Doc, Field, FieldResult, UpdatingFromServer, LayoutSym, AclSym, AclPrivate, AclEdit, AclReadonly, AclAddonly } from "./Doc"; +import { Doc, FieldResult, UpdatingFromServer, LayoutSym, AclPrivate, AclEdit, AclReadonly, AclAddonly, AclSym, fetchProto } from "./Doc"; import { SerializationHelper } from "../client/util/SerializationHelper"; import { ProxyField, PrefetchProxy } from "./Proxy"; import { RefField } from "./RefField"; @@ -9,7 +9,6 @@ import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols"; import { DocServer } from "../client/DocServer"; import { ComputedField } from "./ScriptField"; import { ScriptCast } from "./Types"; -import GroupManager from "../client/util/GroupManager"; function _readOnlySetter(): never { @@ -108,57 +107,65 @@ export function OVERRIDE_ACL(val: boolean) { _overrideAcl = val; } -const HierarchyMapping = new Map<symbol, number>([ - [AclPrivate, 0], - [AclReadonly, 1], - [AclAddonly, 2], - [AclEdit, 3] -]); +let currentUserGroups: string[] = []; +let currentUserEmail: string;// = Doc.CurrentUserEmail; -export function getEffectiveAcl(target: any): symbol { +export function setGroups(groups: string[]) { + currentUserGroups = groups; + currentUserEmail = Doc.CurrentUserEmail; +} - console.log("in getEffectiveAcl"); - if (target[AclSym].ACL) return target[AclSym].ACL; +export function getEffectiveAcl(target: any, in_prop?: string | symbol | number): symbol { - let effectiveAcl = AclEdit; + const HierarchyMapping = new Map<symbol, number>([ + [AclPrivate, 0], + [AclReadonly, 1], + [AclAddonly, 2], + [AclEdit, 3] + ]); - for (const [key, value] of Object.entries(target[AclSym])) { - if (key.startsWith("ACL-")) { - if (GroupManager.Instance.currentUserGroups.includes(key.substring(4)) || Doc.CurrentUserEmail === key.substring(4).replace("_", ".")) { - if (HierarchyMapping.get(value as symbol)! > HierarchyMapping.get(effectiveAcl)!) { - effectiveAcl = value as symbol; - if (effectiveAcl === AclEdit) break; - } - } - } + if (!target[AclSym] && target instanceof Doc) { + fetchProto(target); } - return effectiveAcl; -} + if (target[AclSym] && Object.keys(target[AclSym]).length) { + + if (target.author === currentUserEmail) return AclEdit; + + if (_overrideAcl || (in_prop && DocServer.PlaygroundFields?.includes(in_prop.toString()))) return AclEdit; -function testPermission(target: any, in_prop: string | symbol | number): boolean { + if (target[AclSym].ACL) return target[AclSym].ACL; - console.log("here"); - // if (target[AclSym].ACL !== AclEdit && !_overrideAcl && !DocServer.PlaygroundFields.includes(in_prop.toString())) return false; - if (target[AclSym].ACL === AclEdit) return true; - for (const [key, value] of Object.entries(target[AclSym])) { - if (key.startsWith("ACL-")) { - if (GroupManager.Instance.currentUserGroups.includes(key.substring(4))) { - if (value === AclEdit) return true; + let effectiveAcl = AclPrivate; + let aclPresent = false; + + for (const [key, value] of Object.entries(target[AclSym])) { + if (key.startsWith("ACL-")) { + if (currentUserGroups.includes(key.substring(4)) || currentUserEmail === key.substring(4).replace("_", ".")) { + if (HierarchyMapping.get(value as symbol)! >= HierarchyMapping.get(effectiveAcl)!) { + aclPresent = true; + effectiveAcl = value as symbol; + if (effectiveAcl === AclEdit) break; + } + } } } + return aclPresent ? effectiveAcl : AclEdit; + } + else { + return AclEdit; } - return _overrideAcl || DocServer.PlaygroundFields.includes(in_prop.toString()); } + const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox", "chromeStatus", "viewType", "gridGap", "xMargin", "yMargin", "autoHeight"]; export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean { - console.log("in setter") let prop = in_prop; - // if (target[AclSym] && !_overrideAcl && !DocServer.PlaygroundFields.includes(in_prop.toString())) return true; // generalise to a testpermission function - if (!testPermission(target, in_prop)) return true; + if (getEffectiveAcl(target, in_prop) !== AclEdit) { + return true; + } if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" && (prop.startsWith("_") || layoutProps.includes(prop))) { if (!prop.startsWith("_")) { console.log(prop + " is deprecated - switch to _" + prop); @@ -176,11 +183,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 { - console.log("in getter") let prop = in_prop; - const effectiveAcl = getEffectiveAcl(target); - if (in_prop === AclSym) return _overrideAcl ? undefined : effectiveAcl; - if (effectiveAcl === AclPrivate && !_overrideAcl) return undefined; + if (in_prop === AclSym) return _overrideAcl ? undefined : target[AclSym]; + if (getEffectiveAcl(target) === AclPrivate && !_overrideAcl) return undefined; if (prop === LayoutSym) { return target.__LAYOUT__; } @@ -217,7 +222,6 @@ function getFieldImpl(target: any, prop: string | number, receiver: any, ignoreP } if (field === undefined && !ignoreProto && prop !== "proto") { const proto = getFieldImpl(target, "proto", receiver, true);//TODO tfs: instead of receiver we could use target[SelfProxy]... I don't which semantics we want or if it really matters - console.log("here"); if (proto instanceof Doc && getEffectiveAcl(proto) !== AclPrivate) { return getFieldImpl(proto[Self], prop, receiver, ignoreProto); } |