diff options
author | bobzel <zzzman@gmail.com> | 2023-07-07 15:57:51 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2023-07-07 15:57:51 -0400 |
commit | cf88809ea2299395db70ce608c193df7f24f0fb2 (patch) | |
tree | 57206a4b1281410a4371c5ae4616d388e1d694b7 /src/fields/util.ts | |
parent | 0f0d646e45de42c7f84f6fa316c80d1413f92e5c (diff) |
fixed self-ownership of copied Docs created by someone else. prevent dash from being pasted into itself. fixed inheritance of acls
Diffstat (limited to 'src/fields/util.ts')
-rw-r--r-- | src/fields/util.ts | 60 |
1 files changed, 25 insertions, 35 deletions
diff --git a/src/fields/util.ts b/src/fields/util.ts index 0e9940ced..815f3b186 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -65,7 +65,9 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number const sameAuthor = fromServer || receiver.author === Doc.CurrentUserEmail; const writeToDoc = sameAuthor || effectiveAcl === AclEdit || effectiveAcl === AclAdmin || writeMode === DocServer.WriteMode.Playground || writeMode === DocServer.WriteMode.LivePlayground || (effectiveAcl === AclAugment && value instanceof RichTextField); - const writeToServer = (sameAuthor || effectiveAcl === AclEdit || effectiveAcl === AclAdmin || (effectiveAcl === AclAugment && Doc.CurrentUserEmail !== 'guest' && value instanceof RichTextField)) && !DocServer.Control.isReadOnly(); + const writeToServer = + !DocServer.Control.isReadOnly() && // + (sameAuthor || effectiveAcl === AclEdit || effectiveAcl === AclAdmin || (effectiveAcl === AclAugment && value instanceof RichTextField)); if (writeToDoc) { if (value === undefined) { @@ -230,52 +232,40 @@ function getEffectiveAcl(target: any, user?: string): symbol { * @param inheritingFromCollection whether the target is being assigned rights after being dragged into a collection (and so is inheriting the acls from the collection) * inheritingFromCollection is not currently being used but could be used if acl assignment defaults change */ -export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, inheritingFromCollection?: boolean, visited?: Doc[]) { +export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, visited?: Doc[], allowUpgrade?: boolean) { + const selfKey = `acl-${Doc.CurrentUserEmailNormalized}`; if (!visited) visited = [] as Doc[]; - if (!target || visited.includes(target)) return; - if ((target._type_collection === CollectionViewType.Docking && visited.length > 1) || Doc.GetProto(visited[0]) !== Doc.GetProto(target)) { - if (target.author !== Doc.CurrentUserEmail || key !== `acl-${Doc.CurrentUserEmailNormalized}`) { - target[key] = acl; - } - if (target !== Doc.GetProto(target)) { - //apparently we can't call updateCachedAcls twice (once for the main dashboard, and again for the nested dashboard...???) - updateCachedAcls(target); - } - //return; - } + if (!target || visited.includes(target) || key === selfKey) return; visited.push(target); - let layoutDocChanged = false; // determines whether fetchProto should be called or not (i.e. is there a change that should be reflected in target[AclSym]) - // if it is inheriting from a collection, it only inherits if A) the key doesn't already exist or B) the right being inherited is more restrictive - if (GetEffectiveAcl(target) === AclAdmin && (!inheritingFromCollection || !target[key] || ReverseHierarchyMap.get(StrCast(target[key]))!.level > ReverseHierarchyMap.get(acl)!.level)) { - if (target.author !== Doc.CurrentUserEmail || key !== `acl-${Doc.CurrentUserEmailNormalized}`) { - target[key] = acl; - layoutDocChanged = true; - } - } - let dataDocChanged = false; const dataDoc = target[DocData]; - if (dataDoc && (!inheritingFromCollection || !dataDoc[key] || ReverseHierarchyMap.get(StrCast(dataDoc[key]))! > ReverseHierarchyMap.get(acl)!)) { - if (GetEffectiveAcl(dataDoc) === AclAdmin && (target.author !== Doc.CurrentUserEmail || key !== `acl-${Doc.CurrentUserEmailNormalized}`)) { - dataDoc[key] = acl; - dataDocChanged = true; - } + if (dataDoc && (allowUpgrade || !dataDoc[key] || ReverseHierarchyMap.get(StrCast(dataDoc[key]))! > ReverseHierarchyMap.get(acl)!)) { + // propagate ACLs to links, children, and annotations - // maps over the links of the document - LinkManager.Links(dataDoc).forEach(link => distributeAcls(key, acl, link, inheritingFromCollection, visited)); + LinkManager.Links(dataDoc).forEach(link => distributeAcls(key, acl, link, visited, allowUpgrade)); - // maps over the children of the document DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc)]).forEach(d => { - distributeAcls(key, acl, d, inheritingFromCollection, visited); - d !== d[DocData] && distributeAcls(key, acl, d[DocData], inheritingFromCollection, visited); + distributeAcls(key, acl, d, visited, allowUpgrade); + d !== d[DocData] && distributeAcls(key, acl, d[DocData], visited, allowUpgrade); }); - // maps over the annotations of the document DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc) + '_annotations']).forEach(d => { - distributeAcls(key, acl, d, inheritingFromCollection, visited); - d !== d[DocData] && distributeAcls(key, acl, d[DocData], inheritingFromCollection, visited); + distributeAcls(key, acl, d, visited, allowUpgrade); + d !== d[DocData] && distributeAcls(key, acl, d[DocData], visited, allowUpgrade); }); + + if (GetEffectiveAcl(dataDoc) === AclAdmin) { + dataDoc[key] = acl; + dataDocChanged = true; + } + } + + let layoutDocChanged = false; // determines whether fetchProto should be called or not (i.e. is there a change that should be reflected in target[AclSym]) + // if it is inheriting from a collection, it only inherits if A) allowUpgrade is set B) the key doesn't already exist or c) the right being inherited is more restrictive + if (GetEffectiveAcl(target) === AclAdmin && (allowUpgrade || !target[key] || ReverseHierarchyMap.get(StrCast(target[key]))!.level > ReverseHierarchyMap.get(acl)!.level)) { + target[key] = acl; + layoutDocChanged = true; } layoutDocChanged && updateCachedAcls(target); // updates target[AclSym] when changes to acls have been made |