aboutsummaryrefslogtreecommitdiff
path: root/src/fields/util.ts
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2023-07-07 15:57:51 -0400
committerbobzel <zzzman@gmail.com>2023-07-07 15:57:51 -0400
commitcf88809ea2299395db70ce608c193df7f24f0fb2 (patch)
tree57206a4b1281410a4371c5ae4616d388e1d694b7 /src/fields/util.ts
parent0f0d646e45de42c7f84f6fa316c80d1413f92e5c (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.ts60
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