diff --git a/src/gui/convert.exe b/src/gui/convert.exe new file mode 100644 index 000000000..5f126487e Binary files /dev/null and b/src/gui/convert.exe differ diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 00732bab0..8f61ae20d 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -937,9 +937,14 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo( // If it's not a move it's just a local-NEW if (!moveCheck()) { - postProcessLocalNew(); - finalize(); - return; + const bool isRootEncryptedFolderRename = base._isE2eEncrypted; + if (isRootEncryptedFolderRename) { + // if we're renaming the root encrypted folder, we'd need to mark it's NEW item with _isEncrypted true so the further processing will work correctly + item->_isEncrypted = true; + } + postProcessLocalNew(); + finalize(); + return; } // Check local permission if we are allowed to put move the file here diff --git a/src/libsync/owncloudpropagator.h b/src/libsync/owncloudpropagator.h index ba36ce344..4160191db 100644 --- a/src/libsync/owncloudpropagator.h +++ b/src/libsync/owncloudpropagator.h @@ -178,12 +178,15 @@ protected slots: private: QScopedPointer _restoreJob; + JobParallelism _parallelism; public: PropagateItemJob(OwncloudPropagator *propagator, const SyncFileItemPtr &item) : PropagatorJob(propagator) , _item(item) + , _parallelism(FullParallelism) { + _parallelism = (_item->_isEncrypted || hasEncryptedAncestor()) ? WaitForFinished : FullParallelism; } ~PropagateItemJob(); @@ -199,6 +202,8 @@ public: return true; } + virtual JobParallelism parallelism() override { return _parallelism; } + SyncFileItemPtr _item; public slots: diff --git a/src/libsync/propagateremotedelete.cpp b/src/libsync/propagateremotedelete.cpp index 4dc8ecf3c..26073e7bc 100644 --- a/src/libsync/propagateremotedelete.cpp +++ b/src/libsync/propagateremotedelete.cpp @@ -26,11 +26,6 @@ namespace OCC { Q_LOGGING_CATEGORY(lcPropagateRemoteDelete, "nextcloud.sync.propagator.remotedelete", QtInfoMsg) -PropagatorJob::JobParallelism PropagateRemoteDelete::parallelism() -{ - return _item->_encryptedFileName.isEmpty() ? FullParallelism : WaitForFinished; -} - void PropagateRemoteDelete::start() { if (propagator()->_abortRequested) diff --git a/src/libsync/propagateremotedelete.h b/src/libsync/propagateremotedelete.h index 57d0aeafc..4385e4545 100644 --- a/src/libsync/propagateremotedelete.h +++ b/src/libsync/propagateremotedelete.h @@ -37,7 +37,6 @@ public: : PropagateItemJob(propagator, item) { } - JobParallelism parallelism() override; void start() override; void createDeleteJob(const QString &filename); void abort(PropagatorJob::AbortType abortType) override; diff --git a/src/libsync/propagateremotemkdir.cpp b/src/libsync/propagateremotemkdir.cpp index 8b7228d99..4ce07ddac 100644 --- a/src/libsync/propagateremotemkdir.cpp +++ b/src/libsync/propagateremotemkdir.cpp @@ -32,7 +32,7 @@ PropagateRemoteMkdir::PropagateRemoteMkdir(OwncloudPropagator *propagator, const : PropagateItemJob(propagator, item) , _deleteExisting(false) , _uploadEncryptedHelper(nullptr) - , _parallelism(FullParallelism) + , _isEncryptedRootFolder(_item->_isEncrypted && _item->_encryptedFileName.isEmpty()) { const auto path = _item->_file; const auto slashPosition = path.lastIndexOf('/'); @@ -43,15 +43,6 @@ PropagateRemoteMkdir::PropagateRemoteMkdir(OwncloudPropagator *propagator, const if (!ok) { return; } - - if (hasEncryptedAncestor()) { - _parallelism = WaitForFinished; - } -} - -PropagatorJob::JobParallelism PropagateRemoteMkdir::parallelism() -{ - return _parallelism; } void PropagateRemoteMkdir::start() @@ -203,7 +194,7 @@ void PropagateRemoteMkdir::slotMkcolJobFinished() return; } - if (!_uploadEncryptedHelper) { + if (!_uploadEncryptedHelper && !_isEncryptedRootFolder) { success(); } else { // We still need to mark that folder encrypted @@ -212,7 +203,7 @@ void PropagateRemoteMkdir::slotMkcolJobFinished() // We're expecting directory path in /Foo/Bar convention... Q_ASSERT(_job->path().startsWith('/') && !_job->path().endsWith('/')); // But encryption job expect it in Foo/Bar/ convention - const auto path = _job->path().mid(1); + const auto path = _isEncryptedRootFolder ? _job->path() : _job->path().mid(1); auto job = new OCC::EncryptFolderJob(propagator()->account(), propagator()->_journal, path, _item->_fileId, this); connect(job, &OCC::EncryptFolderJob::finished, this, &PropagateRemoteMkdir::slotEncryptFolderFinished); diff --git a/src/libsync/propagateremotemkdir.h b/src/libsync/propagateremotemkdir.h index 43de418ee..1cbe4defe 100644 --- a/src/libsync/propagateremotemkdir.h +++ b/src/libsync/propagateremotemkdir.h @@ -30,13 +30,10 @@ class PropagateRemoteMkdir : public PropagateItemJob QPointer _job; bool _deleteExisting; PropagateUploadEncrypted *_uploadEncryptedHelper; - JobParallelism _parallelism; friend class PropagateDirectory; // So it can access the _item; public: PropagateRemoteMkdir(OwncloudPropagator *propagator, const SyncFileItemPtr &item); - JobParallelism parallelism() override; - void start() override; void abort(PropagatorJob::AbortType abortType) override; @@ -60,5 +57,8 @@ private slots: void propfindResult(const QVariantMap &); void propfindError(); void success(); + +private: + bool _isEncryptedRootFolder = false; }; } diff --git a/src/libsync/propagateremotemove.cpp b/src/libsync/propagateremotemove.cpp index df9935a7d..7735c46bd 100644 --- a/src/libsync/propagateremotemove.cpp +++ b/src/libsync/propagateremotemove.cpp @@ -85,6 +85,31 @@ void PropagateRemoteMove::start() if (origin == _item->_renameTarget) { // The parent has been renamed already so there is nothing more to do. + + if (!_item->_encryptedFileName.isEmpty()) { + const auto path = _item->_file; + const auto slashPosition = path.lastIndexOf('/'); + const auto parentPath = slashPosition >= 0 ? path.left(slashPosition) : QString(); + + SyncJournalFileRecord parentRec; + bool ok = propagator()->_journal->getFileRecord(parentPath, &parentRec); + if (!ok) { + done(SyncFileItem::NormalError); + return; + } + + // We should be encrypted as well since our parent is + const auto remoteParentPath = parentRec._e2eMangledName.isEmpty() ? parentPath : parentRec._e2eMangledName; + + const auto lastSlashPosition = _item->_encryptedFileName.lastIndexOf('/'); + const auto encryptedName = slashPosition >= 0 ? _item->_encryptedFileName.mid(lastSlashPosition + 1) : QString(); + + if (!encryptedName.isEmpty()) { + _item->_encryptedFileName = remoteParentPath + "/" + encryptedName; + } + + } + finalize(); return; } diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index 7a6653ea4..7f4cf6d86 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -192,7 +192,6 @@ PropagateUploadFileCommon::PropagateUploadFileCommon(OwncloudPropagator *propaga , _finished(false) , _deleteExisting(false) , _aborting(false) - , _parallelism(FullParallelism) , _uploadEncryptedHelper(nullptr) , _uploadingEncrypted(false) { @@ -205,15 +204,6 @@ PropagateUploadFileCommon::PropagateUploadFileCommon(OwncloudPropagator *propaga if (!ok) { return; } - - if (hasEncryptedAncestor()) { - _parallelism = WaitForFinished; - } -} - -PropagatorJob::JobParallelism PropagateUploadFileCommon::parallelism() -{ - return _parallelism; } void PropagateUploadFileCommon::setDeleteExisting(bool enabled) diff --git a/src/libsync/propagateupload.h b/src/libsync/propagateupload.h index d04f10172..38a50b7d4 100644 --- a/src/libsync/propagateupload.h +++ b/src/libsync/propagateupload.h @@ -231,13 +231,10 @@ protected: }; UploadFileInfo _fileToUpload; QByteArray _transmissionChecksumHeader; - JobParallelism _parallelism; public: PropagateUploadFileCommon(OwncloudPropagator *propagator, const SyncFileItemPtr &item); - JobParallelism parallelism() override; - /** * Whether an existing entity with the same name may be deleted before * the upload.