Add context menu entry to encrypt folders
authorClaudio Cambra <claudio.cambra@nextcloud.com>
Fri, 9 Dec 2022 17:15:16 +0000 (18:15 +0100)
committerClaudio Cambra <claudio.cambra@gmail.com>
Tue, 13 Dec 2022 12:27:56 +0000 (13:27 +0100)
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
src/gui/socketapi/socketapi.cpp
src/gui/socketapi/socketapi.h

index eee232d55b7b8b36f4ada9dc6cca70d88eb4ed9e..48f66f4cc978d6f296766b1d4fac67f151e798e3 100644 (file)
@@ -26,6 +26,7 @@
 #include "deletejob.h"
 #include "folderman.h"
 #include "folder.h"
+#include "encryptfolderjob.h"
 #include "theme.h"
 #include "common/syncjournalfilerecord.h"
 #include "syncengine.h"
 // The second number should be changed when there are new features.
 #define MIRALL_SOCKET_API_VERSION "1.1"
 
+namespace {
+constexpr auto encryptJobPropertyFolder = "folder";
+constexpr auto encryptJobPropertyPath = "path";
+}
+
 namespace {
 
 const QLatin1Char RecordSeparator()
@@ -501,6 +507,35 @@ void SocketApi::processFileActivityRequest(const QString &localFile)
     emit fileActivityCommandReceived(fileData.localPath);
 }
 
+void SocketApi::processEncryptRequest(const QString &localFile)
+{
+    Q_ASSERT(QFileInfo(localFile).isDir());
+
+    const auto fileData = FileData::get(localFile);
+    const auto folder = fileData.folder;
+    const auto account = folder->accountState()->account();
+    const auto rec = fileData.journalRecord();
+
+    Q_ASSERT(folder);
+    Q_ASSERT(account);
+    Q_ASSERT(rec.isValid());
+
+    auto choppedPath = rec._path.chopped(1);
+
+    auto job = new OCC::EncryptFolderJob(account, folder->journalDb(), choppedPath, rec.numericFileId(), this);
+    connect(job, &OCC::EncryptFolderJob::finished, this, [fileData, job](const int status) {
+        if (status == OCC::EncryptFolderJob::Error) {
+            const int ret = QMessageBox::critical(nullptr,
+                                                  tr("Failed to encrypt folder at \"%1\"").arg(fileData.folderRelativePath),
+                                                  tr("Server replied with error: %1").arg(job->errorString()));
+            Q_UNUSED(ret)
+        }
+    });
+    job->setProperty(encryptJobPropertyFolder, QVariant::fromValue(folder));
+    job->setProperty(encryptJobPropertyPath, QVariant::fromValue(rec._path));
+    job->start();
+}
+
 void SocketApi::processShareRequest(const QString &localFile, SocketListener *listener)
 {
     auto theme = Theme::instance();
@@ -603,6 +638,13 @@ void SocketApi::command_ACTIVITY(const QString &localFile, SocketListener *liste
     processFileActivityRequest(localFile);
 }
 
+void SocketApi::command_ENCRYPT(const QString &localFile, SocketListener *listener)
+{
+    Q_UNUSED(listener);
+
+    processEncryptRequest(localFile);
+}
+
 void SocketApi::command_MANAGE_PUBLIC_LINKS(const QString &localFile, SocketListener *listener)
 {
     processShareRequest(localFile, listener);
@@ -1215,10 +1257,28 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe
 
         const QFileInfo fileInfo(fileData.localPath);
         sendLockFileInfoMenuEntries(fileInfo, syncFolder, fileData, listener, record);
+
         if (!fileInfo.isDir()) {
             listener->sendMessage(QLatin1String("MENU_ITEM:ACTIVITY") + flagString + tr("Activity"));
         }
 
+        if (fileInfo.isDir() && !isE2eEncryptedPath) {
+            bool anyAncestorEncrypted = false;
+            auto ancestor = fileData.parentFolder();
+            while (ancestor.journalRecord().isValid()) {
+                if (ancestor.journalRecord()._isE2eEncrypted) {
+                    anyAncestorEncrypted = true;
+                    break;
+                }
+
+                ancestor = ancestor.parentFolder();
+            }
+
+            if (!anyAncestorEncrypted) {
+                listener->sendMessage(QStringLiteral("MENU_ITEM:ENCRYPT") + flagString + tr("Encrypt"));
+            }
+        }
+
         DirectEditor* editor = getDirectEditorForLocalFile(fileData.localPath);
         if (editor) {
             //listener->sendMessage(QLatin1String("MENU_ITEM:EDIT") + flagString + tr("Edit via ") + editor->name());
index 5cedd53d7e79bed3f33d71c3db0e2cf0b1faac2a..ab3b6c264f56a13c4cdfada5a2610353cc00b334 100644 (file)
@@ -104,6 +104,7 @@ private:
     void processShareRequest(const QString &localFile, SocketListener *listener);
     void processLeaveShareRequest(const QString &localFile, SocketListener *listener);
     void processFileActivityRequest(const QString &localFile);
+    void processEncryptRequest(const QString &localFile);
 
     Q_INVOKABLE void command_RETRIEVE_FOLDER_STATUS(const QString &argument, OCC::SocketListener *listener);
     Q_INVOKABLE void command_RETRIEVE_FILE_STATUS(const QString &argument, OCC::SocketListener *listener);
@@ -114,6 +115,7 @@ private:
 
     // The context menu actions
     Q_INVOKABLE void command_ACTIVITY(const QString &localFile, OCC::SocketListener *listener);
+    Q_INVOKABLE void command_ENCRYPT(const QString &localFile, SocketListener *listener);
     Q_INVOKABLE void command_SHARE(const QString &localFile, OCC::SocketListener *listener);
     Q_INVOKABLE void command_LEAVESHARE(const QString &localFile, SocketListener *listener);
     Q_INVOKABLE void command_MANAGE_PUBLIC_LINKS(const QString &localFile, OCC::SocketListener *listener);