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:
@@ -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>
|
||||||
|
@@ -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}
|
||||||
|
@@ -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}
|
||||||
|
@@ -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>
|
||||||
|
@@ -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}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
@@ -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}
|
||||||
/>
|
/>
|
||||||
|
@@ -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>
|
||||||
|
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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>
|
||||||
|
@@ -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}
|
||||||
|
@@ -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>
|
||||||
|
@@ -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}
|
||||||
|
Reference in New Issue
Block a user