aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/SharingManager.tsx60
-rw-r--r--src/client/views/DocumentDecorations.tsx2
-rw-r--r--src/fields/util.ts51
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)