File indexing completed on 2024-12-08 04:33:10
0001 /* 0002 0003 * SPDX-FileCopyrightText: 2016 Riccardo Iaconelli <riccardo@kde.org> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.0-or-later 0006 * 0007 */ 0008 0009 #pragma once 0010 0011 #include "libruqolacore_export.h" 0012 #include "rocketchatmessage.h" 0013 #include "room.h" 0014 #include <QAbstractSocket> 0015 #include <QQueue> 0016 #include <QSslError> 0017 #include <functional> 0018 0019 class QJsonObject; 0020 class QJsonDocument; 0021 class RocketChatMessage; 0022 class AbstractWebSocket; 0023 class RocketChatAccount; 0024 class DDPAuthenticationManager; 0025 class DDPManager; 0026 class LIBRUQOLACORE_EXPORT DDPClient : public QObject 0027 { 0028 Q_OBJECT 0029 public: 0030 enum MessageType { 0031 Persistent, 0032 Ephemeral, 0033 }; 0034 0035 explicit DDPClient(RocketChatAccount *account = nullptr, QObject *parent = nullptr); 0036 ~DDPClient() override; 0037 0038 /** 0039 * @brief Call a method with name @param method and parameters @param params and @param messageType with an empty callback 0040 * 0041 * @param method The name of the method to call Rocket.Chat API for 0042 * @param params The parameters 0043 * @param messageType The type of message 0044 * @return unsigned int, the ID of the called method 0045 */ 0046 quint64 method(const QString &method, const QJsonDocument ¶ms, DDPClient::MessageType messageType = DDPClient::Ephemeral); 0047 0048 /** 0049 * @brief Send message over network 0050 * 0051 * @param method The name of the method to call Rocket.Chat API for 0052 * @param params The parameters 0053 * @param callback The pointer to callback function 0054 * @param messageType The type of message 0055 * @return unsigned int, the ID of the called method 0056 */ 0057 quint64 method(const QString &method, 0058 const QJsonDocument ¶ms, 0059 const std::function<void(QJsonObject, RocketChatAccount *)> &callback, 0060 DDPClient::MessageType messageType = DDPClient::Ephemeral); 0061 0062 quint64 method(const RocketChatMessage::RocketChatMessageResult &result, 0063 const std::function<void(QJsonObject, RocketChatAccount *)> &callback, 0064 DDPClient::MessageType messageType = DDPClient::Ephemeral); 0065 0066 /** 0067 * @brief Subscribes to a collection with name @param collection and parameters @param params 0068 * 0069 * @param collection The name of the collection 0070 * @param params The parameters 0071 */ 0072 quint64 subscribe(const QString &collection, const QJsonArray ¶ms); 0073 0074 /** 0075 * @brief Registers a @class DDPManager object to an event, represented by 0076 * a (collection name, event name) pair. 0077 * 0078 * @param collection the name of the collection to which the event belongs 0079 * @param event the name of the event to which subsribe the @class DDPManager object 0080 * @param ddpManager the @class DDPManager instance that will process event messages 0081 * @param subscriptionId a manager specific id that helps the manager keep track of 0082 * the subscription 0083 */ 0084 void registerSubscriber(const QString &collection, const QString &event, DDPManager *ddpManager, int subscriptionId); 0085 0086 /** 0087 * @brief Deregisters a @class DDPManager object to from a given event, represented by 0088 * a (collection name, event name) pair. 0089 * 0090 * The (collection, event) pair should be enough to deregister the subscribed manager, 0091 * but the extra parameters are helpful to debug if subscription/unsubscription parameters 0092 * don't match. 0093 * 0094 * @param collection the name of the collection to which the event belongs 0095 * @param event the name of the event to which subsribe the @class DDPManager object 0096 * @param ddpManager the @class DDPManager instance that will process event messages 0097 * @param subscriptionId a manager specific id that helps the manager keep track of 0098 * the subscription 0099 */ 0100 void deregisterSubscriber(const QString &collection, const QString &event, DDPManager *ddpManager, int subscriptionId); 0101 0102 /** 0103 * @brief Calls a method on the websocket and registers the DDPManager invoking it 0104 * for later response dispatching. 0105 * 0106 * @param method the method to be invoked 0107 * @param params parameters of the call 0108 * @param ddpmanager the manager invoking the call 0109 * @param operationId a manaager specific id to keep track of the operation invoked 0110 * through the method 0111 */ 0112 quint64 invokeMethodAndRegister(const QString &method, const QJsonArray ¶ms, DDPManager *ddpManager, int operationId); 0113 0114 /** 0115 * @brief Deregister an API manager from responses to a method represented by its id. 0116 * 0117 * Silmilarly to deregisterSubscriber(), the @param methodId parameter is enough 0118 * to deregister manager from method responses, but the other parameters are added 0119 * for debugging purposes. 0120 * 0121 * @param methodId the id of the method generated at invocation 0122 * @param manager the current manager subscribed to method responses 0123 * @param operationId the manager specific operation bound to the method invocation 0124 */ 0125 void deregisterFromMethodResponse(quint64 methodId, DDPManager *ddpManager, int operationId); 0126 0127 /** 0128 * @brief Calls method to log in the user with valid username and password 0129 */ 0130 void login(); 0131 0132 /** 0133 * @brief Tries logging in if the client is connected or just sets a flag 0134 * so a login will be tried on connection. 0135 */ 0136 void enqueueLogin(); 0137 0138 /** 0139 * @brief Check whether websocket is connected at url 0140 * 0141 * @return true if connected, else false 0142 */ 0143 [[nodiscard]] bool isConnected() const; 0144 0145 /** 0146 * @brief Reconnects the websocket to new url 0147 */ 0148 void onServerURLChange(); 0149 0150 /** 0151 * @brief Returns the queue used to cache unsent messages 0152 * 0153 *@return QQueue<QPair<QString,QJsonDocument>>, The m_messageQueue object 0154 */ 0155 [[nodiscard]] QQueue<QPair<QString, QJsonDocument>> messageQueue() const; 0156 0157 /** 0158 * @brief Returns standard cache path 0159 * 0160 *@def QString path 0161 */ 0162 [[nodiscard]] QString cachePath() const; 0163 0164 quint64 informTypingStatus(const QString &room, bool typing, const QString &userName); 0165 0166 void setServerUrl(const QString &url); 0167 void start(); 0168 0169 [[nodiscard]] DDPAuthenticationManager *authenticationManager() const; 0170 0171 quint64 joinRoom(const QString &roomId, const QString &joinCode); 0172 quint64 openDirectChannel(const QString &userId); 0173 void subscribeRoomMessage(const QString &roomId); 0174 quint64 setDefaultStatus(User::PresenceStatus status); 0175 quint64 createJitsiConfCall(const QString &roomId); 0176 quint64 userAutocomplete(const QString &pattern, const QString &exception); 0177 quint64 loadHistory(const QJsonArray ¶ms); 0178 quint64 inputChannelAutocomplete(const QString &roomId, const QString &pattern, const QString &exceptions, bool threadDialog); 0179 quint64 inputUserAutocomplete(const QString &roomId, const QString &pattern, const QString &exceptions, bool threadDialog); 0180 quint64 unBlockUser(const QString &rid, const QString &userId); 0181 quint64 blockUser(const QString &rid, const QString &userId); 0182 quint64 deleteFileMessage(const QString &roomId, const QString &fileid, Room::RoomType channelType); 0183 quint64 setRoomEncrypted(const QString &roomId, bool encrypted); 0184 quint64 roomNameExists(const QString &roomId); 0185 quint64 streamNotifyUserOtrEnd(const QString &roomId, const QString &userId); 0186 quint64 streamNotifyUserOtrHandshake(const QString &userFrom, const QString &userTo, const QString &publicKey); 0187 quint64 streamNotifyUserOtrAcknowledge(const QString &roomId, const QString &userId, const QString &publicKey); 0188 quint64 deleteCustomSound(const QString &identifier); 0189 quint64 uploadCustomSound(const QByteArray &sound); 0190 void unsubscribe(quint64 registerId); 0191 quint64 listCustomSounds(); 0192 quint64 enable2fa(); 0193 quint64 disable2fa(const QString &code); 0194 quint64 validateTempToken2fa(const QString &code); 0195 quint64 regenerateCodes2fa(const QString &code); 0196 quint64 deleteOAuthApp(const QString &appId); 0197 quint64 addOAuthApp(const QString &name, bool active, const QString &redirectUrl); 0198 quint64 updateOAuthApp(const QString &name, bool active, const QString &redirectUrl); 0199 quint64 setAdminStatus(const QString &userId, bool admin); 0200 quint64 openRoom(const QString &roomId); 0201 quint64 getRoomById(const QString &roomId); 0202 quint64 bannerDismiss(const QString &bannerId); 0203 quint64 licenseGetModules(); 0204 quint64 videoConferenceAccepted(const QString &roomId, const QString &callId, const QString &userId); 0205 quint64 videoConferenceRejected(const QString &roomId, const QString &callId, const QString &userId); 0206 quint64 videoConferenceCall(const QString &roomId, const QString &callId, const QString &userId); 0207 quint64 videoConferenceConfirmed(const QString &roomId, const QString &callId, const QString &userId); 0208 Q_SIGNALS: 0209 void connecting(); 0210 void connectedChanged(); 0211 void added(const QJsonObject &item); 0212 void changed(const QJsonObject &item); 0213 void removed(const QJsonObject &item); 0214 void socketError(QAbstractSocket::SocketError error, const QString &errorString); 0215 void disconnectedByServer(); 0216 void wsClosedSocketError(); 0217 0218 /** 0219 * @brief Emitted whenever a result is received 0220 * 0221 * @param id The ID received in the method() call 0222 * @param result The response sent by server 0223 */ 0224 void result(quint64 id, const QJsonDocument &result); 0225 0226 private Q_SLOTS: 0227 void onWSConnected(); 0228 void onTextMessageReceived(const QString &message); 0229 void onWSclosed(); 0230 void onSslErrors(const QList<QSslError> &errors); 0231 0232 private: 0233 Q_DISABLE_COPY(DDPClient) 0234 LIBRUQOLACORE_NO_EXPORT void initializeWebSocket(); 0235 LIBRUQOLACORE_NO_EXPORT void connectWebSocket(); 0236 0237 LIBRUQOLACORE_NO_EXPORT QUrl adaptUrl(const QString &url); 0238 0239 LIBRUQOLACORE_NO_EXPORT void pong(); 0240 LIBRUQOLACORE_NO_EXPORT void executeSubsCallBack(const QJsonObject &root); 0241 0242 QString mUrl; 0243 AbstractWebSocket *mWebSocket = nullptr; 0244 0245 /** 0246 * @brief Unique message ID for each message sent over network 0247 */ 0248 quint64 m_uid = 0; 0249 0250 /** 0251 * @brief Stores callback function associated with each message 0252 * 0253 * @def QHash unsigned messageID and std::function<void (QJsonDocument)> pointer to callback 0254 */ 0255 QHash<quint64, std::function<void(QJsonObject, RocketChatAccount *)>> m_callbackHash; 0256 0257 /** 0258 * @brief stores subscription handlers for a given event on a given collection 0259 * 0260 * @def The key of the hash is a QPair<QString, QString>, where the first element 0261 * is the collection (stream) name, and the second is the event name. 0262 * Each value is a pair (DDPManager, int), where the int value is an internal 0263 * reference for the manager to match internally method calls with responses. 0264 * When a subscription response is received by the client, it will be dispatched 0265 * to the corresponding manager iff both the collection and the event name match. 0266 */ 0267 QHash<QPair<QString, QString>, QPair<DDPManager *, int>> mEventSubscriptionHash; 0268 0269 /** 0270 * @brief stores subscription handlers for a given event on a given collection 0271 * 0272 * @def The key of the hash is the generated id of the called method. 0273 * When a method response is received by the client, it will be dispatched 0274 * to the corresponding manager iff the method call id matches. 0275 */ 0276 QHash<int, QPair<DDPManager *, int>> mMethodResponseHash; 0277 0278 bool m_connected = false; 0279 0280 /** 0281 * @brief Abstract queue for all requests regarding network management 0282 * 0283 * @def QPair QString method and QJsonDocument params 0284 */ 0285 QQueue<QPair<QString, QJsonDocument>> m_messageQueue; 0286 0287 friend class Ruqola; 0288 RocketChatMessage *mRocketChatMessage = nullptr; 0289 RocketChatAccount *mRocketChatAccount = nullptr; 0290 DDPAuthenticationManager *mAuthenticationManager = nullptr; 0291 0292 bool mLoginEnqueued = false; 0293 };