summary refs log tree commit diff
path: root/src/timeline
diff options
context:
space:
mode:
authorCH Chethan Reddy <40890937+Chethan2k1@users.noreply.github.com>2020-07-18 01:46:30 +0530
committerCH Chethan Reddy <40890937+Chethan2k1@users.noreply.github.com>2020-07-30 22:10:27 +0530
commit1fcd768f88f7e84978d19283c9fa6205624f2544 (patch)
tree97afdac31c014c4eedb5d0da45362835d7c04d22 /src/timeline
parentUpdating keys of outdated encrypted users (diff)
downloadnheko-1fcd768f88f7e84978d19283c9fa6205624f2544.tar.xz
Adding Room Key Verification Stuff
Diffstat (limited to 'src/timeline')
-rw-r--r--src/timeline/TimelineModel.cpp187
-rw-r--r--src/timeline/TimelineModel.h8
-rw-r--r--src/timeline/TimelineViewManager.cpp76
-rw-r--r--src/timeline/TimelineViewManager.h9
4 files changed, 241 insertions, 39 deletions
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 773a5a23..71cc53c5 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -22,6 +22,8 @@
 #include "Utils.h"
 #include "dialogs/RawMessage.h"
 
+#include <iostream>
+
 Q_DECLARE_METATYPE(QModelIndex)
 
 namespace std {
@@ -116,7 +118,41 @@ struct RoomEventType
         {
                 return qml_mtx_events::EventType::VideoMessage;
         }
-
+        qml_mtx_events::EventType operator()(
+          const mtx::events::Event<mtx::events::msg::KeyVerificationRequest> &)
+        {
+                return qml_mtx_events::EventType::KeyVerificationRequest;
+        }
+        qml_mtx_events::EventType operator()(
+          const mtx::events::Event<mtx::events::msg::KeyVerificationStart> &)
+        {
+                return qml_mtx_events::EventType::KeyVerificationStart;
+        }
+        qml_mtx_events::EventType operator()(
+          const mtx::events::Event<mtx::events::msg::KeyVerificationMac> &)
+        {
+                return qml_mtx_events::EventType::KeyVerificationMac;
+        }
+        qml_mtx_events::EventType operator()(
+          const mtx::events::Event<mtx::events::msg::KeyVerificationAccept> &)
+        {
+                return qml_mtx_events::EventType::KeyVerificationAccept;
+        }
+        qml_mtx_events::EventType operator()(
+          const mtx::events::Event<mtx::events::msg::KeyVerificationCancel> &)
+        {
+                return qml_mtx_events::EventType::KeyVerificationCancel;
+        }
+        qml_mtx_events::EventType operator()(
+          const mtx::events::Event<mtx::events::msg::KeyVerificationKey> &)
+        {
+                return qml_mtx_events::EventType::KeyVerificationKey;
+        }
+        qml_mtx_events::EventType operator()(
+          const mtx::events::Event<mtx::events::msg::KeyVerificationDone> &)
+        {
+                return qml_mtx_events::EventType::KeyVerificationDone;
+        }
         qml_mtx_events::EventType operator()(const mtx::events::Event<mtx::events::msg::Redacted> &)
         {
                 return qml_mtx_events::EventType::Redacted;
@@ -572,6 +608,155 @@ TimelineModel::updateLastMessage()
         }
 }
 
+std::vector<QString>
+TimelineModel::internalAddEvents(
+  const std::vector<mtx::events::collections::TimelineEvents> &timeline)
+{
+        std::vector<QString> ids;
+        for (auto e : timeline) {
+                QString id = QString::fromStdString(mtx::accessors::event_id(e));
+
+                if (this->events.contains(id)) {
+                        this->events.insert(id, e);
+                        int idx = idToIndex(id);
+                        emit dataChanged(index(idx, 0), index(idx, 0));
+                        continue;
+                }
+
+                QString txid = QString::fromStdString(mtx::accessors::transaction_id(e));
+                if (this->pending.removeOne(txid)) {
+                        this->events.insert(id, e);
+                        this->events.remove(txid);
+                        int idx = idToIndex(txid);
+                        if (idx < 0) {
+                                nhlog::ui()->warn("Received index out of range");
+                                continue;
+                        }
+                        eventOrder[idx] = id;
+                        emit dataChanged(index(idx, 0), index(idx, 0));
+                        continue;
+                }
+
+                if (std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest>>(
+                      &e)) {
+                        std::cout << "got a request" << std::endl;
+                }
+
+                if (auto cancelVerification =
+                      std::get_if<mtx::events::RoomEvent<mtx::events::msg::KeyVerificationCancel>>(
+                        &e)) {
+                        std::cout<<"it is happening"<<std::endl;
+                        if (cancelVerification->content.relates_to.has_value()) {
+                                QString event_id = QString::fromStdString(
+                                  cancelVerification->content.relates_to.value()
+                                    .in_reply_to.event_id);
+                                auto request =
+                                  std::find(eventOrder.begin(), eventOrder.end(), event_id);
+                                if (request != eventOrder.end()) {
+                                        auto event = events.value(event_id);
+                                        auto e     = std::get_if<mtx::events::RoomEvent<
+                                          mtx::events::msg::KeyVerificationRequest>>(&event);
+                                        std::cout<<json(*e)<<std::endl;
+                                }
+                        }
+                }
+
+                if (auto redaction =
+                      std::get_if<mtx::events::RedactionEvent<mtx::events::msg::Redaction>>(&e)) {
+                        QString redacts = QString::fromStdString(redaction->redacts);
+                        auto redacted   = std::find(eventOrder.begin(), eventOrder.end(), redacts);
+
+                        auto event = events.value(redacts);
+                        if (auto reaction =
+                              std::get_if<mtx::events::RoomEvent<mtx::events::msg::Reaction>>(
+                                &event)) {
+                                QString reactedTo =
+                                  QString::fromStdString(reaction->content.relates_to.event_id);
+                                reactions[reactedTo].removeReaction(*reaction);
+                                int idx = idToIndex(reactedTo);
+                                if (idx >= 0)
+                                        emit dataChanged(index(idx, 0), index(idx, 0));
+                        }
+
+                        if (redacted != eventOrder.end()) {
+                                auto redactedEvent = std::visit(
+                                  [](const auto &ev)
+                                    -> mtx::events::RoomEvent<mtx::events::msg::Redacted> {
+                                          mtx::events::RoomEvent<mtx::events::msg::Redacted>
+                                            replacement                = {};
+                                          replacement.event_id         = ev.event_id;
+                                          replacement.room_id          = ev.room_id;
+                                          replacement.sender           = ev.sender;
+                                          replacement.origin_server_ts = ev.origin_server_ts;
+                                          replacement.type             = ev.type;
+                                          return replacement;
+                                  },
+                                  e);
+                                events.insert(redacts, redactedEvent);
+
+                                int row = (int)std::distance(eventOrder.begin(), redacted);
+                                emit dataChanged(index(row, 0), index(row, 0));
+                        }
+
+                        continue; // don't insert redaction into timeline
+                }
+
+                if (auto reaction =
+                      std::get_if<mtx::events::RoomEvent<mtx::events::msg::Reaction>>(&e)) {
+                        QString reactedTo =
+                          QString::fromStdString(reaction->content.relates_to.event_id);
+                        events.insert(id, e);
+
+                        // remove local echo
+                        if (!txid.isEmpty()) {
+                                auto rCopy     = *reaction;
+                                rCopy.event_id = txid.toStdString();
+                                reactions[reactedTo].removeReaction(rCopy);
+                        }
+
+                        reactions[reactedTo].addReaction(room_id_.toStdString(), *reaction);
+                        int idx = idToIndex(reactedTo);
+                        if (idx >= 0)
+                                emit dataChanged(index(idx, 0), index(idx, 0));
+                        continue; // don't insert reaction into timeline
+                }
+
+                if (auto event =
+                      std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(&e)) {
+                        auto e_      = decryptEvent(*event).event;
+                        auto encInfo = mtx::accessors::file(e_);
+
+                        if (encInfo)
+                                emit newEncryptedImage(encInfo.value());
+                }
+
+                this->events.insert(id, e);
+                ids.push_back(id);
+
+                auto replyTo  = mtx::accessors::in_reply_to_event(e);
+                auto qReplyTo = QString::fromStdString(replyTo);
+                if (!replyTo.empty() && !events.contains(qReplyTo)) {
+                        http::client()->get_event(
+                          this->room_id_.toStdString(),
+                          replyTo,
+                          [this, id, replyTo](
+                            const mtx::events::collections::TimelineEvents &timeline,
+                            mtx::http::RequestErr err) {
+                                  if (err) {
+                                          nhlog::net()->error(
+                                            "Failed to retrieve event with id {}, which was "
+                                            "requested to show the replyTo for event {}",
+                                            replyTo,
+                                            id.toStdString());
+                                          return;
+                                  }
+                                  emit eventFetched(id, timeline);
+                          });
+                }
+        }
+        return ids;
+}
+
 void
 TimelineModel::setCurrentIndex(int index)
 {
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index 104a475c..708ed38e 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -84,6 +84,14 @@ enum EventType
         VideoMessage,
         Redacted,
         UnknownMessage,
+        KeyVerificationRequest,
+        KeyVerificationStart,
+        KeyVerificationMac,
+        KeyVerificationAccept,
+        KeyVerificationCancel,
+        KeyVerificationKey,
+        KeyVerificationDone,
+        KeyVerificationReady
 };
 Q_ENUM_NS(EventType)
 
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 81c8d6d3..02b74d20 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -101,7 +101,15 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
   , blurhashProvider(new BlurhashProvider())
   , settings(userSettings)
 {
-        qRegisterMetaType<mtx::events::collections::DeviceEvents>();
+        qRegisterMetaType<mtx::events::msg::KeyVerificationAccept>();
+        qRegisterMetaType<mtx::events::msg::KeyVerificationCancel>();
+        qRegisterMetaType<mtx::events::msg::KeyVerificationDone>();
+        qRegisterMetaType<mtx::events::msg::KeyVerificationKey>();
+        qRegisterMetaType<mtx::events::msg::KeyVerificationMac>();
+        qRegisterMetaType<mtx::events::msg::KeyVerificationReady>();
+        qRegisterMetaType<mtx::events::msg::KeyVerificationRequest>();
+        qRegisterMetaType<mtx::events::msg::KeyVerificationStart>();
+
         qmlRegisterUncreatableMetaObject(qml_mtx_events::staticMetaObject,
                                          "im.nheko",
                                          1,
@@ -181,21 +189,19 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
           dynamic_cast<ChatPage *>(parent),
           &ChatPage::recievedDeviceVerificationRequest,
           this,
-          [this](const mtx::events::collections::DeviceEvents &message) {
-                  auto msg =
-                    std::get<mtx::events::DeviceEvent<msgs::KeyVerificationRequest>>(message);
+          [this](const mtx::events::msg::KeyVerificationRequest &msg, std::string sender) {
                   auto flow = new DeviceVerificationFlow(this);
-                  if (!(this->dvList->exist(QString::fromStdString(msg.content.transaction_id)))) {
-                          if (std::find(msg.content.methods.begin(),
-                                        msg.content.methods.end(),
+                  if (!(this->dvList->exist(QString::fromStdString(msg.transaction_id.value())))) {
+                          if (std::find(msg.methods.begin(),
+                                        msg.methods.end(),
                                         mtx::events::msg::VerificationMethods::SASv1) !=
-                              msg.content.methods.end()) {
+                              msg.methods.end()) {
                                   //   flow->sendVerificationReady();
                                   emit newDeviceVerificationRequest(
                                     std::move(flow),
-                                    QString::fromStdString(msg.content.transaction_id),
-                                    QString::fromStdString(msg.sender),
-                                    QString::fromStdString(msg.content.from_device));
+                                    QString::fromStdString(msg.transaction_id.value()),
+                                    QString::fromStdString(sender),
+                                    QString::fromStdString(msg.from_device));
                           } else {
                                   flow->cancelVerification(
                                     DeviceVerificationFlow::Error::UnknownMethod);
@@ -206,33 +212,29 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
           dynamic_cast<ChatPage *>(parent),
           &ChatPage::recievedDeviceVerificationStart,
           this,
-          [this](const mtx::events::collections::DeviceEvents &message) {
-                  auto msg =
-                    std::get<mtx::events::DeviceEvent<msgs::KeyVerificationStart>>(message);
+          [this](const mtx::events::msg::KeyVerificationStart &msg, std::string sender) {
                   auto flow            = new DeviceVerificationFlow(this);
-                  flow->canonical_json = nlohmann::json(msg.content);
-                  if (!(this->dvList->exist(QString::fromStdString(msg.content.transaction_id)))) {
-                          if ((std::find(msg.content.key_agreement_protocols.begin(),
-                                         msg.content.key_agreement_protocols.end(),
+                  flow->canonical_json = nlohmann::json(msg);
+                  if (!(this->dvList->exist(QString::fromStdString(msg.transaction_id.value())))) {
+                          if ((std::find(msg.key_agreement_protocols.begin(),
+                                         msg.key_agreement_protocols.end(),
                                          "curve25519-hkdf-sha256") !=
-                               msg.content.key_agreement_protocols.end()) &&
-                              (std::find(msg.content.hashes.begin(),
-                                         msg.content.hashes.end(),
-                                         "sha256") != msg.content.hashes.end()) &&
-                              (std::find(msg.content.message_authentication_codes.begin(),
-                                         msg.content.message_authentication_codes.end(),
+                               msg.key_agreement_protocols.end()) &&
+                              (std::find(msg.hashes.begin(), msg.hashes.end(), "sha256") !=
+                               msg.hashes.end()) &&
+                              (std::find(msg.message_authentication_codes.begin(),
+                                         msg.message_authentication_codes.end(),
                                          "hmac-sha256") !=
-                               msg.content.message_authentication_codes.end())) {
-                                  if (std::find(msg.content.short_authentication_string.begin(),
-                                                msg.content.short_authentication_string.end(),
+                               msg.message_authentication_codes.end())) {
+                                  if (std::find(msg.short_authentication_string.begin(),
+                                                msg.short_authentication_string.end(),
                                                 mtx::events::msg::SASMethods::Emoji) !=
-                                      msg.content.short_authentication_string.end()) {
+                                      msg.short_authentication_string.end()) {
                                           flow->setMethod(DeviceVerificationFlow::Method::Emoji);
-                                  } else if (std::find(
-                                               msg.content.short_authentication_string.begin(),
-                                               msg.content.short_authentication_string.end(),
-                                               mtx::events::msg::SASMethods::Decimal) !=
-                                             msg.content.short_authentication_string.end()) {
+                                  } else if (std::find(msg.short_authentication_string.begin(),
+                                                       msg.short_authentication_string.end(),
+                                                       mtx::events::msg::SASMethods::Decimal) !=
+                                             msg.short_authentication_string.end()) {
                                           flow->setMethod(DeviceVerificationFlow::Method::Decimal);
                                   } else {
                                           flow->cancelVerification(
@@ -241,10 +243,10 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<UserSettings> userSettin
                                   }
                                   emit newDeviceVerificationRequest(
                                     std::move(flow),
-                                    QString::fromStdString(msg.content.transaction_id),
-                                    QString::fromStdString(msg.sender),
-                                    QString::fromStdString(msg.content.from_device));
-                                  flow->canonical_json = nlohmann::json(msg.content);
+                                    QString::fromStdString(msg.transaction_id.value()),
+                                    QString::fromStdString(sender),
+                                    QString::fromStdString(msg.from_device));
+                                  flow->canonical_json = nlohmann::json(msg);
                           } else {
                                   flow->cancelVerification(
                                     DeviceVerificationFlow::Error::UnknownMethod);
diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index a438ef5e..71aee5ef 100644
--- a/src/timeline/TimelineViewManager.h
+++ b/src/timeline/TimelineViewManager.h
@@ -133,4 +133,11 @@ private:
 
         DeviceVerificationList *dvList;
 };
-Q_DECLARE_METATYPE(mtx::events::collections::DeviceEvents)
+Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationAccept)
+Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationCancel)
+Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationDone)
+Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationKey)
+Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationMac)
+Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationReady)
+Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationRequest)
+Q_DECLARE_METATYPE(mtx::events::msg::KeyVerificationStart)