diff options
author | bobzel <zzzman@gmail.com> | 2022-12-21 11:11:39 -0500 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2022-12-21 11:11:39 -0500 |
commit | e373e66f8ed06f4501e00af8348f15ad113c7424 (patch) | |
tree | 911b512c544d6d522d5899e6dced1123e5789c61 /src/fields/Doc.ts | |
parent | b71e828bc3e6c48d00dade555968c99b5deb412e (diff) |
cleaning up ACLs for performance and clarity
Diffstat (limited to 'src/fields/Doc.ts')
-rw-r--r-- | src/fields/Doc.ts | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index 40152551e..51313a8df 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -113,28 +113,37 @@ export const Initializing = Symbol('Initializing'); export const ForceServerWrite = Symbol('ForceServerWrite'); export const CachedUpdates = Symbol('Cached updates'); -const AclMap = new Map<string, symbol>([ - ['None', AclUnset], - [SharingPermissions.None, AclPrivate], - [SharingPermissions.View, AclReadonly], - [SharingPermissions.Augment, AclAugment], - [SharingPermissions.SelfEdit, AclSelfEdit], - [SharingPermissions.Edit, AclEdit], - [SharingPermissions.Admin, AclAdmin], +export enum aclLevel { + unset = -1, + unshared = 0, + viewable = 1, + augmentable = 2, + selfEditable = 2.5, + editable = 3, + admin = 4, +} +// prettier-ignore +export const HierarchyMapping: Map<symbol, { level:aclLevel; name: SharingPermissions }> = new Map([ + [AclPrivate, { level: aclLevel.unshared, name: SharingPermissions.None }], + [AclReadonly, { level: aclLevel.viewable, name: SharingPermissions.View }], + [AclAugment, { level: aclLevel.augmentable, name: SharingPermissions.Augment}], + [AclSelfEdit, { level: aclLevel.selfEditable, name: SharingPermissions.SelfEdit }], + [AclEdit, { level: aclLevel.editable, name: SharingPermissions.Edit }], + [AclAdmin, { level: aclLevel.admin, name: SharingPermissions.Admin }], + [AclUnset, { level: aclLevel.unset, name: SharingPermissions.Unset }], ]); +export const ReverseHierarchyMap: Map<string, { level: aclLevel; acl: symbol }> = new Map(Array.from(HierarchyMapping.entries()).map(value => [value[1].name, { level: value[1].level, acl: value[0] }])); // caches the document access permissions for the current user. // this recursively updates all protos as well. export function updateCachedAcls(doc: Doc) { if (!doc) return; - const permissions: { [key: string]: symbol } = {}; - - doc[UpdatingFromServer] = true; - Object.keys(doc).filter(key => key.startsWith('acl') && (permissions[key] = AclMap.get(StrCast(doc[key]))!)); - doc[UpdatingFromServer] = false; - if (Object.keys(permissions).length) { - doc[AclSym] = permissions; + const target = (doc as any)?.__fields ?? doc; + const permissions: { [key: string]: symbol } = !target.author || target.author === Doc.CurrentUserEmail ? { 'acl-Me': AclAdmin } : {}; + Object.keys(target).filter(key => key.startsWith('acl') && (permissions[key] = ReverseHierarchyMap.get(StrCast(target[key]))!.acl)); + if (Object.keys(permissions).length || doc[AclSym]?.length) { + runInAction(() => (doc[AclSym] = permissions)); } if (doc.proto instanceof Promise) { @@ -329,6 +338,7 @@ export class Doc extends RefField { @observable private ___fields: any = {}; @observable private ___fieldKeys: any = {}; + /// all of the raw acl's that have been set on this document. Use GetEffectiveAcl to determine the actual ACL of the doc for editing @observable public [AclSym]: { [key: string]: symbol } = {}; @observable public [DirectLinksSym]: Set<Doc> = new Set(); @observable public [AnimationSym]: Opt<Doc>; @@ -939,6 +949,7 @@ export namespace Doc { export function MakeCopy(doc: Doc, copyProto: boolean = false, copyProtoId?: string, retitle = false): Doc { const copy = new Doc(copyProtoId, true); + updateCachedAcls(copy); const exclude = Cast(doc.cloneFieldFilter, listSpec('string'), []); Object.keys(doc).forEach(key => { if (exclude.includes(key)) return; @@ -989,6 +1000,7 @@ export namespace Doc { if (doc) { const delegate = new Doc(id, true); delegate[Initializing] = true; + updateCachedAcls(delegate); delegate.proto = doc; delegate.author = Doc.CurrentUserEmail; Object.keys(doc) |