1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-29 04:01:24 +00:00

copy/move file to enc lib (#5487)

This commit is contained in:
lian 2024-02-07 11:08:41 +08:00 committed by GitHub
parent a84106bb2a
commit 00c2124dff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 137 additions and 62 deletions

View File

@ -144,7 +144,7 @@ class CopyDirent extends React.Component {
} else {
title = gettext('Copy selected item(s) to:');
}
let mode = this.props.repoEncrypted ? 'only_current_library':'current_repo_and_other_repos';
let mode = 'current_repo_and_other_repos';
return (
<Modal isOpen={true} toggle={this.toggle}>
<ModalHeader toggle={this.toggle}><div dangerouslySetInnerHTML={{__html: title}}></div></ModalHeader>

View File

@ -158,7 +158,7 @@ class MoveDirent extends React.Component {
} else {
title = gettext('Move selected item(s) to:');
}
let mode = this.props.repoEncrypted ? 'only_current_library':'current_repo_and_other_repos';
let mode = 'current_repo_and_other_repos';
const { dirent, selectedDirentList } = this.props;
const movedDirent = dirent ? dirent : selectedDirentList[0];
const { permission } = movedDirent;

View File

@ -692,14 +692,6 @@ class LibContentView extends React.Component {
onMoveItems = (destRepo, destDirentPath) => {
let repoID = this.props.repoID;
let selectedDirentList = this.state.selectedDirentList;
if (repoID !== destRepo.repo_id) {
this.setState(() => ({
asyncOperatedFilesLength: selectedDirentList.length,
asyncOperationProgress: 0,
asyncOperationType: 'move',
isCopyMoveProgressDialogShow: true
}));
}
let dirNames = this.getSelectedDirentNames();
let direntPaths = this.getSelectedDirentPaths();
@ -707,6 +699,10 @@ class LibContentView extends React.Component {
if (repoID !== destRepo.repo_id) {
this.setState({
asyncCopyMoveTaskId: res.data.task_id,
asyncOperatedFilesLength: selectedDirentList.length,
asyncOperationProgress: 0,
asyncOperationType: 'move',
isCopyMoveProgressDialogShow: true
}, () => {
// After moving successfully, delete related files
this.getAsyncCopyMoveProgress();
@ -731,15 +727,19 @@ class LibContentView extends React.Component {
}
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
errMessage = Utils.getMoveFailedMessage(dirNames);
if (!error.response.data.lib_need_decrypt) {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
errMessage = Utils.getCopyFailedMessage(dirNames);
}
toaster.danger(errMessage);
} else {
this.setState({
libNeedDecryptWhenMove: true,
destRepoWhenCopyMove: destRepo,
destDirentPathWhenCopyMove: destDirentPath,
});
}
this.setState({
asyncOperationProgress: 0,
isCopyMoveProgressDialogShow: false,
});
toaster.danger(errMessage);
});
};
@ -747,20 +747,15 @@ class LibContentView extends React.Component {
let repoID = this.props.repoID;
let selectedDirentList = this.state.selectedDirentList;
if (repoID !== destRepo.repo_id) {
this.setState({
asyncOperatedFilesLength: selectedDirentList.length,
asyncOperationProgress: 0,
asyncOperationType: 'copy',
isCopyMoveProgressDialogShow: true
});
}
let dirNames = this.getSelectedDirentNames();
seafileAPI.copyDir(repoID, destRepo.repo_id, destDirentPath, this.state.path, dirNames).then(res => {
if (repoID !== destRepo.repo_id) {
this.setState({
asyncCopyMoveTaskId: res.data.task_id,
asyncOperatedFilesLength: selectedDirentList.length,
asyncOperationProgress: 0,
asyncOperationType: 'copy',
isCopyMoveProgressDialogShow: true
}, () => {
this.getAsyncCopyMoveProgress();
});
@ -780,11 +775,19 @@ class LibContentView extends React.Component {
toaster.success(message);
}
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
errMessage = Utils.getCopyFailedMessage(dirNames);
if (!error.response.data.lib_need_decrypt) {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
errMessage = Utils.getCopyFailedMessage(dirNames);
}
toaster.danger(errMessage);
} else {
this.setState({
libNeedDecryptWhenCopy: true,
destRepoWhenCopyMove: destRepo,
destDirentPathWhenCopyMove: destDirentPath,
});
}
toaster.danger(errMessage);
});
};
@ -1168,18 +1171,15 @@ class LibContentView extends React.Component {
}
let direntPath = Utils.joinPath(nodeParentPath, dirName);
if (repoID !== destRepo.repo_id) {
this.setState({
asyncOperatedFilesLength: 1,
asyncOperationProgress: 0,
asyncOperationType: 'move',
isCopyMoveProgressDialogShow: true,
});
}
seafileAPI.moveDir(repoID, destRepo.repo_id, moveToDirentPath, nodeParentPath, dirName).then(res => {
if (repoID !== destRepo.repo_id) {
this.setState({asyncCopyMoveTaskId: res.data.task_id}, () => {
this.setState({
asyncCopyMoveTaskId: res.data.task_id,
asyncOperatedFilesLength: 1,
asyncOperationProgress: 0,
asyncOperationType: 'move',
isCopyMoveProgressDialogShow: true,
}, () => {
this.currentMoveItemName = dirName;
this.currentMoveItemPath = direntPath;
this.getAsyncCopyMoveProgress(dirName, direntPath);
@ -1205,12 +1205,23 @@ class LibContentView extends React.Component {
toaster.success(message);
}
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
errMessage = gettext('Failed to move {name}.');
errMessage = errMessage.replace('{name}', dirName);
if (!error.response.data.lib_need_decrypt) {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
errMessage = gettext('Failed to move {name}.');
errMessage = errMessage.replace('{name}', dirName);
}
toaster.danger(errMessage);
} else {
this.setState({
libNeedDecryptWhenMove: true,
destRepoWhenCopyMove: destRepo,
destDirentPathWhenCopyMove: moveToDirentPath,
copyMoveSingleItem: true,
srcDirentWhenCopyMove: dirent,
srcNodeParentPathWhenCopyMove: nodeParentPath,
});
}
toaster.danger(errMessage);
});
};
@ -1222,20 +1233,15 @@ class LibContentView extends React.Component {
nodeParentPath = this.state.path;
}
if (repoID !== destRepo.repo_id) {
this.setState({
asyncOperatedFilesLength: 1,
asyncOperationProgress: 0,
asyncOperationType: 'copy',
isCopyMoveProgressDialogShow: true
});
}
seafileAPI.copyDir(repoID, destRepo.repo_id, copyToDirentPath, nodeParentPath, dirName).then(res => {
if (repoID !== destRepo.repo_id) {
this.setState({
asyncCopyMoveTaskId: res.data.task_id,
asyncOperatedFilesLength: 1,
asyncOperationProgress: 0,
asyncOperationType: 'copy',
isCopyMoveProgressDialogShow: true
}, () => {
this.getAsyncCopyMoveProgress();
});
@ -1255,12 +1261,23 @@ class LibContentView extends React.Component {
toaster.success(message);
}
}).catch((error) => {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
errMessage = gettext('Failed to copy %(name)s');
errMessage = errMessage.replace('%(name)s', dirName);
if (!error.response.data.lib_need_decrypt) {
let errMessage = Utils.getErrorMsg(error);
if (errMessage === gettext('Error')) {
errMessage = gettext('Failed to copy %(name)s');
errMessage = errMessage.replace('%(name)s', dirName);
}
toaster.danger(errMessage);
} else {
this.setState({
libNeedDecryptWhenCopy: true,
destRepoWhenCopyMove: destRepo,
destDirentPathWhenCopyMove: copyToDirentPath,
copyMoveSingleItem: true,
srcDirentWhenCopyMove: dirent,
srcNodeParentPathWhenCopyMove: nodeParentPath,
});
}
toaster.danger(errMessage);
});
};
@ -1861,6 +1878,39 @@ class LibContentView extends React.Component {
this.loadDirData(this.state.path);
};
onLibDecryptWhenCopyMove = () => {
if (this.state.libNeedDecryptWhenCopy) {
if (this.state.copyMoveSingleItem) {
this.onCopyItem(this.state.destRepoWhenCopyMove,
this.state.srcDirentWhenCopyMove,
this.state.destDirentPathWhenCopyMove,
this.state.srcNodeParentPathWhenCopyMove)
} else {
this.onCopyItems(this.state.destRepoWhenCopyMove,
this.state.destDirentPathWhenCopyMove)
}
this.setState({
libNeedDecryptWhenCopy: false,
copyMoveSingleItem: false,
});
}
if (this.state.libNeedDecryptWhenMove) {
if (this.state.copyMoveSingleItem) {
this.onMoveItem(this.state.destRepoWhenCopyMove,
this.state.srcDirentWhenCopyMove,
this.state.destDirentPathWhenCopyMove,
this.state.srcNodeParentPathWhenCopyMove)
} else {
this.onMoveItems(this.state.destRepoWhenCopyMove,
this.state.destDirentPathWhenCopyMove)
}
this.setState({
libNeedDecryptWhenMove: false,
copyMoveSingleItem: false,
});
}
}
goDraftPage = () => {
window.open(siteRoot + 'drafts/' + this.state.draftID + '/');
};
@ -1951,6 +2001,17 @@ class LibContentView extends React.Component {
);
}
if (this.state.libNeedDecryptWhenCopy || this.state.libNeedDecryptWhenMove) {
return (
<ModalPortal>
<LibDecryptDialog
repoID={this.state.destRepoWhenCopyMove.repo_id}
onLibDecryptDialog={this.onLibDecryptWhenCopyMove}
/>
</ModalPortal>
);
}
if (this.state.errorMsg) {
return (
<Fragment>

View File

@ -1135,7 +1135,8 @@ class ReposAsyncBatchCopyItemView(APIView):
error_msg = 'Folder %s not found.' % src_parent_dir
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
if not seafile_api.get_repo(dst_repo_id):
dst_repo = seafile_api.get_repo(dst_repo_id)
if not dst_repo:
error_msg = 'Library %s not found.' % dst_repo_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
@ -1155,6 +1156,12 @@ class ReposAsyncBatchCopyItemView(APIView):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# 3. if dst repo is encrypted, should decrypt it first
username = request.user.username
if dst_repo.encrypted and not seafile_api.is_password_set(dst_repo.id, username):
result = {'lib_need_decrypt': True}
return Response(result, status=status.HTTP_403_FORBIDDEN)
dirents_map = {}
dst_dirents = []
for src_dirent in src_dirents:
@ -1255,7 +1262,8 @@ class ReposAsyncBatchMoveItemView(APIView):
error_msg = 'Folder %s not found.' % src_parent_dir
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
if not seafile_api.get_repo(dst_repo_id):
dst_repo = seafile_api.get_repo(dst_repo_id)
if not dst_repo:
error_msg = 'Library %s not found.' % dst_repo_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
@ -1274,6 +1282,12 @@ class ReposAsyncBatchMoveItemView(APIView):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# 3. if dst repo is encrypted, should decrypt it first
username = request.user.username
if dst_repo.encrypted and not seafile_api.is_password_set(dst_repo.id, username):
result = {'lib_need_decrypt': True}
return Response(result, status=status.HTTP_403_FORBIDDEN)
# check locked files
username = request.user.username
locked_files = get_locked_files_by_dir(request, src_repo_id, src_parent_dir)