forked from blue/squawk
feat(OMEMO): QXmppClientExtension for OMEMO
This commit is contained in:
parent
b1a8f162ce
commit
006752b31c
@ -47,7 +47,8 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
|
|||||||
network(p_net),
|
network(p_net),
|
||||||
passwordType(Shared::AccountPassword::plain),
|
passwordType(Shared::AccountPassword::plain),
|
||||||
mh(new MessageHandler(this)),
|
mh(new MessageHandler(this)),
|
||||||
rh(new RosterHandler(this))
|
rh(new RosterHandler(this)),
|
||||||
|
omemo(new QXmpp::Omemo::Manager())
|
||||||
{
|
{
|
||||||
config.setUser(p_login);
|
config.setUser(p_login);
|
||||||
config.setDomain(p_server);
|
config.setDomain(p_server);
|
||||||
@ -91,6 +92,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
|
|||||||
client.addExtension(rcpm);
|
client.addExtension(rcpm);
|
||||||
QObject::connect(rcpm, &QXmppMessageReceiptManager::messageDelivered, mh, &MessageHandler::onReceiptReceived);
|
QObject::connect(rcpm, &QXmppMessageReceiptManager::messageDelivered, mh, &MessageHandler::onReceiptReceived);
|
||||||
|
|
||||||
|
client.addExtension(omemo.get());
|
||||||
|
|
||||||
QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
|
QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
|
||||||
path += "/" + name;
|
path += "/" + name;
|
||||||
|
@ -30,23 +30,24 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include <QXmppRosterManager.h>
|
|
||||||
#include <QXmppCarbonManager.h>
|
|
||||||
#include <QXmppDiscoveryManager.h>
|
|
||||||
#include <QXmppMamManager.h>
|
|
||||||
#include <QXmppMucManager.h>
|
|
||||||
#include <QXmppClient.h>
|
|
||||||
#include <QXmppBookmarkManager.h>
|
#include <QXmppBookmarkManager.h>
|
||||||
#include <QXmppBookmarkSet.h>
|
#include <QXmppBookmarkSet.h>
|
||||||
|
#include <QXmppCarbonManager.h>
|
||||||
|
#include <QXmppClient.h>
|
||||||
|
#include <QXmppDiscoveryManager.h>
|
||||||
|
#include <QXmppMamManager.h>
|
||||||
|
#include <QXmppMessageReceiptManager.h>
|
||||||
|
#include <QXmppMucManager.h>
|
||||||
|
#include <QXmppRosterManager.h>
|
||||||
#include <QXmppUploadRequestManager.h>
|
#include <QXmppUploadRequestManager.h>
|
||||||
#include <QXmppVCardIq.h>
|
#include <QXmppVCardIq.h>
|
||||||
#include <QXmppVCardManager.h>
|
#include <QXmppVCardManager.h>
|
||||||
#include <QXmppMessageReceiptManager.h>
|
#include <qomemo/qxmpp_omemo_manager.h>
|
||||||
|
|
||||||
#include "shared/shared.h"
|
|
||||||
#include "contact.h"
|
|
||||||
#include "conference.h"
|
#include "conference.h"
|
||||||
|
#include "contact.h"
|
||||||
#include "networkaccess.h"
|
#include "networkaccess.h"
|
||||||
|
#include "shared/shared.h"
|
||||||
|
|
||||||
#include "handlers/messagehandler.h"
|
#include "handlers/messagehandler.h"
|
||||||
#include "handlers/rosterhandler.h"
|
#include "handlers/rosterhandler.h"
|
||||||
@ -166,6 +167,8 @@ private:
|
|||||||
MessageHandler* mh;
|
MessageHandler* mh;
|
||||||
RosterHandler* rh;
|
RosterHandler* rh;
|
||||||
|
|
||||||
|
QScopedPointer<QXmpp::Omemo::Manager> omemo;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onClientStateChange(QXmppClient::State state);
|
void onClientStateChange(QXmppClient::State state);
|
||||||
void onClientError(QXmppClient::Error err);
|
void onClientError(QXmppClient::Error err);
|
||||||
|
@ -11,4 +11,6 @@ target_sources(squawk PRIVATE
|
|||||||
sce.h
|
sce.h
|
||||||
user_device_list.cpp
|
user_device_list.cpp
|
||||||
user_device_list.h
|
user_device_list.h
|
||||||
|
qxmpp_omemo_manager.cpp
|
||||||
|
qxmpp_omemo_manager.h
|
||||||
)
|
)
|
@ -4,27 +4,12 @@
|
|||||||
|
|
||||||
#include "device_service.h"
|
#include "device_service.h"
|
||||||
|
|
||||||
#include <QXmppClient.h>
|
QXmpp::Omemo::DeviceService::DeviceService(QObject *parent) : QObject(parent) {}
|
||||||
#include <QXmppPubSubIq.h>
|
|
||||||
|
|
||||||
#include <QDebug>
|
void QXmpp::Omemo::DeviceService::onDeviceListReceived(
|
||||||
|
const QString &jid, const QXmpp::Omemo::DeviceList &list) {
|
||||||
|
|
||||||
QXmpp::Omemo::DeviceService::DeviceService(QXmppClient &client, QObject *parent)
|
for (const auto &device : list.devices) {
|
||||||
: QObject(parent), client(client) {
|
qInfo() << "Got device for" << jid << ":" << device.id;
|
||||||
connect(&client, &QXmppClient::iqReceived, this,
|
|
||||||
&DeviceService::onIqReceived);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QXmpp::Omemo::DeviceService::onIqReceived(const QXmppIq &iq) {
|
|
||||||
// Update OMEMO device list
|
|
||||||
}
|
|
||||||
|
|
||||||
void QXmpp::Omemo::DeviceService::fetch() {
|
|
||||||
QXmppPubSubIq fetchOwnDevices{};
|
|
||||||
fetchOwnDevices.setFrom(client.configuration().jid());
|
|
||||||
fetchOwnDevices.setTo(client.configuration().jidBare());
|
|
||||||
fetchOwnDevices.setType(QXmppIq::Get);
|
|
||||||
fetchOwnDevices.setQueryNode("urn:xmpp:omemo:1:devices");
|
|
||||||
|
|
||||||
client.sendPacket(fetchOwnDevices);
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "qomemo.h"
|
||||||
#include "user_device_list.h"
|
#include "user_device_list.h"
|
||||||
|
|
||||||
#include <QXmppClient.h>
|
#include <QXmppClient.h>
|
||||||
@ -14,17 +15,12 @@ class DeviceService : public QObject {
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DeviceService(QXmppClient& client, QObject *parent);
|
explicit DeviceService(QObject *parent);
|
||||||
|
|
||||||
void fetch();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onIqReceived(const QXmppIq& iq);
|
void onDeviceListReceived(const QString& jid, const DeviceList& list);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void announce();
|
|
||||||
|
|
||||||
QXmppClient& client;
|
|
||||||
QMap<QString, UserDeviceList> device_lists{};
|
QMap<QString, UserDeviceList> device_lists{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
using namespace QXmpp::Factories;
|
using namespace QXmpp::Factories;
|
||||||
|
|
||||||
QXmppElement QXmpp::Omemo::DeviceList::toXml() const {
|
QXmppElement QXmpp::Omemo::DeviceList::toXml() const {
|
||||||
auto element = createElement("devices", "urn:xmpp:omemo:1");
|
auto element = createElement("list", "eu.siacs.conversations.axolotl");
|
||||||
|
|
||||||
for (const auto &d : devices) {
|
for (const auto &d : devices) {
|
||||||
element.appendChild(d.toXml());
|
element.appendChild(d.toXml());
|
||||||
@ -28,11 +28,10 @@ QXmppIq QXmpp::Omemo::DeviceList::toIq() const {
|
|||||||
iq.setType(QXmppIq::Set);
|
iq.setType(QXmppIq::Set);
|
||||||
|
|
||||||
auto item = createElement("item");
|
auto item = createElement("item");
|
||||||
item.setAttribute("id", "current");
|
|
||||||
item.appendChild(toXml());
|
item.appendChild(toXml());
|
||||||
|
|
||||||
auto publish = createElement("publish");
|
auto publish = createElement("publish");
|
||||||
publish.setAttribute("node", "urn:xmpp:omemo:1:devices");
|
publish.setAttribute("node", "eu.siacs.conversations.axolotl.devicelist");
|
||||||
publish.appendChild(item);
|
publish.appendChild(item);
|
||||||
|
|
||||||
auto pubSub = createElement("pubsub", "http://jabber.org/protocol/pubsub");
|
auto pubSub = createElement("pubsub", "http://jabber.org/protocol/pubsub");
|
||||||
@ -45,7 +44,7 @@ QXmppIq QXmpp::Omemo::DeviceList::toIq() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QXmpp::Omemo::DeviceList::fromXml(const QXmppElement &element) {
|
void QXmpp::Omemo::DeviceList::fromXml(const QXmppElement &element) {
|
||||||
if (!elementMatches(element, "devices", "urn:xmpp:omemo:1"))
|
if (!elementMatches(element, "list", "eu.siacs.conversations.axolotl"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
devices.clear();
|
devices.clear();
|
||||||
@ -64,10 +63,6 @@ QXmppElement QXmpp::Omemo::Device::toXml() const {
|
|||||||
auto result = createElement("device");
|
auto result = createElement("device");
|
||||||
result.setAttribute("id", QString::number(id));
|
result.setAttribute("id", QString::number(id));
|
||||||
|
|
||||||
if (!label.isEmpty()) {
|
|
||||||
result.setAttribute("label", label);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,12 +71,11 @@ void QXmpp::Omemo::Device::fromXml(const QXmppElement &element) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
id = element.attribute("id").toInt();
|
id = element.attribute("id").toInt();
|
||||||
label = element.attribute("label");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QXmppElement QXmpp::Omemo::PreKey::toXml() const {
|
QXmppElement QXmpp::Omemo::PreKey::toXml() const {
|
||||||
auto pk = createElement("pk");
|
auto pk = createElement("preKeyPublic");
|
||||||
pk.setAttribute("id", QString::number(id));
|
pk.setAttribute("preKeyId", QString::number(id));
|
||||||
// TODO: Base64
|
// TODO: Base64
|
||||||
pk.setValue(data);
|
pk.setValue(data);
|
||||||
|
|
||||||
@ -89,23 +83,23 @@ QXmppElement QXmpp::Omemo::PreKey::toXml() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QXmpp::Omemo::PreKey::fromXml(const QXmppElement &element) {
|
void QXmpp::Omemo::PreKey::fromXml(const QXmppElement &element) {
|
||||||
if (!elementMatches(element, "pk"))
|
if (!elementMatches(element, "preKeyPublic"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
id = element.attribute("id").toInt();
|
id = element.attribute("preKeyId").toInt();
|
||||||
// TODO: Base64
|
// TODO: Base64
|
||||||
data = element.value();
|
data = element.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
QXmppElement QXmpp::Omemo::Bundle::toXml() const {
|
QXmppElement QXmpp::Omemo::Bundle::toXml() const {
|
||||||
auto spkNode = createElement("spk");
|
auto spkNode = createElement("signedPreKeyPublic");
|
||||||
spkNode.setAttribute("id", QString::number(spkId));
|
spkNode.setAttribute("signedPreKeyId", QString::number(spkId));
|
||||||
spkNode.setValue(spk);
|
spkNode.setValue(spk);
|
||||||
|
|
||||||
auto spksNode = createElement("spks");
|
auto spksNode = createElement("signedPreKeySignature");
|
||||||
spksNode.setValue(spks);
|
spksNode.setValue(spks);
|
||||||
|
|
||||||
auto ikNode = createElement("ik");
|
auto ikNode = createElement("identityKey");
|
||||||
ikNode.setValue(ik);
|
ikNode.setValue(ik);
|
||||||
|
|
||||||
auto prekeysNode = createElement("prekeys");
|
auto prekeysNode = createElement("prekeys");
|
||||||
@ -113,7 +107,7 @@ QXmppElement QXmpp::Omemo::Bundle::toXml() const {
|
|||||||
prekeysNode.appendChild(pk.toXml());
|
prekeysNode.appendChild(pk.toXml());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = createElement("bundle", "urn:xmpp:omemo:1");
|
auto result = createElement("bundle", "eu.siacs.conversations.axolotl");
|
||||||
result.appendChild(spkNode);
|
result.appendChild(spkNode);
|
||||||
result.appendChild(spksNode);
|
result.appendChild(spksNode);
|
||||||
result.appendChild(ikNode);
|
result.appendChild(ikNode);
|
||||||
@ -122,22 +116,21 @@ QXmppElement QXmpp::Omemo::Bundle::toXml() const {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QXmppIq QXmpp::Omemo::Bundle::toIq() const {
|
QXmppIq QXmpp::Omemo::Bundle::toIq(int deviceId) const {
|
||||||
QXmppIq iq{};
|
QXmppIq iq{};
|
||||||
|
|
||||||
iq.setType(QXmppIq::Set);
|
iq.setType(QXmppIq::Set);
|
||||||
|
|
||||||
auto item = createElement("item");
|
auto item = createElement("item");
|
||||||
item.setAttribute("id", QString::number(deviceId));
|
|
||||||
item.appendChild(toXml());
|
item.appendChild(toXml());
|
||||||
|
|
||||||
auto publish = createElement("publish");
|
auto publish = createElement("publish");
|
||||||
publish.setAttribute("node", "urn:xmpp:omemo:1:bundles");
|
publish.setAttribute("node", QString("eu.siacs.conversations.axolotl.bundles:%s").arg(deviceId));
|
||||||
publish.appendChild(item);
|
publish.appendChild(item);
|
||||||
|
|
||||||
auto pubSub = createElement("pubsub", "http://jabber.org/protocol/pubsub");
|
auto pubSub = createElement("pubsub", "http://jabber.org/protocol/pubsub");
|
||||||
pubSub.appendChild(publish);
|
pubSub.appendChild(publish);
|
||||||
pubSub.appendChild(createOpenPublishOptions("max"));
|
pubSub.appendChild(createOpenPublishOptions());
|
||||||
|
|
||||||
iq.extensions().push_back(pubSub);
|
iq.extensions().push_back(pubSub);
|
||||||
|
|
||||||
@ -145,7 +138,7 @@ QXmppIq QXmpp::Omemo::Bundle::toIq() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QXmpp::Omemo::Bundle::fromXml(const QXmppElement &element) {
|
void QXmpp::Omemo::Bundle::fromXml(const QXmppElement &element) {
|
||||||
if (!elementMatches(element, "bundle", "urn:xmpp:omemo:1"))
|
if (!elementMatches(element, "bundle", "eu.siacs.conversations.axolotl"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto spkNode = element.firstChildElement("spk");
|
auto spkNode = element.firstChildElement("spk");
|
||||||
@ -184,7 +177,7 @@ void QXmpp::Omemo::Bundle::fromXml(const QXmppElement &element) {
|
|||||||
QXmppPubSubIq QXmpp::Omemo::Bundle::fetchDeviceBundleIq(int deviceId) {
|
QXmppPubSubIq QXmpp::Omemo::Bundle::fetchDeviceBundleIq(int deviceId) {
|
||||||
QXmppPubSubIq iq{};
|
QXmppPubSubIq iq{};
|
||||||
iq.setType(QXmppIq::Get);
|
iq.setType(QXmppIq::Get);
|
||||||
iq.setQueryNode("urn:xmpp:omemo:1:bundles");
|
iq.setQueryNode(QString("eu.siacs.conversations.axolotl.bundles:%1").arg(deviceId));
|
||||||
|
|
||||||
QXmppPubSubItem item{};
|
QXmppPubSubItem item{};
|
||||||
item.setId(QString::number(deviceId));
|
item.setId(QString::number(deviceId));
|
||||||
@ -197,13 +190,8 @@ QXmppElement QXmpp::Omemo::EncryptedMessage::header() const {
|
|||||||
auto result = createElement("header");
|
auto result = createElement("header");
|
||||||
result.setAttribute("sid", QString::number(fromDeviceId));
|
result.setAttribute("sid", QString::number(fromDeviceId));
|
||||||
|
|
||||||
return result;
|
auto ivNode = createElement("iv");
|
||||||
}
|
ivNode.setValue(iv);
|
||||||
|
|
||||||
QXmppElement QXmpp::Omemo::EncryptedMessage::toXml() const {
|
|
||||||
auto result = createElement("encrypted", "urn:xmpp:omemo:1");
|
|
||||||
|
|
||||||
result.appendChild(header());
|
|
||||||
|
|
||||||
for (const auto &key : keys) {
|
for (const auto &key : keys) {
|
||||||
result.appendChild(key.toXml());
|
result.appendChild(key.toXml());
|
||||||
@ -212,6 +200,16 @@ QXmppElement QXmpp::Omemo::EncryptedMessage::toXml() const {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QXmppElement QXmpp::Omemo::EncryptedMessage::toXml() const {
|
||||||
|
auto result = createElement("encrypted", "eu.siacs.conversations.axolotl");
|
||||||
|
|
||||||
|
result.appendChild(header());
|
||||||
|
// TODO: Payload is optional
|
||||||
|
result.appendChild(payload());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
QXmppElement QXmpp::Omemo::EncryptedMessage::payload() const {
|
QXmppElement QXmpp::Omemo::EncryptedMessage::payload() const {
|
||||||
QBuffer buffer;
|
QBuffer buffer;
|
||||||
buffer.open(QIODevice::ReadWrite);
|
buffer.open(QIODevice::ReadWrite);
|
||||||
@ -260,21 +258,11 @@ QXmppElement QXmpp::Omemo::EncryptedMessage::content() const {
|
|||||||
QXmppElement QXmpp::Omemo::MessageKey::toXml() const {
|
QXmppElement QXmpp::Omemo::MessageKey::toXml() const {
|
||||||
auto result = createElement("key");
|
auto result = createElement("key");
|
||||||
|
|
||||||
if (kex)
|
result.setAttribute("rid", QString::number(receivingDeviceId));
|
||||||
result.setAttribute("kex", "true");
|
if (prekey)
|
||||||
|
result.setAttribute("prekey", "true");
|
||||||
|
|
||||||
result.setValue(key);
|
result.setValue(key);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QXmppElement QXmpp::Omemo::HeaderKeys::toXml() const {
|
|
||||||
auto result = createElement("keys");
|
|
||||||
result.setAttribute("jid", jid);
|
|
||||||
|
|
||||||
for (const auto &key : keys) {
|
|
||||||
result.appendChild(key.toXml());
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,6 @@ public:
|
|||||||
void fromXml(const QXmppElement &element);
|
void fromXml(const QXmppElement &element);
|
||||||
|
|
||||||
int id;
|
int id;
|
||||||
QString label;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeviceList {
|
class DeviceList {
|
||||||
@ -27,7 +26,6 @@ public:
|
|||||||
/// Expects a urn:xmpp:omemo:1:devices node
|
/// Expects a urn:xmpp:omemo:1:devices node
|
||||||
void fromXml(const QXmppElement &element);
|
void fromXml(const QXmppElement &element);
|
||||||
|
|
||||||
private:
|
|
||||||
QList<Device> devices;
|
QList<Device> devices;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,11 +44,9 @@ public:
|
|||||||
[[nodiscard]] static QXmppPubSubIq fetchDeviceBundleIq(int deviceId);
|
[[nodiscard]] static QXmppPubSubIq fetchDeviceBundleIq(int deviceId);
|
||||||
|
|
||||||
[[nodiscard]] QXmppElement toXml() const;
|
[[nodiscard]] QXmppElement toXml() const;
|
||||||
[[nodiscard]] QXmppIq toIq() const;
|
[[nodiscard]] QXmppIq toIq(int deviceId) const;
|
||||||
void fromXml(const QXmppElement &element);
|
void fromXml(const QXmppElement &element);
|
||||||
|
|
||||||
int deviceId;
|
|
||||||
|
|
||||||
QString spk;
|
QString spk;
|
||||||
int spkId;
|
int spkId;
|
||||||
QString spks;
|
QString spks;
|
||||||
@ -62,18 +58,11 @@ class MessageKey {
|
|||||||
public:
|
public:
|
||||||
[[nodiscard]] QXmppElement toXml() const;
|
[[nodiscard]] QXmppElement toXml() const;
|
||||||
|
|
||||||
bool kex{};
|
int receivingDeviceId{};
|
||||||
|
bool prekey{};
|
||||||
QString key{};
|
QString key{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class HeaderKeys {
|
|
||||||
public:
|
|
||||||
[[nodiscard]] QXmppElement toXml() const;
|
|
||||||
|
|
||||||
QString jid{};
|
|
||||||
QList<MessageKey> keys{};
|
|
||||||
};
|
|
||||||
|
|
||||||
class EncryptedMessage {
|
class EncryptedMessage {
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] QXmppElement header() const;
|
[[nodiscard]] QXmppElement header() const;
|
||||||
@ -83,11 +72,13 @@ public:
|
|||||||
|
|
||||||
int fromDeviceId{};
|
int fromDeviceId{};
|
||||||
|
|
||||||
QList<HeaderKeys> keys{};
|
QList<MessageKey> keys{};
|
||||||
QString from{};
|
QString from{};
|
||||||
QString to{};
|
QString to{};
|
||||||
QDateTime timestamp{};
|
QDateTime timestamp{};
|
||||||
|
|
||||||
|
QString iv{};
|
||||||
|
|
||||||
QXmppMessage message{};
|
QXmppMessage message{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
66
qomemo/qxmpp_omemo_manager.cpp
Normal file
66
qomemo/qxmpp_omemo_manager.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Created by victoria on 2021-05-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "qxmpp_omemo_manager.h"
|
||||||
|
|
||||||
|
#include <QDomElement>
|
||||||
|
|
||||||
|
#include <QXmppClient.h>
|
||||||
|
#include <QXmppPubSubIq.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
QXmpp::Omemo::Manager::Manager() : deviceService(new QXmpp::Omemo::DeviceService(this)) {
|
||||||
|
connect(this, &Manager::deviceListReceived, deviceService.get(), &DeviceService::onDeviceListReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QXmpp::Omemo::Manager::handleStanza(const QDomElement &stanza) {
|
||||||
|
QString str{};
|
||||||
|
QTextStream info(&str);
|
||||||
|
stanza.save(info, 4);
|
||||||
|
|
||||||
|
std::cout << str.toStdString();
|
||||||
|
|
||||||
|
if (stanza.tagName() == "iq") {
|
||||||
|
if (stanza.attribute("type") == "result") {
|
||||||
|
auto pubsub = stanza.firstChildElement("pubsub");
|
||||||
|
if (!pubsub.isNull()) {
|
||||||
|
auto items = pubsub.firstChildElement("items");
|
||||||
|
if (items.attribute("node") == "eu.siacs.conversations.axolotl.devicelist") {
|
||||||
|
auto item = items.firstChildElement("item");
|
||||||
|
if (!item.isNull()) {
|
||||||
|
auto list = item.firstChildElement("list");
|
||||||
|
if (!list.isNull()) {
|
||||||
|
DeviceList deviceList{};
|
||||||
|
deviceList.fromXml(list);
|
||||||
|
emit deviceListReceived(stanza.attribute("from"), deviceList);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QXmpp::Omemo::Manager::setClient(QXmppClient *client) {
|
||||||
|
QXmppClientExtension::setClient(client);
|
||||||
|
|
||||||
|
if (!client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QObject::connect(client, &QXmppClient::connected, this, &Manager::fetchOwnDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QXmpp::Omemo::Manager::fetchOwnDevices() {
|
||||||
|
QXmppPubSubIq iq{};
|
||||||
|
iq.setFrom(client()->configuration().jid());
|
||||||
|
iq.setTo(client()->configuration().jidBare());
|
||||||
|
iq.setType(QXmppIq::Get);
|
||||||
|
iq.setQueryNode("eu.siacs.conversations.axolotl.devicelist");
|
||||||
|
|
||||||
|
client()->sendPacket(iq);
|
||||||
|
}
|
36
qomemo/qxmpp_omemo_manager.h
Normal file
36
qomemo/qxmpp_omemo_manager.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Created by victoria on 2021-05-12.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "device_service.h"
|
||||||
|
#include "qomemo.h"
|
||||||
|
|
||||||
|
#include <QXmppClientExtension.h>
|
||||||
|
|
||||||
|
namespace QXmpp::Omemo {
|
||||||
|
|
||||||
|
class Manager : public QXmppClientExtension {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Manager();
|
||||||
|
~Manager() override = default;
|
||||||
|
|
||||||
|
bool handleStanza(const QDomElement &stanza) override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void fetchOwnDevices();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void deviceListReceived(const QString& jid, const DeviceList& list);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setClient(QXmppClient *client) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QScopedPointer<DeviceService> deviceService;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QXmpp::Omemo
|
Loading…
Reference in New Issue
Block a user