Assume that folder paths can be mangled
authorKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 23 Jun 2020 16:13:20 +0000 (18:13 +0200)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 30 Jun 2020 09:29:08 +0000 (11:29 +0200)
PropagateUploadEncrypted made the assumption of the folder names never
being mangled. This is not true since the previous commits so make sure
we properly deal with that using the journal db.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
src/libsync/propagateremotemkdir.cpp
src/libsync/propagateupload.cpp
src/libsync/propagateuploadencrypted.cpp
src/libsync/propagateuploadencrypted.h

index 107cc2831d7c6168d64ad2afec80fb9d53a22c3d..15975543a00b852174803e9dfbdee12e77fc88a6 100644 (file)
@@ -103,7 +103,7 @@ void PropagateRemoteMkdir::setDeleteExisting(bool enabled)
 
 void PropagateRemoteMkdir::slotMkdir()
 {
-    const auto parentPath = [=]() {
+    const auto rootPath = [=]() {
         const auto result = propagator()->_remoteFolder;
         if (result.startsWith('/')) {
             return result.mid(1);
@@ -111,17 +111,28 @@ void PropagateRemoteMkdir::slotMkdir()
             return result;
         }
     }();
-    const auto path = parentPath + _item->_file;
+    const auto path = QString(rootPath + _item->_file);
+    const auto parentPath = path.left(path.lastIndexOf('/'));
+
+    SyncJournalFileRecord parentRec;
+    bool ok = propagator()->_journal->getFileRecord(parentPath, &parentRec);
+    if (!ok) {
+        done(SyncFileItem::NormalError);
+        return;
+    }
+
+    const auto remoteParentPath = parentRec._e2eMangledName.isEmpty() ? parentPath : parentRec._e2eMangledName;
     const auto account = propagator()->account();
 
     if (!account->capabilities().clientSideEncryptionAvailable() ||
-        !account->e2e()->isAnyParentFolderEncrypted(path)) {
+        (!account->e2e()->isFolderEncrypted(remoteParentPath + '/') &&
+         !account->e2e()->isAnyParentFolderEncrypted(remoteParentPath + '/'))) {
         slotStartMkcolJob();
         return;
     }
 
     // We should be encrypted as well since our parent is
-    _uploadEncryptedHelper = new PropagateUploadEncrypted(propagator(), _item);
+    _uploadEncryptedHelper = new PropagateUploadEncrypted(propagator(), remoteParentPath, _item);
     connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::folderNotEncrypted,
       this, &PropagateRemoteMkdir::slotStartMkcolJob);
     connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::finalized,
index 6c7d9dd921b93d43a05afee96f70bbda42e2f38a..cd4cc4e2d431e82d25dfa9b14ce624e2fa54f462 100644 (file)
@@ -171,18 +171,41 @@ void PropagateUploadFileCommon::setDeleteExisting(bool enabled)
 
 void PropagateUploadFileCommon::start()
 {
-    if (propagator()->account()->capabilities().clientSideEncryptionAvailable()) {
-      _uploadEncryptedHelper = new PropagateUploadEncrypted(propagator(), _item);
-      connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::folderNotEncrypted,
-        this, &PropagateUploadFileCommon::setupUnencryptedFile);
-      connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::finalized,
-        this, &PropagateUploadFileCommon::setupEncryptedFile);
-      connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::error,
-        []{ qCDebug(lcPropagateUpload) << "Error setting up encryption."; });
-      _uploadEncryptedHelper->start();
-   } else {
-      setupUnencryptedFile();
+    const auto rootPath = [=]() {
+        const auto result = propagator()->_remoteFolder;
+        if (result.startsWith('/')) {
+            return result.mid(1);
+        } else {
+            return result;
+        }
+    }();
+    const auto path = QString(rootPath + _item->_file);
+    const auto parentPath = path.left(path.lastIndexOf('/'));
+
+    SyncJournalFileRecord parentRec;
+    bool ok = propagator()->_journal->getFileRecord(parentPath, &parentRec);
+    if (!ok) {
+        done(SyncFileItem::NormalError);
+        return;
+    }
+
+    const auto remoteParentPath = parentRec._e2eMangledName.isEmpty() ? parentPath : parentRec._e2eMangledName;
+    const auto account = propagator()->account();
+
+    if (!account->capabilities().clientSideEncryptionAvailable() ||
+        !account->e2e()->isFolderEncrypted(remoteParentPath + '/')) {
+        setupUnencryptedFile();
+        return;
     }
+
+    _uploadEncryptedHelper = new PropagateUploadEncrypted(propagator(), remoteParentPath, _item);
+    connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::folderNotEncrypted,
+            this, &PropagateUploadFileCommon::setupUnencryptedFile);
+    connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::finalized,
+            this, &PropagateUploadFileCommon::setupEncryptedFile);
+    connect(_uploadEncryptedHelper, &PropagateUploadEncrypted::error,
+            []{ qCDebug(lcPropagateUpload) << "Error setting up encryption."; });
+    _uploadEncryptedHelper->start();
 }
 
 void PropagateUploadFileCommon::setupEncryptedFile(const QString& path, const QString& filename, quint64 size)
index 2d496c4fe604afa5fbea1464f140e86b7fc2f480..dea1029e30f283dd7847357352be040c01882ba3 100644 (file)
@@ -16,10 +16,11 @@ namespace OCC {
 
 Q_LOGGING_CATEGORY(lcPropagateUploadEncrypted, "nextcloud.sync.propagator.upload.encrypted", QtInfoMsg)
 
-PropagateUploadEncrypted::PropagateUploadEncrypted(OwncloudPropagator *propagator, SyncFileItemPtr item)
-: _propagator(propagator),
- _item(item),
- _metadata(nullptr)
+PropagateUploadEncrypted::PropagateUploadEncrypted(OwncloudPropagator *propagator, const QString &remoteParentPath, SyncFileItemPtr item)
+    : _propagator(propagator)
+    , _remoteParentPath(remoteParentPath)
+    , _item(item)
+    , _metadata(nullptr)
 {
 }
 
@@ -38,9 +39,7 @@ void PropagateUploadEncrypted::start()
       * If the folder is unencrypted we just follow the old way.
       */
       qCDebug(lcPropagateUploadEncrypted) << "Starting to send an encrypted file!";
-      QFileInfo info(_item->_file);
-      auto getEncryptedStatus = new GetFolderEncryptStatusJob(_propagator->account(),
-                                                           info.path());
+      auto getEncryptedStatus = new GetFolderEncryptStatusJob(_propagator->account(), _remoteParentPath);
 
       connect(getEncryptedStatus, &GetFolderEncryptStatusJob::encryptStatusFolderReceived,
               this, &PropagateUploadEncrypted::slotFolderEncryptedStatusFetched);
@@ -157,8 +156,7 @@ void PropagateUploadEncrypted::slotFolderEncryptedMetadataReceived(const QJsonDo
       encryptedFile.mimetype = mdb.mimeTypeForFile(info).name().toLocal8Bit();
   }
 
-  _item->_encryptedFileName = _item->_file.section(QLatin1Char('/'), 0, -2)
-          + QLatin1Char('/') + encryptedFile.encryptedFilename;
+  _item->_encryptedFileName = _remoteParentPath + QLatin1Char('/') + encryptedFile.encryptedFilename;
 
   qCDebug(lcPropagateUploadEncrypted) << "Creating the encrypted file.";
 
@@ -219,7 +217,7 @@ void PropagateUploadEncrypted::slotUpdateMetadataSuccess(const QByteArray& fileI
     qCDebug(lcPropagateUploadEncrypted) << "Encrypted Info:" << outputInfo.path() << outputInfo.fileName() << outputInfo.size();
     qCDebug(lcPropagateUploadEncrypted) << "Finalizing the upload part, now the actuall uploader will take over";
     emit finalized(outputInfo.path() + QLatin1Char('/') + outputInfo.fileName(),
-                   _item->_file.section(QLatin1Char('/'), 0, -2) + QLatin1Char('/') + outputInfo.fileName(),
+                   _remoteParentPath + QLatin1Char('/') + outputInfo.fileName(),
                    outputInfo.size());
 }
 
index 4685e56828dc316101a75ed5fbdda3e6e06b097d..ae7981f9d6c7b21b9c6ecfc0441f094135381cf9 100644 (file)
@@ -32,7 +32,7 @@ class PropagateUploadEncrypted : public QObject
 {
   Q_OBJECT
 public:
-    PropagateUploadEncrypted(OwncloudPropagator *propagator, SyncFileItemPtr item);
+    PropagateUploadEncrypted(OwncloudPropagator *propagator, const QString &remoteParentPath, SyncFileItemPtr item);
     void start();
 
     /* unlocks the current folder that holds this file */
@@ -64,6 +64,7 @@ signals:
 
 private:
   OwncloudPropagator *_propagator;
+  QString _remoteParentPath;
   SyncFileItemPtr _item;
 
   QElapsedTimer _folderLockFirstTry;