aboutsummaryrefslogtreecommitdiff
path: root/src/fields
diff options
context:
space:
mode:
Diffstat (limited to 'src/fields')
-rw-r--r--src/fields/Doc.ts24
-rw-r--r--src/fields/util.ts84
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);
}