diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/SharingManager.tsx | 4 | ||||
-rw-r--r-- | src/client/views/DocComponent.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 2 | ||||
-rw-r--r-- | src/fields/util.ts | 44 |
4 files changed, 28 insertions, 24 deletions
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index 0c8f19eae..914253e3c 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -177,7 +177,7 @@ export class SharingManager extends React.Component<{}> { users.forEach(({ user, sharingDoc }) => { if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); // add the doc to the sharingDoc if it hasn't already been added - else GetEffectiveAcl(doc, undefined, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); // remove the doc from the list if it already exists + else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); // remove the doc from the list if it already exists }); } }); @@ -273,7 +273,7 @@ export class SharingManager extends React.Component<{}> { distributeAcls(acl, permission as SharingPermissions, doc); if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); - else GetEffectiveAcl(doc, undefined, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); + else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); }); } diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx index 98e888538..a55f4adaf 100644 --- a/src/client/views/DocComponent.tsx +++ b/src/client/views/DocComponent.tsx @@ -164,7 +164,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T return false; } else { - if (this.props.Document[AclSym]) { + if (this.props.Document[AclSym] && Object.keys(this.props.Document[AclSym]).length) { added.forEach(d => { for (const [key, value] of Object.entries(this.props.Document[AclSym])) { if (d.author === denormalizeEmail(key.substring(4)) && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true); diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index cfd24545b..a27fa5a66 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -140,7 +140,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus return false; } else { - if (this.props.Document[AclSym]) { + if (this.props.Document[AclSym] && Object.keys(this.props.Document[AclSym])) { added.forEach(d => { for (const [key, value] of Object.entries(this.props.Document[AclSym])) { if (d.author === denormalizeEmail(key.substring(4)) && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true); diff --git a/src/fields/util.ts b/src/fields/util.ts index 56736028a..dd0444d61 100644 --- a/src/fields/util.ts +++ b/src/fields/util.ts @@ -155,32 +155,35 @@ export enum SharingPermissions { } // return acl from cache or cache the acl and return. bcz: Argh! NOT WORKING ... nothing gets invalidated properly.... -const getEffectiveAclCache = computedFn(function (target: any, playgroundProp: boolean, user?: string) { return getEffectiveAcl(target, playgroundProp, user); }, true); +const getEffectiveAclCache = computedFn(function (target: any, user?: string) { return getEffectiveAcl(target, user); }, true); /** * Calculates the effective access right to a document for the current user. */ -export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number, user?: string): symbol { - if (!target) return AclPrivate; - if (in_prop === UpdatingFromServer) return AclAdmin; // requesting the UpdatingFromServer prop must always go through to keep the local DB consistent - const playgroundProp = in_prop && DocServer.PlaygroundFields?.includes(in_prop.toString()) ? true : false; - return getEffectiveAcl(target, playgroundProp, user); +export function GetEffectiveAcl(target: any, user?: string): symbol { + return target ? getEffectiveAcl(target, user) : AclPrivate; } -function getEffectiveAcl(target: any, playgroundProp: boolean, user?: string): symbol { +function getPropAcl(target: any, prop: string | symbol | number) { + if (prop === UpdatingFromServer) return AclAdmin; // requesting the UpdatingFromServer prop must always go through to keep the local DB consistent + if (prop && DocServer.PlaygroundFields?.includes(prop.toString())) return AclEdit; // playground props are always editable + return GetEffectiveAcl(target); +} + +let HierarchyMapping: Map<symbol, number> | undefined; + +function getEffectiveAcl(target: any, user?: string): symbol { if (target[UpdatingFromServer]) return AclAdmin; // all changes received from the server must be processed as Admin // if the current user is the author of the document / the current user is a member of the admin group const userChecked = user || Doc.CurrentUserEmail; - if (userChecked === (target.__fields?.author || target.author)) return AclAdmin; + if (userChecked === (target.__fields?.author || target.author)) return AclAdmin; // target may be a Doc of Proxy, so check __fields.author and .author if (SnappingManager.GetCachedGroupByName("Admin")) return AclAdmin; + const targetAcls = target[AclSym]; - if (target[AclSym] && Object.keys(target[AclSym]).length) { + if (targetAcls && Object.keys(targetAcls).length) { + if (_overrideAcl) return AclEdit; - // if the acl is being overriden or the property being modified is one of the playground fields (which can be freely modified) - if (_overrideAcl || playgroundProp) return AclEdit; - - let effectiveAcl = AclPrivate; - const HierarchyMapping = new Map<symbol, number>([ + HierarchyMapping = HierarchyMapping || new Map<symbol, number>([ [AclPrivate, 0], [AclReadonly, 1], [AclAddonly, 2], @@ -188,12 +191,13 @@ function getEffectiveAcl(target: any, playgroundProp: boolean, user?: string): s [AclAdmin, 4] ]); - for (const [key, value] of Object.entries(target[AclSym])) { + let effectiveAcl = AclPrivate; + for (const [key, value] of Object.entries(targetAcls)) { // there are issues with storing fields with . in the name, so they are replaced with _ during creation // as a result we need to restore them again during this comparison. const entity = denormalizeEmail(key.substring(4)); // an individual or a group - if (SnappingManager.GetCachedGroupByName(entity) || userChecked === entity) { - if (HierarchyMapping.get(value as symbol)! > HierarchyMapping.get(effectiveAcl)!) { + if (HierarchyMapping.get(value as symbol)! > HierarchyMapping.get(effectiveAcl)!) { + if (SnappingManager.GetCachedGroupByName(entity) || userChecked === entity) { effectiveAcl = value as symbol; if (effectiveAcl === AclAdmin) return effectiveAcl; } @@ -201,8 +205,8 @@ function getEffectiveAcl(target: any, playgroundProp: boolean, user?: string): s } // if there's an overriding acl set through the properties panel or sharing menu, that's what's returned if the user isn't an admin of the document - const override = target[AclSym]["acl-Override"]; - if (override !== AclUnset && override !== undefined) effectiveAcl = target[AclSym]["acl-Override"]; + const override = targetAcls["acl-Override"]; + if (override !== AclUnset && override !== undefined) effectiveAcl = override; // if we're in playground mode, return AclEdit (or AclAdmin if that's the user's effectiveAcl) return DocServer?.Control?.isReadOnly?.() && HierarchyMapping.get(effectiveAcl)! < 3 ? AclEdit : effectiveAcl; @@ -282,7 +286,7 @@ const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHe "chromeStatus", "viewType", "gridGap", "xMargin", "yMargin", "autoHeight"]; export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean { let prop = in_prop; - const effectiveAcl = GetEffectiveAcl(target, in_prop); + const effectiveAcl = getPropAcl(target, prop); if (effectiveAcl !== AclEdit && effectiveAcl !== AclAdmin) return true; // if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't |