summary refs log tree commit diff
path: root/src/ui/UserProfile.cpp
diff options
context:
space:
mode:
authorDeepBlueV7.X <nicolas.werner@hotmail.de>2020-10-08 20:08:38 +0200
committerGitHub <noreply@github.com>2020-10-08 20:08:38 +0200
commit517a126a4427972668a97b21fc8684f7160976b9 (patch)
tree27142d719f848abe685897cd367e8d69a9bed719 /src/ui/UserProfile.cpp
parentMerge pull request #294 from trilene/master (diff)
parentTry to fix windows build (diff)
downloadnheko-517a126a4427972668a97b21fc8684f7160976b9.tar.xz
Merge pull request #270 from Chethan2k1/device-verification
Device verification and Cross-Signing
Diffstat (limited to 'src/ui/UserProfile.cpp')
-rw-r--r--src/ui/UserProfile.cpp227
1 files changed, 227 insertions, 0 deletions
diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp
new file mode 100644

index 00000000..2bb0370f --- /dev/null +++ b/src/ui/UserProfile.cpp
@@ -0,0 +1,227 @@ +#include "UserProfile.h" +#include "Cache_p.h" +#include "ChatPage.h" +#include "DeviceVerificationFlow.h" +#include "Logging.h" +#include "Utils.h" +#include "mtx/responses/crypto.hpp" +#include "timeline/TimelineModel.h" +#include "timeline/TimelineViewManager.h" + +UserProfile::UserProfile(QString roomid, + QString userid, + TimelineViewManager *manager_, + TimelineModel *parent) + : QObject(parent) + , roomid_(roomid) + , userid_(userid) + , manager(manager_) + , model(parent) +{ + fetchDeviceList(this->userid_); + + connect(cache::client(), + &Cache::verificationStatusChanged, + this, + [this](const std::string &user_id) { + if (user_id != this->userid_.toStdString()) + return; + + auto status = cache::verificationStatus(user_id); + if (!status) + return; + this->isUserVerified = status->user_verified; + emit userStatusChanged(); + + for (auto &deviceInfo : deviceList_.deviceList_) { + deviceInfo.verification_status = + std::find(status->verified_devices.begin(), + status->verified_devices.end(), + deviceInfo.device_id.toStdString()) == + status->verified_devices.end() + ? verification::UNVERIFIED + : verification::VERIFIED; + } + deviceList_.reset(deviceList_.deviceList_); + }); +} + +QHash<int, QByteArray> +DeviceInfoModel::roleNames() const +{ + return { + {DeviceId, "deviceId"}, + {DeviceName, "deviceName"}, + {VerificationStatus, "verificationStatus"}, + }; +} + +QVariant +DeviceInfoModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= (int)deviceList_.size() || index.row() < 0) + return {}; + + switch (role) { + case DeviceId: + return deviceList_[index.row()].device_id; + case DeviceName: + return deviceList_[index.row()].display_name; + case VerificationStatus: + return QVariant::fromValue(deviceList_[index.row()].verification_status); + default: + return {}; + } +} + +void +DeviceInfoModel::reset(const std::vector<DeviceInfo> &deviceList) +{ + beginResetModel(); + this->deviceList_ = std::move(deviceList); + endResetModel(); +} + +DeviceInfoModel * +UserProfile::deviceList() +{ + return &this->deviceList_; +} + +QString +UserProfile::userid() +{ + return this->userid_; +} + +QString +UserProfile::displayName() +{ + return cache::displayName(roomid_, userid_); +} + +QString +UserProfile::avatarUrl() +{ + return cache::avatarUrl(roomid_, userid_); +} + +bool +UserProfile::getUserStatus() +{ + return isUserVerified; +} + +void +UserProfile::fetchDeviceList(const QString &userID) +{ + auto localUser = utils::localUser(); + + ChatPage::instance()->query_keys( + userID.toStdString(), + [other_user_id = userID.toStdString(), this](const UserKeyCache &other_user_keys, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn("failed to query device keys: {},{}", + err->matrix_error.errcode, + static_cast<int>(err->status_code)); + return; + } + + // Finding if the User is Verified or not based on the Signatures + ChatPage::instance()->query_keys( + utils::localUser().toStdString(), + [other_user_id, other_user_keys, this](const UserKeyCache &res, + mtx::http::RequestErr err) { + using namespace mtx; + std::string local_user_id = utils::localUser().toStdString(); + + if (err) { + nhlog::net()->warn("failed to query device keys: {},{}", + err->matrix_error.errcode, + static_cast<int>(err->status_code)); + return; + } + + if (res.device_keys.empty()) { + nhlog::net()->warn("no devices retrieved {}", local_user_id); + return; + } + + std::vector<DeviceInfo> deviceInfo; + auto devices = other_user_keys.device_keys; + auto verificationStatus = + cache::client()->verificationStatus(other_user_id); + + isUserVerified = verificationStatus.user_verified; + emit userStatusChanged(); + + for (const auto &d : devices) { + auto device = d.second; + verification::Status verified = + verification::Status::UNVERIFIED; + + if (std::find(verificationStatus.verified_devices.begin(), + verificationStatus.verified_devices.end(), + device.device_id) != + verificationStatus.verified_devices.end() && + mtx::crypto::verify_identity_signature( + device, + DeviceId(device.device_id), + UserId(other_user_id))) + verified = verification::Status::VERIFIED; + + deviceInfo.push_back( + {QString::fromStdString(d.first), + QString::fromStdString( + device.unsigned_info.device_display_name), + verified}); + } + + this->deviceList_.queueReset(std::move(deviceInfo)); + }); + }); +} + +void +UserProfile::banUser() +{ + ChatPage::instance()->banUser(this->userid_, ""); +} + +// void ignoreUser(){ + +// } + +void +UserProfile::kickUser() +{ + ChatPage::instance()->kickUser(this->userid_, ""); +} + +void +UserProfile::startChat() +{ + mtx::requests::CreateRoom req; + req.preset = mtx::requests::Preset::PrivateChat; + req.visibility = mtx::requests::Visibility::Private; + if (utils::localUser() != this->userid_) + req.invite = {this->userid_.toStdString()}; + emit ChatPage::instance()->createRoom(req); +} + +void +UserProfile::verify(QString device) +{ + if (!device.isEmpty()) + manager->verifyDevice(userid_, device); + else { + manager->verifyUser(userid_); + } +} + +void +UserProfile::unverify(QString device) +{ + cache::markDeviceUnverified(userid_.toStdString(), device.toStdString()); +}