Stop using e2e()->isFolderEncrypted() in the folder wizard
authorKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 8 Dec 2020 14:36:17 +0000 (15:36 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:59:23 +0000 (10:59 +0100)
We used the same approach than for the FolderStatusModel by getting the
is-encrypted property straight from the LSCOL job.

Signed-off-by: Kevin Ottens <kevin.ottens@nextcloud.com>
src/gui/folderwizard.cpp
src/gui/folderwizard.h
src/gui/selectivesyncdialog.cpp
src/gui/selectivesyncdialog.h

index 27345b46ffdeb14a20cd8d9ed3a7c876ed97e92d..78dab8c8b589b8ebffb712291027e2f13b131fba 100644 (file)
@@ -332,8 +332,10 @@ void FolderWizardRemotePath::slotUpdateDirectories(const QStringList &list)
         path.remove(webdavFolder);
 
         // Don't allow to select subfolders of encrypted subfolders
-        if (_account->capabilities().clientSideEncryptionAvailable() &&
-            _account->e2e()->isAnyParentFolderEncrypted(path)) {
+        const auto isAnyAncestorEncrypted = std::any_of(std::cbegin(_encryptedPaths), std::cend(_encryptedPaths), [=](const QString &encryptedPath) {
+            return path.size() > encryptedPath.size() && path.startsWith(encryptedPath);
+        });
+        if (isAnyAncestorEncrypted) {
             continue;
         }
 
@@ -345,8 +347,21 @@ void FolderWizardRemotePath::slotUpdateDirectories(const QStringList &list)
     root->setExpanded(true);
 }
 
+void FolderWizardRemotePath::slotGatherEncryptedPaths(const QString &path, const QMap<QString, QString> &properties)
+{
+    const auto it = properties.find("is-encrypted");
+    if (it == properties.cend() || *it != QStringLiteral("1")) {
+        return;
+    }
+
+    const auto webdavFolder = QUrl(_account->davUrl()).path();
+    Q_ASSERT(path.startsWith(webdavFolder));
+    _encryptedPaths << path.mid(webdavFolder.size());
+}
+
 void FolderWizardRemotePath::slotRefreshFolders()
 {
+    _encryptedPaths.clear();
     runLsColJob("/");
     _ui.folderTreeWidget->clear();
     _ui.folderEntry->clear();
@@ -364,8 +379,7 @@ void FolderWizardRemotePath::slotCurrentItemChanged(QTreeWidgetItem *item)
         QString dir = item->data(0, Qt::UserRole).toString();
 
         // We don't want to allow creating subfolders in encrypted folders outside of the sync logic
-        const auto encrypted = _account->capabilities().clientSideEncryptionAvailable() &&
-                _account->e2e()->isFolderEncrypted(dir + '/');
+        const auto encrypted = _encryptedPaths.contains(dir);
         _ui.addFolderButton->setEnabled(!encrypted);
 
         if (!dir.startsWith(QLatin1Char('/'))) {
@@ -413,11 +427,17 @@ void FolderWizardRemotePath::slotTypedPathFound(const QStringList &subpaths)
 LsColJob *FolderWizardRemotePath::runLsColJob(const QString &path)
 {
     auto *job = new LsColJob(_account, path, this);
-    job->setProperties(QList<QByteArray>() << "resourcetype");
+    auto props = QList<QByteArray>() << "resourcetype";
+    if (_account->capabilities().clientSideEncryptionAvailable()) {
+        props << "http://nextcloud.org/ns:is-encrypted";
+    }
+    job->setProperties(props);
     connect(job, &LsColJob::directoryListingSubfolders,
         this, &FolderWizardRemotePath::slotUpdateDirectories);
     connect(job, &LsColJob::finishedWithError,
         this, &FolderWizardRemotePath::slotHandleLsColNetworkError);
+    connect(job, &LsColJob::directoryListingIterated,
+        this, &FolderWizardRemotePath::slotGatherEncryptedPaths);
     job->start();
 
     return job;
index 80cb2b8c138dac181a3ad01cc12f2ac1ac864518..58ffa69c053d4a49a32fec16dbd56a1274ff650a 100644 (file)
@@ -96,6 +96,7 @@ protected slots:
     void slotHandleMkdirNetworkError(QNetworkReply *);
     void slotHandleLsColNetworkError(QNetworkReply *);
     void slotUpdateDirectories(const QStringList &);
+    void slotGatherEncryptedPaths(const QString &, const QMap<QString, QString> &);
     void slotRefreshFolders();
     void slotItemExpanded(QTreeWidgetItem *);
     void slotCurrentItemChanged(QTreeWidgetItem *);
@@ -111,6 +112,7 @@ private:
     bool _warnWasVisible;
     AccountPtr _account;
     QTimer _lscolTimer;
+    QStringList _encryptedPaths;
 };
 
 /**
index 8a3e08e09235f8d0b3d37463039014d3aca1a705..919a74ae88cc3cc812b4ddb84c84f21b4871c6e8 100644 (file)
@@ -106,13 +106,21 @@ QSize SelectiveSyncWidget::sizeHint() const
 
 void SelectiveSyncWidget::refreshFolders()
 {
+    _encryptedPaths.clear();
+
     auto *job = new LsColJob(_account, _folderPath, this);
-    job->setProperties(QList<QByteArray>() << "resourcetype"
-                                           << "http://owncloud.org/ns:size");
+    auto props = QList<QByteArray>() << "resourcetype"
+                                     << "http://owncloud.org/ns:size";
+    if (_account->capabilities().clientSideEncryptionAvailable()) {
+        props << "http://nextcloud.org/ns:is-encrypted";
+    }
+    job->setProperties(props);
     connect(job, &LsColJob::directoryListingSubfolders,
         this, &SelectiveSyncWidget::slotUpdateDirectories);
     connect(job, &LsColJob::finishedWithError,
         this, &SelectiveSyncWidget::slotLscolFinishedWithError);
+    connect(job, &LsColJob::directoryListingIterated,
+        this, &SelectiveSyncWidget::slotGatherEncryptedPaths);
     job->start();
     _folderTree->clear();
     _loading->show();
@@ -250,8 +258,10 @@ void SelectiveSyncWidget::slotUpdateDirectories(QStringList list)
         path.remove(pathToRemove);
 
         // Don't allow to select subfolders of encrypted subfolders
-        if (_account->capabilities().clientSideEncryptionAvailable() &&
-            _account->e2e()->isAnyParentFolderEncrypted(_rootName + '/' + path)) {
+        const auto isAnyAncestorEncrypted = std::any_of(std::cbegin(_encryptedPaths), std::cend(_encryptedPaths), [=](const QString &encryptedPath) {
+            return path.size() > encryptedPath.size() && path.startsWith(encryptedPath);
+        });
+        if (isAnyAncestorEncrypted) {
             continue;
         }
 
@@ -288,6 +298,19 @@ void SelectiveSyncWidget::slotLscolFinishedWithError(QNetworkReply *r)
     _loading->resize(_loading->sizeHint()); // because it's not in a layout
 }
 
+void SelectiveSyncWidget::slotGatherEncryptedPaths(const QString &path, const QMap<QString, QString> &properties)
+{
+    const auto it = properties.find("is-encrypted");
+    if (it == properties.cend() || *it != QStringLiteral("1")) {
+        return;
+    }
+
+    const auto webdavFolder = QUrl(_account->davUrl()).path();
+    Q_ASSERT(path.startsWith(webdavFolder));
+    // This dialog use the postfix / convention for folder paths
+    _encryptedPaths << path.mid(webdavFolder.size()) + '/';
+}
+
 void SelectiveSyncWidget::slotItemExpanded(QTreeWidgetItem *item)
 {
     QString dir = item->data(0, Qt::UserRole).toString();
index 7480f8986f5120e07ea604dbf44c67f269ad632e..44e2c1ea623fcc574ac500b6d2fb387df0366f3f 100644 (file)
@@ -59,6 +59,7 @@ private slots:
     void slotItemExpanded(QTreeWidgetItem *);
     void slotItemChanged(QTreeWidgetItem *, int);
     void slotLscolFinishedWithError(QNetworkReply *);
+    void slotGatherEncryptedPaths(const QString &, const QMap<QString, QString> &);
 
 private:
     void refreshFolders();
@@ -78,6 +79,8 @@ private:
     // During account setup we want to filter out excluded folders from the
     // view without having a Folder.SyncEngine.ExcludedFiles instance.
     ExcludedFiles _excludedFiles;
+
+    QStringList _encryptedPaths;
 };
 
 /**