Page MenuHomePhorge

D375.1793002716.diff
No OneTemporary

Authored By
Unknown
Size
24 KB
Referenced Files
None
Subscribers
None

D375.1793002716.diff

diff --git a/src/base/event.hpp b/src/base/event.hpp
--- a/src/base/event.hpp
+++ b/src/base/event.hpp
@@ -102,6 +102,10 @@
friend bool operator==(const Event &a, const Event &b);
inline friend bool operator!=(const Event &a, const Event &b) { return !(a == b); };
+ nlohmann::json toFullJson() const;
+
+ static Event fromFullJson(nlohmann::json j);
+
private:
JsonWrap m_json;
JsonWrap m_decryptedJson;
diff --git a/src/base/event.cpp b/src/base/event.cpp
--- a/src/base/event.cpp
+++ b/src/base/event.cpp
@@ -184,4 +184,23 @@
&& a.raw() == b.raw();
}
+ nlohmann::json Event::toFullJson() const
+ {
+ return json{
+ {"json", m_json},
+ {"decryptedJson", m_decryptedJson},
+ {"decrypted", m_decrypted},
+ {"encrypted", m_encrypted},
+ };
+ }
+
+ Event Event::fromFullJson(nlohmann::json j)
+ {
+ Event e;
+ e.m_json = JsonWrap(std::move(j.at("json")));
+ e.m_decryptedJson = JsonWrap(std::move(j.at("decryptedJson")));
+ e.m_decrypted = std::move(j.at("decrypted"));
+ e.m_encrypted = std::move(j.at("encrypted"));
+ return e;
+ }
}
diff --git a/src/client/actions/sync.cpp b/src/client/actions/sync.cpp
--- a/src/client/actions/sync.cpp
+++ b/src/client/actions/sync.cpp
@@ -11,6 +11,7 @@
#include <zug/transducer/cat.hpp>
#include <zug/transducer/filter.hpp>
#include <zug/sequence.hpp>
+#include <zug/into_vector.hpp>
#include <jobinterface.hpp>
#include <debug.hpp>
@@ -245,10 +246,12 @@
[[nodiscard]] static json popVerificationEvents(ClientModel &m)
{
auto oldToDevice = std::move(m.toDevice);
- auto toDeviceVerificationEvents = intoImmer(
- EventList{},
+ auto toDeviceVerificationEvents = zug::into_vector(
zug::filter([](const auto &e) {
return VerificationTracker::isVerificationEvent(e);
+ })
+ | zug::map([](const auto &e) {
+ return e.toFullJson();
}),
oldToDevice);
m.toDevice = intoImmer(
diff --git a/src/client/client.cpp b/src/client/client.cpp
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -647,7 +647,13 @@
return that.m_ctx.createResolvedPromise(stat);
}
kzo.client.dbg() << "processVerificationEvents: " << stat.data().get().dump() << std::endl;
- EventList ves = stat.data().get().at("verificationEvents").at("toDevice").template get<EventList>();
+ EventList ves = intoImmer(
+ EventList(),
+ zug::map([](const json &j) {
+ return Event::fromFullJson(j);
+ }),
+ stat.data().get().at("verificationEvents").at("toDevice")
+ );
return that.processVerificationEventsFromSync(ves);
});
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -7,13 +7,13 @@
function(libkazv_add_tests)
set(options "")
set(oneValueArgs "")
- set(multiValueArgs EXTRA_LINK_LIBRARIES EXTRA_INCLUDE_DIRECTORIES)
+ set(multiValueArgs EXTRA_LINK_LIBRARIES EXTRA_INCLUDE_DIRECTORIES EXTRA_SOURCES)
cmake_parse_arguments(PARSE_ARGV 0 libkazv_add_tests "${options}" "${oneValueArgs}" "${multiValueArgs}")
foreach(test_source ${libkazv_add_tests_UNPARSED_ARGUMENTS})
string(REGEX REPLACE "\\.cpp$" "" test_executable "${test_source}")
string(REGEX REPLACE "/|\\\\" "--" test_executable "${test_executable}")
message(STATUS "Test ${test_executable} added")
- add_executable("${test_executable}" "${test_source}")
+ add_executable("${test_executable}" "${test_source}" ${libkazv_add_tests_EXTRA_SOURCES})
target_link_libraries("${test_executable}"
PRIVATE Catch2::Catch2WithMain
Threads::Threads
@@ -46,9 +46,9 @@
add_library(client-test-lib SHARED client/client-test-util.cpp)
target_link_libraries(client-test-lib PUBLIC kazvjob kazvclient)
+
libkazv_add_tests(
client/discovery-test.cpp
- client/sync-test.cpp
client/content-test.cpp
client/paginate-test.cpp
client/storage-actions-test.cpp
@@ -66,7 +66,6 @@
client/keys-test.cpp
client/device-ops-test.cpp
client/send-test.cpp
- client/encryption-test.cpp
client/redact-test.cpp
client/tagging-test.cpp
client/account-data-test.cpp
@@ -81,7 +80,6 @@
client/power-levels-desc-test.cpp
client/client-test.cpp
client/create-room-test.cpp
- client/device-list-tracker-test.cpp
client/device-list-tracker-benchmark-test.cpp
client/room/read-receipt-test.cpp
client/room/undecrypted-events-test.cpp
@@ -99,6 +97,15 @@
EXTRA_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/client
)
+libkazv_add_tests(
+ client/sync-test.cpp
+ client/encryption-test.cpp
+ client/device-list-tracker-test.cpp
+ EXTRA_SOURCES encryption-test-utils.cpp
+ EXTRA_LINK_LIBRARIES kazvclient kazveventemitter kazvjob client-test-lib kazvtestfixtures
+ EXTRA_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/client
+)
+
libkazv_add_tests(
basejobtest.cpp
kazvjobtest.cpp
diff --git a/src/tests/client/encryption-test.cpp b/src/tests/client/encryption-test.cpp
--- a/src/tests/client/encryption-test.cpp
+++ b/src/tests/client/encryption-test.cpp
@@ -17,142 +17,6 @@
using namespace Kazv::Factory;
-namespace
-{
- struct CreateE2EESessionResult
- {
- ClientModel receiver1;
- ClientModel receiver2;
- ClientModel sender;
- };
-
- struct CreateMegOlmSessionResult
- {
- Event encryptedRoomEvent;
- Event encryptedKeyEvent;
- Event unencryptedKeyEvent;
- };
-}
-
-static json makeDeviceInfo(const ClientModel &client)
-{
- auto [next, _] = updateClient(client, UploadIdentityKeysAction{});
- return json::parse(std::get<Bytes>(next.nextJobs[0].requestBody()))["device_keys"];
-}
-
-// Make a aware of b
-static void queryOne(ClientModel &a, ClientModel &b)
-{
- auto queryKeysRespJson = json{
- {"device_keys", {{b.userId, {
- {b.deviceId, makeDeviceInfo(b)}
- }}}},
- };
- std::tie(a, std::ignore) = processResponse(a, QueryKeysResponse(
- makeResponse("QueryKeys", withResponseJsonBody(queryKeysRespJson)
- | withResponseDataKV("deviceKeys", json::object({
- {b.userId, {b.deviceId}}
- })))
- ));
-}
-
-static void queryEachOtherKeys(ClientModel &m1, ClientModel &m2)
-{
- queryOne(m1, m2);
- queryOne(m2, m1);
-}
-
-static void createAndClaimOneTimeKey(ClientModel &sender, ClientModel &receiver)
-{
- auto oneTimeKeys = receiver.withCrypto([](Crypto &c) {
- c.genOneTimeKeysWithRandom(genRandomData(Crypto::genOneTimeKeysRandomSize(1)), 1);
- auto k = c.unpublishedOneTimeKeys();
- c.markOneTimeKeysAsPublished();
- return k;
- });
- auto cv25519Key = oneTimeKeys["curve25519"].items().begin().value().template get<std::string>();
- sender.withCrypto([&](auto &c) {
- c.createOutboundSessionWithRandom(
- genRandomData(Crypto::createOutboundSessionRandomSize()),
- receiver.constCrypto().curve25519IdentityKey(), cv25519Key);
- });
-}
-
-static CreateE2EESessionResult createE2EESession()
-{
- auto r1Crypto = makeCrypto();
- auto r1 = makeClient(withCrypto(r1Crypto));
- r1.userId = "@receiver:example.com";
- r1.deviceId = "device1";
- auto r2Crypto = makeCrypto();
- auto r2 = makeClient(withCrypto(r2Crypto));
- r2.userId = "@receiver:example.com";
- r2.deviceId = "device2";
-
- auto queryKeysRespJsonSender = json{
- {"device_keys", {{"@receiver:example.com", {
- {"device1", makeDeviceInfo(r1)},
- {"device2", makeDeviceInfo(r2)},
- }}}},
- };
-
- // Query keys
- auto client = makeClient(withCrypto(makeCrypto()));
- client.userId = "@sender:example.com";
- client.deviceId = "device1";
-
- queryEachOtherKeys(client, r1);
- queryEachOtherKeys(client, r2);
-
- createAndClaimOneTimeKey(client, r1);
- createAndClaimOneTimeKey(client, r2);
-
- return {
- r1,
- r2,
- client,
- };
-}
-
-static CreateMegOlmSessionResult createMegOlmSession(ClientModel &sender, ClientModel &receiver, std::string roomId, Event plainText)
-{
- auto sessionKey = sender.withCrypto([&](auto &c) {
- return c.rotateMegOlmSessionWithRandom(genRandomData(Crypto::rotateMegOlmSessionRandomSize()), 0, roomId);
- });
-
- auto mod = withRoom(makeRoom(withRoomId(roomId) | withRoomEncrypted(true)));
- mod(sender);
- mod(receiver);
-
- auto [encrypted, _noSessionKey] = sender.megOlmEncrypt(plainText, roomId, 0,
- genRandomData(EncryptMegOlmEventAction::maxRandomSize()));
- auto sessionId = encrypted.originalJson().get()["content"]["session_id"].template get<std::string>();
-
- auto keyEventJson = json{
- {"content", {{"algorithm", CryptoConstants::megOlmAlgo},
- {"room_id", roomId},
- {"session_id", sessionId},
- {"session_key", sessionKey}}},
- {"type", "m.room_key"}
- };
-
- auto res = sender.olmEncryptSplit(Event(keyEventJson),
- {{receiver.userId, {receiver.deviceId}}},
- genRandomData(Crypto::encryptOlmMaxRandomSize() * 2));
-
- auto encryptedKeyEventJson = res[receiver.userId][receiver.deviceId].originalJson().get();
- encryptedKeyEventJson["sender"] = sender.userId;
- auto encryptedKeyEvent = Event(encryptedKeyEventJson);
- std::cerr << "room event" << encrypted.originalJson().get().dump() << std::endl;
- std::cerr << "key event" << encryptedKeyEvent.originalJson().get().dump() << std::endl;
-
- keyEventJson["keys"] = json{
- {CryptoConstants::ed25519, sender.constCrypto().ed25519IdentityKey()},
- };
- keyEventJson["sender"] = sender.userId;
- return {encrypted, encryptedKeyEvent, Event(keyEventJson)};
-}
-
static Response syncResponseFromToDevice(Event toDevice)
{
auto j = json{
diff --git a/src/tests/client/sync-test.cpp b/src/tests/client/sync-test.cpp
--- a/src/tests/client/sync-test.cpp
+++ b/src/tests/client/sync-test.cpp
@@ -22,6 +22,7 @@
#include <outbound-group-session.hpp>
#include "client-test-util.hpp"
#include "action-mock-utils.hpp"
+#include "encryption-test-utils.hpp"
#include "factory.hpp"
using namespace Kazv::Factory;
@@ -796,3 +797,50 @@
});
u.io.run();
}
+
+TEST_CASE("Sync correctly pops encrypted verification events", "[client][sync][encryption]")
+{
+ auto sr = createE2EESession();
+ json eventJson = R"({
+ "content": {
+ "methods": [
+ "m.sas.v1"
+ ],
+ "timestamp": 1559598944869,
+ "transaction_id": "S0meUniqueAndOpaqueString"
+ },
+ "type": "m.key.verification.request"
+})"_json;
+ eventJson["content"]["from_device"] = sr.sender.deviceId;
+ auto encrypted = sr.sender.olmEncryptSplit(
+ Event(eventJson),
+ {{sr.receiver1.userId, {sr.receiver1.deviceId}}},
+ {},
+ /* attachSenderDeviceKeys = */ false
+ );
+ auto j = encrypted.at(sr.receiver1.userId).at(sr.receiver1.deviceId).originalJson().get();
+ j["sender"] = sr.sender.userId;
+ auto ev = Event(j);
+
+ auto u = makeMockSdkUtil(sr.receiver1);
+ auto md = u.getMockDispatcher(passDown<ProcessResponseAction>());
+ auto ctx = getMockContext(u.ph, md);
+ auto respBody = R"({
+ "next_batch": "something",
+ "to_device": {"events": []}
+})"_json;
+ respBody["to_device"]["events"].push_back(ev);
+ auto resp = makeResponse("Sync", withResponseJsonBody(respBody) | withResponseDataKV("is", "incremental"));
+ ctx.dispatch(ProcessResponseAction{resp})
+ .then([&u](const EffectStatus &s) {
+ REQUIRE(s.success());
+ REQUIRE(s.dataJson("verificationEvents").at("toDevice").size() == 1);
+ auto ve = Event::fromFullJson(s.dataJson("verificationEvents").at("toDevice").at(0));
+ REQUIRE(ve.type() == "m.key.verification.request");
+ REQUIRE(ve.encrypted());
+ REQUIRE(ve.decrypted());
+ REQUIRE(u.sdk.client().toDevice().make().get().empty());
+ u.io.stop();
+ });
+ u.io.run();
+}
diff --git a/src/tests/encryption-test-utils.hpp b/src/tests/encryption-test-utils.hpp
--- a/src/tests/encryption-test-utils.hpp
+++ b/src/tests/encryption-test-utils.hpp
@@ -7,87 +7,14 @@
#pragma once
#include <libkazv-config.hpp>
#include "factory.hpp"
-#include <catch2/catch_test_macros.hpp>
struct OlmFirstTimeDecryptTestSetup
{
- inline OlmFirstTimeDecryptTestSetup()
- : sender("@example:example.com")
- , recipient("@foo:example.com")
- , senderDeviceId("device1")
- , recipientDeviceId("device2")
- {
- using namespace Kazv;
- using namespace Kazv::Factory;
+ OlmFirstTimeDecryptTestSetup();
- auto cryptoA = makeCrypto();
- auto cryptoB = makeCrypto();
- // A creates an outbound olm session with B
- cryptoB.genOneTimeKeysWithRandom(genRandomData(Crypto::genOneTimeKeysRandomSize(1)), 1);
- auto otk = *(cryptoB.unpublishedOneTimeKeys()[CryptoConstants::curve25519].begin());
- cryptoB.markOneTimeKeysAsPublished();
- cryptoA.createOutboundSessionWithRandom(
- genRandomData(Crypto::createOutboundSessionRandomSize()),
- cryptoB.curve25519IdentityKey(), otk);
+ Kazv::Event encrypt(Kazv::json pt, bool attachSenderDeviceKeys = false);
- infoA = DeviceKeyInfo{
- senderDeviceId,
- cryptoA.ed25519IdentityKey(),
- cryptoA.curve25519IdentityKey(),
- "Device-1",
- DeviceTrustLevel::Verified,
- };
- infoB = DeviceKeyInfo{
- recipientDeviceId,
- cryptoB.ed25519IdentityKey(),
- cryptoB.curve25519IdentityKey(),
- "Device-2",
- DeviceTrustLevel::Verified,
- };
-
- clientA = makeClient(
- withAttr(&ClientModel::userId, sender)
- | withAttr(&ClientModel::deviceId, senderDeviceId)
- | withDevice(recipient, infoB)
- | withCrypto(cryptoA)
- );
- clientWithDevice = makeClient(
- withAttr(&ClientModel::userId, recipient)
- | withAttr(&ClientModel::deviceId, recipientDeviceId)
- | withDevice(sender, infoA)
- | withCrypto(cryptoB)
- );
- clientNoDevice = makeClient(
- withAttr(&ClientModel::userId, recipient)
- | withAttr(&ClientModel::deviceId, recipientDeviceId)
- | withCrypto(cryptoB)
- );
- }
-
- inline Kazv::Event encrypt(Kazv::json pt, bool attachSenderDeviceKeys = false)
- {
- using namespace Kazv;
- auto encrypted = clientA.olmEncryptSplit(
- Event(pt),
- {{recipient, {recipientDeviceId}}},
- {},
- attachSenderDeviceKeys
- );
- auto j = encrypted.at(recipient).at(recipientDeviceId).originalJson().get();
- j["sender"] = sender;
- return Event(j);
- };
-
- inline Kazv::Event decryptOnly(Kazv::Event e)
- {
- using namespace Kazv;
- auto decryptedText = clientWithDevice.withCrypto([&](Crypto &c) {
- return c.decrypt(e.originalJson().get());
- });
- REQUIRE(decryptedText.has_value());
- auto decryptedJson = json::parse(decryptedText.value());
- return e.setDecryptedJson(decryptedJson, Event::Decrypted);
- };
+ Kazv::Event decryptOnly(Kazv::Event e);
std::string sender;
std::string recipient;
@@ -99,3 +26,29 @@
Kazv::ClientModel clientWithDevice;
Kazv::ClientModel clientNoDevice;
};
+
+struct CreateE2EESessionResult
+{
+ Kazv::ClientModel receiver1;
+ Kazv::ClientModel receiver2;
+ Kazv::ClientModel sender;
+};
+
+struct CreateMegOlmSessionResult
+{
+ Kazv::Event encryptedRoomEvent;
+ Kazv::Event encryptedKeyEvent;
+ Kazv::Event unencryptedKeyEvent;
+};
+
+Kazv::json makeDeviceInfo(const Kazv::ClientModel &client);
+
+void queryOne(Kazv::ClientModel &a, Kazv::ClientModel &b);
+
+void queryEachOtherKeys(Kazv::ClientModel &m1, Kazv::ClientModel &m2);
+
+void createAndClaimOneTimeKey(Kazv::ClientModel &sender, Kazv::ClientModel &receiver);
+
+CreateE2EESessionResult createE2EESession();
+
+CreateMegOlmSessionResult createMegOlmSession(Kazv::ClientModel &sender, Kazv::ClientModel &receiver, std::string roomId, Kazv::Event plainText);
diff --git a/src/tests/encryption-test-utils.cpp b/src/tests/encryption-test-utils.cpp
new file mode 100644
--- /dev/null
+++ b/src/tests/encryption-test-utils.cpp
@@ -0,0 +1,207 @@
+/*
+ * This file is part of libkazv.
+ * SPDX-FileCopyrightText: 2026 tusooa <tusooa@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <libkazv-config.hpp>
+#include "encryption-test-utils.hpp"
+#include <client/actions/encryption.hpp>
+#include <client-model.hpp>
+#include <catch2/catch_test_macros.hpp>
+#include <iostream>
+
+using namespace Kazv;
+using namespace Kazv::Factory;
+
+OlmFirstTimeDecryptTestSetup::OlmFirstTimeDecryptTestSetup()
+ : sender("@example:example.com")
+ , recipient("@foo:example.com")
+ , senderDeviceId("device1")
+ , recipientDeviceId("device2")
+{
+ auto cryptoA = makeCrypto();
+ auto cryptoB = makeCrypto();
+ // A creates an outbound olm session with B
+ cryptoB.genOneTimeKeysWithRandom(genRandomData(Crypto::genOneTimeKeysRandomSize(1)), 1);
+ auto otk = *(cryptoB.unpublishedOneTimeKeys()[CryptoConstants::curve25519].begin());
+ cryptoB.markOneTimeKeysAsPublished();
+ cryptoA.createOutboundSessionWithRandom(
+ genRandomData(Crypto::createOutboundSessionRandomSize()),
+ cryptoB.curve25519IdentityKey(), otk);
+
+ infoA = DeviceKeyInfo{
+ senderDeviceId,
+ cryptoA.ed25519IdentityKey(),
+ cryptoA.curve25519IdentityKey(),
+ "Device-1",
+ DeviceTrustLevel::Verified,
+ };
+ infoB = DeviceKeyInfo{
+ recipientDeviceId,
+ cryptoB.ed25519IdentityKey(),
+ cryptoB.curve25519IdentityKey(),
+ "Device-2",
+ DeviceTrustLevel::Verified,
+ };
+
+ clientA = makeClient(
+ withAttr(&ClientModel::userId, sender)
+ | withAttr(&ClientModel::deviceId, senderDeviceId)
+ | withDevice(recipient, infoB)
+ | withCrypto(cryptoA)
+ );
+ clientWithDevice = makeClient(
+ withAttr(&ClientModel::userId, recipient)
+ | withAttr(&ClientModel::deviceId, recipientDeviceId)
+ | withDevice(sender, infoA)
+ | withCrypto(cryptoB)
+ );
+ clientNoDevice = makeClient(
+ withAttr(&ClientModel::userId, recipient)
+ | withAttr(&ClientModel::deviceId, recipientDeviceId)
+ | withCrypto(cryptoB)
+ );
+}
+
+Kazv::Event OlmFirstTimeDecryptTestSetup::encrypt(Kazv::json pt, bool attachSenderDeviceKeys)
+{
+ auto encrypted = clientA.olmEncryptSplit(
+ Event(pt),
+ {{recipient, {recipientDeviceId}}},
+ {},
+ attachSenderDeviceKeys
+ );
+ auto j = encrypted.at(recipient).at(recipientDeviceId).originalJson().get();
+ j["sender"] = sender;
+ return Event(j);
+}
+
+Kazv::Event OlmFirstTimeDecryptTestSetup::decryptOnly(Kazv::Event e)
+{
+ auto decryptedText = clientWithDevice.withCrypto([&](Crypto &c) {
+ return c.decrypt(e.originalJson().get());
+ });
+ REQUIRE(decryptedText.has_value());
+ auto decryptedJson = json::parse(decryptedText.value());
+ return e.setDecryptedJson(decryptedJson, Event::Decrypted);
+};
+
+
+json makeDeviceInfo(const ClientModel &client)
+{
+ auto [next, _] = updateClient(client, UploadIdentityKeysAction{});
+ return json::parse(std::get<Bytes>(next.nextJobs[0].requestBody()))["device_keys"];
+}
+
+void queryOne(ClientModel &a, ClientModel &b)
+{
+ auto queryKeysRespJson = json{
+ {"device_keys", {{b.userId, {
+ {b.deviceId, makeDeviceInfo(b)}
+ }}}},
+ };
+ std::tie(a, std::ignore) = processResponse(a, QueryKeysResponse(
+ makeResponse("QueryKeys", withResponseJsonBody(queryKeysRespJson)
+ | withResponseDataKV("deviceKeys", json::object({
+ {b.userId, {b.deviceId}}
+ })))
+ ));
+}
+
+void queryEachOtherKeys(ClientModel &m1, ClientModel &m2)
+{
+ queryOne(m1, m2);
+ queryOne(m2, m1);
+}
+
+void createAndClaimOneTimeKey(ClientModel &sender, ClientModel &receiver)
+{
+ auto oneTimeKeys = receiver.withCrypto([](Crypto &c) {
+ c.genOneTimeKeysWithRandom(genRandomData(Crypto::genOneTimeKeysRandomSize(1)), 1);
+ auto k = c.unpublishedOneTimeKeys();
+ c.markOneTimeKeysAsPublished();
+ return k;
+ });
+ auto cv25519Key = oneTimeKeys["curve25519"].items().begin().value().template get<std::string>();
+ sender.withCrypto([&](auto &c) {
+ c.createOutboundSessionWithRandom(
+ genRandomData(Crypto::createOutboundSessionRandomSize()),
+ receiver.constCrypto().curve25519IdentityKey(), cv25519Key);
+ });
+}
+
+CreateE2EESessionResult createE2EESession()
+{
+ auto r1Crypto = makeCrypto();
+ auto r1 = makeClient(withCrypto(r1Crypto));
+ r1.userId = "@receiver:example.com";
+ r1.deviceId = "device1";
+ auto r2Crypto = makeCrypto();
+ auto r2 = makeClient(withCrypto(r2Crypto));
+ r2.userId = "@receiver:example.com";
+ r2.deviceId = "device2";
+
+ auto queryKeysRespJsonSender = json{
+ {"device_keys", {{"@receiver:example.com", {
+ {"device1", makeDeviceInfo(r1)},
+ {"device2", makeDeviceInfo(r2)},
+ }}}},
+ };
+
+ // Query keys
+ auto client = makeClient(withCrypto(makeCrypto()));
+ client.userId = "@sender:example.com";
+ client.deviceId = "device1";
+
+ queryEachOtherKeys(client, r1);
+ queryEachOtherKeys(client, r2);
+
+ createAndClaimOneTimeKey(client, r1);
+ createAndClaimOneTimeKey(client, r2);
+
+ return {
+ r1,
+ r2,
+ client,
+ };
+}
+
+CreateMegOlmSessionResult createMegOlmSession(ClientModel &sender, ClientModel &receiver, std::string roomId, Event plainText)
+{
+ auto sessionKey = sender.withCrypto([&](auto &c) {
+ return c.rotateMegOlmSessionWithRandom(genRandomData(Crypto::rotateMegOlmSessionRandomSize()), 0, roomId);
+ });
+
+ auto mod = withRoom(makeRoom(withRoomId(roomId) | withRoomEncrypted(true)));
+ mod(sender);
+ mod(receiver);
+
+ auto [encrypted, _noSessionKey] = sender.megOlmEncrypt(plainText, roomId, 0,
+ genRandomData(EncryptMegOlmEventAction::maxRandomSize()));
+ auto sessionId = encrypted.originalJson().get()["content"]["session_id"].template get<std::string>();
+
+ auto keyEventJson = json{
+ {"content", {{"algorithm", CryptoConstants::megOlmAlgo},
+ {"room_id", roomId},
+ {"session_id", sessionId},
+ {"session_key", sessionKey}}},
+ {"type", "m.room_key"}
+ };
+
+ auto res = sender.olmEncryptSplit(Event(keyEventJson),
+ {{receiver.userId, {receiver.deviceId}}},
+ genRandomData(Crypto::encryptOlmMaxRandomSize() * 2));
+
+ auto encryptedKeyEventJson = res[receiver.userId][receiver.deviceId].originalJson().get();
+ encryptedKeyEventJson["sender"] = sender.userId;
+ auto encryptedKeyEvent = Event(encryptedKeyEventJson);
+ std::cerr << "room event" << encrypted.originalJson().get().dump() << std::endl;
+ std::cerr << "key event" << encryptedKeyEvent.originalJson().get().dump() << std::endl;
+
+ keyEventJson["keys"] = json{
+ {CryptoConstants::ed25519, sender.constCrypto().ed25519IdentityKey()},
+ };
+ keyEventJson["sender"] = sender.userId;
+ return {encrypted, encryptedKeyEvent, Event(keyEventJson)};
+}
diff --git a/src/tests/event-test.cpp b/src/tests/event-test.cpp
--- a/src/tests/event-test.cpp
+++ b/src/tests/event-test.cpp
@@ -170,3 +170,23 @@
}
}
}
+
+TEST_CASE("toFullJson/fromFullJson", "[base][event]")
+{
+ Event e = Event(json{
+ {"type", "m.room.encrypted"},
+ {"content", {
+ {"a", "b"},
+ }},
+ }).setDecryptedJson(json{
+ {"type", "m.room.message"},
+ {"content", {
+ {"c", "d"},
+ }},
+ }, Event::Decrypted);
+
+ auto e2 = Event::fromFullJson(e.toFullJson());
+ REQUIRE(e2 == e);
+ REQUIRE(e2.type() == "m.room.message");
+ REQUIRE(e2.raw().get().at("content").at("c") == "d");
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 26, 1:18 AM (22 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1794781
Default Alt Text
D375.1793002716.diff (24 KB)

Event Timeline