qCDebug(lcPropagateDownload) << _item->_file << propagator()->_activeJobList.count();
- if (propagator()->account()->capabilities().clientSideEncryptionAvailable()) {
- _downloadEncryptedHelper = new PropagateDownloadEncrypted(propagator(), _item, this);
+ const auto rootPath = [=]() {
+ const auto result = propagator()->_remoteFolder;
+ if (result.startsWith('/')) {
+ return result.mid(1);
+ } else {
+ return result;
+ }
+ }();
+ const auto remotePath = QString(rootPath + _item->_file);
+ const auto remoteParentPath = remotePath.left(remotePath.lastIndexOf('/'));
+
+ const auto account = propagator()->account();
+ if (!account->capabilities().clientSideEncryptionAvailable() ||
+ !account->e2e()->isFolderEncrypted(remoteParentPath + '/')) {
+ startAfterIsEncryptedIsChecked();
+ } else {
+ SyncJournalFileRecord parentRec;
+ propagator()->_journal->getFileRecordByE2eMangledName(remoteParentPath, &parentRec);
+ const auto parentPath = parentRec.isValid() ? parentRec._path : remoteParentPath;
+
+ _downloadEncryptedHelper = new PropagateDownloadEncrypted(propagator(), parentPath, _item, this);
connect(_downloadEncryptedHelper, &PropagateDownloadEncrypted::folderStatusNotEncrypted, [this] {
startAfterIsEncryptedIsChecked();
});
tr("File %1 can not be downloaded because encryption information is missing.").arg(QDir::toNativeSeparators(_item->_file)));
});
_downloadEncryptedHelper->start();
- } else {
- startAfterIsEncryptedIsChecked();
}
}
if (_item->_directDownloadUrl.isEmpty()) {
// Normal job, download from oC instance
_job = new GETFileJob(propagator()->account(),
- propagator()->_remoteFolder + _item->_file,
+ propagator()->_remoteFolder + (_isEncrypted ? _item->_encryptedFileName : _item->_file),
&_tmpFile, headers, expectedEtagForResume, _resumeStart, this);
} else {
// We were provided a direct URL, use that one
namespace OCC {
-PropagateDownloadEncrypted::PropagateDownloadEncrypted(OwncloudPropagator *propagator, SyncFileItemPtr item, QObject *parent)
+PropagateDownloadEncrypted::PropagateDownloadEncrypted(OwncloudPropagator *propagator, const QString &localParentPath, SyncFileItemPtr item, QObject *parent)
: QObject(parent)
, _propagator(propagator)
+ , _localParentPath(localParentPath)
, _item(item)
, _info(_item->_file)
{
if (encryptedFilename == file.encryptedFilename) {
_encryptedInfo = file;
_item->_encryptedFileName = _item->_file;
- _item->_file = _item->_file.section(QLatin1Char('/'), 0, -2) + QLatin1Char('/') + _encryptedInfo.originalFilename;
+ _item->_file = _localParentPath + QLatin1Char('/') + _encryptedInfo.originalFilename;
qCDebug(lcPropagateDownloadEncrypted) << "Found matching encrypted metadata for file, starting download";
emit folderStatusEncrypted();
class PropagateDownloadEncrypted : public QObject {
Q_OBJECT
public:
- PropagateDownloadEncrypted(OwncloudPropagator *propagator, SyncFileItemPtr item, QObject *parent = nullptr);
+ PropagateDownloadEncrypted(OwncloudPropagator *propagator, const QString &localParentPath, SyncFileItemPtr item, QObject *parent = nullptr);
void start();
void checkFolderId(const QStringList &list);
bool decryptFile(QFile& tmpFile);
private:
OwncloudPropagator *_propagator;
+ QString _localParentPath;
SyncFileItemPtr _item;
QFileInfo _info;
EncryptedFile _encryptedInfo;
* for more details.
*/
+#include "account.h"
+#include "propagatedownloadencrypted.h"
#include "propagatorjobs.h"
#include "owncloudpropagator.h"
#include "owncloudpropagator_p.h"
if (propagator()->_abortRequested.fetchAndAddRelaxed(0))
return;
+ const auto rootPath = [=]() {
+ const auto result = propagator()->_remoteFolder;
+ if (result.startsWith('/')) {
+ return result.mid(1);
+ } else {
+ return result;
+ }
+ }();
+ const auto remotePath = QString(rootPath + _item->_file);
+ const auto remoteParentPath = remotePath.left(remotePath.lastIndexOf('/'));
+
+ const auto account = propagator()->account();
+ if (!account->capabilities().clientSideEncryptionAvailable() ||
+ !account->e2e()->isFolderEncrypted(remoteParentPath + '/')) {
+ startLocalMkdir();
+ } else {
+ SyncJournalFileRecord parentRec;
+ propagator()->_journal->getFileRecordByE2eMangledName(remoteParentPath, &parentRec);
+ const auto parentPath = parentRec.isValid() ? parentRec._path : remoteParentPath;
+ startDemanglingName(parentPath);
+ }
+}
+
+void PropagateLocalMkdir::setDeleteExistingFile(bool enabled)
+{
+ _deleteExistingFile = enabled;
+}
+
+void PropagateLocalMkdir::startLocalMkdir()
+{
QDir newDir(propagator()->getFilePath(_item->_file));
QString newDirStr = QDir::toNativeSeparators(newDir.path());
done(resultStatus);
}
-void PropagateLocalMkdir::setDeleteExistingFile(bool enabled)
+void PropagateLocalMkdir::startDemanglingName(const QString &parentPath)
{
- _deleteExistingFile = enabled;
+ auto downloadEncryptedHelper = new PropagateDownloadEncrypted(propagator(), parentPath, _item, this);
+ connect(downloadEncryptedHelper, &PropagateDownloadEncrypted::folderStatusEncrypted,
+ this, &PropagateLocalMkdir::startLocalMkdir);
+ connect(downloadEncryptedHelper, &PropagateDownloadEncrypted::folderStatusNotEncrypted, this, [this] {
+ // We were wrong after all? Actually might happen due to legacy clients creating broken encrypted folders
+ qCDebug(lcPropagateLocalMkdir) << "Parent of" << _item->_file << "wasn't encrypted, creating with the original name";
+ startLocalMkdir();
+ });
+ connect(downloadEncryptedHelper, &PropagateDownloadEncrypted::failed, [this] {
+ // This also might happen due to legacy clients creating broken encrypted folders...
+ qCDebug(lcPropagateLocalMkdir) << "Directory" << _item->_file << "doesn't exist in its parent metadata, creating with the original name";
+ startLocalMkdir();
+ });
+ downloadEncryptedHelper->start();
}
void PropagateLocalRename::start()
void setDeleteExistingFile(bool enabled);
private:
+ void startLocalMkdir();
+ void startDemanglingName(const QString &parentPath);
+
bool _deleteExistingFile;
};