summary refs log tree commit diff
path: root/src/encryption/VerificationManager.cpp
blob: b9b51d35659788264a7a727afd90070794254ff8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// SPDX-FileCopyrightText: 2021 Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "VerificationManager.h"
#include "Cache.h"
#include "ChatPage.h"
#include "DeviceVerificationFlow.h"
#include "timeline/TimelineViewManager.h"

VerificationManager::VerificationManager(TimelineViewManager *o)
  : QObject(o)
  , rooms_(o->rooms())
{}

void
VerificationManager::receivedRoomDeviceVerificationRequest(
  const mtx::events::RoomEvent<mtx::events::msg::KeyVerificationRequest> &message,
  TimelineModel *model)
{
    if (this->isInitialSync_)
        return;

    auto event_id = QString::fromStdString(message.event_id);
    if (!this->dvList.contains(event_id)) {
        if (auto flow = DeviceVerificationFlow::NewInRoomVerification(
              this, model, message.content, QString::fromStdString(message.sender), event_id)) {
            dvList[event_id] = flow;
            emit newDeviceVerificationRequest(flow.data());
        }
    }
}

void
VerificationManager::receivedDeviceVerificationRequest(
  const mtx::events::msg::KeyVerificationRequest &msg,
  std::string sender)
{
    if (this->isInitialSync_)
        return;

    if (!msg.transaction_id)
        return;

    auto txnid = QString::fromStdString(msg.transaction_id.value());
    if (!this->dvList.contains(txnid)) {
        if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
              this, msg, QString::fromStdString(sender), txnid)) {
            dvList[txnid] = flow;
            emit newDeviceVerificationRequest(flow.data());
        }
    }
}

void
VerificationManager::receivedDeviceVerificationStart(
  const mtx::events::msg::KeyVerificationStart &msg,
  std::string sender)
{
    if (this->isInitialSync_)
        return;

    if (!msg.transaction_id)
        return;

    auto txnid = QString::fromStdString(msg.transaction_id.value());
    if (!this->dvList.contains(txnid)) {
        if (auto flow = DeviceVerificationFlow::NewToDeviceVerification(
              this, msg, QString::fromStdString(sender), txnid)) {
            dvList[txnid] = flow;
            emit newDeviceVerificationRequest(flow.data());
        }
    }
}

void
VerificationManager::verifyUser(QString userid)
{
    auto joined_rooms = cache::joinedRooms();
    auto room_infos   = cache::getRoomInfo(joined_rooms);

    for (std::string room_id : joined_rooms) {
        if ((room_infos[QString::fromStdString(room_id)].member_count == 2) &&
            cache::isRoomEncrypted(room_id)) {
            auto room_members = cache::roomMembers(room_id);
            if (std::find(room_members.begin(), room_members.end(), (userid).toStdString()) !=
                room_members.end()) {
                if (auto model = rooms_->getRoomById(QString::fromStdString(room_id))) {
                    auto flow =
                      DeviceVerificationFlow::InitiateUserVerification(this, model.data(), userid);
                    connect(model.data(),
                            &TimelineModel::updateFlowEventId,
                            this,
                            [this, flow](std::string eventId) {
                                dvList[QString::fromStdString(eventId)] = flow;
                            });
                    emit newDeviceVerificationRequest(flow.data());
                    return;
                }
            }
        }
    }

    emit ChatPage::instance()->showNotification(
      tr("No encrypted private chat found with this user. Create an "
         "encrypted private chat with this user and try again."));
}

void
VerificationManager::removeVerificationFlow(DeviceVerificationFlow *flow)
{
    for (auto it = dvList.keyValueBegin(); it != dvList.keyValueEnd(); ++it) {
        if ((*it).second == flow) {
            dvList.remove((*it).first);
            return;
        }
    }
}

void
VerificationManager::verifyDevice(QString userid, QString deviceid)
{
    auto flow = DeviceVerificationFlow::InitiateDeviceVerification(this, userid, deviceid);
    this->dvList[flow->transactionId()] = flow;
    emit newDeviceVerificationRequest(flow.data());
}