diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2019-08-01 09:55:00 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2019-08-01 09:55:00 +0900 |
commit | 405271605f334ad09c7dc638fc5d6ef11849cada (patch) | |
tree | ab955483142d8b8b1ca6018a9b8533b147b1211f /lib/events | |
parent | 1ea94b918569dd26452f285c408e605f9dc15343 (diff) | |
parent | f5083ee71e6fad9f28c4b835899f3ad574b426f1 (diff) | |
download | libquotient-405271605f334ad09c7dc638fc5d6ef11849cada.tar.gz libquotient-405271605f334ad09c7dc638fc5d6ef11849cada.zip |
Merge branch 'master' into kitsune-relations
Unified *Key -> *KeyL identifiers in roommessageevent.cpp along the way.
Diffstat (limited to 'lib/events')
-rw-r--r-- | lib/events/encryptedevent.cpp | 29 | ||||
-rw-r--r-- | lib/events/encryptedevent.h | 66 | ||||
-rw-r--r-- | lib/events/encryptionevent.cpp | 15 | ||||
-rw-r--r-- | lib/events/event.h | 2 | ||||
-rw-r--r-- | lib/events/roommessageevent.cpp | 37 |
5 files changed, 123 insertions, 26 deletions
diff --git a/lib/events/encryptedevent.cpp b/lib/events/encryptedevent.cpp new file mode 100644 index 00000000..6942738a --- /dev/null +++ b/lib/events/encryptedevent.cpp @@ -0,0 +1,29 @@ +#include "encryptedevent.h" +#include "room.h" + +using namespace QMatrixClient; +using namespace QtOlm; + +EncryptedEvent::EncryptedEvent(const QJsonObject &ciphertext, const QString &senderKey) + : RoomEvent(typeId(), matrixTypeId(), + { { AlgorithmKeyL , OlmV1Curve25519AesSha2AlgoKey }, + { CiphertextKeyL , ciphertext }, + { SenderKeyKeyL, senderKey } + }) +{ } + +EncryptedEvent::EncryptedEvent(QByteArray ciphertext, const QString &senderKey, const QString& deviceId, const QString& sessionId) + : RoomEvent(typeId(), matrixTypeId(), + { { AlgorithmKeyL , MegolmV1AesSha2AlgoKey }, + { CiphertextKeyL , QString(ciphertext) }, + { DeviceIdKeyL, deviceId }, + { SenderKeyKeyL, senderKey }, + { SessionIdKeyL, sessionId }, + }) +{ } + +EncryptedEvent::EncryptedEvent(const QJsonObject &obj) + : RoomEvent(typeId(), obj) +{ + qCDebug(EVENTS) << "Encrypted event" << id(); +} diff --git a/lib/events/encryptedevent.h b/lib/events/encryptedevent.h new file mode 100644 index 00000000..2f9e4422 --- /dev/null +++ b/lib/events/encryptedevent.h @@ -0,0 +1,66 @@ +#pragma once + +#include "roomevent.h" +#include "e2ee.h" + +namespace QMatrixClient +{ + class Room; + /* + * While the specification states: + * + * "This event type is used when sending encrypted events. + * It can be used either within a room + * (in which case it will have all of the Room Event fields), + * or as a to-device event." + * "The encrypted payload can contain any message event." + * https://matrix.org/docs/spec/client_server/latest#id493 + * + * -- for most of the cases the message event is the room message event. + * And even for the to-device events the context is for the room. + * + * So, to simplify integration to the timeline, EncryptedEvent is a RoomEvent inheritor. + * Strictly speaking though, it's not always a RoomEvent, but an Event in general. + * It's possible, because RoomEvent interface is similar to Event's one + * and doesn't add new restrictions, just provides additional features. + */ + class EncryptedEvent : public RoomEvent + { + Q_GADGET + public: + DEFINE_EVENT_TYPEID("m.room.encrypted", EncryptedEvent) + + /* In case with Olm, the encrypted content of the event is + * a map from the recipient Curve25519 identity key to ciphertext information */ + explicit EncryptedEvent(const QJsonObject& ciphertext, + const QString& senderKey); + /* In case with Megolm, device_id and session_id are required */ + explicit EncryptedEvent(QByteArray ciphertext, + const QString& senderKey, + const QString& deviceId, + const QString& sessionId); + explicit EncryptedEvent(const QJsonObject& obj); + + QString algorithm() const + { + QString algo = content<QString>(AlgorithmKeyL); + if (!SupportedAlgorithms.contains(algo)) { + qWarning(MAIN) << "The EncryptedEvent's algorithm" << algo + << "is not supported"; + } + return algo; + } + QByteArray ciphertext() const { return content<QString>(CiphertextKeyL).toLatin1(); } + QJsonObject ciphertext(const QString& identityKey) const + { + return content<QJsonObject>(CiphertextKeyL).value(identityKey).toObject(); + } + QString senderKey() const { return content<QString>(SenderKeyKeyL); } + + /* device_id and session_id are required with Megolm */ + QString deviceId() const { return content<QString>(DeviceIdKeyL); } + QString sessionId() const { return content<QString>(SessionIdKeyL); } + }; + REGISTER_EVENT_TYPE(EncryptedEvent) + +} // namespace QMatrixClient diff --git a/lib/events/encryptionevent.cpp b/lib/events/encryptionevent.cpp index b8e2b575..ee6c92b1 100644 --- a/lib/events/encryptionevent.cpp +++ b/lib/events/encryptionevent.cpp @@ -7,11 +7,12 @@ #include "converters.h" #include "logging.h" +#include "e2ee.h" #include <array> static const std::array<QString, 1> encryptionStrings = { { - QStringLiteral("m.megolm.v1.aes-sha2") + QMatrixClient::MegolmV1AesSha2AlgoKey } }; namespace QMatrixClient { @@ -36,9 +37,9 @@ using namespace QMatrixClient; EncryptionEventContent::EncryptionEventContent(const QJsonObject& json) : encryption(fromJson<EncryptionType>(json["algorithm"_ls])) - , algorithm(sanitized(json["algorithm"_ls].toString())) - , rotationPeriodMs(json["rotation_period_ms"_ls].toInt(604800000)) - , rotationPeriodMsgs(json["rotation_period_msgs"_ls].toInt(100)) + , algorithm(sanitized(json[AlgorithmKeyL].toString())) + , rotationPeriodMs(json[RotationPeriodMsKeyL].toInt(604800000)) + , rotationPeriodMsgs(json[RotationPeriodMsgsKeyL].toInt(100)) { } void EncryptionEventContent::fillJson(QJsonObject* o) const @@ -47,7 +48,7 @@ void EncryptionEventContent::fillJson(QJsonObject* o) const Q_ASSERT_X(encryption != EncryptionType::Undefined, __FUNCTION__, "The key 'algorithm' must be explicit in EncryptionEventContent"); if (encryption != EncryptionType::Undefined) - o->insert(QStringLiteral("algorithm"), algorithm); - o->insert(QStringLiteral("rotation_period_ms"), rotationPeriodMs); - o->insert(QStringLiteral("rotation_period_msgs"), rotationPeriodMsgs); + o->insert(AlgorithmKey, algorithm); + o->insert(RotationPeriodMsKey, rotationPeriodMs); + o->insert(RotationPeriodMsgsKey, rotationPeriodMsgs); } diff --git a/lib/events/event.h b/lib/events/event.h index b3a58806..dee1c44a 100644 --- a/lib/events/event.h +++ b/lib/events/event.h @@ -57,11 +57,13 @@ namespace QMatrixClient // === Standard Matrix key names and basicEventJson() === static const auto TypeKey = QStringLiteral("type"); + static const auto BodyKey = QStringLiteral("body"); static const auto ContentKey = QStringLiteral("content"); static const auto EventIdKey = QStringLiteral("event_id"); static const auto UnsignedKey = QStringLiteral("unsigned"); static const auto StateKeyKey = QStringLiteral("state_key"); static const auto TypeKeyL = "type"_ls; + static const auto BodyKeyL = "body"_ls; static const auto ContentKeyL = "content"_ls; static const auto EventIdKeyL = "event_id"_ls; static const auto UnsignedKeyL = "unsigned"_ls; diff --git a/lib/events/roommessageevent.cpp b/lib/events/roommessageevent.cpp index d4b0d812..8b6cc730 100644 --- a/lib/events/roommessageevent.cpp +++ b/lib/events/roommessageevent.cpp @@ -30,10 +30,9 @@ using namespace EventContent; using MsgType = RoomMessageEvent::MsgType; -static const auto RelatesToKey = "m.relates_to"_ls; -static const auto MsgTypeKey = "msgtype"_ls; -static const auto BodyKey = "body"_ls; -static const auto FormattedBodyKey = "formatted_body"_ls; +static const auto RelatesToKeyL = "m.relates_to"_ls; +static const auto MsgTypeKeyL = "msgtype"_ls; +static const auto FormattedBodyKeyL = "formatted_body"_ls; static const auto TextTypeKey = "m.text"; static const auto EmoteTypeKey = "m.emote"; @@ -50,7 +49,7 @@ TypedBase* make(const QJsonObject& json) template <> TypedBase* make<TextContent>(const QJsonObject& json) { - return json.contains(FormattedBodyKey) || json.contains(RelatesToKey) + return json.contains(FormattedBodyKeyL) || json.contains(RelatesToKeyL) ? new TextContent(json) : nullptr; } @@ -96,12 +95,12 @@ QJsonObject RoomMessageEvent::assembleContentJson(const QString& plainBody, const QString& jsonMsgType, TypedBase* content) { auto json = content ? content->toJson() : QJsonObject(); - if (json.contains(RelatesToKey)) { + if (json.contains(RelatesToKeyL)) { if (jsonMsgType != TextTypeKey && jsonMsgType != NoticeTypeKey && jsonMsgType != EmoteTypeKey) { - json.remove(RelatesToKey); + json.remove(RelatesToKeyL); qCWarning(EVENTS) - << RelatesToKey << "cannot be used in" << jsonMsgType + << RelatesToKeyL << "cannot be used in" << jsonMsgType << "messages; the relation has been stripped off"; } else { // After the above, we know for sure that the content is TextContent @@ -112,7 +111,7 @@ QJsonObject RoomMessageEvent::assembleContentJson(const QString& plainBody, newContentJson.insert(BodyKey, plainBody); newContentJson.insert(TypeKey, jsonMsgType); json.insert(QStringLiteral("m.new_content"), newContentJson); - json[BodyKey] = "* " + plainBody; + json[BodyKeyL] = "* " + plainBody; } } } @@ -173,9 +172,9 @@ RoomMessageEvent::RoomMessageEvent(const QJsonObject& obj) if (isRedacted()) return; const QJsonObject content = contentJson(); - if ( content.contains(MsgTypeKey) && content.contains(BodyKey) ) + if ( content.contains(MsgTypeKeyL) && content.contains(BodyKeyL) ) { - auto msgtype = content[MsgTypeKey].toString(); + auto msgtype = content[MsgTypeKeyL].toString(); bool msgTypeFound = false; for (const auto& mt: msgTypes) if (mt.matrixType == msgtype) @@ -205,12 +204,12 @@ RoomMessageEvent::MsgType RoomMessageEvent::msgtype() const QString RoomMessageEvent::rawMsgtype() const { - return contentJson()[MsgTypeKey].toString(); + return contentJson()[MsgTypeKeyL].toString(); } QString RoomMessageEvent::plainBody() const { - return contentJson()[BodyKey].toString(); + return contentJson()[BodyKeyL].toString(); } QMimeType RoomMessageEvent::mimeType() const @@ -295,7 +294,7 @@ Omittable<RelatesTo> fromJson(const QJsonValue& jv) } TextContent::TextContent(const QJsonObject& json) - : relatesTo(fromJson<Omittable<RelatesTo>>(json[RelatesToKey])) + : relatesTo(fromJson<Omittable<RelatesTo>>(json[RelatesToKeyL])) { QMimeDatabase db; static const auto PlainTextMimeType = db.mimeTypeForName("text/plain"); @@ -309,25 +308,25 @@ TextContent::TextContent(const QJsonObject& json) if (actualJson["format"_ls].toString() == HtmlContentTypeId) { mimeType = HtmlMimeType; - body = actualJson[FormattedBodyKey].toString(); + body = actualJson[FormattedBodyKeyL].toString(); } else { // Falling back to plain text, as there's no standard way to describe // rich text in messages. mimeType = PlainTextMimeType; - body = actualJson[BodyKey].toString(); + body = actualJson[BodyKeyL].toString(); } } void TextContent::fillJson(QJsonObject* json) const { static const auto FormatKey = QStringLiteral("format"); - static const auto RichBodyKey = QStringLiteral("formatted_body"); + static const auto FormattedBodyKey = QStringLiteral("formatted_body"); Q_ASSERT(json); if (mimeType.inherits("text/html")) { json->insert(FormatKey, HtmlContentTypeId); - json->insert(RichBodyKey, body); + json->insert(FormattedBodyKey, body); } if (!relatesTo.omitted()) { json->insert(QStringLiteral("m.relates_to"), @@ -336,7 +335,7 @@ void TextContent::fillJson(QJsonObject* json) const QJsonObject newContentJson; if (mimeType.inherits("text/html")) { json->insert(FormatKey, HtmlContentTypeId); - json->insert(RichBodyKey, body); + json->insert(FormattedBodyKey, body); } json->insert(QStringLiteral("m.new_content"), newContentJson); } |