From 025e5ab7d90ce8cf474567457301de32d5a3e34a Mon Sep 17 00:00:00 2001
From: Kitsune Ral <Kitsune-Ral@users.sf.net>
Date: Sat, 6 Jul 2019 20:13:38 +0900
Subject: Be stricter on usage of stateKey

A few places in the library dealt with state events without any notion
of state_key inside events, including StateEvent[Base] and relevant
functions in Room. A number of workarounds have been made; e.g.,
Room::setMemberState() accepted userId as a separate parameter, ignoring
the state key inside the RoomMemberEvent already passed to it, and
Room::setLocalAliases() had a bug in the initial version where the
function still tried to pass aliases in an event with an empty state
key. This commit fixes this shortcoming: StateEventBase now gets
stateKey as one more parameter, Room::Private::getCurrentState()
respects stateKey and returns properly constructed stub events, and
Room::setMemberState() gives way to a more generic Room::setState() that
works uniformly with whatever state event you pass to it.
---
 lib/events/roommemberevent.h   |  8 +++++++-
 lib/events/simplestateevents.h | 24 ++++++++++++++++++------
 lib/events/stateevent.cpp      |  6 ++++++
 lib/events/stateevent.h        | 10 ++++++++--
 4 files changed, 39 insertions(+), 9 deletions(-)

(limited to 'lib/events')

diff --git a/lib/events/roommemberevent.h b/lib/events/roommemberevent.h
index 4490fe65..39aa280c 100644
--- a/lib/events/roommemberevent.h
+++ b/lib/events/roommemberevent.h
@@ -56,8 +56,14 @@ namespace QMatrixClient
             explicit RoomMemberEvent(const QJsonObject& obj)
                 : StateEvent(typeId(), obj)
             { }
+            [[deprecated("Use RoomMemberEvent(userId, contentArgs) instead")]]
             RoomMemberEvent(MemberEventContent&& c)
-                : StateEvent(typeId(), matrixTypeId(), c)
+                : StateEvent(typeId(), matrixTypeId(), QString(), c)
+            { }
+            template <typename... ArgTs>
+            RoomMemberEvent(const QString& userId, ArgTs&&... contentArgs)
+                : StateEvent(typeId(), matrixTypeId(), userId,
+                             std::forward<ArgTs>(contentArgs)...)
             { }
 
             /// A special constructor to create unknown RoomMemberEvents
diff --git a/lib/events/simplestateevents.h b/lib/events/simplestateevents.h
index 2c23d9ca..dc6a0868 100644
--- a/lib/events/simplestateevents.h
+++ b/lib/events/simplestateevents.h
@@ -20,8 +20,6 @@
 
 #include "stateevent.h"
 
-#include "converters.h"
-
 namespace QMatrixClient
 {
     namespace EventContent
@@ -63,7 +61,7 @@ namespace QMatrixClient
             explicit _Name() : _Name(value_type()) { } \
             template <typename T> \
             explicit _Name(T&& value) \
-                : StateEvent(typeId(), matrixTypeId(), \
+                : StateEvent(typeId(), matrixTypeId(), QString(), \
                              QStringLiteral(#_ContentKey), \
                              std::forward<T>(value)) \
             { } \
@@ -78,9 +76,6 @@ namespace QMatrixClient
 
     DEFINE_SIMPLE_STATE_EVENT(RoomNameEvent, "m.room.name", QString, name)
     DEFINE_EVENTTYPE_ALIAS(RoomName, RoomNameEvent)
-    DEFINE_SIMPLE_STATE_EVENT(RoomAliasesEvent, "m.room.aliases",
-                              QStringList, aliases)
-    DEFINE_EVENTTYPE_ALIAS(RoomAliases, RoomAliasesEvent)
     DEFINE_SIMPLE_STATE_EVENT(RoomCanonicalAliasEvent, "m.room.canonical_alias",
                               QString, alias)
     DEFINE_EVENTTYPE_ALIAS(RoomCanonicalAlias, RoomCanonicalAliasEvent)
@@ -89,4 +84,21 @@ namespace QMatrixClient
     DEFINE_SIMPLE_STATE_EVENT(EncryptionEvent, "m.room.encryption",
                               QString, algorithm)
     DEFINE_EVENTTYPE_ALIAS(RoomEncryption, EncryptionEvent)
+
+    class RoomAliasesEvent
+        : public StateEvent<EventContent::SimpleContent<QStringList>>
+    {
+    public:
+        DEFINE_EVENT_TYPEID("m.room.aliases", RoomAliasesEvent)
+        explicit RoomAliasesEvent(const QJsonObject& obj)
+            : StateEvent(typeId(), obj, QStringLiteral("aliases"))
+        { }
+        RoomAliasesEvent(const QString& server, const QStringList& aliases)
+            : StateEvent(typeId(), matrixTypeId(), server,
+                         QStringLiteral("aliases"), aliases)
+        { }
+        QString server() const { return stateKey(); }
+        QStringList aliases() const { return content().value; }
+    };
+    REGISTER_EVENT_TYPE(RoomAliasesEvent)
 } // namespace QMatrixClient
diff --git a/lib/events/stateevent.cpp b/lib/events/stateevent.cpp
index 476e0fd6..6a6e7782 100644
--- a/lib/events/stateevent.cpp
+++ b/lib/events/stateevent.cpp
@@ -36,6 +36,12 @@ using namespace QMatrixClient;
             return makeEvent<StateEventBase>(unknownEventTypeId(), json);
         });
 
+StateEventBase::StateEventBase(Event::Type type, event_mtype_t matrixType,
+                               const QString &stateKey,
+                               const QJsonObject &contentJson)
+    : RoomEvent(type, basicStateEventJson(matrixType, contentJson, stateKey))
+{ }
+
 bool StateEventBase::repeatsState() const
 {
     const auto prevContentJson = unsignedJson().value(PrevContentKeyL);
diff --git a/lib/events/stateevent.h b/lib/events/stateevent.h
index 5dadac7f..692f2685 100644
--- a/lib/events/stateevent.h
+++ b/lib/events/stateevent.h
@@ -37,7 +37,12 @@ namespace QMatrixClient {
         public:
             using factory_t = EventFactory<StateEventBase>;
 
-            using RoomEvent::RoomEvent;
+            StateEventBase(Type type, const QJsonObject& json)
+                : RoomEvent(type, json)
+            { }
+            StateEventBase(Type type, event_mtype_t matrixType,
+                           const QString& stateKey = {},
+                           const QJsonObject& contentJson = {});
             ~StateEventBase() override = default;
 
             bool isStateEvent() const override { return true; }
@@ -94,8 +99,9 @@ namespace QMatrixClient {
             }
             template <typename... ContentParamTs>
             explicit StateEvent(Type type, event_mtype_t matrixType,
+                                const QString& stateKey = {},
                                 ContentParamTs&&... contentParams)
-                : StateEventBase(type, matrixType)
+                : StateEventBase(type, matrixType, stateKey)
                 , _content(std::forward<ContentParamTs>(contentParams)...)
             {
                 editJson().insert(ContentKey, _content.toJson());
-- 
cgit v1.2.3