// SPDX-FileCopyrightText: 2020 Linus Jahn // SPDX-FileCopyrightText: 2022 Melvin Keskin // // SPDX-License-Identifier: LGPL-2.1-or-later #ifndef QXMPPPUBSUBMANAGER_H #define QXMPPPUBSUBMANAGER_H #include "QXmppClient.h" #include "QXmppClientExtension.h" #include "QXmppFutureUtils_p.h" #include "QXmppMessage.h" #include "QXmppPubSubIq_p.h" #include "QXmppPubSubPublishOptions.h" #include "QXmppResultSet.h" class QXmppPubSubPublishOptions; class QXmppPubSubSubscribeOptions; class QXMPP_EXPORT QXmppPubSubManager : public QXmppClientExtension { Q_OBJECT public: /// /// Type of PubSub service /// enum ServiceType { PubSubOrPep, ///< PubSub service or PEP service PubSub, ///< PubSub service only Pep ///< PEP service only }; /// /// Pre-defined ID of a PubSub item /// enum StandardItemId { Current ///< Item of a singleton node (i.e., the node's single item) }; /// /// Used to indicate a service type mismatch. /// struct InvalidServiceType { }; template struct Items { QVector items; std::optional continuation; }; using Result = std::variant; using FeaturesResult = std::variant, InvalidServiceType, QXmppError>; using NodesResult = std::variant, QXmppError>; using InstantNodeResult = std::variant; template using ItemResult = std::variant; template using ItemsResult = std::variant, QXmppError>; using ItemIdsResult = std::variant, QXmppError>; using PublishItemResult = std::variant; using PublishItemsResult = std::variant, QXmppError>; using SubscriptionsResult = std::variant, QXmppError>; using AffiliationsResult = std::variant, QXmppError>; using OptionsResult = std::variant; using NodeConfigResult = std::variant; QXmppPubSubManager(); ~QXmppPubSubManager(); // Generic PubSub (the PubSub service is the given entity) QXmppTask requestNodes(const QString &jid); QXmppTask createNode(const QString &jid, const QString &nodeName); QXmppTask createNode(const QString &jid, const QString &nodeName, const QXmppPubSubNodeConfig &config); QXmppTask createInstantNode(const QString &jid); 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 QXmppTask> requestItem(const QString &jid, const QString &nodeName, const QString &itemId); template QXmppTask> requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId); template QXmppTask> requestItems(const QString &jid, const QString &nodeName); template QXmppTask> requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds); template QXmppTask publishItem(const QString &jid, const QString &nodeName, const T &item); template QXmppTask publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); template QXmppTask publishItems(const QString &jid, const QString &nodeName, const QVector &items); template QXmppTask publishItems(const QString &jid, const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions); QXmppTask retractItem(const QString &jid, const QString &nodeName, const QString &itemId); QXmppTask retractItem(const QString &jid, const QString &nodeName, StandardItemId itemId); QXmppTask purgeItems(const QString &jid, const QString &nodeName); QXmppTask requestSubscriptions(const QString &jid); QXmppTask requestSubscriptions(const QString &jid, const QString &nodeName); QXmppTask requestNodeAffiliations(const QString &jid, const QString &nodeName); QXmppTask requestAffiliations(const QString &jid); QXmppTask requestAffiliations(const QString &jid, const QString &nodeName); QXmppTask requestSubscribeOptions(const QString &service, const QString &nodeName); QXmppTask requestSubscribeOptions(const QString &service, const QString &nodeName, const QString &subscriberJid); QXmppTask setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options); QXmppTask setSubscribeOptions(const QString &service, const QString &nodeName, const QXmppPubSubSubscribeOptions &options, const QString &subscriberJid); QXmppTask requestNodeConfiguration(const QString &service, const QString &nodeName); QXmppTask configureNode(const QString &service, const QString &nodeName, const QXmppPubSubNodeConfig &config); QXmppTask cancelNodeConfiguration(const QString &service, const QString &nodeName); QXmppTask subscribeToNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); QXmppTask unsubscribeFromNode(const QString &serviceJid, const QString &nodeName, const QString &subscriberJid); // PEP-specific (the PubSub service is the current account) QXmppTask requestOwnPepNodes() { return requestNodes(client()->configuration().jidBare()); }; 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 QXmppTask> requestOwnPepItem(const QString &nodeName, const QString &itemId) { return requestItem(client()->configuration().jidBare(), nodeName, itemId); } template QXmppTask> requestOwnPepItem(const QString &nodeName, StandardItemId itemId) { return requestItem(client()->configuration().jidBare(), nodeName, itemId); } template QXmppTask> requestOwnPepItems(const QString &nodeName) { return requestItems(client()->configuration().jidBare(), nodeName); } QXmppTask requestOwnPepItemIds(const QString &nodeName) { return requestItemIds(client()->configuration().jidBare(), nodeName); } template QXmppTask publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions); template QXmppTask publishOwnPepItem(const QString &nodeName, const T &item); template QXmppTask publishOwnPepItems(const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions); template QXmppTask publishOwnPepItems(const QString &nodeName, const QVector &items); QXmppTask retractOwnPepItem(const QString &nodeName, const QString &itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } QXmppTask retractOwnPepItem(const QString &nodeName, StandardItemId itemId) { return retractItem(client()->configuration().jidBare(), nodeName, itemId); } QXmppTask purgeOwnPepItems(const QString &nodeName) { return purgeItems(client()->configuration().jidBare(), nodeName); } QXmppTask requestOwnPepNodeConfiguration(const QString &nodeName) { return requestNodeConfiguration(client()->configuration().jidBare(), nodeName); } QXmppTask configureOwnPepNode(const QString &nodeName, const QXmppPubSubNodeConfig &config) { return configureNode(client()->configuration().jidBare(), nodeName, config); } QXmppTask cancelOwnPepNodeConfiguration(const QString &nodeName) { return cancelNodeConfiguration(client()->configuration().jidBare(), nodeName); } static QString standardItemIdToString(StandardItemId itemId); /// \cond QStringList discoveryFeatures() const override; bool handleStanza(const QDomElement &element) override; /// \endcond private: // for private requestFeatures() API friend class tst_QXmppPubSubManager; friend class QXmppOmemoManagerPrivate; QXmppTask requestFeatures(const QString &serviceJid, ServiceType serviceType = PubSubOrPep); QXmppTask requestOwnPepFeatures() { return requestFeatures(client()->configuration().jidBare(), Pep); }; QXmppTask publishItem(QXmpp::Private::PubSubIqBase &&iq); QXmppTask publishItems(QXmpp::Private::PubSubIqBase &&iq); static QXmpp::Private::PubSubIq<> requestItemsIq(const QString &jid, const QString &nodeName, const QStringList &itemIds); }; /// /// Requests a specific item of an entity's node. /// /// \param jid Jabber ID of the entity hosting the pubsub service. For PEP this /// should be an account's bare JID /// \param nodeName the name of the node to query /// \param itemId the ID of the item to retrieve /// \return /// template QXmppTask> QXmppPubSubManager::requestItem(const QString &jid, const QString &nodeName, const QString &itemId) { using namespace QXmpp::Private; return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, { itemId })), this, [](PubSubIq &&iq) -> ItemResult { if (!iq.items().isEmpty()) { return iq.items().constFirst(); } return QXmppError { QStringLiteral("No such item has been found."), {} }; }); } /// /// Requests a specific item of an entity's node. /// /// \param jid Jabber ID of the entity hosting the pubsub service. For PEP this /// should be an account's bare JID /// \param nodeName the name of the node to query /// \param itemId the ID of the item to retrieve /// \return /// template QXmppTask> QXmppPubSubManager::requestItem(const QString &jid, const QString &nodeName, StandardItemId itemId) { return requestItem(jid, nodeName, standardItemIdToString(itemId)); } /// /// Requests all items of an entity's node. /// /// \param jid Jabber ID of the entity hosting the pubsub service. For PEP this /// should be an account's bare JID /// \param nodeName the name of the node to query /// \return /// template QXmppTask> QXmppPubSubManager::requestItems(const QString &jid, const QString &nodeName) { return requestItems(jid, nodeName, {}); } /// /// Requests items of an entity's node. /// /// \param jid Jabber ID of the entity hosting the pubsub service. For PEP this /// should be an account's bare JID /// \param nodeName the name of the node to query /// \param itemIds the IDs of the items to retrieve. If empty, retrieves all /// items /// \return /// template QXmppTask> QXmppPubSubManager::requestItems(const QString &jid, const QString &nodeName, const QStringList &itemIds) { using namespace QXmpp::Private; return chainIq(client()->sendIq(requestItemsIq(jid, nodeName, itemIds)), this, [](PubSubIq &&iq) -> ItemsResult { return Items { iq.items(), iq.itemsContinuation(), }; }); } /// /// Publishs one item to a pubsub node. /// /// This is a convenience method equivalent to calling /// QXmppPubSubManager::publishItem with no publish options. /// /// \param jid Jabber ID of the entity hosting the pubsub service /// \param nodeName the name of the node to publish the item to /// \param item the item to publish /// \return /// template QXmppTask QXmppPubSubManager::publishItem(const QString &jid, const QString &nodeName, const T &item) { QXmpp::Private::PubSubIq request; request.setTo(jid); request.setItems({ item }); request.setQueryNode(nodeName); return publishItem(std::move(request)); } /// /// Publishs one item to a pubsub node. /// /// This is a convenience method equivalent to calling /// QXmppPubSubManager::publishItem with no publish options. /// /// \param jid Jabber ID of the entity hosting the pubsub service /// \param nodeName the name of the node to publish the item to /// \param item the item to publish /// \param publishOptions publish-options for the items /// \return /// template QXmppTask QXmppPubSubManager::publishItem(const QString &jid, const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions) { QXmpp::Private::PubSubIq request; request.setTo(jid); request.setItems({ item }); request.setQueryNode(nodeName); request.setDataForm(publishOptions.toDataForm()); return publishItem(std::move(request)); } /// /// Publishs items to a pubsub node. /// /// \param jid Jabber ID of the entity hosting the pubsub service /// \param nodeName the name of the node to publish the items to /// \param items the items to publish /// \return /// template QXmppTask QXmppPubSubManager::publishItems(const QString &jid, const QString &nodeName, const QVector &items) { QXmpp::Private::PubSubIq request; request.setTo(jid); request.setItems(items); request.setQueryNode(nodeName); return publishItems(std::move(request)); } /// /// Publishs items to a pubsub node. /// /// \param jid Jabber ID of the entity hosting the pubsub service /// \param nodeName the name of the node to publish the items to /// \param items the items to publish /// \param publishOptions publish-options for the items /// \return /// template QXmppTask QXmppPubSubManager::publishItems(const QString &jid, const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions) { QXmpp::Private::PubSubIq request; request.setTo(jid); request.setItems(items); request.setQueryNode(nodeName); request.setDataForm(publishOptions.toDataForm()); return publishItems(std::move(request)); } /// /// Publishs one item to a PEP node. /// /// \param nodeName the name of the PEP node to publish the item to /// \param item the item to publish /// \param publishOptions publish-options for fine tuning /// \return /// template QXmppTask QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item, const QXmppPubSubPublishOptions &publishOptions) { return publishItem(client()->configuration().jidBare(), nodeName, item, publishOptions); } /// /// Publishs one item to a PEP node. /// /// \param nodeName the name of the PEP node to publish the item to /// \param item the item to publish /// \return /// template QXmppTask QXmppPubSubManager::publishOwnPepItem(const QString &nodeName, const T &item) { return publishItem(client()->configuration().jidBare(), nodeName, item); } /// /// Publishs items to a PEP node. /// /// \param nodeName the name of the PEP node to publish the items to /// \param items the items to publish /// \param publishOptions publish-options for fine tuning (optional). Pass /// an empty form to honor the default options of the PEP node /// \return /// template QXmppTask QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector &items, const QXmppPubSubPublishOptions &publishOptions) { return publishItems(client()->configuration().jidBare(), nodeName, items, publishOptions); } /// /// Publishs items to a PEP node. /// /// \param nodeName the name of the PEP node to publish the items to /// \param items the items to publish /// \return /// template QXmppTask QXmppPubSubManager::publishOwnPepItems(const QString &nodeName, const QVector &items) { return publishItems(client()->configuration().jidBare(), nodeName, items); } #endif // QXMPPPUBSUBMANAGER_H