1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-01 23:20:51 +00:00

[share] added permission check (#2900)

This commit is contained in:
llj
2019-01-29 10:06:26 +08:00
committed by Daniel Pan
parent 53f42e4283
commit d9a2f6ded9
12 changed files with 193 additions and 29 deletions

View File

@@ -1,7 +1,7 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Modal, ModalHeader, ModalBody, TabContent, TabPane, Nav, NavItem, NavLink } from 'reactstrap'; import { Modal, ModalHeader, ModalBody, TabContent, TabPane, Nav, NavItem, NavLink } from 'reactstrap';
import { gettext } from '../../utils/constants'; import { gettext, canGenerateShareLink, canGenerateUploadLink } from '../../utils/constants';
import ShareToUser from './share-to-user'; import ShareToUser from './share-to-user';
import ShareToGroup from './share-to-group'; import ShareToGroup from './share-to-group';
import GenerateShareLink from './generate-share-link'; import GenerateShareLink from './generate-share-link';
@@ -21,10 +21,24 @@ class ShareDialog extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
activeTab: 'shareLink' activeTab: this.getInitialActiveTab()
}; };
} }
getInitialActiveTab = () => {
const {repoEncrypted, userPerm, enableDirPrivateShare} = this.props;
const enableShareLink = !repoEncrypted && canGenerateShareLink;
const enableUploadLink = !repoEncrypted && canGenerateUploadLink && userPerm == 'rw';
if (enableShareLink) {
return 'shareLink';
} else if (enableUploadLink) {
return 'uploadLink';
} else if (enableDirPrivateShare) {
return 'shareToUser';
}
}
toggle = (tab) => { toggle = (tab) => {
if (this.state.activeTab !== tab) { if (this.state.activeTab !== tab) {
this.setState({activeTab: tab}); this.setState({activeTab: tab});
@@ -33,20 +47,31 @@ class ShareDialog extends React.Component {
renderDirContent = () => { renderDirContent = () => {
let activeTab = this.state.activeTab; let activeTab = this.state.activeTab;
const {repoEncrypted, userPerm, enableDirPrivateShare} = this.props;
const enableShareLink = !repoEncrypted && canGenerateShareLink;
const enableUploadLink = !repoEncrypted && canGenerateUploadLink && userPerm == 'rw';
return ( return (
<Fragment> <Fragment>
<div className="share-dialog-side"> <div className="share-dialog-side">
<Nav pills vertical> <Nav pills vertical>
{enableShareLink &&
<NavItem> <NavItem>
<NavLink className={activeTab === 'shareLink' ? 'active' : ''} onClick={this.toggle.bind(this, 'shareLink')}> <NavLink className={activeTab === 'shareLink' ? 'active' : ''} onClick={this.toggle.bind(this, 'shareLink')}>
{gettext('Share Link')} {gettext('Share Link')}
</NavLink> </NavLink>
</NavItem> </NavItem>
}
{enableUploadLink &&
<NavItem> <NavItem>
<NavLink className={activeTab === 'uploadLink' ? 'active' : ''} onClick={this.toggle.bind(this, 'uploadLink')}> <NavLink className={activeTab === 'uploadLink' ? 'active' : ''} onClick={this.toggle.bind(this, 'uploadLink')}>
{gettext('Upload Link')} {gettext('Upload Link')}
</NavLink> </NavLink>
</NavItem> </NavItem>
}
{enableDirPrivateShare &&
<Fragment>
<NavItem> <NavItem>
<NavLink className={activeTab === 'shareToUser' ? 'active' : ''} onClick={this.toggle.bind(this, 'shareToUser')}> <NavLink className={activeTab === 'shareToUser' ? 'active' : ''} onClick={this.toggle.bind(this, 'shareToUser')}>
{gettext('Share to user')} {gettext('Share to user')}
@@ -57,10 +82,13 @@ class ShareDialog extends React.Component {
{gettext('Share to group')} {gettext('Share to group')}
</NavLink> </NavLink>
</NavItem> </NavItem>
</Fragment>
}
</Nav> </Nav>
</div> </div>
<div className="share-dialog-main"> <div className="share-dialog-main">
<TabContent activeTab={this.state.activeTab}> <TabContent activeTab={this.state.activeTab}>
{enableShareLink &&
<TabPane tabId="shareLink"> <TabPane tabId="shareLink">
<GenerateShareLink <GenerateShareLink
itemPath={this.props.itemPath} itemPath={this.props.itemPath}
@@ -68,6 +96,8 @@ class ShareDialog extends React.Component {
closeShareDialog={this.props.toggleDialog} closeShareDialog={this.props.toggleDialog}
/> />
</TabPane> </TabPane>
}
{enableUploadLink &&
<TabPane tabId="uploadLink"> <TabPane tabId="uploadLink">
<GenerateUploadLink <GenerateUploadLink
itemPath={this.props.itemPath} itemPath={this.props.itemPath}
@@ -75,12 +105,17 @@ class ShareDialog extends React.Component {
closeShareDialog={this.props.toggleDialog} closeShareDialog={this.props.toggleDialog}
/> />
</TabPane> </TabPane>
}
{enableDirPrivateShare &&
<Fragment>
<TabPane tabId="shareToUser"> <TabPane tabId="shareToUser">
<ShareToUser isGroupOwnedRepo={this.props.isGroupOwnedRepo} itemPath={this.props.itemPath} repoID={this.props.repoID} /> <ShareToUser isGroupOwnedRepo={this.props.isGroupOwnedRepo} itemPath={this.props.itemPath} repoID={this.props.repoID} />
</TabPane> </TabPane>
<TabPane tabId="shareToGroup"> <TabPane tabId="shareToGroup">
<ShareToGroup isGroupOwnedRepo={this.props.isGroupOwnedRepo} itemPath={this.props.itemPath} repoID={this.props.repoID} /> <ShareToGroup isGroupOwnedRepo={this.props.isGroupOwnedRepo} itemPath={this.props.itemPath} repoID={this.props.repoID} />
</TabPane> </TabPane>
</Fragment>
}
</TabContent> </TabContent>
</div> </div>
</Fragment> </Fragment>
@@ -116,14 +151,15 @@ class ShareDialog extends React.Component {
} }
render() { render() {
let { itemType, itemName } = this.props; const { itemType, itemName, repoEncrypted } = this.props;
const enableShareLink = !repoEncrypted && canGenerateShareLink;
return ( return (
<div> <div>
<Modal isOpen={true} style={{maxWidth: '720px'}} className="share-dialog"> <Modal isOpen={true} style={{maxWidth: '720px'}} className="share-dialog">
<ModalHeader toggle={this.props.toggleDialog}>{gettext('Share')} <span className="sf-font" title={itemName}>{itemName}</span></ModalHeader> <ModalHeader toggle={this.props.toggleDialog}>{gettext('Share')} <span className="sf-font" title={itemName}>{itemName}</span></ModalHeader>
<ModalBody className="dialog-list-container share-dialog-content"> <ModalBody className="dialog-list-container share-dialog-content">
{(itemType === 'library' || itemType === 'dir') && this.renderDirContent()} {(itemType === 'library' || itemType === 'dir') && this.renderDirContent()}
{itemType === 'file' && this.renderFileContent()} {(itemType === 'file' && enableShareLink) && this.renderFileContent()}
</ModalBody> </ModalBody>
</Modal> </Modal>
</div> </div>

View File

@@ -23,6 +23,10 @@ const propTypes = {
repoName: PropTypes.string.isRequired, repoName: PropTypes.string.isRequired,
repoEncrypted: PropTypes.bool.isRequired, repoEncrypted: PropTypes.bool.isRequired,
showShareBtn: PropTypes.bool.isRequired, showShareBtn: PropTypes.bool.isRequired,
enableDirPrivateShare: PropTypes.bool.isRequired,
userPerm: PropTypes.string.isRequired,
isAdmin: PropTypes.bool.isRequired,
isGroupOwnedRepo: PropTypes.bool.isRequired,
pathExist: PropTypes.bool.isRequired, pathExist: PropTypes.bool.isRequired,
permission: PropTypes.bool.isRequired, permission: PropTypes.bool.isRequired,
isDirentListLoading: PropTypes.bool.isRequired, isDirentListLoading: PropTypes.bool.isRequired,
@@ -66,16 +70,10 @@ class DirPanel extends React.Component {
currentDirent: null, currentDirent: null,
currentMode: 'list', currentMode: 'list',
isDirentDetailShow: false, isDirentDetailShow: false,
isRepoOwner: false,
}; };
} }
componentDidMount() { componentDidMount() {
let currentRepoInfo = this.props.currentRepoInfo;
if (currentRepoInfo) {
let isRepoOwner = currentRepoInfo.owner_email === username;
this.setState({isRepoOwner: isRepoOwner});
}
} }
onPathClick = (path) => { onPathClick = (path) => {
@@ -156,7 +154,13 @@ class DirPanel extends React.Component {
isViewFile={false} isViewFile={false}
path={this.props.path} path={this.props.path}
repoID={this.props.repoID} repoID={this.props.repoID}
repoName={this.props.repoName}
repoEncrypted={this.props.repoEncrypted}
showShareBtn={this.props.showShareBtn} showShareBtn={this.props.showShareBtn}
enableDirPrivateShare={this.props.enableDirPrivateShare}
userPerm={this.props.userPerm}
isAdmin={this.props.isAdmin}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
direntList={this.props.direntList} direntList={this.props.direntList}
onAddFile={this.props.onAddFile} onAddFile={this.props.onAddFile}
onAddFolder={this.props.onAddFolder} onAddFolder={this.props.onAddFolder}
@@ -213,6 +217,10 @@ class DirPanel extends React.Component {
path={this.props.path} path={this.props.path}
repoID={this.props.repoID} repoID={this.props.repoID}
repoEncrypted={this.props.repoEncrypted} repoEncrypted={this.props.repoEncrypted}
isRepoOwner={this.props.isRepoOwner}
isAdmin={this.props.isAdmin}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
enableDirPrivateShare={this.props.enableDirPrivateShare}
direntList={this.props.direntList} direntList={this.props.direntList}
sortBy={this.props.sortBy} sortBy={this.props.sortBy}
sortOrder={this.props.sortOrder} sortOrder={this.props.sortOrder}
@@ -220,7 +228,6 @@ class DirPanel extends React.Component {
currentRepoInfo={this.props.currentRepoInfo} currentRepoInfo={this.props.currentRepoInfo}
isDirentListLoading={this.props.isDirentListLoading} isDirentListLoading={this.props.isDirentListLoading}
isAllItemSelected={this.props.isAllDirentSelected} isAllItemSelected={this.props.isAllDirentSelected}
isRepoOwner={this.state.isRepoOwner}
onAddFile={this.props.onAddFile} onAddFile={this.props.onAddFile}
onDirentClick={this.onDirentClick} onDirentClick={this.onDirentClick}
onItemDetails={this.onItemDetails} onItemDetails={this.onItemDetails}

View File

@@ -1,7 +1,7 @@
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import moment from 'moment'; import moment from 'moment';
import { siteRoot, canGenerateShareLink, canGenerateUploadLink, username } from '../../utils/constants'; import { isPro, siteRoot, canGenerateShareLink, canGenerateUploadLink, username } from '../../utils/constants';
import { seafileAPI } from '../../utils/seafile-api'; import { seafileAPI } from '../../utils/seafile-api';
import { Utils } from '../../utils/utils'; import { Utils } from '../../utils/utils';
import { gettext } from '../../utils/constants'; import { gettext } from '../../utils/constants';
@@ -31,6 +31,7 @@ class DirView extends React.Component {
repoName: '', repoName: '',
repoID: '', repoID: '',
repoEncrypted: false, repoEncrypted: false,
isGroupOwnedRepo: false,
isAdmin: false, isAdmin: false,
ownerEmail: '', ownerEmail: '',
userPerm: '', userPerm: '',
@@ -91,12 +92,22 @@ class DirView extends React.Component {
repoID: repoInfo.repo_id, repoID: repoInfo.repo_id,
repoName: repoInfo.repo_name, repoName: repoInfo.repo_name,
repoEncrypted: repoInfo.encrypted, repoEncrypted: repoInfo.encrypted,
isVirtual: repoInfo.is_virtual,
isAdmin: repoInfo.is_admin, isAdmin: repoInfo.is_admin,
ownerEmail: repoInfo.owner_email, ownerEmail: repoInfo.owner_email,
permission: repoInfo.permission === 'rw', permission: repoInfo.permission === 'rw',
libNeedDecrypt: res.data.lib_need_decrypt, libNeedDecrypt: res.data.lib_need_decrypt,
}); });
const ownerEmail = repoInfo.owner_email;
if (repoInfo.owner_email.indexOf('@seafile_group') != -1) {
const groupID = ownerEmail.substring(0, ownerEmail.indexOf('@'));
this.getGroupInfo(groupID);
this.setState({
isGroupOwnedRepo: true
});
}
let repoName = repoInfo.repo_name; let repoName = repoInfo.repo_name;
let repoID = repoInfo.repo_id; let repoID = repoInfo.repo_id;
let path = location.slice(location.indexOf(repoID) + repoID.length); // get the string after repoID let path = location.slice(location.indexOf(repoID) + repoID.length); // get the string after repoID
@@ -138,6 +149,16 @@ class DirView extends React.Component {
this.lastModifyTime = new Date(); this.lastModifyTime = new Date();
} }
getGroupInfo = (groupID) => {
seafileAPI.getGroup(groupID).then(res => {
if (res.data.admins.indexOf(username) != -1) {
this.setState({
isDepartmentAdmin: true
});
}
});
}
onRepoUpdateEvent = () => { onRepoUpdateEvent = () => {
let currentTime = new Date(); let currentTime = new Date();
if ((parseFloat(currentTime - this.lastModifyTime)/1000) <= 5) { if ((parseFloat(currentTime - this.lastModifyTime)/1000) <= 5) {
@@ -669,14 +690,18 @@ class DirView extends React.Component {
} }
render() { render() {
let showShareBtn = false; let showShareBtn = false,
const { repoEncrypted, isAdmin, ownerEmail, userPerm } = this.state; enableDirPrivateShare = false;
const { repoEncrypted, isAdmin, ownerEmail, userPerm, isVirtual, isDepartmentAdmin } = this.state;
const isRepoOwner = ownerEmail == username; const isRepoOwner = ownerEmail == username;
if (!repoEncrypted && ( if (!repoEncrypted && (
canGenerateShareLink || canGenerateUploadLink || canGenerateShareLink || canGenerateUploadLink ||
isRepoOwner || isAdmin) && ( isRepoOwner || isAdmin) && (
userPerm == 'rw' || userPerm == 'r')) { userPerm == 'rw' || userPerm == 'r')) {
showShareBtn = true; showShareBtn = true;
if (!isVirtual && (isRepoOwner || isAdmin || isDepartmentAdmin)) {
enableDirPrivateShare = true;
}
} }
return ( return (
@@ -694,6 +719,11 @@ class DirView extends React.Component {
isDirentSelected={this.state.isDirentSelected} isDirentSelected={this.state.isDirentSelected}
isAllDirentSelected={this.state.isAllDirentSelected} isAllDirentSelected={this.state.isAllDirentSelected}
showShareBtn={showShareBtn} showShareBtn={showShareBtn}
enableDirPrivateShare={enableDirPrivateShare}
userPerm={userPerm}
isRepoOwner={isRepoOwner}
isAdmin={isAdmin}
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
direntList={this.state.direntList} direntList={this.state.direntList}
sortBy={this.state.sortBy} sortBy={this.state.sortBy}
sortOrder={this.state.sortOrder} sortOrder={this.state.sortOrder}

View File

@@ -2,7 +2,7 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import MD5 from 'MD5'; import MD5 from 'MD5';
import { UncontrolledTooltip } from 'reactstrap'; import { UncontrolledTooltip } from 'reactstrap';
import { gettext, siteRoot, mediaUrl } from '../../utils/constants'; import { gettext, siteRoot, mediaUrl, canGenerateShareLink, canGenerateUploadLink } from '../../utils/constants';
import { Utils } from '../../utils/utils'; import { Utils } from '../../utils/utils';
import { seafileAPI } from '../../utils/seafile-api'; import { seafileAPI } from '../../utils/seafile-api';
import URLDecorator from '../../utils/url-decorator'; import URLDecorator from '../../utils/url-decorator';
@@ -365,6 +365,14 @@ class DirentListItem extends React.Component {
iconUrl = Utils.getFolderIconUrl({isReadOnly, size}); iconUrl = Utils.getFolderIconUrl({isReadOnly, size});
} }
const {repoEncrypted, isRepoOwner, isAdmin} = this.props;
let showShare = false;
if (!repoEncrypted &&
(dirent.permission == 'rw' || dirent.permission == 'r')) {
showShare = dirent.type == 'file' ? canGenerateShareLink :
(canGenerateShareLink || canGenerateUploadLink || (isRepoOwner || isAdmin));
}
return ( return (
<Fragment> <Fragment>
<tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.onMouseEnter} onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave} onClick={this.onDirentClick}> <tr className={this.state.highlight ? 'tr-highlight' : ''} onMouseEnter={this.onMouseEnter} onMouseOver={this.onMouseOver} onMouseLeave={this.onMouseLeave} onClick={this.onDirentClick}>
@@ -415,9 +423,11 @@ class DirentListItem extends React.Component {
<li className="operation-group-item"> <li className="operation-group-item">
<i className="op-icon sf2-icon-download" title={gettext('Download')} onClick={this.onItemDownload}></i> <i className="op-icon sf2-icon-download" title={gettext('Download')} onClick={this.onItemDownload}></i>
</li> </li>
{showShare &&
<li className="operation-group-item"> <li className="operation-group-item">
<i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i> <i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i>
</li> </li>
}
<li className="operation-group-item"> <li className="operation-group-item">
<i className="op-icon sf2-icon-delete" title={gettext('Delete')} onClick={this.onItemDelete}></i> <i className="op-icon sf2-icon-delete" title={gettext('Delete')} onClick={this.onItemDelete}></i>
</li> </li>
@@ -476,7 +486,12 @@ class DirentListItem extends React.Component {
itemType={dirent.type} itemType={dirent.type}
itemName={dirent.name} itemName={dirent.name}
itemPath={direntPath} itemPath={direntPath}
userPerm={dirent.permission}
repoID={this.props.repoID} repoID={this.props.repoID}
repoEncrypted={false}
enableDirPrivateShare={this.props.enableDirPrivateShare}
isAdmin={this.props.isAdmin}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
toggleDialog={this.closeSharedDialog} toggleDialog={this.closeSharedDialog}
/> />
</ModalPortal> </ModalPortal>

View File

@@ -267,6 +267,10 @@ class DirentListView extends React.Component {
onDirentClick={this.props.onDirentClick} onDirentClick={this.props.onDirentClick}
onItemDetails={this.onItemDetails} onItemDetails={this.onItemDetails}
showImagePopup={this.showImagePopup} showImagePopup={this.showImagePopup}
repoEncrypted={this.props.repoEncrypted}
enableDirPrivateShare={this.props.enableDirPrivateShare}
isAdmin={this.props.isAdmin}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
/> />
); );
}) })

View File

@@ -313,6 +313,8 @@ class SharedRepoListItem extends React.Component {
renderPCUI = () => { renderPCUI = () => {
let { iconUrl, iconTitle, libPath } = this.getRepoComputeParams(); let { iconUrl, iconTitle, libPath } = this.getRepoComputeParams();
let { repo } = this.props; let { repo } = this.props;
// TODO: enableDirPrivateShare, isGroupOwnedRepo
let isGroupOwnedRepo = repo.owner_email.indexOf('@seafile_group') > -1; let isGroupOwnedRepo = repo.owner_email.indexOf('@seafile_group') > -1;
return ( return (
<Fragment> <Fragment>
@@ -331,6 +333,10 @@ class SharedRepoListItem extends React.Component {
itemName={repo.repo_name} itemName={repo.repo_name}
itemPath={'/'} itemPath={'/'}
repoID={repo.repo_id} repoID={repo.repo_id}
repoEncrypted={repo.encrypted}
enableDirPrivateShare={true}
userPerm={repo.permission}
isAdmin={repo.is_admin}
isGroupOwnedRepo={isGroupOwnedRepo} isGroupOwnedRepo={isGroupOwnedRepo}
toggleDialog={this.toggleShareDialog} toggleDialog={this.toggleShareDialog}
/> />
@@ -363,6 +369,10 @@ class SharedRepoListItem extends React.Component {
itemName={repo.repo_name} itemName={repo.repo_name}
itemPath={'/'} itemPath={'/'}
repoID={repo.repo_id} repoID={repo.repo_id}
repoEncrypted={repo.encrypted}
enableDirPrivateShare={true}
userPerm={repo.permission}
isAdmin={repo.is_admin}
isGroupOwnedRepo={isGroupOwnedRepo} isGroupOwnedRepo={isGroupOwnedRepo}
toggleDialog={this.toggleShareDialog} toggleDialog={this.toggleShareDialog}
/> />

View File

@@ -177,9 +177,9 @@ class DirOperationToolbar extends React.Component {
} }
render() { render() {
let { path, isViewFile } = this.props; let { path, isViewFile, repoName } = this.props;
let itemType = isViewFile ? 'file' : 'dir'; let itemType = isViewFile ? 'file' : 'dir';
let itemName = isViewFile ? Utils.getFileName(path) : Utils.getFolderName(path); let itemName = isViewFile ? Utils.getFileName(path) : (path == '/' ? repoName : Utils.getFolderName(path));
return ( return (
<Fragment> <Fragment>
<div className="operation"> <div className="operation">
@@ -251,6 +251,11 @@ class DirOperationToolbar extends React.Component {
itemName={itemName} itemName={itemName}
itemPath={this.props.path} itemPath={this.props.path}
repoID={this.props.repoID} repoID={this.props.repoID}
repoEncrypted={this.props.repoEncrypted}
enableDirPrivateShare={this.props.enableDirPrivateShare}
userPerm={this.props.userPerm}
isAdmin={this.props.isAdmin}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
toggleDialog={this.onShareClick} toggleDialog={this.onShareClick}
/> />
</ModalPortal> </ModalPortal>

View File

@@ -15,6 +15,9 @@ class Repo {
this.modifier_email = object.modifier_email; this.modifier_email = object.modifier_email;
this.modifier_name = object.modifier_name; this.modifier_name = object.modifier_name;
this.type = object.type; this.type = object.type;
if (object.is_admin != undefined) {
this.is_admin = object.is_admin;
}
} }
} }

View File

@@ -270,6 +270,9 @@ class Item extends Component {
itemName={data.repo_name} itemName={data.repo_name}
itemPath={'/'} itemPath={'/'}
repoID={data.repo_id} repoID={data.repo_id}
repoEncrypted={data.encrypted}
enableDirPrivateShare={true}
userPerm={data.permission}
toggleDialog={this.toggleShareDialog} toggleDialog={this.toggleShareDialog}
/> />
</ModalPotal> </ModalPotal>
@@ -298,6 +301,9 @@ class Item extends Component {
itemName={data.repo_name} itemName={data.repo_name}
itemPath={'/'} itemPath={'/'}
repoID={data.repo_id} repoID={data.repo_id}
repoEncrypted={data.encrypted}
enableDirPrivateShare={true}
userPerm={data.permission}
toggleDialog={this.toggleShareDialog} toggleDialog={this.toggleShareDialog}
/> />
</ModalPotal> </ModalPotal>

View File

@@ -23,8 +23,13 @@ const propTypes = {
permission: PropTypes.string, permission: PropTypes.string,
hash: PropTypes.string, hash: PropTypes.string,
path: PropTypes.string.isRequired, path: PropTypes.string.isRequired,
repoName: PropTypes.string.isRequired,
repoEncrypted: PropTypes.bool.isRequired, repoEncrypted: PropTypes.bool.isRequired,
showShareBtn: PropTypes.bool.isRequired, showShareBtn: PropTypes.bool.isRequired,
enableDirPrivateShare: PropTypes.bool.isRequired,
userPerm: PropTypes.string.isRequired,
isAdmin: PropTypes.bool.isRequired,
isGroupOwnedRepo: PropTypes.bool.isRequired,
// whether the file or dir corresponding to the path exist // whether the file or dir corresponding to the path exist
pathExist: PropTypes.bool.isRequired, pathExist: PropTypes.bool.isRequired,
isFileLoading: PropTypes.bool.isRequired, isFileLoading: PropTypes.bool.isRequired,
@@ -78,20 +83,14 @@ class MainPanel extends Component {
currentDirent: null, currentDirent: null,
direntPath: '', direntPath: '',
currentRepoInfo: null, currentRepoInfo: null,
isRepoOwner: false,
}; };
} }
componentDidMount() { componentDidMount() {
seafileAPI.getRepoInfo(repoID).then(res => { seafileAPI.getRepoInfo(repoID).then(res => {
let repoInfo = new RepoInfo(res.data); let repoInfo = new RepoInfo(res.data);
seafileAPI.getAccountInfo().then(res => { this.setState({
let user_email = res.data.email; currentRepoInfo: repoInfo,
let isRepoOwner = repoInfo.owner_email === user_email;
this.setState({
currentRepoInfo: repoInfo,
isRepoOwner: isRepoOwner,
});
}); });
}); });
if (this.props.hash) { if (this.props.hash) {
@@ -185,12 +184,18 @@ class MainPanel extends Component {
<DirOperationToolBar <DirOperationToolBar
path={this.props.path} path={this.props.path}
repoID={repoID} repoID={repoID}
repoName={this.props.repoName}
repoEncrypted={this.props.repoEncrypted}
isDraft={this.props.isDraft} isDraft={this.props.isDraft}
hasDraft={this.props.hasDraft} hasDraft={this.props.hasDraft}
direntList={this.props.direntList} direntList={this.props.direntList}
permission={this.props.permission} permission={this.props.permission}
isViewFile={this.props.isViewFile} isViewFile={this.props.isViewFile}
showShareBtn={this.props.showShareBtn} showShareBtn={this.props.showShareBtn}
enableDirPrivateShare={this.props.enableDirPrivateShare}
userPerm={this.props.userPerm}
isAdmin={this.props.isAdmin}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
onAddFile={this.props.onAddFile} onAddFile={this.props.onAddFile}
onAddFolder={this.props.onAddFolder} onAddFolder={this.props.onAddFolder}
onUploadFile={this.onUploadFile} onUploadFile={this.onUploadFile}
@@ -262,6 +267,10 @@ class MainPanel extends Component {
path={this.props.path} path={this.props.path}
repoID={repoID} repoID={repoID}
repoEncrypted={this.props.repoEncrypted} repoEncrypted={this.props.repoEncrypted}
isRepoOwner={this.props.isRepoOwner}
isAdmin={this.props.isAdmin}
isGroupOwnedRepo={this.props.isGroupOwnedRepo}
enableDirPrivateShare={this.props.enableDirPrivateShare}
direntList={this.props.direntList} direntList={this.props.direntList}
sortBy={this.props.sortBy} sortBy={this.props.sortBy}
sortOrder={this.props.sortOrder} sortOrder={this.props.sortOrder}
@@ -277,7 +286,6 @@ class MainPanel extends Component {
isDirentListLoading={this.props.isDirentListLoading} isDirentListLoading={this.props.isDirentListLoading}
updateDirent={this.props.updateDirent} updateDirent={this.props.updateDirent}
currentRepoInfo={this.state.currentRepoInfo} currentRepoInfo={this.state.currentRepoInfo}
isRepoOwner={this.state.isRepoOwner}
isAllItemSelected={this.props.isAllDirentSelected} isAllItemSelected={this.props.isAllDirentSelected}
onAllItemSelected={this.props.onAllDirentSelected} onAllItemSelected={this.props.onAllDirentSelected}
onItemSelected={this.props.onItemSelected} onItemSelected={this.props.onItemSelected}

View File

@@ -177,7 +177,6 @@ class Item extends Component {
} }
render() { render() {
if (this.state.unshared) { if (this.state.unshared) {
return null; return null;
} }
@@ -227,6 +226,10 @@ class Item extends Component {
itemName={data.repo_name} itemName={data.repo_name}
itemPath={'/'} itemPath={'/'}
repoID={data.repo_id} repoID={data.repo_id}
repoEncrypted={data.encrypted}
enableDirPrivateShare={true}
userPerm={data.permission}
isAdmin={true}
toggleDialog={this.toggleShareDialog} toggleDialog={this.toggleShareDialog}
/> />
</ModalPotal> </ModalPotal>
@@ -258,6 +261,10 @@ class Item extends Component {
itemName={data.repo_name} itemName={data.repo_name}
itemPath={'/'} itemPath={'/'}
repoID={data.repo_id} repoID={data.repo_id}
repoEncrypted={data.encrypted}
enableDirPrivateShare={true}
userPerm={data.permission}
isAdmin={true}
toggleDialog={this.toggleShareDialog} toggleDialog={this.toggleShareDialog}
/> />
</ModalPotal> </ModalPotal>

View File

@@ -30,7 +30,9 @@ class Wiki extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
repoName: '',
repoEncrypted: false, repoEncrypted: false,
isGroupOwnedRepo: false,
isAdmin: false, isAdmin: false,
ownerEmail: '', ownerEmail: '',
userPerm: '', userPerm: '',
@@ -83,11 +85,22 @@ class Wiki extends Component {
let repoInfo = new RepoInfo(res.data); let repoInfo = new RepoInfo(res.data);
this.setState({ this.setState({
libNeedDecrypt: res.data.lib_need_decrypt, libNeedDecrypt: res.data.lib_need_decrypt,
repoName: repoInfo.repo_name,
repoEncrypted: repoInfo.encrypted, repoEncrypted: repoInfo.encrypted,
isVirtual: repoInfo.is_virtual,
isAdmin: repoInfo.is_admin, isAdmin: repoInfo.is_admin,
ownerEmail: repoInfo.owner_email ownerEmail: repoInfo.owner_email
}); });
const ownerEmail = repoInfo.owner_email;
if (repoInfo.owner_email.indexOf('@seafile_group') != -1) {
const groupID = ownerEmail.substring(0, ownerEmail.indexOf('@'));
this.getGroupInfo(groupID);
this.setState({
isGroupOwnedRepo: true
});
}
if (!res.data.lib_need_decrypt) { if (!res.data.lib_need_decrypt) {
this.loadWikiData(); this.loadWikiData();
} }
@@ -102,6 +115,16 @@ class Wiki extends Component {
this.lastModifyTime = new Date(); this.lastModifyTime = new Date();
} }
getGroupInfo = (groupID) => {
seafileAPI.getGroup(groupID).then(res => {
if (res.data.admins.indexOf(username) != -1) {
this.setState({
isDepartmentAdmin: true
});
}
});
}
onRepoUpdateEvent = () => { onRepoUpdateEvent = () => {
let currentTime = new Date(); let currentTime = new Date();
if ((parseFloat(currentTime - this.lastModifyTime)/1000) <= 5) { if ((parseFloat(currentTime - this.lastModifyTime)/1000) <= 5) {
@@ -1018,14 +1041,18 @@ class Wiki extends Component {
) )
} }
let showShareBtn = false; let showShareBtn = false,
const { repoEncrypted, isAdmin, ownerEmail, userPerm } = this.state; enableDirPrivateShare = false;
const { repoEncrypted, isAdmin, ownerEmail, userPerm, isVirtual, isDepartmentAdmin } = this.state;
const isRepoOwner = ownerEmail == username; const isRepoOwner = ownerEmail == username;
if (!repoEncrypted && ( if (!repoEncrypted && (
canGenerateShareLink || canGenerateUploadLink || canGenerateShareLink || canGenerateUploadLink ||
isRepoOwner || isAdmin) && ( isRepoOwner || isAdmin) && (
userPerm == 'rw' || userPerm == 'r')) { userPerm == 'rw' || userPerm == 'r')) {
showShareBtn = true; showShareBtn = true;
if (!isVirtual && (isRepoOwner || isAdmin || isDepartmentAdmin)) {
enableDirPrivateShare = true;
}
} }
return ( return (
@@ -1047,6 +1074,7 @@ class Wiki extends Component {
/> />
<MainPanel <MainPanel
path={this.state.path} path={this.state.path}
repoName={this.state.repoName}
repoEncrypted={this.state.repoEncrypted} repoEncrypted={this.state.repoEncrypted}
isViewFile={this.state.isViewFile} isViewFile={this.state.isViewFile}
pathExist={this.state.pathExist} pathExist={this.state.pathExist}
@@ -1057,6 +1085,11 @@ class Wiki extends Component {
lastModified={this.state.lastModified} lastModified={this.state.lastModified}
latestContributor={this.state.latestContributor} latestContributor={this.state.latestContributor}
showShareBtn={showShareBtn} showShareBtn={showShareBtn}
enableDirPrivateShare={enableDirPrivateShare}
userPerm={userPerm}
isRepoOwner={isRepoOwner}
isAdmin={isAdmin}
isGroupOwnedRepo={this.state.isGroupOwnedRepo}
direntList={this.state.direntList} direntList={this.state.direntList}
sortBy={this.state.sortBy} sortBy={this.state.sortBy}
sortOrder={this.state.sortOrder} sortOrder={this.state.sortOrder}