diff options
| author | Linus Jahn <lnj@kaidan.im> | 2020-07-06 00:25:36 +0200 |
|---|---|---|
| committer | Linus Jahn <lnj@kaidan.im> | 2021-08-22 16:09:02 +0200 |
| commit | 086f366d800bd93563742426533848dc24aa6f30 (patch) | |
| tree | 46aed3ee693d4d3486d376ce63194e5fa9bf8bd5 /src/base | |
| parent | b53a3e4ac270cdea8d69529f06b844d917c345c1 (diff) | |
| download | qxmpp-086f366d800bd93563742426533848dc24aa6f30.tar.gz | |
Add QXmppPubSubSubscription
Diffstat (limited to 'src/base')
| -rw-r--r-- | src/base/QXmppConstants.cpp | 2 | ||||
| -rw-r--r-- | src/base/QXmppConstants_p.h | 2 | ||||
| -rw-r--r-- | src/base/QXmppPubSubSubscription.cpp | 335 | ||||
| -rw-r--r-- | src/base/QXmppPubSubSubscription.h | 121 |
4 files changed, 460 insertions, 0 deletions
diff --git a/src/base/QXmppConstants.cpp b/src/base/QXmppConstants.cpp index ff7a7de8..5876a9cf 100644 --- a/src/base/QXmppConstants.cpp +++ b/src/base/QXmppConstants.cpp @@ -60,6 +60,8 @@ const char* ns_vcard = "vcard-temp"; const char* ns_rsm = "http://jabber.org/protocol/rsm"; // XEP-0060: Publish-Subscribe const char* ns_pubsub = "http://jabber.org/protocol/pubsub"; +const char* ns_pubsub_event = "http://jabber.org/protocol/pubsub#event"; +const char* ns_pubsub_owner = "http://jabber.org/protocol/pubsub#owner"; // XEP-0065: SOCKS5 Bytestreams const char* ns_bytestreams = "http://jabber.org/protocol/bytestreams"; // XEP-0066: Out of Band Data diff --git a/src/base/QXmppConstants_p.h b/src/base/QXmppConstants_p.h index cdef36ee..4e0ee8b0 100644 --- a/src/base/QXmppConstants_p.h +++ b/src/base/QXmppConstants_p.h @@ -72,6 +72,8 @@ extern const char* ns_vcard; extern const char* ns_rsm; // XEP-0060: Publish-Subscribe extern const char* ns_pubsub; +extern const char* ns_pubsub_event; +extern const char* ns_pubsub_owner; // XEP-0065: SOCKS5 Bytestreams extern const char* ns_bytestreams; // XEP-0066: Out of Band Data diff --git a/src/base/QXmppPubSubSubscription.cpp b/src/base/QXmppPubSubSubscription.cpp new file mode 100644 index 00000000..158d5db7 --- /dev/null +++ b/src/base/QXmppPubSubSubscription.cpp @@ -0,0 +1,335 @@ +/* + * Copyright (C) 2008-2021 The QXmpp developers + * + * Author: + * Linus Jahn + * + * Source: + * https://github.com/qxmpp-project/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + */ + +#include "QXmppPubSubSubscription.h" + +#include "QXmppConstants_p.h" +#include "QXmppUtils.h" + +#include <QDateTime> +#include <QDomElement> +#include <QXmlStreamWriter> + +/// +/// \class QXmppPubSubSubscription +/// +/// The QXmppPubSubSubscription class represents a PubSub subscription contained +/// in event notifications and IQ requests, as defined in \xep{0060, Publish- +/// Subscribe}. +/// +/// \ingroup Stanzas +/// +/// \since QXmpp 1.5 +/// + +static const QStringList SUBSCRIPTION_STATES = { + QString(), + QStringLiteral("none"), + QStringLiteral("pending"), + QStringLiteral("subscribed"), + QStringLiteral("unconfigured"), +}; + +class QXmppPubSubSubscriptionPrivate : public QSharedData +{ +public: + QXmppPubSubSubscriptionPrivate(const QString &jid, + const QString &node, + const QString &subId, + QXmppPubSubSubscription::State state, + QXmppPubSubSubscription::ConfigurationSupport configurationSupport, + const QDateTime &expiry); + + QString jid; + QString node; + QString subId; + QDateTime expiry; + QXmppPubSubSubscription::State state; + QXmppPubSubSubscription::ConfigurationSupport configurationSupport; +}; + +QXmppPubSubSubscriptionPrivate::QXmppPubSubSubscriptionPrivate(const QString &jid, + const QString &node, + const QString &subId, + QXmppPubSubSubscription::State state, + QXmppPubSubSubscription::ConfigurationSupport configurationSupport, + const QDateTime &expiry) + : jid(jid), + node(node), + subId(subId), + expiry(expiry), + state(state), + configurationSupport(configurationSupport) +{ +} + +/// +/// Converts a subscription state to string. +/// +QString QXmppPubSubSubscription::stateToString(State state) +{ + return SUBSCRIPTION_STATES.at(int(state)); +} + +/// +/// Converts a string with a subscription state to the enum value. +/// +QXmppPubSubSubscription::State QXmppPubSubSubscription::stateFromString(const QString &str) +{ + if (const auto state = SUBSCRIPTION_STATES.indexOf(str); state != -1) { + return State(state); + } + return Invalid; +} + +/// +/// Creates a new QXmppPubSubSubscription. +/// +/// \param jid +/// \param node +/// \param subId +/// \param state +/// \param configurationSupport +/// \param expiry +/// +QXmppPubSubSubscription::QXmppPubSubSubscription(const QString &jid, + const QString &node, + const QString &subId, + State state, + ConfigurationSupport configurationSupport, + const QDateTime &expiry) + : d(new QXmppPubSubSubscriptionPrivate(jid, node, subId, state, configurationSupport, expiry)) +{ +} + +/// Copy contructor. +QXmppPubSubSubscription::QXmppPubSubSubscription(const QXmppPubSubSubscription &) = default; + +QXmppPubSubSubscription::~QXmppPubSubSubscription() = default; + +/// Copy assignment operator. +QXmppPubSubSubscription &QXmppPubSubSubscription::operator=(const QXmppPubSubSubscription &) = default; + +/// +/// Returns the JID of the user of this subscription. +/// +QString QXmppPubSubSubscription::jid() const +{ + return d->jid; +} + +/// +/// Sets the JID of the user of this subscription. +/// +void QXmppPubSubSubscription::setJid(const QString &jid) +{ + d->jid = jid; +} + +/// +/// Returns the node name of this subscription. +/// +QString QXmppPubSubSubscription::node() const +{ + return d->node; +} + +/// +/// Sets the node name of this subscription. +/// +void QXmppPubSubSubscription::setNode(const QString &node) +{ + d->node = node; +} + +/// +/// Returns the subscription ID (may be empty). +/// +QString QXmppPubSubSubscription::subId() const +{ + return d->subId; +} + +/// +/// Sets the subscription ID (may be empty). +/// +void QXmppPubSubSubscription::setSubId(const QString &subId) +{ + d->subId = subId; +} + +/// +/// Returns the state of the subscription. +/// +QXmppPubSubSubscription::State QXmppPubSubSubscription::state() const +{ + return d->state; +} + +/// +/// Sets the state of the subscription. +/// +void QXmppPubSubSubscription::setState(State state) +{ + d->state = state; +} + +/// +/// Returns the expiry date of the subscription. +/// +/// If this timestamp is valid, the subscription is going to be cancelled at +/// this date. +/// +QDateTime QXmppPubSubSubscription::expiry() const +{ + return d->expiry; +} + +/// +/// Sets the expiry date of the subscription. +/// +/// If this timestamp is valid, the subscription is going to be cancelled at +/// this date. +/// +void QXmppPubSubSubscription::setExpiry(const QDateTime &expiry) +{ + d->expiry = expiry; +} + +/// +/// Returns the availability of a subscription configuration. +/// +QXmppPubSubSubscription::ConfigurationSupport QXmppPubSubSubscription::configurationSupport() const +{ + return d->configurationSupport; +} + +/// +/// Sets the availability of a subscription configuration. +/// +void QXmppPubSubSubscription::setConfigurationSupport(ConfigurationSupport support) +{ + d->configurationSupport = support; +} + +/// +/// Returns whether a configuration of the subscription is possible. +/// +bool QXmppPubSubSubscription::isConfigurationSupported() const +{ + return d->configurationSupport > Unavailable; +} + +/// +/// Returns whether configuration of the subscription required before event +/// notifications are going to be sent to the user. +/// +bool QXmppPubSubSubscription::isConfigurationRequired() const +{ + return d->configurationSupport == Required || d->state == Unconfigured; +} + +/// +/// Returns true, if the element is a PubSub subscription element. +/// +bool QXmppPubSubSubscription::isSubscription(const QDomElement &element) +{ + if (element.tagName() != QStringLiteral("subscription")) { + return false; + } + + if (element.hasAttribute(QStringLiteral("subscription"))) { + const auto subStateStr = element.attribute(QStringLiteral("subscription")); + if (!SUBSCRIPTION_STATES.contains(subStateStr)) { + return false; + } + } + + if (element.namespaceURI() == ns_pubsub || element.namespaceURI() == ns_pubsub_event) { + return element.hasAttribute(QStringLiteral("jid")); + } + if (element.namespaceURI() == ns_pubsub_owner) { + return element.hasAttribute(QStringLiteral("jid")) && + element.hasAttribute(QStringLiteral("subscription")); + } + return false; +} + +/// \cond +void QXmppPubSubSubscription::parse(const QDomElement &element) +{ + bool isPubSub = element.namespaceURI() == ns_pubsub; + bool isPubSubEvent = !isPubSub && element.namespaceURI() == ns_pubsub_event; + + d->jid = element.attribute(QStringLiteral("jid")); + d->state = stateFromString(element.attribute(QStringLiteral("subscription"))); + + if (isPubSub || isPubSubEvent) { + d->node = element.attribute(QStringLiteral("node")); + d->subId = element.attribute(QStringLiteral("subid")); + + if (isPubSubEvent) { + if (element.hasAttribute(QStringLiteral("expiry"))) { + d->expiry = QXmppUtils::datetimeFromString( + element.attribute(QStringLiteral("expiry"))); + } + } else if (isPubSub) { + auto options = element.firstChildElement(QStringLiteral("subscribe-options")); + if (options.isNull()) { + d->configurationSupport = Unavailable; + } else { + if (!options.firstChildElement(QStringLiteral("required")).isNull()) { + d->configurationSupport = Required; + } else { + d->configurationSupport = Available; + } + } + } + } +} + +void QXmppPubSubSubscription::toXml(QXmlStreamWriter *writer) const +{ + writer->writeStartElement(QStringLiteral("subscription")); + + // jid is required + writer->writeAttribute(QStringLiteral("jid"), d->jid); + helperToXmlAddAttribute(writer, QStringLiteral("node"), d->node); + helperToXmlAddAttribute(writer, QStringLiteral("subscription"), stateToString(d->state)); + helperToXmlAddAttribute(writer, QStringLiteral("subid"), d->subId); + if (d->expiry.isValid()) { + writer->writeAttribute(QStringLiteral("expiry"), + QXmppUtils::datetimeToString(d->expiry)); + } + + if (d->configurationSupport > Unavailable) { + writer->writeStartElement(QStringLiteral("subscribe-options")); + if (d->configurationSupport == Required) { + writer->writeEmptyElement(QStringLiteral("required")); + } + writer->writeEndElement(); + } + + writer->writeEndElement(); +} +/// \endcond diff --git a/src/base/QXmppPubSubSubscription.h b/src/base/QXmppPubSubSubscription.h new file mode 100644 index 00000000..0a0a010d --- /dev/null +++ b/src/base/QXmppPubSubSubscription.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2008-2021 The QXmpp developers + * + * Author: + * Linus Jahn + * + * Source: + * https://github.com/qxmpp-project/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + */ + +#ifndef QXMPPPUBSUBSUBSCRIPTION_H +#define QXMPPPUBSUBSUBSCRIPTION_H + +#include "QXmppGlobal.h" + +#include <QDateTime> +#include <QMetaType> +#include <QSharedDataPointer> + +class QXmppPubSubSubscriptionPrivate; +class QXmlStreamWriter; +class QDomElement; + +class QXMPP_EXPORT QXmppPubSubSubscription +{ +public: + /// + /// The State enum describes the state of a subscription. + /// + enum State : uint8_t { + /// No state information is included. + Invalid, + /// There is no subscription with the node. + None, + /// A subscription is pending. + Pending, + /// The user is subscribed to the node. + Subscribed, + /// The subscription requires configuration before it becomes active. + Unconfigured, + }; + static QString stateToString(State); + static State stateFromString(const QString &); + + /// + /// The SubscribeOptionsSupport enum describes whether the availability of a + /// subscription configuration. This is also known as + /// <subscribe-options/>. + /// + enum ConfigurationSupport : uint8_t { + /// A subscription configuration is not advertised. + Unavailable, + /// Configuration of the subscription is possible, but not required. + Available, + /// Configuration of the subscription is required. No event + /// notifications are going to be sent until the subscription has been + /// configured. + Required, + }; + + QXmppPubSubSubscription(const QString &jid = {}, + const QString &node = {}, + const QString &subId = {}, + State state = Invalid, + ConfigurationSupport configurationSupport = Unavailable, + const QDateTime &expiry = {}); + QXmppPubSubSubscription(const QXmppPubSubSubscription &); + ~QXmppPubSubSubscription(); + + QXmppPubSubSubscription &operator=(const QXmppPubSubSubscription &); + + QString jid() const; + void setJid(const QString &jid); + + QString node() const; + void setNode(const QString &node); + + QString subId() const; + void setSubId(const QString &subId); + + QDateTime expiry() const; + void setExpiry(const QDateTime &expiry); + + State state() const; + void setState(State state); + + ConfigurationSupport configurationSupport() const; + void setConfigurationSupport(ConfigurationSupport support); + bool isConfigurationSupported() const; + bool isConfigurationRequired() const; + + static bool isSubscription(const QDomElement &); + + /// \cond + void parse(const QDomElement &); + void toXml(QXmlStreamWriter *writer) const; + /// \endcond + +private: + QSharedDataPointer<QXmppPubSubSubscriptionPrivate> d; +}; + +Q_DECLARE_TYPEINFO(QXmppPubSubSubscription, Q_MOVABLE_TYPE); +Q_DECLARE_METATYPE(QXmppPubSubSubscription) +Q_DECLARE_METATYPE(QXmppPubSubSubscription::State) +Q_DECLARE_METATYPE(QXmppPubSubSubscription::ConfigurationSupport) + +#endif // QXMPPPUBSUBSUBSCRIPTION_H |
