diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/SharingManager.tsx | 60 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 2 | ||||
-rw-r--r-- | src/fields/util.ts | 51 |
3 files changed, 99 insertions, 14 deletions
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx index a95874fd7..59a88b404 100644 --- a/src/client/util/SharingManager.tsx +++ b/src/client/util/SharingManager.tsx @@ -6,11 +6,11 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import Select from 'react-select'; import * as RequestPromise from 'request-promise'; -import { Doc, DocListCast, DocListCastAsync, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc'; +import { Doc, DocCastAsync, DocListCast, DocListCastAsync, HierarchyMapping, ReverseHierarchyMap } from '../../fields/Doc'; import { AclAdmin, AclPrivate, AclUnset, DocAcl, DocData } from '../../fields/DocSymbols'; import { Id } from '../../fields/FieldSymbols'; import { List } from '../../fields/List'; -import { NumCast, StrCast } from '../../fields/Types'; +import { DocCast, NumCast, StrCast } from '../../fields/Types'; import { distributeAcls, GetEffectiveAcl, normalizeEmail, SharingPermissions, TraceMobx } from '../../fields/util'; import { Utils } from '../../Utils'; import { DocServer } from '../DocServer'; @@ -24,6 +24,7 @@ import { GroupManager, UserOptions } from './GroupManager'; import { GroupMemberView } from './GroupMemberView'; import { SelectionManager } from './SelectionManager'; import './SharingManager.scss'; +import { Docs } from '../documents/Documents'; export interface User { email: string; @@ -199,7 +200,7 @@ export class SharingManager extends React.Component<{}> { setInternalGroupSharing = (group: Doc | { title: string }, permission: string, targetDoc?: Doc) => { const target = targetDoc || this.targetDoc!; const key = normalizeEmail(StrCast(group.title)); - const acl = `acl-${key}`; + let acl = `acl-${key}`; const isDashboard = DocListCast(Doc.MyDashboards.data).indexOf(target) !== -1; // setting the same acl for a docs within the doc being shared if they haven't been set yet @@ -213,6 +214,9 @@ export class SharingManager extends React.Component<{}> { const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document); + if (acl == 'acl-Public' && this.layoutDocAcls){ + acl = 'acl-Public-layout'; + } // ! ensures it returns true if document has been shared successfully, false otherwise return !docs .map(doc => (this.layoutDocAcls ? doc : doc[DocData])) @@ -511,7 +515,7 @@ export class SharingManager extends React.Component<{}> { docs = newDocs.filter(doc => GetEffectiveAcl(doc) === AclAdmin); } - const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; + const targetDoc: Doc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; // tslint:disable-next-line: no-unnecessary-callback-wrapper const effectiveAcls = docs.map(doc => GetEffectiveAcl(doc)); @@ -527,7 +531,24 @@ export class SharingManager extends React.Component<{}> { .map(({ user, linkDatabase, sharingDoc, userColor }) => { const userKey = `acl-${normalizeEmail(user.email)}`; const uniform = docs.map(doc => (this.layoutDocAcls ? doc : doc[DocData])).every(doc => doc?.[DocAcl]?.[userKey] === docs[0]?.[DocAcl]?.[userKey]); - const permissions = uniform ? StrCast(targetDoc?.[userKey]) : '-multiple-'; + // const permissions = uniform ? StrCast(targetDoc?.[userKey]) : '-multiple-'; + let permissions = this.layoutDocAcls ? (targetDoc[DocAcl][userKey] ? HierarchyMapping.get(targetDoc[DocAcl][userKey])?.name : StrCast(Doc.GetProto(targetDoc)[userKey])) : StrCast(targetDoc[userKey]); + if (this.layoutDocAcls){ + if (targetDoc[DocAcl][userKey]){ + permissions = HierarchyMapping.get(targetDoc[DocAcl][userKey])?.name; + } + else{ + if (targetDoc['embedContainer']){ + permissions = StrCast(Doc.GetProto(DocCast(targetDoc['embedContainer']))[userKey]); + } + else{ + permissions = uniform ? StrCast(Doc.GetProto(targetDoc)?.[userKey]) : '-multiple-'; + } + } + } + else{ + permissions = uniform ? StrCast(targetDoc?.[userKey]) : '-multiple-'; + } return !permissions ? null : ( <div key={userKey} className={'container'}> @@ -579,12 +600,35 @@ export class SharingManager extends React.Component<{}> { const groupListMap: (Doc | { title: string })[] = groups.filter(({ title }) => (docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(StrCast(title))}`) : true)); groupListMap.unshift({ title: 'Public' }); //, { title: "ALL" }); const groupListContents = groupListMap.map(group => { - const groupKey = `acl-${StrCast(group.title)}`; + let groupKey = `acl-${StrCast(group.title)}`; const uniform = docs .map(doc => (this.layoutDocAcls ? doc : doc[DocData])) .every(doc => (this.layoutDocAcls ? doc?.[DocAcl]?.[groupKey] === docs[0]?.[DocAcl]?.[groupKey] : doc?.[DocData]?.[DocAcl]?.[groupKey] === docs[0]?.[DocData]?.[DocAcl]?.[groupKey])); - const permissions = uniform ? StrCast(targetDoc?.[`acl-${StrCast(group.title)}`]) : '-multiple-'; - + // const permissions = uniform ? StrCast(targetDoc?.[`acl-${StrCast(group.title)}`]) : '-multiple-'; + let permissions = this.layoutDocAcls ? (targetDoc[DocAcl][groupKey] ? HierarchyMapping.get(targetDoc[DocAcl][groupKey])?.name : StrCast(Doc.GetProto(targetDoc)[groupKey])) : StrCast(targetDoc[groupKey]); + if (this.layoutDocAcls){ + if (groupKey == 'acl-Public'){ + groupKey = 'acl-Public-layout' + } + if (targetDoc[DocAcl][groupKey]){ + permissions = HierarchyMapping.get(targetDoc[DocAcl][groupKey])?.name; + } + else{ + if (groupKey == 'acl-Public-layout'){ + groupKey = 'acl-Public' + } + if (targetDoc['embedContainer']){ + permissions = StrCast(Doc.GetProto(DocCast(targetDoc['embedContainer']))[groupKey]); + } + else{ + permissions = uniform ? StrCast(Doc.GetProto(targetDoc)?.[groupKey]) : '-multiple-'; + } + } + } + else{ + permissions = uniform ? StrCast(targetDoc?.[groupKey]) : '-multiple-'; + } + return !permissions ? null : ( <div key={groupKey} className={'container'}> <div className={'padding'}>{StrCast(group.title)}</div> diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 19ab98cea..b9fef5cf8 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -203,7 +203,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P if (effectiveLayoutAcl != AclAdmin && effectiveLayoutAcl != AclEdit && effectiveLayoutAcl != AclAugment){ return false; } -const dragDocView = SelectionManager.Views()[0]; + const dragDocView = SelectionManager.Views()[0]; const containers = new Set<Doc | undefined>(); SelectionManager.Views().forEach(v => containers.add(DocCast(v.rootDoc.embedContainer))); if (containers.size > 1) return false; 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) |