Delete E2EE files/folders for accounts that have had E2EE disabled
authorClaudio Cambra <claudio.cambra@nextcloud.com>
Fri, 11 Nov 2022 17:32:12 +0000 (18:32 +0100)
committerClaudio Cambra <claudio.cambra@nextcloud.com>
Tue, 24 Jan 2023 16:00:14 +0000 (17:00 +0100)
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
src/gui/accountsettings.cpp
src/gui/folder.cpp
src/gui/folder.h
src/gui/folderman.cpp
src/gui/folderman.h

index b51cc1188629e73ec83fd17565b439f0474b01a6..02a218e0560bb72bd9a59c209c9e2980f5c875d8 100644 (file)
@@ -1614,6 +1614,11 @@ void AccountSettings::resetE2eEncryption()
     _ui->encryptionMessage->setIcon({});
     initializeE2eEncryption();
     checkClientSideEncryptionState();
+
+    const auto account = _accountState->account();
+    if (account->e2e()->_mnemonic.isEmpty()) {
+        FolderMan::instance()->removeE2eFiles(account);
+    }
 }
 
 void AccountSettings::removeActionFromEncryptionMessage(const QString &actionId)
index 0ed956f276f31e20fc06b94c4b29128a4d4e81fd..4e297847ee50df6c96afec8690fc4a527b1eb485 100644 (file)
@@ -1332,6 +1332,60 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction dir, std::functio
     msgBox->open();
 }
 
+void Folder::removeLocalE2eFiles()
+{
+    qCDebug(lcFolder) << "Removing local E2EE files";
+    QByteArrayList e2eFiles;
+    const auto couldGetFiles = _journal.getFilesBelowPath("", [&e2eFiles](const SyncJournalFileRecord &rec) {
+        if (rec._isE2eEncrypted) {
+            e2eFiles.append(rec._path);
+        }
+    });
+
+    if (!couldGetFiles) {
+        qCWarning(lcFolder) << "Could not fetch E2EE files to delete in this folder:" << path();
+        return;
+    } else if (e2eFiles.isEmpty()) {
+        qCWarning(lcFolder) << "No E2EE files found at path" << path();
+        return;
+    }
+
+    const auto currentSyncPaused = syncPaused();
+    setSyncPaused(true);
+
+    qCDebug(lcFolder) << "About to remove: " << e2eFiles;
+
+    for (const auto &e2eFilePath : qAsConst(e2eFiles)) {
+        if (!_journal.deleteFileRecord(e2eFilePath, true)) {
+            qCWarning(lcFolder) << "Failed to delete file record from local DB" << e2eFilePath
+                                << "it might have already been deleted.";
+            continue;
+        }
+
+        qCDebug(lcFolder) << "Removing local copy of" << e2eFilePath;
+
+        const auto fullPath = QString(path() + e2eFilePath);
+        const QFileInfo pathInfo(fullPath);
+
+        if (pathInfo.isDir() && pathInfo.exists()) {
+            QDir dir(fullPath);
+            if (!dir.removeRecursively()) {
+                qCWarning(lcFolder) << "Unable to remove directory and contents at:" << fullPath;
+            }
+        } else if (pathInfo.exists()) {
+            if (!QFile::remove(fullPath)) {
+                qCWarning(lcFolder) << "Unable to delete file:" << fullPath;
+            }
+        } else {
+            qCWarning(lcFolder) << "Unable to delete:" << fullPath << "as it does not exist!";
+        }
+    }
+
+    setSyncPaused(currentSyncPaused);
+    _journal.forceRemoteDiscoveryNextSync();
+    scheduleThisFolderSoon();
+}
+
 QString Folder::fileFromLocalPath(const QString &localPath) const
 {
     return localPath.mid(cleanPath().length() + 1);
index 8b0e5a8f5462db9c9daa190557dc52f9cce20daf..1f9dd79e3e00175c8f856f7f1cba05b9018f5392 100644 (file)
@@ -370,6 +370,11 @@ public slots:
 
     void setSilenceErrorsUntilNextSync(bool silenceErrors);
 
+    /** Deletes local copies of E2EE files.
+     * Intended for clean-up after disabling E2EE for an account.
+     */
+    void removeLocalE2eFiles();
+
 private slots:
     void slotSyncStarted();
     void slotSyncFinished(bool);
index b6f9758dceaef464e7932d2882db50a36a644e52..b8cecf7d297a060e04b474f6cf6bdaa7e8923e27 100644 (file)
@@ -658,6 +658,16 @@ void FolderMan::forceSyncForFolder(Folder *folder)
     scheduleFolderNext(folder);
 }
 
+void FolderMan::removeE2eFiles(const AccountPtr &account) const
+{
+    Q_ASSERT(account->e2e()->_mnemonic.isEmpty());
+    for (const auto folder : map()) {
+        if(folder->accountState()->account()->id() == account->id()) {
+            folder->removeLocalE2eFiles();
+        }
+    }
+}
+
 void FolderMan::slotScheduleAppRestart()
 {
     _appRestartRequired = true;
index ee39c259fac13dc2f56c8bf7ec1581567fbe3bc9..a384bd6434e15ec3bdfff32b61293459087558ba 100644 (file)
@@ -271,6 +271,8 @@ public slots:
 
     void forceSyncForFolder(OCC::Folder *folder);
 
+    void removeE2eFiles(const AccountPtr &account) const;
+
 private slots:
     void slotFolderSyncPaused(OCC::Folder *, bool paused);
     void slotFolderCanSyncChanged();