[network/ruqola] src/rocketchatrestapi-qt: Prepare to add setroomkeyidjob

Laurent Montel <[email protected]> Wed, 5 Aug 2026 06:11:21 +0000 (UTC)
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit 3ea90b69ab0ac8cddcf80e92fcc1d0f6677b3a2b by Laurent Montel.
Committed on 05/08/2026 at 05:44.
Pushed by mlaurent into branch 'master'.

Prepare to add setroomkeyidjob

M  +2    -0    src/rocketchatrestapi-qt/CMakeLists.txt
M  +1    -0    src/rocketchatrestapi-qt/autotests/CMakeLists.txt
A  +90   -0    src/rocketchatrestapi-qt/autotests/setroomkeyidjobtest.cpp     [License: LGPL(v2.0+)]
A  +22   -0    src/rocketchatrestapi-qt/autotests/setroomkeyidjobtest.h     [License: LGPL(v2.0+)]
A  +102  -0    src/rocketchatrestapi-qt/e2e/setroomkeyidjob.cpp     [License: LGPL(v2.0+)]
A  +46   -0    src/rocketchatrestapi-qt/e2e/setroomkeyidjob.h     [License: LGPL(v2.0+)]
M  +1    -1    src/rocketchatrestapi-qt/invite/listinvitejob.cpp

https://invent.kde.org/network/ruqola/-/commit/3ea90b69ab0ac8cddcf80e92fcc1d0f6677b3a2b

diff --git a/src/rocketchatrestapi-qt/CMakeLists.txt b/src/rocketchatrestapi-qt/CMakeLists.txt
index ff3c4ff8f7..be5d369ad4 100644
--- a/src/rocketchatrestapi-qt/CMakeLists.txt
+++ b/src/rocketchatrestapi-qt/CMakeLists.txt
@@ -201,6 +201,8 @@ target_sources(
         e2e/getusersofroomwithoutkey.cpp
         e2e/fetchuserswaitingforgroupkeyjob.h
         e2e/fetchuserswaitingforgroupkeyjob.cpp
+        e2e/setroomkeyidjob.cpp
+        e2e/setroomkeyidjob.h
         emoji/emojicustomalljob.cpp
         emoji/emojicustomalljob.h
         emoji/emojicustomcreatejob.cpp
diff --git a/src/rocketchatrestapi-qt/autotests/CMakeLists.txt b/src/rocketchatrestapi-qt/autotests/CMakeLists.txt
index d52515a386..0241183824 100644
--- a/src/rocketchatrestapi-qt/autotests/CMakeLists.txt
+++ b/src/rocketchatrestapi-qt/autotests/CMakeLists.txt
@@ -323,3 +323,4 @@ add_rocketchatrestapi_test(customsoundsdeletejobtest.cpp)
 add_rocketchatrestapi_test(imblockuserjobtest.cpp)
 add_rocketchatrestapi_test(deletemessagefilejobtest.cpp)
 add_rocketchatrestapi_test(fetchuserswaitingforgroupkeyjobtest.cpp)
+add_rocketchatrestapi_test(setroomkeyidjobtest.cpp)
diff --git a/src/rocketchatrestapi-qt/autotests/setroomkeyidjobtest.cpp b/src/rocketchatrestapi-qt/autotests/setroomkeyidjobtest.cpp
new file mode 100644
index 0000000000..665a2b3423
--- /dev/null
+++ b/src/rocketchatrestapi-qt/autotests/setroomkeyidjobtest.cpp
@@ -0,0 +1,90 @@
+/*
+   SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+
+   SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+#include "setroomkeyidjobtest.h"
+
+#include "e2e/setroomkeyidjob.h"
+#include "restapimethod.h"
+#include "ruqola_restapi_helper.h"
+
+#include <QJsonDocument>
+#include <QTest>
+
+QTEST_GUILESS_MAIN(SetRoomKeyIDJobTest)
+using namespace Qt::Literals::StringLiterals;
+using namespace RocketChatRestApi;
+SetRoomKeyIDJobTest::SetRoomKeyIDJobTest(QObject *parent)
+    : QObject(parent)
+{
+}
+
+void SetRoomKeyIDJobTest::shouldHaveDefaultValue()
+{
+    SetRoomKeyIDJob job;
+    RuqolaRestApiHelper::verifyDefaultValue(&job);
+    QVERIFY(job.requireHttpAuthentication());
+
+    QVERIFY(!job.setUserPublicAndPrivateKeysInfo().isValid());
+    QVERIFY(!job.hasQueryParameterSupport());
+}
+
+void SetRoomKeyIDJobTest::shouldGenerateRequest()
+{
+    SetRoomKeyIDJob job;
+    QNetworkRequest request = QNetworkRequest(QUrl());
+    RuqolaRestApiHelper::verifyAuthentication(&job, request);
+    QCOMPARE(request.url(), QUrl(u"http://www.kde.org/api/v1/e2e.setUserPublicAndPrivateKeys"_s));
+    QCOMPARE(request.header(QNetworkRequest::ContentTypeHeader).toString(), u"application/json"_s);
+}
+
+void SetRoomKeyIDJobTest::shouldGenerateJson()
+{
+    SetRoomKeyIDJob job;
+    SetRoomKeyIDJob::SetUserPublicAndPrivateKeysInfo info;
+    const QString rsapublic = u"foo1"_s;
+    const QString rsaprivate = u"private"_s;
+    info.rsaPrivateKey = rsaprivate;
+    info.rsaPublicKey = rsapublic;
+    job.setSetUserPublicAndPrivateKeysInfo(info);
+    QCOMPARE(job.json().toJson(QJsonDocument::Compact),
+             QStringLiteral(R"({"force":false,"private_key":"%2","public_key":"%1"})").arg(rsapublic, rsaprivate).toLatin1());
+
+    info.force = true;
+    job.setSetUserPublicAndPrivateKeysInfo(info);
+    QCOMPARE(job.json().toJson(QJsonDocument::Compact),
+             QStringLiteral(R"({"force":true,"private_key":"%2","public_key":"%1"})").arg(rsapublic, rsaprivate).toLatin1());
+}
+
+void SetRoomKeyIDJobTest::shouldNotStarting()
+{
+    SetRoomKeyIDJob job;
+
+    RestApiMethod method;
+    method.setServerUrl(u"http://www.kde.org"_s);
+    job.setRestApiMethod(&method);
+
+    QNetworkAccessManager mNetworkAccessManager;
+    job.setNetworkAccessManager(&mNetworkAccessManager);
+    QVERIFY(!job.canStart());
+    const QString auth = u"foo"_s;
+    const QString userId = u"foo"_s;
+    job.setAuthToken(auth);
+    QVERIFY(!job.canStart());
+    job.setUserId(userId);
+    QVERIFY(!job.canStart());
+
+    SetRoomKeyIDJob::SetUserPublicAndPrivateKeysInfo info;
+    const QString rsapublic = u"foo1"_s;
+    const QString rsaprivate = u"private"_s;
+    info.rsaPrivateKey = rsaprivate;
+    job.setSetUserPublicAndPrivateKeysInfo(info);
+    QVERIFY(!job.canStart());
+    info.rsaPublicKey = rsapublic;
+    job.setSetUserPublicAndPrivateKeysInfo(info);
+    QVERIFY(job.canStart());
+}
+
+#include "moc_setroomkeyidjobtest.cpp"
diff --git a/src/rocketchatrestapi-qt/autotests/setroomkeyidjobtest.h b/src/rocketchatrestapi-qt/autotests/setroomkeyidjobtest.h
new file mode 100644
index 0000000000..b2c953d7df
--- /dev/null
+++ b/src/rocketchatrestapi-qt/autotests/setroomkeyidjobtest.h
@@ -0,0 +1,22 @@
+/*
+   SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+
+   SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+#pragma once
+
+#include <QObject>
+
+class SetRoomKeyIDJobTest : public QObject
+{
+    Q_OBJECT
+public:
+    explicit SetRoomKeyIDJobTest(QObject *parent = nullptr);
+    ~SetRoomKeyIDJobTest() override = default;
+private Q_SLOTS:
+    void shouldHaveDefaultValue();
+    void shouldGenerateRequest();
+    void shouldGenerateJson();
+    void shouldNotStarting();
+};
diff --git a/src/rocketchatrestapi-qt/e2e/setroomkeyidjob.cpp b/src/rocketchatrestapi-qt/e2e/setroomkeyidjob.cpp
new file mode 100644
index 0000000000..8c91a5c5cc
--- /dev/null
+++ b/src/rocketchatrestapi-qt/e2e/setroomkeyidjob.cpp
@@ -0,0 +1,102 @@
+/*
+   SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+
+   SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+#include "setroomkeyidjob.h"
+
+#include "restapimethod.h"
+#include "rocketchatqtrestapi_debug.h"
+
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QNetworkRequest>
+
+using namespace RocketChatRestApi;
+using namespace Qt::Literals::StringLiterals;
+SetRoomKeyIDJob::SetRoomKeyIDJob(QObject *parent)
+    : RestApiAbstractJob(parent)
+{
+}
+
+SetRoomKeyIDJob::~SetRoomKeyIDJob() = default;
+
+bool SetRoomKeyIDJob::start()
+{
+    if (!canStart()) {
+        deleteLater();
+        return false;
+    }
+    addStartRestApiInfo("SetRoomKeyIDJob::start");
+    submitPostRequest(json());
+
+    return true;
+}
+
+void SetRoomKeyIDJob::onPostRequestResponse(const QString &replyErrorString, const QJsonDocument &replyJson)
+{
+    const QJsonObject replyObject = replyJson.object();
+
+    if (replyObject["success"_L1].toBool()) {
+        addLoggerInfo("SetRoomKeyIDJob: success: "_ba + replyJson.toJson(QJsonDocument::Indented));
+        Q_EMIT setUserPublicAndPrivateKeysDone();
+    } else {
+        emitFailedMessage(replyErrorString, replyObject);
+        addLoggerWarning("SetRoomKeyIDJob: Problem: "_ba + replyJson.toJson(QJsonDocument::Indented));
+    }
+}
+
+SetRoomKeyIDJob::SetUserPublicAndPrivateKeysInfo SetRoomKeyIDJob::setUserPublicAndPrivateKeysInfo() const
+{
+    return mSetUserPublicAndPrivateKeysInfo;
+}
+
+void SetRoomKeyIDJob::setSetUserPublicAndPrivateKeysInfo(const SetUserPublicAndPrivateKeysInfo &newSetUserPublicAndPrivateKeysInfo)
+{
+    mSetUserPublicAndPrivateKeysInfo = newSetUserPublicAndPrivateKeysInfo;
+}
+
+bool SetRoomKeyIDJob::requireHttpAuthentication() const
+{
+    return true;
+}
+
+bool SetRoomKeyIDJob::canStart() const
+{
+    if (!RestApiAbstractJob::canStart()) {
+        return false;
+    }
+    if (!mSetUserPublicAndPrivateKeysInfo.isValid()) {
+        qCWarning(ROCKETCHATQTRESTAPI_LOG) << "SetRoomKeyIDJob: mSetUserPublicAndPrivateKeysInfo is invalid";
+        return false;
+    }
+    return true;
+}
+
+QNetworkRequest SetRoomKeyIDJob::request() const
+{
+    const QUrl url = mRestApiMethod->generateUrl(RestApiUtil::RestApiUrlType::E2ESetUserPublicAndPrivateKeys);
+    QNetworkRequest request(url);
+    addAuthRawHeader(request);
+    addRequestAttribute(request);
+    return request;
+}
+
+QJsonDocument SetRoomKeyIDJob::json() const
+{
+    QJsonObject jsonObj;
+    jsonObj["public_key"_L1] = mSetUserPublicAndPrivateKeysInfo.rsaPublicKey;
+    jsonObj["private_key"_L1] = mSetUserPublicAndPrivateKeysInfo.rsaPrivateKey;
+    jsonObj["force"_L1] = mSetUserPublicAndPrivateKeysInfo.force;
+
+    const QJsonDocument postData = QJsonDocument(jsonObj);
+    return postData;
+}
+
+bool SetRoomKeyIDJob::SetUserPublicAndPrivateKeysInfo::isValid() const
+{
+    return !rsaPublicKey.isEmpty() && !rsaPrivateKey.isEmpty();
+}
+
+#include "moc_setroomkeyidjob.cpp"
diff --git a/src/rocketchatrestapi-qt/e2e/setroomkeyidjob.h b/src/rocketchatrestapi-qt/e2e/setroomkeyidjob.h
new file mode 100644
index 0000000000..242f74a74a
--- /dev/null
+++ b/src/rocketchatrestapi-qt/e2e/setroomkeyidjob.h
@@ -0,0 +1,46 @@
+/*
+   SPDX-FileCopyrightText: 2026 Laurent Montel <[email protected]>
+
+   SPDX-License-Identifier: LGPL-2.0-or-later
+*/
+
+#pragma once
+
+#include "librocketchatrestapi-qt_export.h"
+#include "restapiabstractjob.h"
+namespace RocketChatRestApi
+{
+class LIBROCKETCHATRESTAPI_QT_EXPORT SetRoomKeyIDJob : public RestApiAbstractJob
+{
+    Q_OBJECT
+
+    // Since rocketchat 0.70
+public:
+    struct LIBROCKETCHATRESTAPI_QT_EXPORT SetUserPublicAndPrivateKeysInfo {
+        QString rsaPublicKey;
+        QString rsaPrivateKey;
+        bool force = false;
+        [[nodiscard]] bool isValid() const;
+    };
+
+    explicit SetRoomKeyIDJob(QObject *parent = nullptr);
+    ~SetRoomKeyIDJob() override;
+
+    [[nodiscard]] bool start() override;
+    [[nodiscard]] bool requireHttpAuthentication() const override;
+    [[nodiscard]] bool canStart() const override;
+    [[nodiscard]] QNetworkRequest request() const override;
+
+    [[nodiscard]] QJsonDocument json() const;
+
+    [[nodiscard]] SetUserPublicAndPrivateKeysInfo setUserPublicAndPrivateKeysInfo() const;
+    void setSetUserPublicAndPrivateKeysInfo(const SetUserPublicAndPrivateKeysInfo &newSetUserPublicAndPrivateKeysInfo);
+
+Q_SIGNALS:
+    void setUserPublicAndPrivateKeysDone();
+
+private:
+    LIBROCKETCHATRESTAPI_QT_NO_EXPORT void onPostRequestResponse(const QString &replyErrorString, const QJsonDocument &replyJson) override;
+    SetUserPublicAndPrivateKeysInfo mSetUserPublicAndPrivateKeysInfo;
+};
+}
diff --git a/src/rocketchatrestapi-qt/invite/listinvitejob.cpp b/src/rocketchatrestapi-qt/invite/listinvitejob.cpp
index b8488b80c4..f2c85560d7 100644
--- a/src/rocketchatrestapi-qt/invite/listinvitejob.cpp
+++ b/src/rocketchatrestapi-qt/invite/listinvitejob.cpp
@@ -9,7 +9,7 @@
 #include <QJsonDocument>
 #include <QNetworkRequest>
 #include <QUrlQuery>
-
+using namespace Qt::Literals::StringLiterals;
 using namespace RocketChatRestApi;
 ListInviteJob::ListInviteJob(QObject *parent)
     : RestApiAbstractJob(parent)