aboutsummaryrefslogtreecommitdiff
path: root/lib/connection.cpp
diff options
context:
space:
mode:
authorAlexey Rusakov <Kitsune-Ral@users.sf.net>2022-06-17 10:35:22 +0200
committerAlexey Rusakov <Kitsune-Ral@users.sf.net>2022-06-17 10:38:40 +0200
commitf779b235ddac990d17a9a8d8dd222b9e0e7abd49 (patch)
treec56650a322fa5b4a6fc66b9230152e3b8f9d4f9a /lib/connection.cpp
parentda5156f5e2da08123549b554d9eafcf366fa4e11 (diff)
downloadlibquotient-f779b235ddac990d17a9a8d8dd222b9e0e7abd49.tar.gz
libquotient-f779b235ddac990d17a9a8d8dd222b9e0e7abd49.zip
Make Connection::sendToDevices() an actual slot
Although Qt 5 didn't complain about that, you could never really use sendToDevices() in its slot (or even invocable) capacity because Qt's meta-type system could not handle move-only UsersToDevicesToEvents. Qt 6 is more stringent; the build fails at trying to instantiate QMetaType for that type (with a rather unhelpful error message thrown by Clang, and more helpful but very verbose diagnostic from MSVC) because it does not provide a copy constructor. However, sendToDevice doesn't really need to have full-blown events in that parameter; just the content of the event is equally fine. This commit does exactly that: replaces UsersToDevicesToEvents with UsersToDevicesToContent that contains QJsonObject's instead of EventPtr's. The code around is updated accordingly. Also: factor out the key event JSON creation from makeMessageEventForSessionKey() because it's the same JSON for each target device; the function therefore is called encryptSessionKeyEvent() now.
Diffstat (limited to 'lib/connection.cpp')
-rw-r--r--lib/connection.cpp74
1 files changed, 32 insertions, 42 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 101bef89..3e44513b 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -381,10 +381,9 @@ public:
const QString& device) const;
QString edKeyForUserDevice(const QString& userId,
const QString& device) const;
- std::unique_ptr<EncryptedEvent> makeEventForSessionKey(
- const QString& roomId, const QString& targetUserId,
- const QString& targetDeviceId, const QByteArray& sessionId,
- const QByteArray& sessionKey) const;
+ QJsonObject encryptSessionKeyEvent(QJsonObject payloadJson,
+ const QString& targetUserId,
+ const QString& targetDeviceId) const;
#endif
void saveAccessTokenToKeychain() const
@@ -1365,17 +1364,10 @@ ForgetRoomJob* Connection::forgetRoom(const QString& id)
}
SendToDeviceJob* Connection::sendToDevices(
- const QString& eventType, const UsersToDevicesToEvents& eventsMap)
+ const QString& eventType, const UsersToDevicesToContent& contents)
{
- QHash<QString, QHash<QString, QJsonObject>> json;
- json.reserve(int(eventsMap.size()));
- for (const auto& [userId, devicesToEvents] : eventsMap) {
- auto& jsonUser = json[userId];
- for (const auto& [deviceId, event] : devicesToEvents)
- jsonUser.insert(deviceId, event->contentJson());
- }
return callApi<SendToDeviceJob>(BackgroundRequest, eventType,
- generateTxnId(), json);
+ generateTxnId(), contents);
}
SendMessageJob* Connection::sendMessage(const QString& roomId,
@@ -2354,30 +2346,15 @@ bool Connection::Private::createOlmSession(const QString& targetUserId,
return true;
}
-std::unique_ptr<EncryptedEvent> Connection::Private::makeEventForSessionKey(
- const QString& roomId, const QString& targetUserId,
- const QString& targetDeviceId, const QByteArray& sessionId,
- const QByteArray& sessionKey) const
+QJsonObject Connection::Private::encryptSessionKeyEvent(
+ QJsonObject payloadJson, const QString& targetUserId,
+ const QString& targetDeviceId) const
{
- // Noisy but nice for debugging
- // qDebug(E2EE) << "Creating the payload for" << data->userId() << device <<
- // sessionId << sessionKey.toHex();
- const auto event = makeEvent<RoomKeyEvent>("m.megolm.v1.aes-sha2", roomId,
- sessionId, sessionKey,
- data->userId());
- auto payloadJson = event->fullJson();
payloadJson.insert("recipient"_ls, targetUserId);
- payloadJson.insert(SenderKeyL, data->userId());
payloadJson.insert("recipient_keys"_ls,
QJsonObject { { Ed25519Key,
edKeyForUserDevice(targetUserId,
targetDeviceId) } });
- payloadJson.insert("keys"_ls,
- QJsonObject {
- { Ed25519Key,
- QString(olmAccount->identityKeys().ed25519) } });
- payloadJson.insert("sender_device"_ls, data->deviceId());
-
const auto [type, cipherText] = olmEncryptMessage(
targetUserId, targetDeviceId,
QJsonDocument(payloadJson).toJson(QJsonDocument::Compact));
@@ -2387,8 +2364,8 @@ std::unique_ptr<EncryptedEvent> Connection::Private::makeEventForSessionKey(
{ "body"_ls, QString(cipherText) } } }
};
- return makeEvent<EncryptedEvent>(encrypted,
- olmAccount->identityKeys().curve25519);
+ return EncryptedEvent(encrypted, olmAccount->identityKeys().curve25519)
+ .contentJson();
}
void Connection::sendSessionKeyToDevices(
@@ -2409,11 +2386,21 @@ void Connection::sendSessionKeyToDevices(
if (hash.isEmpty())
return;
+ auto keyEventJson = RoomKeyEvent(MegolmV1AesSha2AlgoKey, roomId, sessionId,
+ sessionKey, userId())
+ .fullJson();
+ keyEventJson.insert(SenderKeyL, userId());
+ keyEventJson.insert("sender_device"_ls, deviceId());
+ keyEventJson.insert(
+ "keys"_ls,
+ QJsonObject {
+ { Ed25519Key, QString(olmAccount()->identityKeys().ed25519) } });
+
auto job = callApi<ClaimKeysJob>(hash);
- connect(job, &BaseJob::success, this, [job, this, roomId, sessionId, sessionKey, devices, index] {
- UsersToDevicesToEvents usersToDevicesToEvents;
- const auto oneTimeKeys = job->oneTimeKeys();
- for (const auto& [targetUserId, targetDeviceId] :
+ connect(job, &BaseJob::success, this, [job, this, roomId, sessionId, keyEventJson, devices, index] {
+ QHash<QString, QHash<QString, QJsonObject>> usersToDevicesToContent;
+ for (const auto oneTimeKeys = job->oneTimeKeys();
+ const auto& [targetUserId, targetDeviceId] :
asKeyValueRange(devices)) {
if (!hasOlmSession(targetUserId, targetDeviceId)
&& !d->createOlmSession(
@@ -2421,12 +2408,15 @@ void Connection::sendSessionKeyToDevices(
oneTimeKeys[targetUserId][targetDeviceId]))
continue;
- usersToDevicesToEvents[targetUserId][targetDeviceId] =
- d->makeEventForSessionKey(roomId, targetUserId, targetDeviceId,
- sessionId, sessionKey);
+ // Noisy but nice for debugging
+// qDebug(E2EE) << "Creating the payload for" << targetUserId
+// << targetDeviceId << sessionId << sessionKey.toHex();
+ usersToDevicesToContent[targetUserId][targetDeviceId] =
+ d->encryptSessionKeyEvent(keyEventJson, targetUserId,
+ targetDeviceId);
}
- if (!usersToDevicesToEvents.empty()) {
- sendToDevices(EncryptedEvent::TypeId, usersToDevicesToEvents);
+ if (!usersToDevicesToContent.empty()) {
+ sendToDevices(EncryptedEvent::TypeId, usersToDevicesToContent);
QVector<std::tuple<QString, QString, QString>> receivedDevices;
receivedDevices.reserve(devices.size());
for (const auto& [user, device] : asKeyValueRange(devices))