mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-02 07:27:04 +00:00
corrent logic for check generate share link, and share link permissions (#4121)
This commit is contained in:
@@ -25,11 +25,6 @@ class GenerateShareLink extends React.Component {
|
||||
this.isExpireDaysNoLimit = (parseInt(shareLinkExpireDaysMin) === 0 && parseInt(shareLinkExpireDaysMax) === 0 && shareLinkExpireDaysDefault == 0);
|
||||
this.defaultExpireDays = this.isExpireDaysNoLimit ? '' : shareLinkExpireDaysDefault;
|
||||
|
||||
if (isPro) {
|
||||
this.editOption = 'edit_download';
|
||||
this.permissionOptions = ['preview_download', 'preview_only'];
|
||||
}
|
||||
|
||||
this.state = {
|
||||
isValidate: false,
|
||||
isShowPasswordInput: false,
|
||||
@@ -42,7 +37,8 @@ class GenerateShareLink extends React.Component {
|
||||
sharedLinkInfo: null,
|
||||
isNoticeMessageShow: false,
|
||||
isLoading: true,
|
||||
currentPermission: isPro ? this.permissionOptions[0] : '',
|
||||
permissionOptions: [],
|
||||
currentPermission: '',
|
||||
isSendLinkShown: false
|
||||
};
|
||||
}
|
||||
@@ -65,17 +61,34 @@ class GenerateShareLink extends React.Component {
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
|
||||
if (isPro && Utils.isEditableOfficeFile(path)) {
|
||||
seafileAPI.getFileInfo(repoID, path).then((res) => {
|
||||
if (res.data.can_edit) {
|
||||
this.permissionOptions.push(this.editOption);
|
||||
if (isPro) {
|
||||
if (this.props.itemType === 'library') {
|
||||
let permissionOptions = Utils.getShareLinkPermissionList(this.props.itemType, '', path);
|
||||
this.setState({
|
||||
permissionOptions: permissionOptions,
|
||||
currentPermission: permissionOptions[0],
|
||||
});
|
||||
} else {
|
||||
let getDirentInfoAPI;
|
||||
if (this.props.itemType === 'file') {
|
||||
getDirentInfoAPI = seafileAPI.getFileInfo(repoID, path);
|
||||
} else if (this.props.itemType === 'dir') {
|
||||
getDirentInfoAPI = seafileAPI.getDirInfo(repoID, path);
|
||||
}
|
||||
getDirentInfoAPI.then((res) => {
|
||||
let permission = res.data.permission;
|
||||
let permissionOptions = Utils.getShareLinkPermissionList(this.props.itemType, permission, path);
|
||||
this.setState({
|
||||
permissionOptions: permissionOptions,
|
||||
currentPermission: permissionOptions[0],
|
||||
});
|
||||
}).catch(error => {
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onPasswordInputChecked = () => {
|
||||
this.setState({
|
||||
@@ -260,7 +273,6 @@ class GenerateShareLink extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if (this.state.isLoading) {
|
||||
return <Loading />;
|
||||
}
|
||||
@@ -394,7 +406,7 @@ class GenerateShareLink extends React.Component {
|
||||
<span>{gettext('Set permission')}</span>
|
||||
</Label>
|
||||
</FormGroup>
|
||||
{this.permissionOptions.map((item, index) => {
|
||||
{this.state.permissionOptions.map((item, index) => {
|
||||
return (
|
||||
<FormGroup check className="permission" key={index}>
|
||||
<Label className="form-check-label">
|
||||
|
@@ -129,6 +129,7 @@ class ShareDialog extends React.Component {
|
||||
itemPath={this.props.itemPath}
|
||||
repoID={this.props.repoID}
|
||||
closeShareDialog={this.props.toggleDialog}
|
||||
itemType={itemType}
|
||||
/>
|
||||
</TabPane>
|
||||
}
|
||||
@@ -166,6 +167,7 @@ class ShareDialog extends React.Component {
|
||||
|
||||
renderFileContent = () => {
|
||||
let activeTab = this.state.activeTab;
|
||||
const { itemType } = this.props;
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
@@ -190,6 +192,7 @@ class ShareDialog extends React.Component {
|
||||
itemPath={this.props.itemPath}
|
||||
repoID={this.props.repoID}
|
||||
closeShareDialog={this.props.toggleDialog}
|
||||
itemType={itemType}
|
||||
/>
|
||||
</TabPane>
|
||||
{activeTab === 'internalLink' &&
|
||||
|
@@ -494,11 +494,13 @@ class DirentListItem extends React.Component {
|
||||
}
|
||||
|
||||
renderItemOperation = () => {
|
||||
let { dirent, selectedDirentList, currentRepoInfo } = this.props;
|
||||
if (currentRepoInfo.permission === 'cloud-edit' || currentRepoInfo.permission === 'preview') {
|
||||
return '';
|
||||
}
|
||||
let showShareBtn = Utils.isHasPermissionToShare(currentRepoInfo, dirent.permission, dirent);
|
||||
let { dirent, selectedDirentList } = this.props;
|
||||
|
||||
// no need to check whether show shareBtn or not.
|
||||
// according to specification below, shareBtn aways show.
|
||||
// check for "generate uploadlink" or other tabs should put inside the shareDialog.
|
||||
// https://dev.seafile.com/seahub/lib/d6f300e7-bb2b-4722-b83e-cf45e370bfbc/file/seaf-server%20%E5%8A%9F%E8%83%BD%E8%AE%BE%E8%AE%A1/%E6%9D%83%E9%99%90%E7%9B%B8%E5%85%B3/%E8%B5%84%E6%96%99%E5%BA%93%E6%9D%83%E9%99%90%E8%A7%84%E8%8C%83.md
|
||||
// let showShareBtn = Utils.isHasPermissionToShare(currentRepoInfo, dirent.permission, dirent);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
@@ -512,11 +514,9 @@ class DirentListItem extends React.Component {
|
||||
<i className="op-icon sf2-icon-download" title={gettext('Download')} onClick={this.onItemDownload}></i>
|
||||
</li>
|
||||
)}
|
||||
{showShareBtn && (
|
||||
<li className="operation-group-item">
|
||||
<i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i>
|
||||
</li>
|
||||
)}
|
||||
{dirent.permission === 'rw' && (
|
||||
<li className="operation-group-item">
|
||||
<i className="op-icon sf2-icon-delete" title={gettext('Delete')} onClick={this.onItemDelete}></i>
|
||||
@@ -546,7 +546,7 @@ class DirentListItem extends React.Component {
|
||||
<i className="op-icon sf2-icon-download" title={gettext('Download')} onClick={this.onItemDownload}></i>
|
||||
</li>
|
||||
)}
|
||||
{showShareBtn && (
|
||||
{(
|
||||
<li className="operation-group-item">
|
||||
<i className="op-icon sf2-icon-share" title={gettext('Share')} onClick={this.onItemShare}></i>
|
||||
</li>
|
||||
|
@@ -46,6 +46,10 @@ class SelectEditor extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps() {
|
||||
this.setOptions();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('click', this.onHideSelect);
|
||||
}
|
||||
|
@@ -91,56 +91,60 @@ class Item extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const item = this.props.item;
|
||||
|
||||
if (isPro) {
|
||||
this.editOption = 'edit_download';
|
||||
this.permissionOptions = ['preview_download', 'preview_only'];
|
||||
this.updatePermissionOptions();
|
||||
}
|
||||
|
||||
this.state = {
|
||||
currentPermission: isPro ? this.getCurrentPermission() : '',
|
||||
isOpIconShown: false,
|
||||
isOpMenuOpen: false, // for mobile
|
||||
isPermSelectDialogOpen: false, // for mobile
|
||||
isLinkDialogOpen: false
|
||||
isLinkDialogOpen: false,
|
||||
permissionOptions: [],
|
||||
currentPermission: '',
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (isPro) {
|
||||
this.updatePermissionOptions();
|
||||
}
|
||||
}
|
||||
|
||||
updatePermissionOptions = () => {
|
||||
const item = this.props.item;
|
||||
let options = this.permissionOptions;
|
||||
|
||||
if (!Utils.isEditableOfficeFile(item.obj_name)) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (item.permissions.can_edit) {
|
||||
options.push(this.editOption);
|
||||
return ;
|
||||
}
|
||||
|
||||
seafileAPI.getFileInfo(item.repo_id, item.path).then((res) => {
|
||||
if (res.data.can_edit) {
|
||||
options.push(this.editOption);
|
||||
return ;
|
||||
}
|
||||
if (item.is_dir && item.path === '/') {
|
||||
let permissionOptions = Utils.getShareLinkPermissionList('library', '', item.path);
|
||||
this.setState({
|
||||
permissionOptions: permissionOptions,
|
||||
});
|
||||
} else {
|
||||
let { repo_id, path } = item;
|
||||
let getDirentInfoAPI = item.is_dir ? seafileAPI.getDirInfo(repo_id, path) : seafileAPI.getFileInfo(repo_id, path);
|
||||
getDirentInfoAPI.then((res) => {
|
||||
let itemType = item.is_dir ? 'dir' : 'file';
|
||||
let permission = res.data.permission;
|
||||
let permissionOptions = Utils.getShareLinkPermissionList(itemType, permission, item.path);
|
||||
this.setState({
|
||||
permissionOptions: permissionOptions,
|
||||
});
|
||||
}).catch(error => {
|
||||
return ;
|
||||
let errMessage = Utils.getErrorMsg(error);
|
||||
toaster.danger(errMessage);
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
currentPermission: this.getCurrentPermission(),
|
||||
});
|
||||
}
|
||||
|
||||
getCurrentPermission = () => {
|
||||
const options = this.permissionOptions;
|
||||
const { can_edit, can_download } = this.props.item.permissions;
|
||||
switch (`${can_edit} ${can_download}`) {
|
||||
case 'false true':
|
||||
return options[0];
|
||||
return 'preview_download';
|
||||
case 'false false':
|
||||
return options[1];
|
||||
return 'preview_only';
|
||||
case 'true true':
|
||||
return this.editOption;
|
||||
return 'edit_download';
|
||||
case 'true false':
|
||||
return 'cloud_edit';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +218,7 @@ class Item extends Component {
|
||||
|
||||
render() {
|
||||
const item = this.props.item;
|
||||
const { currentPermission, isOpIconShown, isPermSelectDialogOpen, isLinkDialogOpen } = this.state;
|
||||
const { currentPermission, permissionOptions , isOpIconShown, isPermSelectDialogOpen, isLinkDialogOpen } = this.state;
|
||||
|
||||
let iconUrl, objUrl;
|
||||
if (item.is_dir) {
|
||||
@@ -242,7 +246,7 @@ class Item extends Component {
|
||||
isTextMode={true}
|
||||
isEditIconShow={isOpIconShown && !item.is_expired}
|
||||
currentPermission={currentPermission}
|
||||
permissionOptions={this.permissionOptions}
|
||||
permissionOptions={permissionOptions}
|
||||
onPermissionChanged={this.changePerm}
|
||||
/>
|
||||
</td>
|
||||
@@ -294,7 +298,7 @@ class Item extends Component {
|
||||
{isPermSelectDialogOpen &&
|
||||
<ShareLinkPermissionSelect
|
||||
currentPerm={currentPermission}
|
||||
permissions={this.permissionOptions}
|
||||
permissions={permissionOptions}
|
||||
changePerm={this.changePerm}
|
||||
toggleDialog={this.togglePermSelectDialog}
|
||||
/>
|
||||
|
@@ -109,6 +109,39 @@ export const Utils = {
|
||||
}
|
||||
},
|
||||
|
||||
getShareLinkPermissionList: function(itemType, permission, path) {
|
||||
// itemType: library, dir, file
|
||||
// permission: rw, r, admin, cloud-edit, preview
|
||||
|
||||
// if item is library, can preview and download, no need to check
|
||||
// if item is dir, check can download
|
||||
// if item is file, check can download and check can edit
|
||||
|
||||
let editDownloadOption = 'edit_download';
|
||||
let editOnly = 'cloud_edit';
|
||||
let downloadOption = 'preview_download';
|
||||
let permissionOptions = ['preview_only'];
|
||||
|
||||
if (itemType === 'library') {
|
||||
permissionOptions.push(downloadOption);
|
||||
} else if (itemType === 'dir') {
|
||||
if (permission == 'rw' || permission == 'admin' || permission == 'r') {
|
||||
permissionOptions.push(downloadOption);
|
||||
}
|
||||
} else if (itemType === 'file') {
|
||||
if (permission == 'rw' || permission == 'admin' || permission == 'r') {
|
||||
permissionOptions.push(downloadOption);
|
||||
}
|
||||
if (this.isEditableOfficeFile(path) && (permission == 'rw' || permission == 'admin')) {
|
||||
permissionOptions.push(editDownloadOption);
|
||||
}
|
||||
if (this.isEditableOfficeFile(path) && (permission == 'cloud-edit')) {
|
||||
permissionOptions.push(editOnly);
|
||||
}
|
||||
}
|
||||
return permissionOptions;
|
||||
},
|
||||
|
||||
isEditableOfficeFile: function(filename) {
|
||||
// no file ext
|
||||
if (filename.lastIndexOf('.') == -1) {
|
||||
@@ -562,7 +595,19 @@ export const Utils = {
|
||||
"can_download": true
|
||||
}
|
||||
};
|
||||
case 'cloud_edit':
|
||||
return {
|
||||
value: permission,
|
||||
text: gettext('Edit on cloud'),
|
||||
permissionDetails: {
|
||||
'can_edit': true,
|
||||
"can_download": false
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
text: '',
|
||||
};
|
||||
},
|
||||
|
||||
formatSize: function(options) {
|
||||
|
@@ -563,7 +563,8 @@ class DirDetailView(APIView):
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# permission check
|
||||
if not check_folder_permission(request, repo_id, path):
|
||||
permission = check_folder_permission(request, repo_id, path)
|
||||
if not permission:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
@@ -579,6 +580,7 @@ class DirDetailView(APIView):
|
||||
'path': path,
|
||||
'name': dir_obj.obj_name,
|
||||
'mtime': timestamp_to_isoformat_timestr(dir_obj.mtime),
|
||||
'permission': permission,
|
||||
}
|
||||
|
||||
return Response(dir_info)
|
||||
|
@@ -29,7 +29,6 @@ from seahub.utils import gen_shared_link, is_org_context, normalize_file_path, \
|
||||
normalize_dir_path, is_pro_version, get_file_type_and_ext
|
||||
from seahub.utils.file_op import if_locked_by_online_office
|
||||
from seahub.utils.file_types import IMAGE, VIDEO, XMIND
|
||||
from seahub.views import check_folder_permission
|
||||
from seahub.utils.timeutils import datetime_to_isoformat_timestr, \
|
||||
timestamp_to_isoformat_timestr
|
||||
from seahub.utils.repo import parse_repo_perm
|
||||
@@ -288,11 +287,12 @@ class ShareLinks(APIView):
|
||||
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
if parse_repo_perm(check_folder_permission(request, repo_id, path)).can_download is False:
|
||||
username = request.user.username
|
||||
permission_by_path = seafile_api.check_permission_by_path(repo_id, path, username)
|
||||
if parse_repo_perm(permission_by_path).can_generate_share_link is False:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
username = request.user.username
|
||||
org_id = request.user.org.org_id if is_org_context(request) else None
|
||||
if s_type == 'f':
|
||||
fs = FileShare.objects.get_file_link_by_path(username, repo_id, path)
|
||||
|
@@ -54,6 +54,7 @@ def parse_repo_perm(perm):
|
||||
'can_edit_on_web', # edit files on web
|
||||
'can_copy', # copy files/folders on web
|
||||
'can_preview', # preview files on web
|
||||
'can_generate_share_link', # generate share link
|
||||
])
|
||||
|
||||
RP.can_download = True if perm in [
|
||||
@@ -70,6 +71,10 @@ def parse_repo_perm(perm):
|
||||
PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN,
|
||||
PERMISSION_PREVIEW, PERMISSION_PREVIEW_EDIT
|
||||
] else False
|
||||
RP.can_generate_share_link = True if perm in [
|
||||
PERMISSION_READ_WRITE, PERMISSION_READ, PERMISSION_ADMIN,
|
||||
PERMISSION_PREVIEW, PERMISSION_PREVIEW_EDIT
|
||||
] else False
|
||||
return RP
|
||||
|
||||
def list_dir_by_path(cmmt, path):
|
||||
|
Reference in New Issue
Block a user