diff options
Diffstat (limited to 'src/fields/util.ts')
-rw-r--r-- | src/fields/util.ts | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/src/fields/util.ts b/src/fields/util.ts index 1ac450b9a..f9090e977 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -170,6 +170,11 @@ const getEffectiveAclCache = computedFn(function (target: any, user?: string) { return getEffectiveAcl(target, user); }, true); +// return layout acl from cache or chache the acl and return. +const getEffectiveLayoutAclCache = computedFn(function (target: any, user?: string) { + return getEffectiveLayoutAcl(target, user); + }, true); + /** * Calculates the effective access right to a document for the current user. */ @@ -180,14 +185,13 @@ export function GetEffectiveAcl(target: any, user?: string): symbol { } /** - * Calculates the effective access layout right to a document for the current user. By getting the container's effective acl if the layout acl isn't set. - */ +* Calculates the effective access layout right to a document for the current user. By getting the container's effective acl if the layout acl isn't set. +*/ export function GetEffectiveLayoutAcl(target: any, user?: string): symbol { if (!target) return AclPrivate; if (target[UpdatingFromServer]) return AclAdmin; - // if (getEffectiveAclCache(target, user)) return getEffectiveAclCache(target, user); - return getEffectiveAclCache(Doc.GetProto(target['embedContainer']), user); -} + return getEffectiveLayoutAclCache(target, user); + } function getPropAcl(target: any, prop: string | symbol | number) { if (typeof prop === 'symbol' || target[UpdatingFromServer]) return AclAdmin; // requesting the UpdatingFromServer prop or AclSym must always go through to keep the local DB consistent @@ -230,6 +234,43 @@ function getEffectiveAcl(target: any, user?: string): symbol { if (targetAuthor && targetAuthor !== userChecked) return AclPrivate; return AclAdmin; } + +/** +* Returns the layout acl that is effective on the document passed through as the target. If no layout acls +* have been set, it returns the regular acls for the document target is contained in. +*/ +function getEffectiveLayoutAcl(target: any, user?: string): symbol { + const targetAcls = target[DocAcl]; + + 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 (targetAcls && Object.keys(targetAcls).length) { + var effectiveAcl; + for (const [key, value] of Object.entries(targetAcls)) { + const entity = denormalizeEmail(key.substring(4)); // an individual or a group + if ((GetCachedGroupByName(entity) || userChecked === entity || entity === 'Me') && entity != 'Public') { + if (effectiveAcl && HierarchyMapping.get(value as symbol)!.level > HierarchyMapping.get(effectiveAcl)!.level) { + effectiveAcl = value as symbol; + } + else{ + effectiveAcl = value as symbol; + } + } + } + + if (effectiveAcl){ + return DocServer?.Control?.isReadOnly?.() && HierarchyMapping.get(effectiveAcl)!.level < aclLevel.editable ? AclEdit : effectiveAcl; + } + else{ + return GetEffectiveAcl(Doc.GetProto(target['embedContainer']), user); + } + } + // authored documents are private until an ACL is set. + const targetAuthor = target.__fieldTuples?.author || target.author; // target may be a Doc of Proxy, so check __fieldTuples.author and .author + if (targetAuthor && targetAuthor !== userChecked) return AclPrivate; + return AclAdmin; +} + + /** * Recursively distributes the access right for a user across the children of a document and its annotations. * @param key the key storing the access right (e.g. acl-groupname) |