DONT TAKE, BROKEN! first application of delay manager in code, reception of bundles

This commit is contained in:
Blue 2023-03-10 21:43:31 +03:00
parent 5ba97ecc25
commit 927bdf0dab
Signed by: blue
GPG Key ID: 9B203B252A63EE38
16 changed files with 261 additions and 139 deletions

View File

@ -55,6 +55,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
reconnectScheduled(false), reconnectScheduled(false),
reconnectTimer(new QTimer), reconnectTimer(new QTimer),
network(p_net), network(p_net),
delay(nullptr),
passwordType(Shared::AccountPassword::plain), passwordType(Shared::AccountPassword::plain),
lastError(Error::none), lastError(Error::none),
pepSupport(Shared::Support::unknown), pepSupport(Shared::Support::unknown),
@ -67,6 +68,12 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
config.setPassword(p_password); config.setPassword(p_password);
config.setAutoAcceptSubscriptions(true); config.setAutoAcceptSubscriptions(true);
//config.setAutoReconnectionEnabled(false); //config.setAutoReconnectionEnabled(false);
delay = new DelayManager::Manager(getBareJid());
QObject::connect(delay, &DelayManager::Manager::gotInfo, this, &Account::infoReady);
QObject::connect(delay, &DelayManager::Manager::gotOwnInfo, this, &Account::infoReady);
QObject::connect(delay, &DelayManager::Manager::requestOwnVCard, vm, &QXmppVCardManager::requestClientVCard);
QObject::connect(delay, &DelayManager::Manager::requestVCard, vm, &QXmppVCardManager::requestVCard);
rh->initialize(); rh->initialize();
vh->initialize(); vh->initialize();
@ -104,6 +111,9 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
client.addExtension(psm); client.addExtension(psm);
#ifdef WITH_OMEMO #ifdef WITH_OMEMO
QObject::connect(delay, &DelayManager::Manager::requestBundles, oh, &OmemoHandler::requestBundles);
QObject::connect(delay, &DelayManager::Manager::requestOwnBundles, oh, &OmemoHandler::requestOwnBundles);
client.addExtension(tm); client.addExtension(tm);
client.addExtension(om); client.addExtension(om);
om->setSecurityPolicy(QXmpp::Toakafa); om->setSecurityPolicy(QXmpp::Toakafa);
@ -164,6 +174,7 @@ Account::~Account() {
delete mm; delete mm;
delete am; delete am;
delete cm; delete cm;
delete delay;
} }
Shared::ConnectionState Core::Account::getState() const { Shared::ConnectionState Core::Account::getState() const {
@ -313,7 +324,6 @@ void Core::Account::runDiscoveryService() {
dm->requestInfo(getServer()); dm->requestInfo(getServer());
} }
void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) { void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) {
QString id = p_presence.from(); QString id = p_presence.from();
QStringList comps = id.split("/"); QStringList comps = id.split("/");
@ -642,9 +652,9 @@ void Core::Account::setPepSupport(Shared::Support support) {
void Core::Account::handleDisconnection() { void Core::Account::handleDisconnection() {
setPepSupport(Shared::Support::unknown); setPepSupport(Shared::Support::unknown);
delay->disconnected();
cm->setCarbonsEnabled(false); cm->setCarbonsEnabled(false);
rh->handleOffline(); rh->handleOffline();
vh->handleOffline();
archiveQueries.clear(); archiveQueries.clear();
} }
@ -702,7 +712,9 @@ void Core::Account::setPasswordType(Shared::AccountPassword pt) {
passwordType = pt; } passwordType = pt; }
void Core::Account::setLogin(const QString& p_login) { void Core::Account::setLogin(const QString& p_login) {
config.setUser(p_login);} config.setUser(p_login);
delay->setOwnJid(getBareJid());
}
void Core::Account::setName(const QString& p_name) { void Core::Account::setName(const QString& p_name) {
name = p_name;} name = p_name;}
@ -713,7 +725,9 @@ void Core::Account::setPassword(const QString& p_password) {
} }
void Core::Account::setServer(const QString& p_server) { void Core::Account::setServer(const QString& p_server) {
config.setDomain(p_server);} config.setDomain(p_server);
delay->setOwnJid(getBareJid());
}
void Core::Account::sendMessage(const Shared::Message& data) { void Core::Account::sendMessage(const Shared::Message& data) {
mh->sendMessage(data);} mh->sendMessage(data);}
@ -730,7 +744,8 @@ void Core::Account::replaceMessage(const QString& originalId, const Shared::Mess
void Core::Account::requestInfo(const QString& jid) { void Core::Account::requestInfo(const QString& jid) {
//TODO switch case of what kind of entity this info request is about //TODO switch case of what kind of entity this info request is about
//right now it could be only about myself or some contact //right now it could be only about myself or some contact
vh->requestVCard(jid); delay->getInfo(jid);
//vh->requestVCard(jid);
} }
void Core::Account::updateInfo(const Shared::Info& info) { void Core::Account::updateInfo(const Shared::Info& info) {

View File

@ -50,6 +50,7 @@
#include "contact.h" #include "contact.h"
#include "conference.h" #include "conference.h"
#include <core/components/networkaccess.h> #include <core/components/networkaccess.h>
#include <core/delayManager/manager.h>
#include "handlers/messagehandler.h" #include "handlers/messagehandler.h"
#include "handlers/rosterhandler.h" #include "handlers/rosterhandler.h"
@ -73,6 +74,10 @@ class Account : public QObject
friend class RosterHandler; friend class RosterHandler;
friend class VCardHandler; friend class VCardHandler;
friend class DiscoveryHandler; friend class DiscoveryHandler;
#ifdef WITH_OMEMO
friend class OmemoHandler;
friend class TrustHandler;
#endif
public: public:
enum class Error { enum class Error {
authentication, authentication,
@ -202,6 +207,7 @@ private:
QTimer* reconnectTimer; QTimer* reconnectTimer;
NetworkAccess* network; NetworkAccess* network;
DelayManager::Manager* delay;
Shared::AccountPassword passwordType; Shared::AccountPassword passwordType;
Error lastError; Error lastError;
Shared::Support pepSupport; Shared::Support pepSupport;

View File

@ -1,5 +1,5 @@
set(SOURCE_FILES set(SOURCE_FILES
delaymanager.cpp manager.cpp
job.cpp job.cpp
cardinternal.cpp cardinternal.cpp
infoforuser.cpp infoforuser.cpp
@ -10,7 +10,7 @@ set(SOURCE_FILES
) )
set(HEADER_FILES set(HEADER_FILES
delaymanager.h manager.h
job.h job.h
cardinternal.h cardinternal.h
infoforuser.h infoforuser.h

View File

@ -14,7 +14,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "delaymanager.h" #include "manager.h"
#include <QDebug>
#include "cardinternal.h" #include "cardinternal.h"
#include "infoforuser.h" #include "infoforuser.h"
@ -59,6 +61,9 @@ Core::DelayManager::Job::Id Core::DelayManager::Manager::getNextJobId() {
} }
void Core::DelayManager::Manager::getInfo(const QString& jid) { void Core::DelayManager::Manager::getInfo(const QString& jid) {
if (jid == ownJid)
return getOwnInfo();
Job* job = nullptr; Job* job = nullptr;
#ifdef WITH_OMEMO #ifdef WITH_OMEMO
std::map<QString, Job::Id>::const_iterator bitr = requestedBundles.find(jid); std::map<QString, Job::Id>::const_iterator bitr = requestedBundles.find(jid);
@ -91,10 +96,14 @@ void Core::DelayManager::Manager::getVCard(const QString& jid) {
} }
void Core::DelayManager::Manager::getOwnVCard() { void Core::DelayManager::Manager::getOwnVCard() {
if (ownInfoJobId == 0) if (ownVCardJobId == 0)
scheduleJob(new OwnCardInternal(getNextJobId())); scheduleJob(new OwnCardInternal(getNextJobId()));
} }
bool Core::DelayManager::Manager::isOwnVCardPending() const {
return ownVCardJobId != 0;
}
Core::DelayManager::Job* Core::DelayManager::Manager::getVCardJob(const QString& jid) { Core::DelayManager::Job* Core::DelayManager::Manager::getVCardJob(const QString& jid) {
Job* job = nullptr; Job* job = nullptr;
std::map<QString, Job::Id>::const_iterator sitr = scheduledVCards.find(jid); std::map<QString, Job::Id>::const_iterator sitr = scheduledVCards.find(jid);
@ -207,7 +216,7 @@ void Core::DelayManager::Manager::jobIsCanceled(Job* job, bool wasRunning) {
else else
scheduledVCards.erase(jb->jid); scheduledVCards.erase(jb->jid);
emit receivedVCard(jb->jid, Shared::VCard()); emit gotVCard(jb->jid, Shared::VCard());
} }
break; break;
case Job::Type::infoForUser: { case Job::Type::infoForUser: {
@ -219,7 +228,7 @@ void Core::DelayManager::Manager::jobIsCanceled(Job* job, bool wasRunning) {
else else
scheduledVCards.erase(jb->jid); scheduledVCards.erase(jb->jid);
emit receivedVCard(jb->jid, Shared::VCard()); emit gotVCard(jb->jid, Shared::VCard());
break; break;
case InfoForUser::Stage::waitingForBundles: case InfoForUser::Stage::waitingForBundles:
requestedBundles.erase(jb->jid); requestedBundles.erase(jb->jid);
@ -227,23 +236,23 @@ void Core::DelayManager::Manager::jobIsCanceled(Job* job, bool wasRunning) {
default: default:
break; break;
} }
emit receivedInfo(Shared::Info(jb->jid)); emit gotInfo(Shared::Info(jb->jid));
} }
break; break;
case Job::Type::ownInfoForUser: { case Job::Type::ownInfoForUser: {
OwnInfoForUser* jb = dynamic_cast<OwnInfoForUser*>(job); OwnInfoForUser* jb = dynamic_cast<OwnInfoForUser*>(job);
if (jb->getStage() == OwnInfoForUser::Stage::waitingForVCard) { if (jb->getStage() == OwnInfoForUser::Stage::waitingForVCard) {
ownVCardJobId = 0; ownVCardJobId = 0;
emit receivedOwnCard(Shared::VCard()); emit gotOwnVCard(Shared::VCard());
} }
ownInfoJobId = 0; ownInfoJobId = 0;
emit receivedOwnInfo(Shared::Info (ownJid)); emit gotOwnInfo(Shared::Info (ownJid));
} }
break; break;
case Job::Type::ownCardInternal: case Job::Type::ownCardInternal:
ownVCardJobId = 0; ownVCardJobId = 0;
emit receivedOwnCard(Shared::VCard()); emit gotOwnVCard(Shared::VCard());
break; break;
} }
@ -264,7 +273,8 @@ void Core::DelayManager::Manager::disconnected() {
void Core::DelayManager::Manager::receivedVCard(const QString& jid, const Shared::VCard& card) { void Core::DelayManager::Manager::receivedVCard(const QString& jid, const Shared::VCard& card) {
std::map<QString, Job::Id>::const_iterator cardItr = requestedVCards.find(jid); std::map<QString, Job::Id>::const_iterator cardItr = requestedVCards.find(jid);
if (cardItr == requestedVCards.end()) { if (cardItr == requestedVCards.end()) {
throw 8575; //never supposed to happen, the state is not correct; qDebug() << "received VCard for" << jid << "but it was never requested through manager, ignoring";
return;
} }
Job::Id jobId = cardItr->second; Job::Id jobId = cardItr->second;
requestedVCards.erase(cardItr); requestedVCards.erase(cardItr);
@ -272,7 +282,7 @@ void Core::DelayManager::Manager::receivedVCard(const QString& jid, const Shared
switch (job->type) { switch (job->type) {
case Job::Type::cardInternal: case Job::Type::cardInternal:
jobIsDone(jobId); jobIsDone(jobId);
emit receivedCard(jid, card); emit gotVCard(jid, card);
break; break;
case Job::Type::infoForUser: { case Job::Type::infoForUser: {
#ifdef WITH_OMEMO #ifdef WITH_OMEMO
@ -283,10 +293,10 @@ void Core::DelayManager::Manager::receivedVCard(const QString& jid, const Shared
#else #else
Shared::Info info(jid); Shared::Info info(jid);
info.turnIntoContact(card); info.turnIntoContact(card);
emit receivedInfo(info); emit gotInfo(info);
jobIsDone(jobId); jobIsDone(jobId);
#endif #endif
emit receivedCard(jid, card); emit gotVCard(jid, card);
} }
break; break;
default: default:
@ -294,27 +304,27 @@ void Core::DelayManager::Manager::receivedVCard(const QString& jid, const Shared
} }
} }
void Core::DelayManager::Manager::ownVCardReceived(const Shared::VCard& card) { void Core::DelayManager::Manager::receivedOwnVCard(const Shared::VCard& card) {
Job::Id jobId = ownVCardJobId; Job::Id jobId = ownVCardJobId;
ownVCardJobId = 0; ownVCardJobId = 0;
Job* job = runningJobs.at(jobId); Job* job = runningJobs.at(jobId);
switch (job->type) { switch (job->type) {
case Job::Type::ownCardInternal: case Job::Type::ownCardInternal:
jobIsDone(jobId); jobIsDone(jobId);
emit receivedOwnCard(card); emit gotOwnVCard(card);
break; break;
case Job::Type::ownInfoForUser: { case Job::Type::ownInfoForUser: {
#ifdef WITH_OMEMO #ifdef WITH_OMEMO
OwnInfoForUser* jb = dynamic_cast<OwnInfoForUser*>(job); OwnInfoForUser* jb = dynamic_cast<OwnInfoForUser*>(job);
jb->receivedVCard(card); jb->receivedVCard(card);
emit requestOwnBundle(); emit requestOwnBundles();
#else #else
Shared::Info info(ownJid); Shared::Info info(ownJid);
info.turnIntoOwnAccount(card); info.turnIntoOwnAccount(card);
emit receivedOwnInfo(info); emit gotOwnInfo(info);
jobIsDone(jobId); jobIsDone(jobId);
#endif #endif
emit receivedOwnCard(card); emit gotOwnVCard(card);
} }
break; break;
default: default:
@ -335,7 +345,7 @@ void Core::DelayManager::Manager::receivedBundles(const QString& jid, const std:
Shared::Info info(jid); Shared::Info info(jid);
info.turnIntoContact(job->claim(), new std::list<Shared::KeyInfo>(keys)); info.turnIntoContact(job->claim(), new std::list<Shared::KeyInfo>(keys));
emit receivedInfo(info); emit gotInfo(info);
jobIsDone(jobId); jobIsDone(jobId);
} }
@ -347,7 +357,7 @@ void Core::DelayManager::Manager::receivedOwnBundles(const std::list<Shared::Key
Shared::Info info(ownJid); Shared::Info info(ownJid);
info.turnIntoOwnAccount(job->claim(), new std::list<Shared::KeyInfo>(keys)); info.turnIntoOwnAccount(job->claim(), new std::list<Shared::KeyInfo>(keys));
emit receivedOwnInfo(info); emit gotOwnInfo(info);
jobIsDone(jobId); jobIsDone(jobId);
} }

View File

@ -43,26 +43,29 @@ public:
Manager(const QString& ownJid, Job::Id maxParallelJobs = 5, QObject* parent = nullptr); Manager(const QString& ownJid, Job::Id maxParallelJobs = 5, QObject* parent = nullptr);
~Manager(); ~Manager();
void setOwnJid(const QString& jid);
bool isOwnVCardPending() const;
public slots:
void getOwnVCard(); void getOwnVCard();
void getOwnInfo(); void getOwnInfo();
void getVCard(const QString& jid); void getVCard(const QString& jid);
void getInfo(const QString& jid); void getInfo(const QString& jid);
void setOwnJid(const QString& jid);
signals: signals:
void requestVCard(const QString& jid); void requestVCard(const QString& jid);
void requestOwnVCard(); void requestOwnVCard();
void requestBundles(const QString& jid); void requestBundles(const QString& jid);
void requestOwnBundle(); void requestOwnBundles();
void receivedCard(const QString& jid, const Shared::VCard& info); void gotVCard(const QString& jid, const Shared::VCard& info);
void receivedOwnCard(const Shared::VCard& info); void gotOwnVCard(const Shared::VCard& info);
void receivedInfo(const Shared::Info& info); void gotInfo(const Shared::Info& info);
void receivedOwnInfo(const Shared::Info& info); void gotOwnInfo(const Shared::Info& info);
public slots: public slots:
void disconnected(); void disconnected();
void ownVCardReceived(const Shared::VCard& card); void receivedOwnVCard(const Shared::VCard& card);
void receivedVCard(const QString& jid, const Shared::VCard& card); void receivedVCard(const QString& jid, const Shared::VCard& card);
void receivedBundles(const QString& jid, const std::list<Shared::KeyInfo>& keys); void receivedBundles(const QString& jid, const std::list<Shared::KeyInfo>& keys);
void receivedOwnBundles(const std::list<Shared::KeyInfo>& keys); void receivedOwnBundles(const std::list<Shared::KeyInfo>& keys);

View File

@ -19,7 +19,10 @@
#include "core/account.h" #include "core/account.h"
#include "core/adapterfunctions.h" #include "core/adapterfunctions.h"
constexpr const char* ns_omemo_2 = "urn:xmpp:omemo:2";
Core::OmemoHandler::OmemoHandler(Account* account) : Core::OmemoHandler::OmemoHandler(Account* account) :
QObject(),
QXmppOmemoStorage(), QXmppOmemoStorage(),
acc(account), acc(account),
ownDevice(std::nullopt), ownDevice(std::nullopt),
@ -166,6 +169,51 @@ void Core::OmemoHandler::getDevices(const QString& jid, std::list<Shared::KeyInf
} }
} }
void Core::OmemoHandler::requestBundles(const QString& jid) {
QXmppTask<void> task = acc->om->buildMissingSessions({jid});
task.then(this, std::bind(&OmemoHandler::onBundlesReceived, this, jid));
}
void Core::OmemoHandler::requestOwnBundles() {
QXmppTask<void> task = acc->om->buildMissingSessions({acc->getBareJid()});
task.then(this, std::bind(&OmemoHandler::onOwnBundlesReceived, this));
}
void Core::OmemoHandler::onBundlesReceived(const QString& jid) {
std::list<Shared::KeyInfo> keys;
acc->oh->getDevices(jid, keys);
std::map<QByteArray, Shared::TrustLevel> trustLevels = acc->th->getKeys(ns_omemo_2, jid);
qDebug() << "OMEMO info for " << jid << " devices:" << keys.size() << ", trustLevels:" << trustLevels.size();
for (Shared::KeyInfo& key : keys) {
std::map<QByteArray, Shared::TrustLevel>::const_iterator itr = trustLevels.find(key.fingerPrint);
if (itr != trustLevels.end()) {
key.trustLevel = itr->second;
qDebug() << "Found a trust level for a device!";
}
}
acc->delay->receivedBundles(jid, keys);
}
void Core::OmemoHandler::onOwnBundlesReceived() {
QString jid = acc->getBareJid();
std::list<Shared::KeyInfo> keys;
acc->oh->getDevices(jid, keys);
std::map<QByteArray, Shared::TrustLevel> trustLevels = acc->th->getKeys(ns_omemo_2, jid);
qDebug() << "OMEMO info for " << jid << " devices:" << keys.size() << ", trustLevels:" << trustLevels.size();
for (Shared::KeyInfo& key : keys) {
std::map<QByteArray, Shared::TrustLevel>::const_iterator itr = trustLevels.find(key.fingerPrint);
if (itr != trustLevels.end()) {
key.trustLevel = itr->second;
qDebug() << "Found a trust level for a device!";
}
}
acc->delay->receivedOwnBundles(keys);
}
QDataStream & operator >> (QDataStream& in, QXmppOmemoStorage::Device& device) { QDataStream & operator >> (QDataStream& in, QXmppOmemoStorage::Device& device) {
in >> device.label; in >> device.label;

View File

@ -19,6 +19,7 @@
#include <map> #include <map>
#include <list> #include <list>
#include <functional>
#include <QXmppOmemoStorage.h> #include <QXmppOmemoStorage.h>
#include <cache.h> #include <cache.h>
@ -32,8 +33,9 @@ Q_DECLARE_METATYPE(QXmppOmemoStorage::Device);
namespace Core { namespace Core {
class Account; class Account;
class OmemoHandler : public QXmppOmemoStorage class OmemoHandler :public QObject, public QXmppOmemoStorage
{ {
Q_OBJECT
public: public:
typedef std::pair<QDateTime, QByteArray> SignedPreKeyPair; typedef std::pair<QDateTime, QByteArray> SignedPreKeyPair;
@ -58,8 +60,14 @@ public:
bool hasOwnDevice(); bool hasOwnDevice();
void requestBundles(const QString& jid);
void requestOwnBundles();
void getDevices(const QString& jid, std::list<Shared::KeyInfo>& out) const; void getDevices(const QString& jid, std::list<Shared::KeyInfo>& out) const;
private slots:
void onBundlesReceived(const QString& jid);
void onOwnBundlesReceived();
private: private:
Account* acc; Account* acc;
std::optional<OwnDevice> ownDevice; std::optional<OwnDevice> ownDevice;

View File

@ -156,7 +156,7 @@ void Core::RosterHandler::careAboutAvatar(Core::RosterItem* item, QMap<QString,
} else { } else {
data.insert("avatarState", QVariant::fromValue(Shared::Avatar::empty)); data.insert("avatarState", QVariant::fromValue(Shared::Avatar::empty));
data.insert("avatarPath", ""); data.insert("avatarPath", "");
acc->vh->requestVCard(item->jid); acc->delay->requestVCard(item->jid);
} }
} }
@ -197,7 +197,7 @@ void Core::RosterHandler::handleNewRosterItem(Core::RosterItem* contact)
connect(contact, &RosterItem::historyResponse, this->acc, &Account::onContactHistoryResponse); connect(contact, &RosterItem::historyResponse, this->acc, &Account::onContactHistoryResponse);
connect(contact, &RosterItem::nameChanged, this, &RosterHandler::onContactNameChanged); connect(contact, &RosterItem::nameChanged, this, &RosterHandler::onContactNameChanged);
connect(contact, &RosterItem::avatarChanged, this, &RosterHandler::onContactAvatarChanged); connect(contact, &RosterItem::avatarChanged, this, &RosterHandler::onContactAvatarChanged);
connect(contact, &RosterItem::requestVCard, this->acc->vh, &VCardHandler::requestVCard); connect(contact, &RosterItem::requestVCard, acc->delay, &DelayManager::Manager::getVCard);
} }
void Core::RosterHandler::handleNewContact(Core::Contact* contact) void Core::RosterHandler::handleNewContact(Core::Contact* contact)

View File

@ -36,6 +36,7 @@
#include <shared/message.h> #include <shared/message.h>
#include <core/contact.h> #include <core/contact.h>
#include <core/conference.h> #include <core/conference.h>
#include <core/delayManager/manager.h>
namespace Core { namespace Core {

View File

@ -89,8 +89,12 @@ QXmppTask<QXmpp::TrustLevel> Core::TrustHandler::trustLevel(
const QString& keyOwnerJid, const QString& keyOwnerJid,
const QByteArray& keyId) const QByteArray& keyId)
{ {
Keys map = getCache(encryption)->getRecord(keyOwnerJid); KeyCache* cache = getCache(encryption);
Shared::TrustLevel level = map.at(keyId); Shared::TrustLevel level = Shared::TrustLevel::undecided;
try {
Keys map = cache->getRecord(keyOwnerJid);
level = map.at(keyId);
} catch (const DataBase::NotFound& e) {}
return Core::makeReadyTask(std::move(convert(level))); return Core::makeReadyTask(std::move(convert(level)));
} }
@ -134,15 +138,22 @@ QXmppTask<QHash<QString, QMultiHash<QString, QByteArray>>> Core::TrustHandler::s
for (MultySB::const_iterator itr = keyIds.begin(), end = keyIds.end(); itr != end; ++itr) { for (MultySB::const_iterator itr = keyIds.begin(), end = keyIds.end(); itr != end; ++itr) {
const QString& keyOwnerJid = itr.key(); const QString& keyOwnerJid = itr.key();
const QByteArray& keyId = itr.value(); const QByteArray& keyId = itr.value();
Keys map = cache->getRecord(keyOwnerJid); try {
std::pair<Keys::iterator, bool> result = map.insert(std::make_pair(keyId, level)); Keys map = cache->getRecord(keyOwnerJid);
if (result.second) { std::pair<Keys::iterator, bool> result = map.insert(std::make_pair(keyId, level));
bool changed = result.second;
if (!changed && result.first->second != level) {
result.first->second = level;
changed = true;
}
if (changed) {
modifiedKeys[encryption].insert(keyOwnerJid, keyId);
cache->changeRecord(keyOwnerJid, map);
}
} catch (const DataBase::NotFound& e) {
Keys map({{keyId, level}});
modifiedKeys[encryption].insert(keyOwnerJid, keyId); modifiedKeys[encryption].insert(keyOwnerJid, keyId);
cache->changeRecord(keyOwnerJid, map); cache->addRecord(keyOwnerJid, map);
} else if (result.first->second != level) {
result.first->second = level;
modifiedKeys[encryption].insert(keyOwnerJid, keyId);
cache->changeRecord(keyOwnerJid, map);
} }
} }
return Core::makeReadyTask(std::move(modifiedKeys)); return Core::makeReadyTask(std::move(modifiedKeys));
@ -199,9 +210,8 @@ QXmppTask<QHash<QXmpp::TrustLevel, QMultiHash<QString, QByteArray>>> TrustHandle
for (const std::pair<const QString, Keys>& value : storage) { for (const std::pair<const QString, Keys>& value : storage) {
for (const std::pair<const QByteArray, Shared::TrustLevel>& pair : value.second) { for (const std::pair<const QByteArray, Shared::TrustLevel>& pair : value.second) {
QXmpp::TrustLevel level = convert(pair.second); QXmpp::TrustLevel level = convert(pair.second);
if (!trustLevels || trustLevels.testFlag(level)) { if (!trustLevels || trustLevels.testFlag(level))
res[level].insert(value.first, pair.first); res[level].insert(value.first, pair.first);
}
} }
} }
return Core::makeReadyTask(std::move(res)); return Core::makeReadyTask(std::move(res));
@ -219,9 +229,8 @@ QXmppTask<void> TrustHandler::removeKeys(const QString& encryption, const QStrin
QXmppTask<void> TrustHandler::removeKeys(const QString& encryption, const QList<QByteArray>& keyIds) { QXmppTask<void> TrustHandler::removeKeys(const QString& encryption, const QList<QByteArray>& keyIds) {
std::set<QByteArray> set; std::set<QByteArray> set;
for (const QByteArray& keyId : keyIds) { for (const QByteArray& keyId : keyIds)
set.insert(keyId); set.insert(keyId);
}
KeyCache* cache = getCache(encryption); KeyCache* cache = getCache(encryption);
std::map<QString, Keys> data = cache->readAll(); std::map<QString, Keys> data = cache->readAll();
@ -233,19 +242,16 @@ QXmppTask<void> TrustHandler::removeKeys(const QString& encryption, const QList<
if (set.erase(keyId)) { if (set.erase(keyId)) {
byOwner.erase(itr++); byOwner.erase(itr++);
changed = true; changed = true;
} else { } else
++itr; ++itr;
}
} }
if (byOwner.size() > 0) { if (byOwner.size() > 0)
data.erase(cItr++); data.erase(cItr++);
} else { else
++cItr; ++cItr;
}
} }
if (changed) { if (changed)
cache->replaceAll(data); cache->replaceAll(data);
}
return Core::makeReadyTask(); return Core::makeReadyTask();
} }
@ -266,9 +272,8 @@ QXmppTask<void> TrustHandler::addKeys(
} catch (const DataBase::NotFound& e) {} } catch (const DataBase::NotFound& e) {}
for (const QByteArray& keyId : keyIds) { for (const QByteArray& keyId : keyIds) {
std::pair<Keys::iterator, bool> result = data.insert(std::make_pair(keyId, level)); std::pair<Keys::iterator, bool> result = data.insert(std::make_pair(keyId, level));
if (!result.second) { if (!result.second)
result.first->second = level; result.first->second = level;
}
} }
if (had) { if (had) {

View File

@ -17,13 +17,9 @@
#include "vcardhandler.h" #include "vcardhandler.h"
#include "core/account.h" #include "core/account.h"
constexpr const char* ns_omemo_2 = "urn:xmpp:omemo:2";
Core::VCardHandler::VCardHandler(Account* account): Core::VCardHandler::VCardHandler(Account* account):
QObject(), QObject(),
acc(account), acc(account),
ownVCardRequestInProgress(false),
pendingVCardRequests(),
avatarHash(), avatarHash(),
avatarType() avatarType()
{ {
@ -90,36 +86,20 @@ void Core::VCardHandler::onVCardReceived(const QXmppVCardIq& card) {
if (comps.size() > 1) { if (comps.size() > 1) {
resource = comps.back(); resource = comps.back();
} }
pendingVCardRequests.erase(id);
RosterItem* item = acc->rh->getRosterItem(jid); RosterItem* item = acc->rh->getRosterItem(jid);
if (item == 0) { if (item == 0) {
if (jid == acc->getBareJid()) { if (jid == acc->getBareJid())
onOwnVCardReceived(card); onOwnVCardReceived(card);
} else { else
qDebug() << "received vCard" << jid << "doesn't belong to any of known contacts or conferences, skipping"; qDebug() << "received vCard" << jid << "doesn't belong to any of known contacts or conferences, skipping";
}
return; return;
} }
Shared::Info info(jid, Shared::EntryType::contact); Shared::VCard vCard;
item->handleResponseVCard(card, resource, info.getVCardRef()); item->handleResponseVCard(card, resource, vCard);
#ifdef WITH_OMEMO acc->delay->receivedVCard(id, vCard);
std::list<Shared::KeyInfo>& aks = info.getActiveKeysRef();
acc->oh->getDevices(jid, aks);
std::map<QByteArray, Shared::TrustLevel> trustLevels = acc->th->getKeys(ns_omemo_2, jid);
qDebug() << "OMEMO info for " << jid << " devices:" << aks.size() << ", trustLevels:" << trustLevels.size();
for (Shared::KeyInfo& key : aks) {
std::map<QByteArray, Shared::TrustLevel>::const_iterator itr = trustLevels.find(key.fingerPrint);
if (itr != trustLevels.end()) {
key.trustLevel = itr->second;
qDebug() << "Found a trust level for a device!";
}
}
#endif
emit acc->infoReady(info);
} }
void Core::VCardHandler::onOwnVCardReceived(const QXmppVCardIq& card) { void Core::VCardHandler::onOwnVCardReceived(const QXmppVCardIq& card) {
@ -201,10 +181,7 @@ void Core::VCardHandler::onOwnVCardReceived(const QXmppVCardIq& card) {
emit acc->changed(change); emit acc->changed(change);
} }
ownVCardRequestInProgress = false; Shared::VCard vCard;
Shared::Info info(acc->getBareJid(), Shared::EntryType::ownAccount);
Shared::VCard& vCard = info.getVCardRef();
initializeVCard(vCard, card); initializeVCard(vCard, card);
if (avatarType.size() > 0) { if (avatarType.size() > 0) {
@ -214,52 +191,24 @@ void Core::VCardHandler::onOwnVCardReceived(const QXmppVCardIq& card) {
vCard.setAvatarType(Shared::Avatar::empty); vCard.setAvatarType(Shared::Avatar::empty);
} }
emit acc->infoReady(info); if (acc->delay->isOwnVCardPending())
} acc->delay->receivedOwnVCard(vCard);
void Core::VCardHandler::handleOffline() {
pendingVCardRequests.clear();
for (const QString& jid : pendingVCardRequests) {
Shared::Info info(jid, Shared::EntryType::none);
emit acc->infoReady(info); //need to show it better in the future, like with an error
}
pendingVCardRequests.clear();
ownVCardRequestInProgress = false;
}
void Core::VCardHandler::requestVCard(const QString& jid) {
if (pendingVCardRequests.find(jid) == pendingVCardRequests.end()) {
qDebug() << "requesting vCard" << jid;
if (jid == acc->getBareJid()) {
if (!ownVCardRequestInProgress) {
acc->vm->requestClientVCard();
ownVCardRequestInProgress = true;
}
} else {
acc->vm->requestVCard(jid);
pendingVCardRequests.insert(jid);
}
}
} }
void Core::VCardHandler::handlePresenceOfMyAccountChange(const QXmppPresence& p_presence) { void Core::VCardHandler::handlePresenceOfMyAccountChange(const QXmppPresence& p_presence) {
if (!ownVCardRequestInProgress) { if (!acc->delay->isOwnVCardPending()) {
switch (p_presence.vCardUpdateType()) { switch (p_presence.vCardUpdateType()) {
case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo
break; break;
case QXmppPresence::VCardUpdateNotReady: //let's say the photo didn't change here case QXmppPresence::VCardUpdateNotReady: //let's say the photo didn't change here
break; break;
case QXmppPresence::VCardUpdateNoPhoto: //there is no photo, need to drop if any case QXmppPresence::VCardUpdateNoPhoto: //there is no photo, need to drop if any
if (avatarType.size() > 0) { if (avatarType.size() > 0)
acc->vm->requestClientVCard(); acc->delay->getOwnVCard();
ownVCardRequestInProgress = true;
}
break; break;
case QXmppPresence::VCardUpdateValidPhoto: //there is a photo, need to load case QXmppPresence::VCardUpdateValidPhoto: //there is a photo, need to load
if (avatarHash != p_presence.photoHash()) { if (avatarHash != p_presence.photoHash())
acc->vm->requestClientVCard(); acc->delay->getOwnVCard();
ownVCardRequestInProgress = true;
}
break; break;
} }
} }

View File

@ -42,8 +42,6 @@ public:
VCardHandler(Account* account); VCardHandler(Account* account);
~VCardHandler(); ~VCardHandler();
void handleOffline();
void requestVCard(const QString& jid);
void handlePresenceOfMyAccountChange(const QXmppPresence& p_presence); void handlePresenceOfMyAccountChange(const QXmppPresence& p_presence);
void uploadVCard(const Shared::VCard& card); void uploadVCard(const Shared::VCard& card);
QString getAvatarPath() const; QString getAvatarPath() const;
@ -57,8 +55,6 @@ private slots:
private: private:
Account* acc; Account* acc;
bool ownVCardRequestInProgress;
std::set<QString> pendingVCardRequests;
QString avatarHash; QString avatarHash;
QString avatarType; QString avatarType;
}; };

View File

@ -1,7 +1,17 @@
target_sources(squawk PRIVATE set(SOURCE_FILES
main.cpp main.cpp
application.cpp application.cpp
application.h
dialogqueue.cpp dialogqueue.cpp
dialogqueue.h root.cpp
)
set(HEADER_FILES
application.h
dialogqueue.h
root.h
)
target_sources(squawk PRIVATE
${SOURCE_FILES}
${HEADER_FILES}
) )

View File

@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "root.h"
#include "shared/global.h" #include "shared/global.h"
#include "shared/messageinfo.h" #include "shared/messageinfo.h"
#include "shared/pathcheck.h" #include "shared/pathcheck.h"
@ -31,7 +32,6 @@
#include <QTranslator> #include <QTranslator>
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtWidgets/QApplication>
#include <QDir> #include <QDir>
#ifdef WITH_OMEMO #ifdef WITH_OMEMO
@ -59,13 +59,13 @@ int main(int argc, char *argv[])
qRegisterMetaType<QXmppOmemoStorage::Device>("QXmppOmemoStorage::Device"); qRegisterMetaType<QXmppOmemoStorage::Device>("QXmppOmemoStorage::Device");
#endif #endif
QApplication app(argc, argv); Root app(argc, argv);
SignalCatcher sc(&app); SignalCatcher sc(&app);
QApplication::setApplicationName("squawk"); Root::setApplicationName("squawk");
QApplication::setOrganizationName("macaw.me"); Root::setOrganizationName("macaw.me");
QApplication::setApplicationDisplayName("Squawk"); Root::setApplicationDisplayName("Squawk");
QApplication::setApplicationVersion("0.2.3"); Root::setApplicationVersion("0.2.3");
app.setDesktopFileName("squawk"); app.setDesktopFileName("squawk");
QTranslator qtTranslator; QTranslator qtTranslator;
@ -97,7 +97,7 @@ int main(int argc, char *argv[])
icon.addFile(":images/logo.svg", QSize(128, 128)); icon.addFile(":images/logo.svg", QSize(128, 128));
icon.addFile(":images/logo.svg", QSize(256, 256)); icon.addFile(":images/logo.svg", QSize(256, 256));
icon.addFile(":images/logo.svg", QSize(512, 512)); icon.addFile(":images/logo.svg", QSize(512, 512));
QApplication::setWindowIcon(icon); Root::setWindowIcon(icon);
new Shared::Global(); //translates enums new Shared::Global(); //translates enums
@ -139,7 +139,7 @@ int main(int argc, char *argv[])
//QObject::connect(&app, &QApplication::aboutToQuit, &w, &QMainWindow::close); //QObject::connect(&app, &QApplication::aboutToQuit, &w, &QMainWindow::close);
QObject::connect(squawk, &Core::Squawk::quit, squawk, &Core::Squawk::deleteLater); QObject::connect(squawk, &Core::Squawk::quit, squawk, &Core::Squawk::deleteLater);
QObject::connect(squawk, &Core::Squawk::destroyed, coreThread, &QThread::quit, Qt::QueuedConnection); QObject::connect(squawk, &Core::Squawk::destroyed, coreThread, &QThread::quit, Qt::QueuedConnection);
QObject::connect(coreThread, &QThread::finished, &app, &QApplication::quit, Qt::QueuedConnection); QObject::connect(coreThread, &QThread::finished, &app, &Root::quit, Qt::QueuedConnection);
coreThread->start(); coreThread->start();
int result = app.exec(); int result = app.exec();

43
main/root.cpp Normal file
View File

@ -0,0 +1,43 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "root.h"
#include <QDebug>
#include <QThread>
Root::Root(int& argc, char *argv[]) :
QApplication(argc, argv)
{}
bool Root::notify(QObject* receiver, QEvent* e) {
try {
return QApplication::notify(receiver, e);
} catch(const std::runtime_error& e) {
qDebug() << "std::runtime_error in thread : " << QThread::currentThreadId();
qDebug() << e.what();
} catch(const std::exception& e) {
qDebug() << "std::exception in thread : " << QThread::currentThreadId();
qDebug() << e.what();
} catch(const int& e) {
qDebug() << "int exception in thread : " << QThread::currentThreadId();
qDebug() << e;
} catch(...) {
qDebug() << "exception thread : " << QThread::currentThreadId();
}
qDebug() << "catch in notify ";
return false;
}

28
main/root.h Normal file
View File

@ -0,0 +1,28 @@
// Squawk messenger.
// Copyright (C) 2019 Yury Gubich <blue@macaw.me>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef ROOT_H
#define ROOT_H
#include <QApplication>
class Root : public QApplication {
public:
Root(int& argc, char* argv[]);
bool notify(QObject* receiver, QEvent* e) override;
};
#endif // ROOT_H