From c5642526513363608d538417d0e50e00f9cd5e46 Mon Sep 17 00:00:00 2001 From: Jonah Brüchert Date: Thu, 9 Mar 2023 13:30:58 +0100 Subject: Fix compilation on MSVC 2019 --- src/base/QXmppPromise.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/QXmppPromise.h b/src/base/QXmppPromise.h index 4900dae1..6408ad0c 100644 --- a/src/base/QXmppPromise.h +++ b/src/base/QXmppPromise.h @@ -45,7 +45,7 @@ public: #ifdef QXMPP_DOC void reportFinished(T &&value) #else - template && std::is_same_v> * = nullptr> + template && std::is_same_v> * = nullptr> void finish(U &&value) #endif { @@ -61,7 +61,7 @@ public: } /// \cond - template && std::is_constructible_v && !std::is_same_v> * = nullptr> + template && std::is_constructible_v && !std::is_same_v> * = nullptr> void finish(U &&value) { Q_ASSERT(!d.isFinished()); -- cgit v1.2.3 From 72571909c4b0e95f1b5ab3865de2b25fe859b367 Mon Sep 17 00:00:00 2001 From: Melvin Keskin Date: Sat, 4 Mar 2023 01:09:23 +0100 Subject: Organize OMEMO includes --- src/base/QXmppOmemoElement_p.h | 2 +- src/omemo/QXmppOmemoData.cpp | 2 -- src/omemo/QXmppOmemoDeviceList_p.h | 2 +- src/omemo/QXmppOmemoManager.cpp | 3 --- tests/qxmppomemomanager/tst_qxmppomemomanager.cpp | 2 -- 5 files changed, 2 insertions(+), 9 deletions(-) (limited to 'src/base') diff --git a/src/base/QXmppOmemoElement_p.h b/src/base/QXmppOmemoElement_p.h index 1e160479..cd95ea00 100644 --- a/src/base/QXmppOmemoElement_p.h +++ b/src/base/QXmppOmemoElement_p.h @@ -7,13 +7,13 @@ #define QXMPPOMEMOELEMENT_H #include "QXmppGlobal.h" +#include "QXmppOmemoEnvelope_p.h" #include #include class QDomElement; -class QXmppOmemoEnvelope; class QXmlStreamWriter; class QXMPP_EXPORT QXmppOmemoElement diff --git a/src/omemo/QXmppOmemoData.cpp b/src/omemo/QXmppOmemoData.cpp index d1dd2a88..d457326a 100644 --- a/src/omemo/QXmppOmemoData.cpp +++ b/src/omemo/QXmppOmemoData.cpp @@ -8,10 +8,8 @@ #include "QXmppOmemoDeviceElement_p.h" #include "QXmppOmemoDeviceList_p.h" #include "QXmppOmemoElement_p.h" -#include "QXmppOmemoEnvelope_p.h" #include "QXmppOmemoIq_p.h" #include "QXmppOmemoItems_p.h" -#include "QXmppUtils.h" #include #include diff --git a/src/omemo/QXmppOmemoDeviceList_p.h b/src/omemo/QXmppOmemoDeviceList_p.h index 76bff435..46ac724d 100644 --- a/src/omemo/QXmppOmemoDeviceList_p.h +++ b/src/omemo/QXmppOmemoDeviceList_p.h @@ -7,12 +7,12 @@ #define QXMPPOMEMODEVICELIST_H #include "QXmppGlobal.h" +#include "QXmppOmemoDeviceElement_p.h" #include "QList" class QDomElement; class QXmlStreamWriter; -class QXmppOmemoDeviceElement; class QXMPP_AUTOTEST_EXPORT QXmppOmemoDeviceList : public QList { diff --git a/src/omemo/QXmppOmemoManager.cpp b/src/omemo/QXmppOmemoManager.cpp index 7b38c73e..f3137889 100644 --- a/src/omemo/QXmppOmemoManager.cpp +++ b/src/omemo/QXmppOmemoManager.cpp @@ -5,10 +5,7 @@ #include "QXmppClient.h" #include "QXmppConstants_p.h" -#include "QXmppOmemoDeviceElement_p.h" -#include "QXmppOmemoDeviceList_p.h" #include "QXmppOmemoElement_p.h" -#include "QXmppOmemoEnvelope_p.h" #include "QXmppOmemoIq_p.h" #include "QXmppOmemoItems_p.h" #include "QXmppOmemoManager_p.h" diff --git a/tests/qxmppomemomanager/tst_qxmppomemomanager.cpp b/tests/qxmppomemomanager/tst_qxmppomemomanager.cpp index 95c70237..e6d2c7ed 100644 --- a/tests/qxmppomemomanager/tst_qxmppomemomanager.cpp +++ b/tests/qxmppomemomanager/tst_qxmppomemomanager.cpp @@ -12,11 +12,9 @@ #include "QXmppE2eeMetadata.h" #include "QXmppMessage.h" #include "QXmppOmemoElement_p.h" -#include "QXmppOmemoEnvelope_p.h" #include "QXmppOmemoManager.h" #include "QXmppOmemoManager_p.h" #include "QXmppOmemoMemoryStorage.h" -#include "QXmppPubSubItem.h" #include "QXmppPubSubManager.h" #include "IntegrationTesting.h" -- cgit v1.2.3 From 18353901a2215376e2f0274a408ce2213c180f16 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Thu, 9 Mar 2023 17:36:17 +0100 Subject: SaslDigestMd5: Fix UB when at the end of input byte array [Qt6 only] Also adds a unit test. Fixes #541. --- src/base/QXmppSasl.cpp | 8 ++++++-- tests/qxmppsasl/tst_qxmppsasl.cpp | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'src/base') diff --git a/src/base/QXmppSasl.cpp b/src/base/QXmppSasl.cpp index d8a86bb0..86e67b01 100644 --- a/src/base/QXmppSasl.cpp +++ b/src/base/QXmppSasl.cpp @@ -896,8 +896,12 @@ QMap QXmppSaslDigestMd5::parseMessage(const QByteArray & const QByteArray key = ba.mid(startIndex, pos - startIndex).trimmed(); pos++; - // check whether string is quoted - if (ba.at(pos) == '"') { + if (pos == ba.size()) { + // end of the input + map.insert(key, QByteArray()); + startIndex = pos; + } else if (ba.at(pos) == '"') { + // check whether string is quoted // skip opening quote pos++; int endPos = ba.indexOf('"', pos); diff --git a/tests/qxmppsasl/tst_qxmppsasl.cpp b/tests/qxmppsasl/tst_qxmppsasl.cpp index 951af0b4..88dd5673 100644 --- a/tests/qxmppsasl/tst_qxmppsasl.cpp +++ b/tests/qxmppsasl/tst_qxmppsasl.cpp @@ -28,6 +28,7 @@ private: Q_SLOT void testClientAnonymous(); Q_SLOT void testClientDigestMd5(); Q_SLOT void testClientDigestMd5_data(); + Q_SLOT void testDigestMd5ParseMessage(); Q_SLOT void testClientFacebook(); Q_SLOT void testClientGoogle(); Q_SLOT void testClientPlain(); @@ -220,6 +221,15 @@ void tst_QXmppSasl::testClientDigestMd5_data() QTest::newRow("qop-multi") << QByteArray(",qop=\"auth,auth-int\""); } +void tst_QXmppSasl::testDigestMd5ParseMessage() +{ + auto result = QXmppSaslDigestMd5::parseMessage("charset=utf-8,digest-uri=\"xmpp/0.0.0.0\",nc=00000001,qop=auth,realm=0.0.0.0,response=9c3ee0a919d714c9d72853ff51c0a4f3,username="); + QCOMPARE(result["username"], QByteArray()); + + result = QXmppSaslDigestMd5::parseMessage("nc=00000001,username=,qop=auth,realm=0.0.0.0,response=9c3ee0a919d714c9d72853ff51c0a4f3"); + QCOMPARE(result["username"], QByteArray()); +} + void tst_QXmppSasl::testClientDigestMd5() { QFETCH(QByteArray, qop); -- cgit v1.2.3 From fcd8224256e38d50d4ec67b71c504dcb6e480e95 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Thu, 9 Mar 2023 18:48:21 +0100 Subject: Rename PubSubItem -> PubSubBaseItem to be able to include old PubSubItem --- src/CMakeLists.txt | 4 +- src/base/QXmppGeolocItem.cpp | 2 +- src/base/QXmppGeolocItem.h | 4 +- src/base/QXmppMixInfoItem.h | 4 +- src/base/QXmppMixItems.cpp | 4 +- src/base/QXmppMixParticipantItem.h | 4 +- src/base/QXmppPubSubBaseItem.cpp | 152 +++++++++++++++++++++ src/base/QXmppPubSubBaseItem.h | 87 ++++++++++++ src/base/QXmppPubSubEvent.h | 4 +- src/base/QXmppPubSubIq_p.h | 4 +- src/base/QXmppPubSubItem.cpp | 152 --------------------- src/base/QXmppPubSubItem.h | 90 ------------ src/base/QXmppUserTuneItem.cpp | 2 +- src/base/QXmppUserTuneItem.h | 4 +- src/client/QXmppPubSubManager.cpp | 10 +- src/client/QXmppPubSubManager.h | 14 +- src/omemo/QXmppOmemoData.cpp | 4 +- src/omemo/QXmppOmemoItems_p.h | 6 +- src/omemo/QXmppOmemoManager_p.cpp | 2 +- tests/pubsubutil.h | 8 +- tests/qxmpppubsub/tst_qxmpppubsub.cpp | 8 +- tests/qxmpppubsubevent/tst_qxmpppubsubevent.cpp | 22 +-- tests/qxmpppubsubiq/tst_qxmpppubsubiq.cpp | 6 +- .../qxmpppubsubmanager/tst_qxmpppubsubmanager.cpp | 20 +-- 24 files changed, 307 insertions(+), 310 deletions(-) create mode 100644 src/base/QXmppPubSubBaseItem.cpp create mode 100644 src/base/QXmppPubSubBaseItem.h delete mode 100644 src/base/QXmppPubSubItem.cpp delete mode 100644 src/base/QXmppPubSubItem.h (limited to 'src/base') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4a260a7b..0f533a01 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -52,7 +52,7 @@ set(INSTALL_HEADER_FILES base/QXmppPubSubAffiliation.h base/QXmppPubSubEvent.h base/QXmppPubSubIq_p.h - base/QXmppPubSubItem.h + base/QXmppPubSubBaseItem.h base/QXmppPubSubMetadata.h base/QXmppPubSubNodeConfig.h base/QXmppPubSubPublishOptions.h @@ -184,7 +184,7 @@ set(SOURCE_FILES base/QXmppPubSubAffiliation.cpp base/QXmppPubSubEvent.cpp base/QXmppPubSubIq.cpp - base/QXmppPubSubItem.cpp + base/QXmppPubSubBaseItem.cpp base/QXmppPubSubMetadata.cpp base/QXmppPubSubNodeConfig.cpp base/QXmppPubSubSubscribeOptions.cpp diff --git a/src/base/QXmppGeolocItem.cpp b/src/base/QXmppGeolocItem.cpp index b6bf0b85..32e08189 100644 --- a/src/base/QXmppGeolocItem.cpp +++ b/src/base/QXmppGeolocItem.cpp @@ -146,7 +146,7 @@ bool QXmppGeolocItem::isItem(const QDomElement &itemElement) payload.namespaceURI() == ns_geoloc; }; - return QXmppPubSubItem::isItem(itemElement, isPayloadValid); + return QXmppPubSubBaseItem::isItem(itemElement, isPayloadValid); } /// \cond diff --git a/src/base/QXmppGeolocItem.h b/src/base/QXmppGeolocItem.h index 05d42dba..58914b1b 100644 --- a/src/base/QXmppGeolocItem.h +++ b/src/base/QXmppGeolocItem.h @@ -5,7 +5,7 @@ #ifndef QXMPPGEOLOCITEM_H #define QXMPPGEOLOCITEM_H -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" #include @@ -13,7 +13,7 @@ class QXmppGeolocItemPrivate; -class QXMPP_EXPORT QXmppGeolocItem : public QXmppPubSubItem +class QXMPP_EXPORT QXmppGeolocItem : public QXmppPubSubBaseItem { public: QXmppGeolocItem(); diff --git a/src/base/QXmppMixInfoItem.h b/src/base/QXmppMixInfoItem.h index 9a28decb..313c3e14 100644 --- a/src/base/QXmppMixInfoItem.h +++ b/src/base/QXmppMixInfoItem.h @@ -5,11 +5,11 @@ #ifndef QXMPPMIXINFOITEM_H #define QXMPPMIXINFOITEM_H -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" class QXmppMixInfoItemPrivate; -class QXMPP_EXPORT QXmppMixInfoItem : public QXmppPubSubItem +class QXMPP_EXPORT QXmppMixInfoItem : public QXmppPubSubBaseItem { public: QXmppMixInfoItem(); diff --git a/src/base/QXmppMixItems.cpp b/src/base/QXmppMixItems.cpp index e08dd3f2..a19edbb0 100644 --- a/src/base/QXmppMixItems.cpp +++ b/src/base/QXmppMixItems.cpp @@ -138,7 +138,7 @@ void QXmppMixInfoItem::setContactJids(QStringList contactJids) /// bool QXmppMixInfoItem::isItem(const QDomElement &element) { - return QXmppPubSubItem::isItem(element, [](const QDomElement &payload) { + return QXmppPubSubBaseItem::isItem(element, [](const QDomElement &payload) { // check FORM_TYPE without parsing a full QXmppDataForm if (payload.tagName() != u'x' || payload.namespaceURI() != ns_data) { return false; @@ -264,7 +264,7 @@ void QXmppMixParticipantItem::serializePayload(QXmlStreamWriter *writer) const /// bool QXmppMixParticipantItem::isItem(const QDomElement &element) { - return QXmppPubSubItem::isItem(element, [](const QDomElement &payload) { + return QXmppPubSubBaseItem::isItem(element, [](const QDomElement &payload) { return payload.tagName() == QStringLiteral("participant") && payload.namespaceURI() == ns_mix; }); diff --git a/src/base/QXmppMixParticipantItem.h b/src/base/QXmppMixParticipantItem.h index f0f2abaa..ce179fbe 100644 --- a/src/base/QXmppMixParticipantItem.h +++ b/src/base/QXmppMixParticipantItem.h @@ -5,11 +5,11 @@ #ifndef QXMPPMIXPARTICIPANTITEM_H #define QXMPPMIXPARTICIPANTITEM_H -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" class QXmppMixParticipantItemPrivate; -class QXMPP_EXPORT QXmppMixParticipantItem : public QXmppPubSubItem +class QXMPP_EXPORT QXmppMixParticipantItem : public QXmppPubSubBaseItem { public: QXmppMixParticipantItem(); diff --git a/src/base/QXmppPubSubBaseItem.cpp b/src/base/QXmppPubSubBaseItem.cpp new file mode 100644 index 00000000..43b1aa88 --- /dev/null +++ b/src/base/QXmppPubSubBaseItem.cpp @@ -0,0 +1,152 @@ +// SPDX-FileCopyrightText: 2019 Jeremy Lainé +// SPDX-FileCopyrightText: 2019 Linus Jahn +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include "QXmppPubSubBaseItem.h" + +#include "QXmppElement.h" +#include "QXmppUtils.h" + +#include + +class QXmppPubSubBaseItemPrivate : public QSharedData +{ +public: + QXmppPubSubBaseItemPrivate(const QString &id, const QString &publisher); + + QString id; + QString publisher; +}; + +QXmppPubSubBaseItemPrivate::QXmppPubSubBaseItemPrivate(const QString &id, const QString &publisher) + : id(id), publisher(publisher) +{ +} + +/// +/// \class QXmppPubSubBaseItem +/// +/// The QXmppPubSubBaseItem class represents a publish-subscribe item as defined by +/// \xep{0060, Publish-Subscribe}. +/// +/// To access the payload of an item, you need to create a derived class of this +/// and override QXmppPubSubBaseItem::parsePayload() and +/// QXmppPubSubBaseItem::serializePayload(). +/// +/// It is also required that you override QXmppPubSubBaseItem::isItem() and also +/// check for the correct payload of the PubSub item. This can be easily done by +/// using the protected overload of isItem() with an function that checks the +/// tag name and namespace of the payload. The function is only called if a +/// payload exists. +/// +/// In short, you need to reimplement these methods: +/// * QXmppPubSubBaseItem::parsePayload() +/// * QXmppPubSubBaseItem::serializePayload() +/// * QXmppPubSubBaseItem::isItem() +/// +/// \since QXmpp 1.5 +/// + +/// +/// Constructs an item with \a id and \a publisher. +/// +/// \param id +/// \param publisher +/// +QXmppPubSubBaseItem::QXmppPubSubBaseItem(const QString &id, const QString &publisher) + : d(new QXmppPubSubBaseItemPrivate(id, publisher)) +{ +} + +/// Default copy-constructor +QXmppPubSubBaseItem::QXmppPubSubBaseItem(const QXmppPubSubBaseItem &iq) = default; +/// Default move-constructor +QXmppPubSubBaseItem::QXmppPubSubBaseItem(QXmppPubSubBaseItem &&) = default; +QXmppPubSubBaseItem::~QXmppPubSubBaseItem() = default; +/// Default assignment operator +QXmppPubSubBaseItem &QXmppPubSubBaseItem::operator=(const QXmppPubSubBaseItem &iq) = default; +/// Default move-assignment operator +QXmppPubSubBaseItem &QXmppPubSubBaseItem::operator=(QXmppPubSubBaseItem &&iq) = default; + +/// +/// Returns the ID of the PubSub item. +/// +QString QXmppPubSubBaseItem::id() const +{ + return d->id; +} + +/// +/// Sets the ID of the PubSub item. +/// +/// \param id +/// +void QXmppPubSubBaseItem::setId(const QString &id) +{ + d->id = id; +} + +/// +/// Returns the JID of the publisher of the item. +/// +QString QXmppPubSubBaseItem::publisher() const +{ + return d->publisher; +} + +/// +/// Sets the JID of the publisher of the item. +/// +void QXmppPubSubBaseItem::setPublisher(const QString &publisher) +{ + d->publisher = publisher; +} + +/// \cond +void QXmppPubSubBaseItem::parse(const QDomElement &element) +{ + d->id = element.attribute(QStringLiteral("id")); + d->publisher = element.attribute(QStringLiteral("publisher")); + + parsePayload(element.firstChildElement()); +} + +void QXmppPubSubBaseItem::toXml(QXmlStreamWriter *writer) const +{ + writer->writeStartElement(QStringLiteral("item")); + helperToXmlAddAttribute(writer, QStringLiteral("id"), d->id); + helperToXmlAddAttribute(writer, QStringLiteral("publisher"), d->publisher); + + serializePayload(writer); + + writer->writeEndElement(); +} +/// \endcond + +/// +/// Returns true, if the element is possibly a PubSub item. +/// +bool QXmppPubSubBaseItem::isItem(const QDomElement &element) +{ + return element.tagName() == QStringLiteral("item"); +} + +/// +/// Parses the payload of the item (the child element of the <item/>). +/// +/// This method needs to be overriden to perform the payload-specific parsing. +/// +void QXmppPubSubBaseItem::parsePayload(const QDomElement &) +{ +} + +/// +/// Serializes the payload of the item (the child element of the <item/>). +/// +/// This method needs to be overriden to perform the payload-specific +/// serialization. +/// +void QXmppPubSubBaseItem::serializePayload(QXmlStreamWriter *) const +{ +} diff --git a/src/base/QXmppPubSubBaseItem.h b/src/base/QXmppPubSubBaseItem.h new file mode 100644 index 00000000..20702662 --- /dev/null +++ b/src/base/QXmppPubSubBaseItem.h @@ -0,0 +1,87 @@ +// SPDX-FileCopyrightText: 2019 Jeremy Lainé +// SPDX-FileCopyrightText: 2019 Linus Jahn +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#pragma once + +#include "QXmppGlobal.h" + +#include +#include +#include + +class QXmlStreamWriter; +class QXmppPubSubBaseItemPrivate; + +class QXMPP_EXPORT QXmppPubSubBaseItem +{ +public: + QXmppPubSubBaseItem(const QString &id = {}, const QString &publisher = {}); + QXmppPubSubBaseItem(const QXmppPubSubBaseItem &); + QXmppPubSubBaseItem(QXmppPubSubBaseItem &&); + virtual ~QXmppPubSubBaseItem(); + + QXmppPubSubBaseItem &operator=(const QXmppPubSubBaseItem &); + QXmppPubSubBaseItem &operator=(QXmppPubSubBaseItem &&); + + QString id() const; + void setId(const QString &id); + + QString publisher() const; + void setPublisher(const QString &publisher); + + /// \cond + void parse(const QDomElement &element); + void toXml(QXmlStreamWriter *writer) const; + /// \endcond + + static bool isItem(const QDomElement &element); + +protected: + virtual void parsePayload(const QDomElement &payloadElement); + virtual void serializePayload(QXmlStreamWriter *writer) const; + + template + static bool isItem(const QDomElement &element, PayloadChecker isPayloadValid); + +private: + QSharedDataPointer d; +}; + +/// +/// Returns true, if the element is a valid PubSub item and (if existant) the +/// payload is correct. +/// +/// \param element The element to be checked to be an <item/> element. +/// \param isPayloadValid A function that validates the payload element (first +/// child element). The functions needs to return true, if the payload is valid. +/// In case there is no payload, the function is not called. +/// +/// Here is an example covering how this could be used to check for the +/// \xep{0118, User Tune} payload: +/// \code +/// auto isPayloadValid = [](const QDomElement &payload) -> bool { +/// return payload.tagName() == "tune" && payload.namespaceURI() == ns_tune; +/// }; +/// +/// bool valid = QXmppPubSubItem::isItem(itemElement, isPayloadValid); +/// \endcode +/// +template +bool QXmppPubSubBaseItem::isItem(const QDomElement &element, PayloadChecker isPayloadValid) +{ + if (!isItem(element)) { + return false; + } + + const QDomElement payload = element.firstChildElement(); + + // we can only check the payload if it's existant + if (!payload.isNull()) { + return isPayloadValid(payload); + } + return true; +} + +Q_DECLARE_METATYPE(QXmppPubSubBaseItem) diff --git a/src/base/QXmppPubSubEvent.h b/src/base/QXmppPubSubEvent.h index 0faf62b6..3625c8aa 100644 --- a/src/base/QXmppPubSubEvent.h +++ b/src/base/QXmppPubSubEvent.h @@ -15,7 +15,7 @@ class QXmppDataForm; class QXmppPubSubEventPrivate; -class QXmppPubSubItem; +class QXmppPubSubBaseItem; class QXMPP_EXPORT QXmppPubSubEventBase : public QXmppMessage { @@ -73,7 +73,7 @@ private: QSharedDataPointer d; }; -template +template class QXmppPubSubEvent : public QXmppPubSubEventBase { public: diff --git a/src/base/QXmppPubSubIq_p.h b/src/base/QXmppPubSubIq_p.h index eb5ed43f..6868eb84 100644 --- a/src/base/QXmppPubSubIq_p.h +++ b/src/base/QXmppPubSubIq_p.h @@ -15,7 +15,7 @@ class QXmppDataForm; class QXmppPubSubIqPrivate; -class QXmppPubSubItem; +class QXmppPubSubBaseItem; class QXmppPubSubSubscription; class QXmppPubSubAffiliation; class QXmppResultSetReply; @@ -103,7 +103,7 @@ private: QSharedDataPointer d; }; -template +template class PubSubIq : public PubSubIqBase { public: diff --git a/src/base/QXmppPubSubItem.cpp b/src/base/QXmppPubSubItem.cpp deleted file mode 100644 index f87c5d6e..00000000 --- a/src/base/QXmppPubSubItem.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// SPDX-FileCopyrightText: 2019 Jeremy Lainé -// SPDX-FileCopyrightText: 2019 Linus Jahn -// -// SPDX-License-Identifier: LGPL-2.1-or-later - -#include "QXmppPubSubItem.h" - -#include "QXmppElement.h" -#include "QXmppUtils.h" - -#include - -class QXmppPubSubItemPrivate : public QSharedData -{ -public: - QXmppPubSubItemPrivate(const QString &id, const QString &publisher); - - QString id; - QString publisher; -}; - -QXmppPubSubItemPrivate::QXmppPubSubItemPrivate(const QString &id, const QString &publisher) - : id(id), publisher(publisher) -{ -} - -/// -/// \class QXmppPubSubItem -/// -/// The QXmppPubSubItem class represents a publish-subscribe item as defined by -/// \xep{0060, Publish-Subscribe}. -/// -/// To access the payload of an item, you need to create a derived class of this -/// and override QXmppPubSubItem::parsePayload() and -/// QXmppPubSubItem::serializePayload(). -/// -/// It is also required that you override QXmppPubSubItem::isItem() and also -/// check for the correct payload of the PubSub item. This can be easily done by -/// using the protected overload of isItem() with an function that checks the -/// tag name and namespace of the payload. The function is only called if a -/// payload exists. -/// -/// In short, you need to reimplement these methods: -/// * QXmppPubSubItem::parsePayload() -/// * QXmppPubSubItem::serializePayload() -/// * QXmppPubSubItem::isItem() -/// -/// \since QXmpp 1.5 -/// - -/// -/// Constructs an item with \a id and \a publisher. -/// -/// \param id -/// \param publisher -/// -QXmppPubSubItem::QXmppPubSubItem(const QString &id, const QString &publisher) - : d(new QXmppPubSubItemPrivate(id, publisher)) -{ -} - -/// Default copy-constructor -QXmppPubSubItem::QXmppPubSubItem(const QXmppPubSubItem &iq) = default; -/// Default move-constructor -QXmppPubSubItem::QXmppPubSubItem(QXmppPubSubItem &&) = default; -QXmppPubSubItem::~QXmppPubSubItem() = default; -/// Default assignment operator -QXmppPubSubItem &QXmppPubSubItem::operator=(const QXmppPubSubItem &iq) = default; -/// Default move-assignment operator -QXmppPubSubItem &QXmppPubSubItem::operator=(QXmppPubSubItem &&iq) = default; - -/// -/// Returns the ID of the PubSub item. -/// -QString QXmppPubSubItem::id() const -{ - return d->id; -} - -/// -/// Sets the ID of the PubSub item. -/// -/// \param id -/// -void QXmppPubSubItem::setId(const QString &id) -{ - d->id = id; -} - -/// -/// Returns the JID of the publisher of the item. -/// -QString QXmppPubSubItem::publisher() const -{ - return d->publisher; -} - -/// -/// Sets the JID of the publisher of the item. -/// -void QXmppPubSubItem::setPublisher(const QString &publisher) -{ - d->publisher = publisher; -} - -/// \cond -void QXmppPubSubItem::parse(const QDomElement &element) -{ - d->id = element.attribute(QStringLiteral("id")); - d->publisher = element.attribute(QStringLiteral("publisher")); - - parsePayload(element.firstChildElement()); -} - -void QXmppPubSubItem::toXml(QXmlStreamWriter *writer) const -{ - writer->writeStartElement(QStringLiteral("item")); - helperToXmlAddAttribute(writer, QStringLiteral("id"), d->id); - helperToXmlAddAttribute(writer, QStringLiteral("publisher"), d->publisher); - - serializePayload(writer); - - writer->writeEndElement(); -} -/// \endcond - -/// -/// Returns true, if the element is possibly a PubSub item. -/// -bool QXmppPubSubItem::isItem(const QDomElement &element) -{ - return element.tagName() == QStringLiteral("item"); -} - -/// -/// Parses the payload of the item (the child element of the <item/>). -/// -/// This method needs to be overriden to perform the payload-specific parsing. -/// -void QXmppPubSubItem::parsePayload(const QDomElement &) -{ -} - -/// -/// Serializes the payload of the item (the child element of the <item/>). -/// -/// This method needs to be overriden to perform the payload-specific -/// serialization. -/// -void QXmppPubSubItem::serializePayload(QXmlStreamWriter *) const -{ -} diff --git a/src/base/QXmppPubSubItem.h b/src/base/QXmppPubSubItem.h deleted file mode 100644 index e585de9d..00000000 --- a/src/base/QXmppPubSubItem.h +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-FileCopyrightText: 2019 Jeremy Lainé -// SPDX-FileCopyrightText: 2019 Linus Jahn -// -// SPDX-License-Identifier: LGPL-2.1-or-later - -#ifndef QXMPPPUBSUBITEM_H -#define QXMPPPUBSUBITEM_H - -#include "QXmppGlobal.h" - -#include -#include -#include - -class QXmlStreamWriter; -class QXmppPubSubItemPrivate; - -class QXMPP_EXPORT QXmppPubSubItem -{ -public: - QXmppPubSubItem(const QString &id = {}, const QString &publisher = {}); - QXmppPubSubItem(const QXmppPubSubItem &); - QXmppPubSubItem(QXmppPubSubItem &&); - virtual ~QXmppPubSubItem(); - - QXmppPubSubItem &operator=(const QXmppPubSubItem &); - QXmppPubSubItem &operator=(QXmppPubSubItem &&); - - QString id() const; - void setId(const QString &id); - - QString publisher() const; - void setPublisher(const QString &publisher); - - /// \cond - void parse(const QDomElement &element); - void toXml(QXmlStreamWriter *writer) const; - /// \endcond - - static bool isItem(const QDomElement &element); - -protected: - virtual void parsePayload(const QDomElement &payloadElement); - virtual void serializePayload(QXmlStreamWriter *writer) const; - - template - static bool isItem(const QDomElement &element, PayloadChecker isPayloadValid); - -private: - QSharedDataPointer d; -}; - -/// -/// Returns true, if the element is a valid PubSub item and (if existant) the -/// payload is correct. -/// -/// \param element The element to be checked to be an <item/> element. -/// \param isPayloadValid A function that validates the payload element (first -/// child element). The functions needs to return true, if the payload is valid. -/// In case there is no payload, the function is not called. -/// -/// Here is an example covering how this could be used to check for the -/// \xep{0118, User Tune} payload: -/// \code -/// auto isPayloadValid = [](const QDomElement &payload) -> bool { -/// return payload.tagName() == "tune" && payload.namespaceURI() == ns_tune; -/// }; -/// -/// bool valid = QXmppPubSubItem::isItem(itemElement, isPayloadValid); -/// \endcode -/// -template -bool QXmppPubSubItem::isItem(const QDomElement &element, PayloadChecker isPayloadValid) -{ - if (!isItem(element)) { - return false; - } - - const QDomElement payload = element.firstChildElement(); - - // we can only check the payload if it's existant - if (!payload.isNull()) { - return isPayloadValid(payload); - } - return true; -} - -Q_DECLARE_METATYPE(QXmppPubSubItem) - -#endif // QXMPPPUBSUBITEM_H diff --git a/src/base/QXmppUserTuneItem.cpp b/src/base/QXmppUserTuneItem.cpp index 6d8fb8bf..55d30333 100644 --- a/src/base/QXmppUserTuneItem.cpp +++ b/src/base/QXmppUserTuneItem.cpp @@ -224,7 +224,7 @@ bool QXmppTuneItem::isItem(const QDomElement &itemElement) payload.namespaceURI() == ns_tune; }; - return QXmppPubSubItem::isItem(itemElement, isPayloadValid); + return QXmppPubSubBaseItem::isItem(itemElement, isPayloadValid); } /// \cond diff --git a/src/base/QXmppUserTuneItem.h b/src/base/QXmppUserTuneItem.h index 03bafb1e..c4b1f0a8 100644 --- a/src/base/QXmppUserTuneItem.h +++ b/src/base/QXmppUserTuneItem.h @@ -5,7 +5,7 @@ #ifndef QXMPPUSERTUNEITEM_H #define QXMPPUSERTUNEITEM_H -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" #include #include @@ -16,7 +16,7 @@ class QXmppTuneItemPrivate; class QUrl; -class QXMPP_EXPORT QXmppTuneItem : public QXmppPubSubItem +class QXMPP_EXPORT QXmppTuneItem : public QXmppPubSubBaseItem { public: QXmppTuneItem(); diff --git a/src/client/QXmppPubSubManager.cpp b/src/client/QXmppPubSubManager.cpp index 18ad9d7a..de7a9db0 100644 --- a/src/client/QXmppPubSubManager.cpp +++ b/src/client/QXmppPubSubManager.cpp @@ -10,7 +10,7 @@ #include "QXmppConstants_p.h" #include "QXmppPubSubAffiliation.h" #include "QXmppPubSubEventHandler.h" -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" #include "QXmppPubSubSubscribeOptions.h" #include "QXmppPubSubSubscription.h" #include "QXmppStanza.h" @@ -435,7 +435,7 @@ auto QXmppPubSubManager::retractItem(const QString &jid, const QString &nodeName request.setType(QXmppIq::Set); request.setQueryType(PubSubIq<>::Retract); request.setQueryNode(nodeName); - request.setItems({ QXmppPubSubItem(itemId) }); + request.setItems({ QXmppPubSubBaseItem(itemId) }); request.setTo(jid); return client()->sendGenericIq(std::move(request)); @@ -1006,10 +1006,10 @@ PubSubIq<> QXmppPubSubManager::requestItemsIq(const QString &jid, const QString request.setQueryNode(nodeName); if (!itemIds.isEmpty()) { - QVector items; + QVector items; items.reserve(itemIds.size()); for (const auto &id : itemIds) { - items << QXmppPubSubItem(id); + items << QXmppPubSubBaseItem(id); } request.setItems(items); } @@ -1038,7 +1038,7 @@ auto QXmppPubSubManager::publishItems(PubSubIqBase &&request) -> QXmppTasksendIq(std::move(request)), this, [](const PubSubIq<> &iq) -> PublishItemsResult { - const auto itemToId = [](const QXmppPubSubItem &item) { + const auto itemToId = [](const QXmppPubSubBaseItem &item) { return item.id(); }; diff --git a/src/client/QXmppPubSubManager.h b/src/client/QXmppPubSubManager.h index 73a5b4d4..154f585d 100644 --- a/src/client/QXmppPubSubManager.h +++ b/src/client/QXmppPubSubManager.h @@ -79,13 +79,13 @@ public: QXmppTask createInstantNode(const QString &jid, const QXmppPubSubNodeConfig &config); QXmppTask deleteNode(const QString &jid, const QString &nodeName); QXmppTask requestItemIds(const QString &serviceJid, const QString &nodeName); - template + template QXmppTask> requestItem(const QString &jid, const QString &nodeName, const QString &itemId); - template + template QXmppTask> requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId); - template + template QXmppTask> requestItems(const QString &jid, const QString &nodeName); - template + template QXmppTask> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds); template QXmppTask publishItem(const QString &jid, const QString &nodeName, const T &item); @@ -118,11 +118,11 @@ public: QXmppTask createOwnPepNode(const QString &nodeName) { return createNode(client()->configuration().jidBare(), nodeName); } QXmppTask createOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return createNode(client()->configuration().jidBare(), nodeName, config); } QXmppTask deleteOwnPepNode(const QString &nodeName) { return deleteNode(client()->configuration().jidBare(), nodeName); } - template + template QXmppTask> requestOwnPepItem(const QString &nodeName, const QString &itemId) { return requestItem(client()->configuration().jidBare(), nodeName, itemId); } - template + template QXmppTask> requestOwnPepItem(const QString &nodeName, StandardItemId itemId) { return requestItem(client()->configuration().jidBare(), nodeName, itemId); } - template + template QXmppTask> requestOwnPepItems(const QString &nodeName) { return requestItems(client()->configuration().jidBare(), nodeName); } QXmppTask requestOwnPepItemIds(const QString &nodeName) { return requestItemIds(client()->configuration().jidBare(), nodeName); } template diff --git a/src/omemo/QXmppOmemoData.cpp b/src/omemo/QXmppOmemoData.cpp index 6bc1815b..43e00c35 100644 --- a/src/omemo/QXmppOmemoData.cpp +++ b/src/omemo/QXmppOmemoData.cpp @@ -424,7 +424,7 @@ void QXmppOmemoDeviceBundleItem::setDeviceBundle(const QXmppOmemoDeviceBundle &d bool QXmppOmemoDeviceBundleItem::isItem(const QDomElement &itemElement) { - return QXmppPubSubItem::isItem(itemElement, QXmppOmemoDeviceBundle::isOmemoDeviceBundle); + return QXmppPubSubBaseItem::isItem(itemElement, QXmppOmemoDeviceBundle::isOmemoDeviceBundle); } void QXmppOmemoDeviceBundleItem::parsePayload(const QDomElement &payloadElement) @@ -449,7 +449,7 @@ void QXmppOmemoDeviceListItem::setDeviceList(const QXmppOmemoDeviceList &deviceL bool QXmppOmemoDeviceListItem::isItem(const QDomElement &itemElement) { - return QXmppPubSubItem::isItem(itemElement, QXmppOmemoDeviceList::isOmemoDeviceList); + return QXmppPubSubBaseItem::isItem(itemElement, QXmppOmemoDeviceList::isOmemoDeviceList); } void QXmppOmemoDeviceListItem::parsePayload(const QDomElement &payloadElement) diff --git a/src/omemo/QXmppOmemoItems_p.h b/src/omemo/QXmppOmemoItems_p.h index 9b816ed8..abc6a65f 100644 --- a/src/omemo/QXmppOmemoItems_p.h +++ b/src/omemo/QXmppOmemoItems_p.h @@ -7,9 +7,9 @@ #include "QXmppOmemoDeviceBundle_p.h" #include "QXmppOmemoDeviceList_p.h" -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" -class QXmppOmemoDeviceBundleItem : public QXmppPubSubItem +class QXmppOmemoDeviceBundleItem : public QXmppPubSubBaseItem { public: QXmppOmemoDeviceBundle deviceBundle() const; @@ -25,7 +25,7 @@ private: QXmppOmemoDeviceBundle m_deviceBundle; }; -class QXmppOmemoDeviceListItem : public QXmppPubSubItem +class QXmppOmemoDeviceListItem : public QXmppPubSubBaseItem { public: QXmppOmemoDeviceList deviceList() const; diff --git a/src/omemo/QXmppOmemoManager_p.cpp b/src/omemo/QXmppOmemoManager_p.cpp index 8da77f5f..d8830d0d 100644 --- a/src/omemo/QXmppOmemoManager_p.cpp +++ b/src/omemo/QXmppOmemoManager_p.cpp @@ -12,7 +12,7 @@ #include "QXmppOmemoEnvelope_p.h" #include "QXmppOmemoIq_p.h" #include "QXmppOmemoItems_p.h" -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" #include "QXmppSceEnvelope_p.h" #include "QXmppTrustManager.h" #include "QXmppUtils.h" diff --git a/tests/pubsubutil.h b/tests/pubsubutil.h index 20b02785..f8059a6c 100644 --- a/tests/pubsubutil.h +++ b/tests/pubsubutil.h @@ -5,17 +5,17 @@ #ifndef PUBSUBUTIL_H #define PUBSUBUTIL_H -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" #include #include #include -class TestItem : public QXmppPubSubItem +class TestItem : public QXmppPubSubBaseItem { public: TestItem(const QString &id = {}) - : QXmppPubSubItem(id) + : QXmppPubSubBaseItem(id) { } @@ -34,7 +34,7 @@ public: static bool isItem(const QDomElement &element) { isItemCalled = true; - return QXmppPubSubItem::isItem(element, [](const QDomElement &payload) { + return QXmppPubSubBaseItem::isItem(element, [](const QDomElement &payload) { return payload.tagName() == "test-payload"; }); } diff --git a/tests/qxmpppubsub/tst_qxmpppubsub.cpp b/tests/qxmpppubsub/tst_qxmpppubsub.cpp index b34f34cf..ca1d6640 100644 --- a/tests/qxmpppubsub/tst_qxmpppubsub.cpp +++ b/tests/qxmpppubsub/tst_qxmpppubsub.cpp @@ -211,7 +211,7 @@ void tst_QXmppPubSub::testItem() { const auto xml = QByteArrayLiteral(""); - QXmppPubSubItem item; + QXmppPubSubBaseItem item; parsePacket(item, xml); QCOMPARE(item.id(), QStringLiteral("abc1337")); @@ -221,11 +221,11 @@ void tst_QXmppPubSub::testItem() serializePacket(item, xml); // test serialization with constructor values - item = QXmppPubSubItem("abc1337", "lnj@qxmpp.org"); + item = QXmppPubSubBaseItem("abc1337", "lnj@qxmpp.org"); serializePacket(item, xml); // test serialization with setters - item = QXmppPubSubItem(); + item = QXmppPubSubBaseItem(); item.setId("abc1337"); item.setPublisher("lnj@qxmpp.org"); serializePacket(item, xml); @@ -261,7 +261,7 @@ void tst_QXmppPubSub::testIsItem() QFETCH(QByteArray, xml); QFETCH(bool, valid); - QCOMPARE(QXmppPubSubItem::isItem(xmlToDom(xml)), valid); + QCOMPARE(QXmppPubSubBaseItem::isItem(xmlToDom(xml)), valid); } void tst_QXmppPubSub::testTestItem() diff --git a/tests/qxmpppubsubevent/tst_qxmpppubsubevent.cpp b/tests/qxmpppubsubevent/tst_qxmpppubsubevent.cpp index a3b457e9..8f37d943 100644 --- a/tests/qxmpppubsubevent/tst_qxmpppubsubevent.cpp +++ b/tests/qxmpppubsubevent/tst_qxmpppubsubevent.cpp @@ -4,7 +4,7 @@ #include "QXmppDataForm.h" #include "QXmppPubSubEvent.h" -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" #include "pubsubutil.h" #include "util.h" @@ -31,7 +31,7 @@ void tst_QXmppPubSubEvent::testBasic_data() QTest::addColumn("retractIds"); QTest::addColumn("redirectUri"); QTest::addColumn>("subscription"); - QTest::addColumn>("items"); + QTest::addColumn>("items"); QTest::addColumn>("configurationForm"); #define ROW(name, xml, type, node, retractIds, redirectUri, subscription, items, configForm) \ @@ -57,7 +57,7 @@ void tst_QXmppPubSubEvent::testBasic_data() QStringList(), QString(), std::nullopt, - QVector() << QXmppPubSubItem("ae890ac52d0df67ed7cfdf51b644e901"), + QVector() << QXmppPubSubBaseItem("ae890ac52d0df67ed7cfdf51b644e901"), std::nullopt); ROW("retract", @@ -75,7 +75,7 @@ void tst_QXmppPubSubEvent::testBasic_data() << "34324897shdfjk948577342343243243", QString(), std::nullopt, - QVector(), + QVector(), std::nullopt); ROW("configuration-notify", @@ -89,7 +89,7 @@ void tst_QXmppPubSubEvent::testBasic_data() QStringList(), QString(), std::nullopt, - QVector(), + QVector(), std::nullopt); ROW("configuration", @@ -112,7 +112,7 @@ void tst_QXmppPubSubEvent::testBasic_data() QStringList(), QString(), std::nullopt, - QVector(), + QVector(), QXmppDataForm(QXmppDataForm::Result, QList() << QXmppDataForm::Field(QXmppDataForm::Field::HiddenField, @@ -133,7 +133,7 @@ void tst_QXmppPubSubEvent::testBasic_data() QStringList(), QString(), std::nullopt, - QVector(), + QVector(), std::nullopt); ROW("subscription-subscribed", @@ -147,7 +147,7 @@ void tst_QXmppPubSubEvent::testBasic_data() QStringList(), QString(), QXmppPubSubSubscription("horatio@denmark.lit", "princely_musings", {}, QXmppPubSubSubscription::Subscribed), - QVector(), + QVector(), std::nullopt); ROW("subscription-none", @@ -161,7 +161,7 @@ void tst_QXmppPubSubEvent::testBasic_data() QStringList(), QString(), QXmppPubSubSubscription("polonius@denmark.lit", "princely_musings", {}, QXmppPubSubSubscription::None), - QVector(), + QVector(), std::nullopt); ROW("subscription-expiry", @@ -180,7 +180,7 @@ void tst_QXmppPubSubEvent::testBasic_data() QXmppPubSubSubscription::Subscribed, QXmppPubSubSubscription::Unavailable, QDateTime({ 2006, 02, 28 }, { 23, 59, 59 }, Qt::UTC)), - QVector(), + QVector(), std::nullopt); #undef ROW @@ -194,7 +194,7 @@ void tst_QXmppPubSubEvent::testBasic() QFETCH(QStringList, retractIds); QFETCH(QString, redirectUri); QFETCH(std::optional, subscription); - QFETCH(QVector, items); + QFETCH(QVector, items); QFETCH(std::optional, configurationForm); // parse diff --git a/tests/qxmpppubsubiq/tst_qxmpppubsubiq.cpp b/tests/qxmpppubsubiq/tst_qxmpppubsubiq.cpp index 2d59124f..bb6c0768 100644 --- a/tests/qxmpppubsubiq/tst_qxmpppubsubiq.cpp +++ b/tests/qxmpppubsubiq/tst_qxmpppubsubiq.cpp @@ -4,7 +4,7 @@ // SPDX-License-Identifier: LGPL-2.1-or-later #include "QXmppPubSubIq_p.h" -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" #include "QXmppPubSubSubscription.h" #include "QXmppResultSet.h" @@ -193,7 +193,7 @@ void tst_QXmppPubSubIq::testPublish() serializePacket(iq, xml); // serialize using setters - QXmppPubSubItem item(QStringLiteral("current")); + QXmppPubSubBaseItem item(QStringLiteral("current")); iq = PubSubIq(); iq.setId(QLatin1String("items1")); @@ -245,7 +245,7 @@ void tst_QXmppPubSubIq::testRetractItem() iq.setQueryJid({}); iq.setQueryNode(QLatin1String("princely_musings")); - QXmppPubSubItem item; + QXmppPubSubBaseItem item; item.setId(QStringLiteral("ae890ac52d0df67ed7cfdf51b644e901")); iq.setItems({ item }); diff --git a/tests/qxmpppubsubmanager/tst_qxmpppubsubmanager.cpp b/tests/qxmpppubsubmanager/tst_qxmpppubsubmanager.cpp index eef1912e..6589b92e 100644 --- a/tests/qxmpppubsubmanager/tst_qxmpppubsubmanager.cpp +++ b/tests/qxmpppubsubmanager/tst_qxmpppubsubmanager.cpp @@ -8,7 +8,7 @@ #include "QXmppMessage.h" #include "QXmppPubSubAffiliation.h" #include "QXmppPubSubEventHandler.h" -#include "QXmppPubSubItem.h" +#include "QXmppPubSubBaseItem.h" #include "QXmppPubSubManager.h" #include "QXmppPubSubPublishOptions.h" #include "QXmppPubSubSubscribeOptions.h" @@ -421,7 +421,7 @@ void tst_QXmppPubSubManager::testPublishItems_data() QTest::addColumn("isPep"); QTest::addColumn("jid"); QTest::addColumn("node"); - QTest::addColumn>("items"); + QTest::addColumn>("items"); QTest::addColumn("publishOptions"); QTest::addColumn("returnIds"); @@ -434,14 +434,14 @@ void tst_QXmppPubSubManager::testPublishItems_data() item2.setArtist("Rick Astley"); item2.setTitle("Never gonna give you up"); - QVector items1 { item1 }; - QVector items2 { item1, item2 }; + QVector items1 { item1 }; + QVector items2 { item1, item2 }; QXmppPubSubPublishOptions publishOptions; publishOptions.setAccessModel(QXmppPubSubPublishOptions::Presence); auto addRow = [&](const char *name, bool isPep, QString &&jid, - QString &&node, const QVector &items) { + QString &&node, const QVector &items) { QTest::addRow("%s", name) << isPep << jid << node << items << OptionsOpt() << false; QTest::addRow("%s%s", name, "ReturnIds") << isPep << jid << node << items << OptionsOpt() << true; QTest::addRow("%s%s", name, "WithOptions") << isPep << jid << node << items << std::make_optional(publishOptions) << false; @@ -459,7 +459,7 @@ void tst_QXmppPubSubManager::testPublishItems() QFETCH(bool, isPep); QFETCH(QString, jid); QFETCH(QString, node); - QFETCH(QVector, items); + QFETCH(QVector, items); QFETCH(std::optional, publishOptions); QFETCH(bool, returnIds); @@ -736,7 +736,7 @@ void tst_QXmppPubSubManager::testRequestCurrentItem() "" "")); - const auto item = expectFutureVariant(future); + const auto item = expectFutureVariant(future); QCOMPARE(item.id(), QStringLiteral("current")); } @@ -892,7 +892,7 @@ void tst_QXmppPubSubManager::testRequestCurrentPepItem() "" "")); - const auto item = expectFutureVariant(future); + const auto item = expectFutureVariant(future); QCOMPARE(item.id(), QStringLiteral("current")); } @@ -915,7 +915,7 @@ void tst_QXmppPubSubManager::testRequestPepItem() "" "")); - const auto item = expectFutureVariant(future); + const auto item = expectFutureVariant(future); QCOMPARE(item.id(), QStringLiteral("ae890ac52d0df67ed7cfdf51b644e901")); } @@ -937,7 +937,7 @@ void tst_QXmppPubSubManager::testRequestPepItems() "" "")); - const auto items = expectFutureVariant>(future); + const auto items = expectFutureVariant>(future); QCOMPARE(items.items.first().id(), QStringLiteral("368866411b877c30064a5f62b917cffe")); QCOMPARE(items.items.last().id(), QStringLiteral("3300659945416e274474e469a1f0154c")); } -- cgit v1.2.3 From 7c7ce1ac0b06455cf08186543452c65410fe79a9 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Thu, 9 Mar 2023 20:36:08 +0100 Subject: Readd old PubSubIq and PubSubItem for compatibility There is at least one package that actually uses this API and this way QXmpp 1.5 can be easily adopted. --- src/CMakeLists.txt | 4 + src/base/compat/QXmppPubSubIq.cpp | 210 ++++++++++++++++++++++++++++++++++++ src/base/compat/QXmppPubSubIq.h | 66 ++++++++++++ src/base/compat/QXmppPubSubItem.cpp | 76 +++++++++++++ src/base/compat/QXmppPubSubItem.h | 42 ++++++++ 5 files changed, 398 insertions(+) create mode 100644 src/base/compat/QXmppPubSubIq.cpp create mode 100644 src/base/compat/QXmppPubSubIq.h create mode 100644 src/base/compat/QXmppPubSubItem.cpp create mode 100644 src/base/compat/QXmppPubSubItem.h (limited to 'src/base') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0f533a01..54120b8a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -81,6 +81,8 @@ set(INSTALL_HEADER_FILES base/QXmppUtils.h base/QXmppVCardIq.h base/QXmppVersionIq.h + base/compat/QXmppPubSubIq.h + base/compat/QXmppPubSubItem.h # Client client/QXmppArchiveManager.h @@ -212,6 +214,8 @@ set(SOURCE_FILES base/QXmppUtils.cpp base/QXmppVCardIq.cpp base/QXmppVersionIq.cpp + base/compat/QXmppPubSubIq.cpp + base/compat/QXmppPubSubItem.cpp # Client client/QXmppArchiveManager.cpp diff --git a/src/base/compat/QXmppPubSubIq.cpp b/src/base/compat/QXmppPubSubIq.cpp new file mode 100644 index 00000000..9df2fdf1 --- /dev/null +++ b/src/base/compat/QXmppPubSubIq.cpp @@ -0,0 +1,210 @@ +// SPDX-FileCopyrightText: 2010 Jeremy Lainé +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include "QXmppPubSubIq.h" + +#include "QXmppConstants_p.h" +#include "QXmppUtils.h" + +#include +#include + +/// \cond +QT_WARNING_PUSH +QT_WARNING_DISABLE_DEPRECATED + +static const QStringList PUBSUB_QUERIES = { + QStringLiteral("affiliations"), + QStringLiteral("default"), + QStringLiteral("items"), + QStringLiteral("publish"), + QStringLiteral("retract"), + QStringLiteral("subscribe"), + QStringLiteral("subscription"), + QStringLiteral("subscriptions"), + QStringLiteral("unsubscribe"), +}; + +class QXmppPubSubIqPrivate : public QSharedData +{ +public: + QXmppPubSubIqPrivate(); + + QXmppPubSubIq::QueryType queryType; + QString queryJid; + QString queryNode; + QList items; + QString subscriptionId; + QString subscriptionType; +}; + +QXmppPubSubIqPrivate::QXmppPubSubIqPrivate() + : queryType(QXmppPubSubIq::ItemsQuery) +{ +} + +QXmppPubSubIq::QXmppPubSubIq() + : d(new QXmppPubSubIqPrivate) +{ +} + +QXmppPubSubIq::QXmppPubSubIq(const QXmppPubSubIq &iq) = default; + +QXmppPubSubIq::~QXmppPubSubIq() = default; + +QXmppPubSubIq &QXmppPubSubIq::operator=(const QXmppPubSubIq &iq) = default; + +/// Returns the PubSub queryType for this IQ. + +QXmppPubSubIq::QueryType QXmppPubSubIq::queryType() const +{ + return d->queryType; +} + +/// Sets the PubSub queryType for this IQ. +/// +/// \param queryType + +void QXmppPubSubIq::setQueryType(QXmppPubSubIq::QueryType queryType) +{ + d->queryType = queryType; +} + +/// Returns the JID being queried. + +QString QXmppPubSubIq::queryJid() const +{ + return d->queryJid; +} + +/// Sets the JID being queried. +/// +/// \param queryJid + +void QXmppPubSubIq::setQueryJid(const QString &queryJid) +{ + d->queryJid = queryJid; +} + +/// Returns the node being queried. + +QString QXmppPubSubIq::queryNode() const +{ + return d->queryNode; +} + +/// Sets the node being queried. +/// +/// \param queryNode + +void QXmppPubSubIq::setQueryNode(const QString &queryNode) +{ + d->queryNode = queryNode; +} + +/// Returns the subscription ID. + +QString QXmppPubSubIq::subscriptionId() const +{ + return d->subscriptionId; +} + +/// Sets the subscription ID. +/// +/// \param subscriptionId + +void QXmppPubSubIq::setSubscriptionId(const QString &subscriptionId) +{ + d->subscriptionId = subscriptionId; +} + +/// Returns the IQ's items. + +QList QXmppPubSubIq::items() const +{ + return d->items; +} + +/// Sets the IQ's items. +/// +/// \param items + +void QXmppPubSubIq::setItems(const QList &items) +{ + d->items = items; +} + +bool QXmppPubSubIq::isPubSubIq(const QDomElement &element) +{ + return element.firstChildElement(QStringLiteral("pubsub")).namespaceURI() == ns_pubsub; +} + +void QXmppPubSubIq::parseElementFromChild(const QDomElement &element) +{ + const QDomElement pubSubElement = element.firstChildElement(QStringLiteral("pubsub")); + + const QDomElement queryElement = pubSubElement.firstChildElement(); + + // determine query type + const QString tagName = queryElement.tagName(); + int queryType = PUBSUB_QUERIES.indexOf(queryElement.tagName()); + if (queryType > -1) + d->queryType = QueryType(queryType); + + d->queryJid = queryElement.attribute(QStringLiteral("jid")); + d->queryNode = queryElement.attribute(QStringLiteral("node")); + + // parse contents + QDomElement childElement; + switch (d->queryType) { + case QXmppPubSubIq::ItemsQuery: + case QXmppPubSubIq::PublishQuery: + case QXmppPubSubIq::RetractQuery: + childElement = queryElement.firstChildElement(QStringLiteral("item")); + while (!childElement.isNull()) { + QXmppPubSubItem item; + item.parse(childElement); + d->items << item; + childElement = childElement.nextSiblingElement(QStringLiteral("item")); + } + break; + case QXmppPubSubIq::SubscriptionQuery: + d->subscriptionId = queryElement.attribute(QStringLiteral("subid")); + d->subscriptionType = queryElement.attribute(QStringLiteral("subscription")); + break; + default: + break; + } +} + +void QXmppPubSubIq::toXmlElementFromChild(QXmlStreamWriter *writer) const +{ + writer->writeStartElement(QStringLiteral("pubsub")); + writer->writeDefaultNamespace(ns_pubsub); + + // write query type + writer->writeStartElement(PUBSUB_QUERIES.at(d->queryType)); + helperToXmlAddAttribute(writer, QStringLiteral("jid"), d->queryJid); + helperToXmlAddAttribute(writer, QStringLiteral("node"), d->queryNode); + + // write contents + switch (d->queryType) { + case QXmppPubSubIq::ItemsQuery: + case QXmppPubSubIq::PublishQuery: + case QXmppPubSubIq::RetractQuery: + for (const auto &item : d->items) + item.toXml(writer); + break; + case QXmppPubSubIq::SubscriptionQuery: + helperToXmlAddAttribute(writer, QStringLiteral("subid"), d->subscriptionId); + helperToXmlAddAttribute(writer, QStringLiteral("subscription"), d->subscriptionType); + break; + default: + break; + } + writer->writeEndElement(); + writer->writeEndElement(); +} +QT_WARNING_POP +/// \endcond diff --git a/src/base/compat/QXmppPubSubIq.h b/src/base/compat/QXmppPubSubIq.h new file mode 100644 index 00000000..057efa98 --- /dev/null +++ b/src/base/compat/QXmppPubSubIq.h @@ -0,0 +1,66 @@ +// SPDX-FileCopyrightText: 2010 Jeremy Lainé +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifndef QXMPPPUBSUBIQ_H +#define QXMPPPUBSUBIQ_H + +#include "QXmppIq.h" + +#include + +#if QXMPP_DEPRECATED_SINCE(1, 2) +#include "QXmppPubSubItem.h" +#endif + +class QXmppPubSubIqPrivate; + +#if QXMPP_DEPRECATED_SINCE(1, 5) +class QXMPP_EXPORT QXmppPubSubIq : public QXmppIq +{ +public: + enum [[deprecated]] QueryType { + AffiliationsQuery, + DefaultQuery, + ItemsQuery, + PublishQuery, + RetractQuery, + SubscribeQuery, + SubscriptionQuery, + SubscriptionsQuery, + UnsubscribeQuery + }; + + [[deprecated]] QXmppPubSubIq(); + QXmppPubSubIq(const QXmppPubSubIq &iq); + ~QXmppPubSubIq(); + + QXmppPubSubIq &operator=(const QXmppPubSubIq &iq); + + [[deprecated]] QXmppPubSubIq::QueryType queryType() const; + [[deprecated]] void setQueryType(QXmppPubSubIq::QueryType queryType); + + [[deprecated]] QString queryJid() const; + [[deprecated]] void setQueryJid(const QString &jid); + + [[deprecated]] QString queryNode() const; + [[deprecated]] void setQueryNode(const QString &node); + + [[deprecated]] QList items() const; + [[deprecated]] void setItems(const QList &items); + + [[deprecated]] QString subscriptionId() const; + [[deprecated]] void setSubscriptionId(const QString &id); + + [[deprecated]] static bool isPubSubIq(const QDomElement &element); + +protected: + void parseElementFromChild(const QDomElement &) override; + void toXmlElementFromChild(QXmlStreamWriter *writer) const override; + +private: + QSharedDataPointer d; +}; +#endif + +#endif // QXMPPPUBSUBIQ_H diff --git a/src/base/compat/QXmppPubSubItem.cpp b/src/base/compat/QXmppPubSubItem.cpp new file mode 100644 index 00000000..cfd2724e --- /dev/null +++ b/src/base/compat/QXmppPubSubItem.cpp @@ -0,0 +1,76 @@ +// SPDX-FileCopyrightText: 2010 Jeremy Lainé +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include "QXmppPubSubItem.h" + +#include "QXmppElement.h" +#include "QXmppUtils.h" + +#include + +/// \cond +class QXmppPubSubItemPrivate : public QSharedData +{ +public: + QString id; + QXmppElement contents; +}; + +QXmppPubSubItem::QXmppPubSubItem() + : d(new QXmppPubSubItemPrivate) +{ +} + +QXmppPubSubItem::QXmppPubSubItem(const QXmppPubSubItem &iq) = default; + +QXmppPubSubItem::~QXmppPubSubItem() = default; + +QXmppPubSubItem &QXmppPubSubItem::operator=(const QXmppPubSubItem &iq) = default; + +/// Returns the ID of the PubSub item. + +QString QXmppPubSubItem::id() const +{ + return d->id; +} + +/// Sets the ID of the PubSub item. +/// +/// \param id + +void QXmppPubSubItem::setId(const QString &id) +{ + d->id = id; +} + +/// Returns the contents of the PubSub item. + +QXmppElement QXmppPubSubItem::contents() const +{ + return d->contents; +} + +/// Sets the contents of the PubSub item. +/// +/// \param contents + +void QXmppPubSubItem::setContents(const QXmppElement &contents) +{ + d->contents = contents; +} + +void QXmppPubSubItem::parse(const QDomElement &element) +{ + d->id = element.attribute(QStringLiteral("id")); + d->contents = QXmppElement(element.firstChildElement()); +} + +void QXmppPubSubItem::toXml(QXmlStreamWriter *writer) const +{ + writer->writeStartElement(QStringLiteral("item")); + helperToXmlAddAttribute(writer, QStringLiteral("id"), d->id); + d->contents.toXml(writer); + writer->writeEndElement(); +} +/// \endcond diff --git a/src/base/compat/QXmppPubSubItem.h b/src/base/compat/QXmppPubSubItem.h new file mode 100644 index 00000000..1d8dc4d3 --- /dev/null +++ b/src/base/compat/QXmppPubSubItem.h @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2010 Jeremy Lainé +// +// SPDX-License-Identifier: LGPL-2.1-or-later + +#ifndef QXMPPPUBSUBITEM_H +#define QXMPPPUBSUBITEM_H + +#include "QXmppGlobal.h" + +#include + +class QDomElement; +class QXmlStreamWriter; + +class QXmppElement; +class QXmppPubSubItemPrivate; + +#if QXMPP_DEPRECATED_SINCE(1, 5) +class QXMPP_EXPORT QXmppPubSubItem +{ +public: + [[deprecated]] QXmppPubSubItem(); + QXmppPubSubItem(const QXmppPubSubItem &iq); + ~QXmppPubSubItem(); + + QXmppPubSubItem &operator=(const QXmppPubSubItem &iq); + + [[deprecated]] QString id() const; + [[deprecated]] void setId(const QString &id); + + [[deprecated]] QXmppElement contents() const; + [[deprecated]] void setContents(const QXmppElement &contents); + + [[deprecated]] void parse(const QDomElement &element); + [[deprecated]] void toXml(QXmlStreamWriter *writer) const; + +private: + QSharedDataPointer d; +}; +#endif + +#endif // QXMPPPUBSUBITEM_H -- cgit v1.2.3 From 70a8585a38797d24537b8109354bb83cd9262176 Mon Sep 17 00:00:00 2001 From: Linus Jahn Date: Thu, 9 Mar 2023 21:07:05 +0100 Subject: PubSubIq_p: Rename Private class to avoid conflicts --- src/base/QXmppPubSubIq.cpp | 8 ++++++-- src/base/QXmppPubSubIq_p.h | 5 +++-- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src/base') diff --git a/src/base/QXmppPubSubIq.cpp b/src/base/QXmppPubSubIq.cpp index d45df2d3..27da0e4b 100644 --- a/src/base/QXmppPubSubIq.cpp +++ b/src/base/QXmppPubSubIq.cpp @@ -81,7 +81,9 @@ static const QStringList PUBSUB_QUERIES = { QStringLiteral("unsubscribe"), }; -class QXmppPubSubIqPrivate : public QSharedData +namespace QXmpp::Private { + +class PubSubIqPrivate : public QSharedData { public: PubSubIqBase::QueryType queryType = PubSubIqBase::Items; @@ -95,11 +97,13 @@ public: std::optional itemsContinuation; }; +} + /// /// Constructs a PubSub IQ. /// PubSubIqBase::PubSubIqBase() - : d(new QXmppPubSubIqPrivate) + : d(new PubSubIqPrivate) { } diff --git a/src/base/QXmppPubSubIq_p.h b/src/base/QXmppPubSubIq_p.h index 6868eb84..c8828579 100644 --- a/src/base/QXmppPubSubIq_p.h +++ b/src/base/QXmppPubSubIq_p.h @@ -14,7 +14,6 @@ #include class QXmppDataForm; -class QXmppPubSubIqPrivate; class QXmppPubSubBaseItem; class QXmppPubSubSubscription; class QXmppPubSubAffiliation; @@ -22,6 +21,8 @@ class QXmppResultSetReply; namespace QXmpp::Private { +class PubSubIqPrivate; + class QXMPP_EXPORT PubSubIqBase : public QXmppIq { public: @@ -100,7 +101,7 @@ private: static std::optional queryTypeFromDomElement(const QDomElement &element); static bool queryTypeIsOwnerIq(QueryType type); - QSharedDataPointer d; + QSharedDataPointer d; }; template -- cgit v1.2.3