diff --git a/src/Cache.cpp b/src/Cache.cpp
index 5afeab06..553d1e97 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -2885,7 +2885,6 @@ Cache::statusMessage(const std::string &user_id)
void
to_json(json &j, const UserCache &info)
{
- j["user_id"] = info.user_id;
j["is_user_verified"] = info.is_user_verified;
j["cross_verified"] = info.cross_verified;
j["keys"] = info.keys;
@@ -2894,13 +2893,12 @@ to_json(json &j, const UserCache &info)
void
from_json(const json &j, UserCache &info)
{
- info.user_id = j.at("user_id");
info.is_user_verified = j.at("is_user_verified");
info.cross_verified = j.at("cross_verified").get<std::vector<std::string>>();
info.keys = j.at("keys").get<mtx::responses::QueryKeys>();
}
-UserCache
+std::optional<UserCache>
Cache::getUserCache(const std::string &user_id)
{
lmdb::val verifiedVal;
@@ -2909,14 +2907,15 @@ Cache::getUserCache(const std::string &user_id)
auto db = getUserCacheDb(txn);
auto res = lmdb::dbi_get(txn, db, lmdb::val(user_id), verifiedVal);
+ txn.commit();
+
UserCache verified_state;
if (res) {
verified_state = json::parse(std::string(verifiedVal.data(), verifiedVal.size()));
+ return verified_state;
+ } else {
+ return {};
}
-
- txn.commit();
-
- return verified_state;
}
//! be careful when using make sure is_user_verified is not changed
@@ -2948,18 +2947,18 @@ Cache::deleteUserCache(const std::string &user_id)
void
to_json(json &j, const DeviceVerifiedCache &info)
{
- j["user_id"] = info.user_id;
j["device_verified"] = info.device_verified;
+ j["device_blocked"] = info.device_blocked;
}
void
from_json(const json &j, DeviceVerifiedCache &info)
{
- info.user_id = j.at("user_id");
info.device_verified = j.at("device_verified").get<std::vector<std::string>>();
+ info.device_blocked = j.at("device_blocked").get<std::vector<std::string>>();
}
-DeviceVerifiedCache
+std::optional<DeviceVerifiedCache>
Cache::getVerifiedCache(const std::string &user_id)
{
lmdb::val verifiedVal;
@@ -2968,14 +2967,15 @@ Cache::getVerifiedCache(const std::string &user_id)
auto db = getDeviceVerifiedDb(txn);
auto res = lmdb::dbi_get(txn, db, lmdb::val(user_id), verifiedVal);
+ txn.commit();
+
DeviceVerifiedCache verified_state;
if (res) {
verified_state = json::parse(std::string(verifiedVal.data(), verifiedVal.size()));
+ return verified_state;
+ } else {
+ return {};
}
-
- txn.commit();
-
- return verified_state;
}
int
@@ -3172,7 +3172,7 @@ statusMessage(const std::string &user_id)
{
return instance_->statusMessage(user_id);
}
-UserCache
+std::optional<UserCache>
getUserCache(const std::string &user_id)
{
return instance_->getUserCache(user_id);
@@ -3190,7 +3190,7 @@ deleteUserCache(const std::string &user_id)
return instance_->deleteUserCache(user_id);
}
-DeviceVerifiedCache
+std::optional<DeviceVerifiedCache>
getVerifiedCache(const std::string &user_id)
{
return instance_->getVerifiedCache(user_id);
diff --git a/src/Cache.h b/src/Cache.h
index 34e79ab5..0c955c92 100644
--- a/src/Cache.h
+++ b/src/Cache.h
@@ -61,7 +61,7 @@ std::string
statusMessage(const std::string &user_id);
//! user Cache
-UserCache
+std::optional<UserCache>
getUserCache(const std::string &user_id);
int
@@ -71,7 +71,7 @@ int
deleteUserCache(const std::string &user_id);
//! verified Cache
-DeviceVerifiedCache
+std::optional<DeviceVerifiedCache>
getVerifiedCache(const std::string &user_id);
int
diff --git a/src/CacheCryptoStructs.h b/src/CacheCryptoStructs.h
index 7344aef9..241cac76 100644
--- a/src/CacheCryptoStructs.h
+++ b/src/CacheCryptoStructs.h
@@ -68,8 +68,6 @@ struct OlmSessionStorage
struct UserCache
{
- //! user_id of the user
- std::string user_id;
//! this stores if the user is verified (with cross-signing)
bool is_user_verified = false;
//! list of verified device_ids with cross-signing
@@ -85,10 +83,9 @@ from_json(const nlohmann::json &j, UserCache &info);
struct DeviceVerifiedCache
{
- //! user_id of the user
- std::string user_id;
//! list of verified device_ids with device-verification
std::vector<std::string> device_verified;
+ std::vector<std::string> device_blocked;
};
void
diff --git a/src/Cache_p.h b/src/Cache_p.h
index cf4416ce..60fa930f 100644
--- a/src/Cache_p.h
+++ b/src/Cache_p.h
@@ -55,12 +55,12 @@ public:
std::string statusMessage(const std::string &user_id);
// user cache stores user keys
- UserCache getUserCache(const std::string &user_id);
+ std::optional<UserCache> getUserCache(const std::string &user_id);
int setUserCache(const std::string &user_id, const UserCache &body);
int deleteUserCache(const std::string &user_id);
// device verified cache
- DeviceVerifiedCache getVerifiedCache(const std::string &user_id);
+ std::optional<DeviceVerifiedCache> getVerifiedCache(const std::string &user_id);
int setVerifiedCache(const std::string &user_id, const DeviceVerifiedCache &body);
static void removeDisplayName(const QString &room_id, const QString &user_id);
diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp
index c637280b..8c6fb8e4 100644
--- a/src/ui/UserProfile.cpp
+++ b/src/ui/UserProfile.cpp
@@ -7,11 +7,25 @@
#include <iostream> // only for debugging
+Q_DECLARE_METATYPE(UserProfile::Status)
+
UserProfile::UserProfile(QObject *parent)
: QObject(parent)
-{}
+{
+ qRegisterMetaType<UserProfile::Status>();
+ connect(
+ this, &UserProfile::updateDeviceList, this, [this]() { fetchDeviceList(this->userId); });
+ connect(
+ this,
+ &UserProfile::appendDeviceList,
+ this,
+ [this](QString device_id, QString device_name, UserProfile::Status verification_status) {
+ this->deviceList.push_back(
+ DeviceInfo{device_id, device_name, verification_status});
+ });
+}
-QVector<DeviceInfo>
+std::vector<DeviceInfo>
UserProfile::getDeviceList()
{
return this->deviceList;
@@ -37,7 +51,8 @@ UserProfile::setUserId(const QString &user_id)
void
UserProfile::callback_fn(const mtx::responses::QueryKeys &res,
mtx::http::RequestErr err,
- std::string user_id)
+ std::string user_id,
+ std::optional<std::vector<std::string>> cross_verified)
{
if (err) {
nhlog::net()->warn("failed to query device keys: {},{}",
@@ -52,24 +67,40 @@ UserProfile::callback_fn(const mtx::responses::QueryKeys &res,
}
auto devices = res.device_keys.at(user_id);
- QVector<DeviceInfo> deviceInfo;
+ std::vector<DeviceInfo> deviceInfo;
+ auto device_verified = cache::getVerifiedCache(user_id);
for (const auto &d : devices) {
auto device = d.second;
// TODO: Verify signatures and ignore those that don't pass.
- DeviceInfo newdevice(
- QString::fromStdString(d.first),
- QString::fromStdString(device.unsigned_info.device_display_name));
- QString::fromStdString(device.unsigned_info.device_display_name);
+ UserProfile::Status verified = UserProfile::Status::UNVERIFIED;
+ if (cross_verified.has_value()) {
+ if (std::find(cross_verified->begin(), cross_verified->end(), d.first) !=
+ cross_verified->end())
+ verified = UserProfile::Status::VERIFIED;
+ } else if (device_verified.has_value()) {
+ if (std::find(device_verified->device_verified.begin(),
+ device_verified->device_verified.end(),
+ d.first) != device_verified->device_verified.end())
+ verified = UserProfile::Status::VERIFIED;
+ } else if (device_verified.has_value()) {
+ if (std::find(device_verified->device_blocked.begin(),
+ device_verified->device_blocked.end(),
+ d.first) != device_verified->device_blocked.end())
+ verified = UserProfile::Status::BLOCKED;
+ }
- deviceInfo.append(std::move(newdevice));
+ emit UserProfile::appendDeviceList(
+ QString::fromStdString(d.first),
+ QString::fromStdString(device.unsigned_info.device_display_name),
+ verified);
}
- std::sort(
- deviceInfo.begin(), deviceInfo.end(), [](const DeviceInfo &a, const DeviceInfo &b) {
- return a.device_id > b.device_id;
- });
+ // std::sort(
+ // deviceInfo.begin(), deviceInfo.end(), [](const DeviceInfo &a, const DeviceInfo &b) {
+ // return a.device_id > b.device_id;
+ // });
this->deviceList = std::move(deviceInfo);
emit UserProfile::deviceListUpdated();
@@ -81,9 +112,9 @@ UserProfile::fetchDeviceList(const QString &userID)
auto localUser = utils::localUser();
auto user_cache = cache::getUserCache(userID.toStdString());
- if (user_cache.user_id == userID.toStdString()) {
- mtx::http::ClientError error;
- this->callback_fn(user_cache.keys, std::move(error), userID.toStdString());
+ if (user_cache.has_value()) {
+ this->callback_fn(
+ user_cache->keys, {}, userID.toStdString(), user_cache->cross_verified);
} else {
mtx::requests::QueryKeys req;
req.device_keys[userID.toStdString()] = {};
@@ -91,18 +122,12 @@ UserProfile::fetchDeviceList(const QString &userID)
req,
[user_id = userID.toStdString(), this](const mtx::responses::QueryKeys &res,
mtx::http::RequestErr err) {
- this->callback_fn(res, err, user_id);
+ this->callback_fn(res, err, user_id, {});
});
}
}
void
-UserProfile::updateDeviceList()
-{
- fetchDeviceList(this->userId);
-}
-
-void
UserProfile::banUser()
{
ChatPage::instance()->banUser(this->userId, "");
diff --git a/src/ui/UserProfile.h b/src/ui/UserProfile.h
index befd82ec..1725b961 100644
--- a/src/ui/UserProfile.h
+++ b/src/ui/UserProfile.h
@@ -5,36 +5,32 @@
#include <QVector>
#include "MatrixClient.h"
-class DeviceInfo
-{
-public:
- DeviceInfo(const QString deviceID, const QString displayName)
- : device_id(deviceID)
- , display_name(displayName)
- {}
- DeviceInfo() {}
-
- QString device_id;
- QString display_name;
-};
+class DeviceInfo;
class UserProfile : public QObject
{
Q_OBJECT
Q_PROPERTY(QString userId READ getUserId WRITE setUserId NOTIFY userIdChanged)
- Q_PROPERTY(QVector<DeviceInfo> deviceList READ getDeviceList NOTIFY deviceListUpdated)
+ Q_PROPERTY(std::vector<DeviceInfo> deviceList READ getDeviceList NOTIFY deviceListUpdated)
public:
// constructor
explicit UserProfile(QObject *parent = 0);
// getters
- QVector<DeviceInfo> getDeviceList();
+ std::vector<DeviceInfo> getDeviceList();
QString getUserId();
// setters
void setUserId(const QString &userId);
- Q_INVOKABLE void fetchDeviceList(const QString &userID);
- Q_INVOKABLE void updateDeviceList();
+ enum Status
+ {
+ VERIFIED,
+ UNVERIFIED,
+ BLOCKED
+ };
+ Q_ENUM(Status)
+
+ void fetchDeviceList(const QString &userID);
Q_INVOKABLE void banUser();
// Q_INVOKABLE void ignoreUser();
Q_INVOKABLE void kickUser();
@@ -43,12 +39,34 @@ public:
signals:
void userIdChanged();
void deviceListUpdated();
+ void updateDeviceList();
+ void appendDeviceList(const QString device_id,
+ const QString device_naem,
+ const UserProfile::Status verification_status);
private:
- QVector<DeviceInfo> deviceList;
+ std::vector<DeviceInfo> deviceList;
QString userId;
+ std::optional<std::string> cross_verified;
void callback_fn(const mtx::responses::QueryKeys &res,
mtx::http::RequestErr err,
- std::string user_id);
+ std::string user_id,
+ std::optional<std::vector<std::string>> cross_verified);
+};
+
+class DeviceInfo
+{
+public:
+ DeviceInfo(const QString deviceID,
+ const QString displayName,
+ UserProfile::Status verification_status_)
+ : device_id(deviceID)
+ , display_name(displayName)
+ , verification_status(verification_status_)
+ {}
+
+ QString device_id;
+ QString display_name;
+ UserProfile::Status verification_status;
};
\ No newline at end of file
diff --git a/src/ui/UserProfileModel.cpp b/src/ui/UserProfileModel.cpp
index ec0456cd..3fa8fe2d 100644
--- a/src/ui/UserProfileModel.cpp
+++ b/src/ui/UserProfileModel.cpp
@@ -1,11 +1,23 @@
#include "UserProfileModel.h"
-#include "UserProfile.h"
#include <QModelIndex>
UserProfileModel::UserProfileModel(QObject *parent)
: QAbstractListModel(parent)
, deviceList(nullptr)
-{}
+{
+ this->deviceList = new UserProfile(this);
+
+ connect(this->deviceList, &UserProfile::userIdChanged, this, [this]() {
+ emit this->deviceList->updateDeviceList();
+ });
+ connect(this->deviceList, &UserProfile::deviceListUpdated, this, [this]() {
+ beginResetModel();
+ this->beginInsertRows(
+ QModelIndex(), 0, this->deviceList->getDeviceList().size() - 1);
+ this->endInsertRows();
+ endResetModel();
+ });
+}
int
UserProfileModel::rowCount(const QModelIndex &parent) const
@@ -18,7 +30,8 @@ UserProfileModel::rowCount(const QModelIndex &parent) const
QVariant
UserProfileModel::data(const QModelIndex &index, int role) const
{
- if (!index.isValid() || !this->deviceList)
+ if (!index.isValid() &&
+ static_cast<int>(this->deviceList->getDeviceList().size()) <= index.row())
return QVariant();
const DeviceInfo device = this->deviceList->getDeviceList().at(index.row());
@@ -27,6 +40,8 @@ UserProfileModel::data(const QModelIndex &index, int role) const
return QVariant(device.device_id);
case DISPLAYNAME:
return QVariant(device.display_name);
+ case VERIFIED_STATUS:
+ return device.verification_status;
}
return QVariant();
}
@@ -35,8 +50,9 @@ QHash<int, QByteArray>
UserProfileModel::roleNames() const
{
QHash<int, QByteArray> names;
- names[DEVICEID] = "deviceID";
- names[DISPLAYNAME] = "displayName";
+ names[DEVICEID] = "deviceID";
+ names[DISPLAYNAME] = "displayName";
+ names[VERIFIED_STATUS] = "verified_status";
return names;
}
@@ -45,22 +61,3 @@ UserProfileModel::getList() const
{
return (this->deviceList);
}
-
-void
-UserProfileModel::setList(UserProfile *devices)
-{
- beginResetModel();
-
- if (devices)
- devices->disconnect(this);
-
- if (this->deviceList) {
- const int index = this->deviceList->getDeviceList().size();
- beginInsertRows(QModelIndex(), index, index);
- endInsertRows();
- }
-
- this->deviceList = devices;
-
- endResetModel();
-}
\ No newline at end of file
diff --git a/src/ui/UserProfileModel.h b/src/ui/UserProfileModel.h
index c21a806d..ba7a2525 100644
--- a/src/ui/UserProfileModel.h
+++ b/src/ui/UserProfileModel.h
@@ -1,5 +1,6 @@
#pragma once
+#include "UserProfile.h"
#include <QAbstractListModel>
class UserProfile; // forward declaration of the class UserProfile
@@ -7,7 +8,7 @@ class UserProfile; // forward declaration of the class UserProfile
class UserProfileModel : public QAbstractListModel
{
Q_OBJECT
- Q_PROPERTY(UserProfile *deviceList READ getList WRITE setList)
+ Q_PROPERTY(UserProfile *deviceList READ getList)
public:
explicit UserProfileModel(QObject *parent = nullptr);
@@ -15,10 +16,10 @@ public:
enum
{
DEVICEID,
- DISPLAYNAME
+ DISPLAYNAME,
+ VERIFIED_STATUS
};
UserProfile *getList() const;
- void setList(UserProfile *devices);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role) const override;
|