diff --git a/src/core/ddpapi/ddpclient.cpp b/src/core/ddpapi/ddpclient.cpp index 9da09771..ee6e91a4 100644 --- a/src/core/ddpapi/ddpclient.cpp +++ b/src/core/ddpapi/ddpclient.cpp @@ -1,955 +1,956 @@ /* * Copyright 2016 Riccardo Iaconelli * Copyright (C) 2017-2020 Laurent Montel * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "ddpclient.h" #include "restapirequest.h" #include "utils.h" #include "ruqola_ddpapi_debug.h" #include "ruqola_ddpapi_command_debug.h" #include "rocketchatmessage.h" #include "ruqolawebsocket.h" #include "rocketchataccount.h" #include "messagequeue.h" #include "ruqolalogger.h" #include "rocketchatbackend.h" #include "plugins/pluginauthenticationinterface.h" #include #include #include #include namespace RuqolaTestWebSocket { LIBRUQOLACORE_EXPORT AbstractWebSocket *_k_ruqola_webSocket = nullptr; } void user_ignore(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("User Ignore:") + QJsonDocument(root).toJson()); } } void block_user(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Block User:") + QJsonDocument(root).toJson()); } } void unblock_user(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("UnBlock User:") + QJsonDocument(root).toJson()); } } void input_user_channel_autocomplete(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Input channel/User autocomplete:") + QJsonDocument(root).toJson()); } const QJsonObject obj = root.value(QLatin1String("result")).toObject(); account->inputTextManager()->inputTextCompleter(obj); } void process_backlog(const QJsonObject &root, RocketChatAccount *account) { const QJsonObject obj = root.value(QLatin1String("result")).toObject(); //qCDebug(RUQOLA_DDPAPI_LOG) << obj.value(QLatin1String("messages")).toArray().size(); account->rocketChatBackend()->processIncomingMessages(obj.value(QLatin1String("messages")).toArray()); } void add_user_to_room(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Add User To Room:") + QJsonDocument(root).toJson()); } } void star_message(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Star message:") + QJsonDocument(root).toJson()); } } void change_notifications_settings(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Change Notifications Settings:") + QJsonDocument(root).toJson()); } } void change_room_settings(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Change Room Settings:") + QJsonDocument(root).toJson()); } } void erase_room(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Delete Room:") + QJsonDocument(root).toJson()); } qDebug()<< "void erase_room(const QJsonObject &root, RocketChatAccount *account)"<ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Delete Message:") + QJsonDocument(root).toJson()); } } void channel_and_private_autocomplete(const QJsonObject &root, RocketChatAccount *account) { const QJsonObject obj = root.value(QLatin1String("result")).toObject(); account->loadAutoCompleteChannel(obj); if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Channel And Private AutoComplete:") + QJsonDocument(root).toJson()); } } void create_jitsi_conf_call(const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Create Jitsi Conf Call:") + QJsonDocument(root).toJson()); } } void open_direct_channel(const QJsonObject &root, RocketChatAccount *account) { const QJsonObject obj = root.value(QLatin1String("result")).toObject(); if (!obj.isEmpty()) { const QString rid = obj.value(QLatin1String("rid")).toString(); if (!rid.isEmpty()) { account->ddp()->subscribeRoomMessage(rid); } } if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Open Direct channel:") + QJsonDocument(root).toJson()); } } void join_room(const QJsonObject &obj, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Join Room :") + QJsonDocument(obj).toJson()); } } void change_default_status(const QJsonObject &obj, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Change Default Status :") + QJsonDocument(obj).toJson()); } } void empty_callback(const QJsonObject &obj, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Empty call back :") + QJsonDocument(obj).toJson()); } else { qCWarning(RUQOLA_DDPAPI_LOG) << "empty_callback "<< obj; } } void login_result(const QJsonObject &obj, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Login result: ") + QJsonDocument(obj).toJson()); } else { qCWarning(RUQOLA_DDPAPI_LOG) << "Login result: "<< obj; } const QJsonObject result = obj.value(QLatin1String("result")).toObject(); //qDebug() << " result token " << result[QStringLiteral("token")].toString(); const qint64 tokenExpires = Utils::parseDate(QStringLiteral("tokenExpires"), result); //qDebug() << " result tokenExpires " << tokenExpires; account->settings()->setExpireToken(tokenExpires); } void create_channel(const QJsonObject &root, RocketChatAccount *account) { const QJsonObject obj = root.value(QLatin1String("result")).toObject(); if (!obj.isEmpty()) { const QString rid = obj.value(QLatin1String("rid")).toString(); if (!rid.isEmpty()) { account->joinRoom(rid); } if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("create Channel :") + QJsonDocument(root).toJson()); } } } DDPClient::DDPClient(RocketChatAccount *account, QObject *parent) : QObject(parent) , m_uid(1) , m_loginStatus(NotConnected) , mRocketChatMessage(new RocketChatMessage) , mRocketChatAccount(account) { } DDPClient::~DDPClient() { + disconnect(mWebSocket, &AbstractWebSocket::disconnected, this, &DDPClient::onWSclosed); mWebSocket->close(); //Don't delete socket when we use specific socket. if (!RuqolaTestWebSocket::_k_ruqola_webSocket) { delete mWebSocket; mWebSocket = nullptr; } delete mRocketChatMessage; mRocketChatMessage = nullptr; } void DDPClient::setServerUrl(const QString &url) { mUrl = url; } void DDPClient::initializeWebSocket() { mWebSocket->ignoreSslErrors(); connect(mWebSocket, &AbstractWebSocket::connected, this, &DDPClient::onWSConnected); connect(mWebSocket, &AbstractWebSocket::textMessageReceived, this, &DDPClient::onTextMessageReceived); connect(mWebSocket, &AbstractWebSocket::disconnected, this, &DDPClient::onWSclosed); connect(mWebSocket, &AbstractWebSocket::socketError, this, &DDPClient::socketError); connect(mWebSocket, &AbstractWebSocket::sslErrors, this, &DDPClient::onSslErrors); } void DDPClient::start() { if (!mWebSocket) { if (!RuqolaTestWebSocket::_k_ruqola_webSocket) { mWebSocket = new RuqolaWebSocket(mRocketChatAccount->ruqolaLogger(), this); } else { mWebSocket = RuqolaTestWebSocket::_k_ruqola_webSocket; } initializeWebSocket(); } connect(mRocketChatAccount, &RocketChatAccount::serverUrlChanged, this, &DDPClient::onServerURLChange); if (!mUrl.isEmpty()) { const QUrl serverUrl = adaptUrl(mUrl); if (!serverUrl.isValid()) { setLoginStatus(LoginFailed); } else { mWebSocket->openUrl(serverUrl); qCDebug(RUQOLA_DDPAPI_LOG) << "Trying to connect to URL" << serverUrl; } } else { qCDebug(RUQOLA_DDPAPI_LOG) << "url is empty"; } } void DDPClient::setLoginJobId(quint64 jobid) { m_loginJob = jobid; } QUrl DDPClient::adaptUrl(const QString &url) { return Utils::generateServerUrl(url); } void DDPClient::onServerURLChange() { if (mRocketChatAccount->settings()->serverUrl() != mUrl || !mWebSocket->isValid()) { if (mWebSocket->isValid()) { mWebSocket->flush(); mWebSocket->close(); } mUrl = mRocketChatAccount->settings()->serverUrl(); mWebSocket->openUrl(adaptUrl(mUrl)); connect(mWebSocket, &AbstractWebSocket::connected, this, &DDPClient::onWSConnected); qCDebug(RUQOLA_DDPAPI_LOG) << "Reconnecting" << mUrl; } } DDPClient::LoginStatus DDPClient::loginStatus() const { return m_loginStatus; } void DDPClient::setLoginStatus(DDPClient::LoginStatus l) { qCDebug(RUQOLA_DDPAPI_LOG) << "Setting login status to" << l; m_loginStatus = l; Q_EMIT loginStatusChanged(); // reset flags if (l == LoginFailed) { m_attemptedPasswordLogin = false; } } bool DDPClient::isConnected() const { return m_connected; } bool DDPClient::isLoggedIn() const { return m_loginStatus == LoggedIn; } QString DDPClient::cachePath() const { return QStandardPaths::writableLocation(QStandardPaths::CacheLocation); } QQueue > DDPClient::messageQueue() const { return m_messageQueue; } quint64 DDPClient::leaveRoom(const QString &roomID) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->leaveRoom(roomID, m_uid); return method(result, empty_callback, DDPClient::Persistent); } quint64 DDPClient::hideRoom(const QString &roomID) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->hideRoom(roomID, m_uid); return method(result, empty_callback, DDPClient::Persistent); } quint64 DDPClient::toggleFavorite(const QString &roomID, bool favorite) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->toggleFavorite(roomID, favorite, m_uid); return method(result, empty_callback, DDPClient::Persistent); } quint64 DDPClient::createChannel(const QString &name, const QStringList &userList, bool readOnly) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->createChannel(name, userList, readOnly, m_uid); return method(result, create_channel, DDPClient::Persistent); } quint64 DDPClient::setRoomName(const QString &roomId, const QString &name) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setRoomName(roomId, name, m_uid); return method(result, change_room_settings, DDPClient::Persistent); } quint64 DDPClient::setRoomTopic(const QString &roomId, const QString &topic) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setRoomTopic(roomId, topic, m_uid); return method(result, change_room_settings, DDPClient::Persistent); } quint64 DDPClient::setRoomType(const QString &roomId, bool privateChannel) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setRoomType(roomId, privateChannel, m_uid); return method(result, change_room_settings, DDPClient::Persistent); } quint64 DDPClient::setRoomEncrypted(const QString &roomId, bool encrypted) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setRoomEncrypted(roomId, encrypted, m_uid); return method(result, change_room_settings, DDPClient::Persistent); } quint64 DDPClient::setRoomDescription(const QString &roomId, const QString &description) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setRoomDescription(roomId, description, m_uid); return method(result, change_room_settings, DDPClient::Persistent); } quint64 DDPClient::archiveRoom(const QString &roomId) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->archiveRoom(roomId, m_uid); return method(result, change_room_settings, DDPClient::Persistent); } quint64 DDPClient::setRoomIsReadOnly(const QString &roomId, bool readOnly) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setRoomIsReadOnly(roomId, readOnly, m_uid); return method(result, change_room_settings, DDPClient::Persistent); } quint64 DDPClient::setRoomAnnouncement(const QString &roomId, const QString &announcement) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setRoomAnnouncement(roomId, announcement, m_uid); return method(result, change_room_settings, DDPClient::Persistent); } quint64 DDPClient::disableNotifications(const QString &roomId, bool disabled) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->disableNotifications(roomId, disabled, m_uid); return method(result, change_notifications_settings, DDPClient::Persistent); } quint64 DDPClient::hideUnreadStatus(const QString &roomId, bool disabled) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->hideUnreadStatus(roomId, disabled, m_uid); return method(result, change_notifications_settings, DDPClient::Persistent); } quint64 DDPClient::audioNotifications(const QString &roomId, const QString &value) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->audioNotifications(roomId, value, m_uid); return method(result, change_notifications_settings, DDPClient::Persistent); } quint64 DDPClient::mobilePushNotifications(const QString &roomId, const QString &value) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->mobilePushNotifications(roomId, value, m_uid); return method(result, change_notifications_settings, DDPClient::Persistent); } quint64 DDPClient::desktopNotifications(const QString &roomId, const QString &value) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->desktopNotifications(roomId, value, m_uid); return method(result, change_notifications_settings, DDPClient::Persistent); } quint64 DDPClient::emailNotifications(const QString &roomId, const QString &value) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->emailNotifications(roomId, value, m_uid); return method(result, change_notifications_settings, DDPClient::Persistent); } quint64 DDPClient::unreadAlert(const QString &roomId, const QString &value) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->unreadAlert(roomId, value, m_uid); return method(result, change_notifications_settings, DDPClient::Persistent); } void DDPClient::subscribeRoomMessage(const QString &roomId) { QJsonArray params; params.append(QJsonValue(roomId)); subscribe(QStringLiteral("stream-room-messages"), params); const QJsonArray params2{ QJsonValue(QStringLiteral("%1/%2").arg(roomId).arg(QStringLiteral("deleteMessage"))), true }; subscribe(QStringLiteral("stream-notify-room"), params2); const QJsonArray params3{ QJsonValue(QStringLiteral("%1/%2").arg(roomId).arg(QStringLiteral("typing"))), true }; subscribe(QStringLiteral("stream-notify-room"), params3); } quint64 DDPClient::eraseRoom(const QString &roomID) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->eraseRoom(roomID, m_uid); return method(result, erase_room, DDPClient::Persistent); } quint64 DDPClient::openDirectChannel(const QString &userId) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->openDirectChannel(userId, m_uid); return method(result, open_direct_channel, DDPClient::Persistent); } quint64 DDPClient::setReaction(const QString &emoji, const QString &messageId) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setReaction(emoji, messageId, m_uid); return method(result, empty_callback, DDPClient::Persistent); } quint64 DDPClient::createPrivateGroup(const QString &name, const QStringList &userList) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->createPrivateGroup(name, userList, m_uid); return method(result, empty_callback, DDPClient::Persistent); } quint64 DDPClient::deleteMessage(const QString &messageId) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->deleteMessage(messageId, m_uid); return method(result, delete_message, DDPClient::Persistent); } quint64 DDPClient::deleteFileMessage(const QString &roomId, const QString &fileid, const QString &channelType) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->deleteFileMessage(fileid, m_uid); std::function callback = [ roomId, channelType ](const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Delete Attachment File:") + QJsonDocument(root).toJson()); } else { qCDebug(RUQOLA_DDPAPI_LOG) << " parse users for room" << roomId; } account->roomFiles(roomId, channelType); }; return method(result, callback, DDPClient::Persistent); } quint64 DDPClient::joinRoom(const QString &roomId, const QString &joinCode) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->joinRoom(roomId, joinCode, m_uid); return method(result, join_room, DDPClient::Persistent); } quint64 DDPClient::setDefaultStatus(User::PresenceStatus status) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->setDefaultStatus(status, m_uid); return method(result, change_default_status, DDPClient::Persistent); } quint64 DDPClient::userAutocomplete(const QString &pattern, const QString &exception) { const quint64 subscribeId = m_uid; const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->userAutocomplete(pattern, exception, subscribeId); std::function callback = [=](const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("User AutoComplete:") + QJsonDocument(root).toJson()); } else { qCDebug(RUQOLA_DDPAPI_LOG) << " User AutoComplete" << root; } account->insertCompleterUsers(); const RocketChatMessage::RocketChatMessageResult resultUnsubscribe = mRocketChatMessage->unsubscribe(subscribeId); std::function callbackUnsubscribeAutoComplete = [=](const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()-> dataReceived(QByteArrayLiteral( "Unsubscribe AutoComplete:") + QJsonDocument(root).toJson()); } else { qDebug() << " Unsubscribe AutoComplete" << root; qCDebug(RUQOLA_DDPAPI_LOG) << " Unsubscribe AutoComplete" << root; } }; method(resultUnsubscribe, callbackUnsubscribeAutoComplete, DDPClient::Persistent); }; return method(result, callback, DDPClient::Persistent); } quint64 DDPClient::channelAndPrivateAutocomplete(const QString &pattern, const QString &exception) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->channelAndPrivateAutocomplete(pattern, exception, m_uid); return method(result, channel_and_private_autocomplete, DDPClient::Persistent); } quint64 DDPClient::getUsersOfRoom(const QString &roomId, bool showAll) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->getUsersOfRoom(roomId, showAll, m_uid); std::function callback = [ roomId ](const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Get Users of Room:") + QJsonDocument(root).toJson()); } else { qCDebug(RUQOLA_DDPAPI_LOG) << " parse users for room" << roomId; } RocketChatRestApi::ChannelBaseJob::ChannelInfo info; info.channelInfoType = RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; account->parseUsersForRooms(root, info); }; return method(result, callback, DDPClient::Persistent); } #if 0 quint64 DDPClient::roomFiles(const QString &roomId) { const quint64 subscribeId = m_uid; const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->roomFiles(roomId, subscribeId); std::function callback = [=](const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()->dataReceived(QByteArrayLiteral("Room File done:") + QJsonDocument(root).toJson()); } else { qDebug() << "Room Files " << root; qCDebug(RUQOLA_DDPAPI_LOG) << " Room Files" << root; } account->insertFilesList(roomId); const RocketChatMessage::RocketChatMessageResult resultUnsubscribe = mRocketChatMessage->unsubscribe(subscribeId); std::function callbackUnsubscribeAutoComplete = [=](const QJsonObject &root, RocketChatAccount *account) { if (account->ruqolaLogger()) { account->ruqolaLogger()-> dataReceived(QByteArrayLiteral( "Unsubscribe room files:") + QJsonDocument(root).toJson()); } else { qDebug() << " Unsubscribe room files" << root; qCDebug(RUQOLA_DDPAPI_LOG) << " Unsubscribe room files" << root; } }; method(resultUnsubscribe, callbackUnsubscribeAutoComplete, DDPClient::Persistent); }; return method(result, callback, DDPClient::Persistent); } #endif quint64 DDPClient::createJitsiConfCall(const QString &roomId) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->createJitsiConfCall(roomId, m_uid); return method(result, create_jitsi_conf_call, DDPClient::Persistent); } quint64 DDPClient::clearUnreadMessages(const QString &roomID) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->readMessages(roomID, m_uid); return method(result, empty_callback, DDPClient::Persistent); } quint64 DDPClient::inputChannelAutocomplete(const QString &pattern, const QString &exceptions) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->inputChannelAutocomplete(pattern, exceptions, m_uid); return method(result, input_user_channel_autocomplete, DDPClient::Persistent); } quint64 DDPClient::inputUserAutocomplete(const QString &pattern, const QString &exceptions) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->inputUserAutocomplete(pattern, exceptions, m_uid); return method(result, input_user_channel_autocomplete, DDPClient::Persistent); } quint64 DDPClient::loginProvider(const QString &credentialToken, const QString &credentialSecret) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->loginProvider(credentialToken, credentialSecret, m_uid); return method(result, empty_callback, DDPClient::Ephemeral); } quint64 DDPClient::login(const QString &username, const QString &password) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->login(username, password, mRocketChatAccount->settings()->twoFactorAuthenticationCode(), m_uid); return method(result, login_result, DDPClient::Ephemeral); } quint64 DDPClient::addUserToRoom(const QString &username, const QString &roomId) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->addUserToRoom(username, roomId, m_uid); return method(result, add_user_to_room, DDPClient::Persistent); } quint64 DDPClient::starMessage(const QString &messageId, const QString &rid, bool starred) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->starMessage(messageId, rid, starred, m_uid); return method(result, star_message, DDPClient::Persistent); } quint64 DDPClient::unBlockUser(const QString &rid, const QString &userId) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->unblockUser(rid, userId, m_uid); return method(result, unblock_user, DDPClient::Persistent); } quint64 DDPClient::blockUser(const QString &rid, const QString &userId) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->blockUser(rid, userId, m_uid); return method(result, block_user, DDPClient::Persistent); } quint64 DDPClient::informTypingStatus(const QString &roomId, bool typing, const QString &userName) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->informTypingStatus(roomId, userName, typing, m_uid); qint64 bytes = mWebSocket->sendTextMessage(result.result); if (bytes < result.result.length()) { qCDebug(RUQOLA_DDPAPI_LOG) << "ERROR! I couldn't send all of my message. This is a bug! (try again)"; qCDebug(RUQOLA_DDPAPI_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); } else { qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << result.result; } const quint64 value = m_uid; m_uid++; return value; } quint64 DDPClient::ignoreUser(const QString &roomId, const QString &userId, bool ignore) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->ignoreUser(roomId, userId, ignore, m_uid); return method(result, user_ignore, DDPClient::Persistent); } quint64 DDPClient::method(const RocketChatMessage::RocketChatMessageResult &result, std::function callback, DDPClient::MessageType messageType) { qint64 bytes = mWebSocket->sendTextMessage(result.result); if (bytes < result.result.length()) { qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "ERROR! I couldn't send all of my message. This is a bug! (try again)"; qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); if (messageType == DDPClient::Persistent) { m_messageQueue.enqueue(qMakePair(result.method, result.jsonDocument)); mRocketChatAccount->messageQueue()->processQueue(); } } else { qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << result.result; } m_callbackHash[m_uid] = callback; const quint64 value = m_uid; m_uid++; return value; } quint64 DDPClient::method(const QString &m, const QJsonDocument ¶ms, DDPClient::MessageType messageType) { return method(m, params, empty_callback, messageType); } quint64 DDPClient::method(const QString &method, const QJsonDocument ¶ms, std::function callback, DDPClient::MessageType messageType) { const RocketChatMessage::RocketChatMessageResult result = mRocketChatMessage->generateMethod(method, params, m_uid); qint64 bytes = mWebSocket->sendTextMessage(result.result); if (bytes < result.result.length()) { qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "ERROR! I couldn't send all of my message. This is a bug! (try again)"; qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); if (messageType == DDPClient::Persistent) { m_messageQueue.enqueue(qMakePair(result.method, result.jsonDocument)); mRocketChatAccount->messageQueue()->processQueue(); } } else { qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << result.result; } m_callbackHash[m_uid] = callback; const quint64 uidCurrent = m_uid; m_uid++; return uidCurrent; } void DDPClient::subscribe(const QString &collection, const QJsonArray ¶ms) { QJsonObject json; json[QStringLiteral("msg")] = QStringLiteral("sub"); json[QStringLiteral("id")] = QString::number(m_uid); json[QStringLiteral("name")] = collection; QJsonArray newParams = params; if (mRocketChatAccount->needAdaptNewSubscriptionRC60()) { QJsonArray args; QJsonObject obj; obj[QStringLiteral("useCollection")] = false; obj[QStringLiteral("args")] = args; newParams.append(obj); } json[QStringLiteral("params")] = newParams; qint64 bytes = mWebSocket->sendTextMessage(QString::fromUtf8(QJsonDocument(json).toJson(QJsonDocument::Compact))); if (bytes < json.length()) { qCDebug(RUQOLA_DDPAPI_LOG) << "ERROR! I couldn't send all of my message. This is a bug! (try again)"; qCDebug(RUQOLA_DDPAPI_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); } else { qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << json; } m_uid++; } void DDPClient::onTextMessageReceived(const QString &message) { QJsonDocument response = QJsonDocument::fromJson(message.toUtf8()); if (!response.isNull() && response.isObject()) { QJsonObject root = response.object(); const QString messageType = root.value(QLatin1String("msg")).toString(); if (messageType == QLatin1String("updated")) { //nothing to do. qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << " message updated ! not implemented yet" << response; } else if (messageType == QLatin1String("result")) { quint64 id = root.value(QLatin1String("id")).toString().toULongLong(); if (m_callbackHash.contains(id)) { std::function callback = m_callbackHash.take(id); callback(root, mRocketChatAccount); } Q_EMIT result(id, QJsonDocument(root.value(QLatin1String("result")).toObject())); if (id == m_loginJob) { const QJsonObject error(root.value(QLatin1String("error")).toObject()); const QJsonValue errorValue(error.value(QLatin1String("error"))); if (errorValue.toInt() == 403) { qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "Wrong password or token expired"; login(); // Let's keep trying to log in } else if (errorValue.toString() == QLatin1String("totp-required") || errorValue.toString() == QLatin1String("totp-invalid")) { qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "A 2FA code or backup code is required to login"; setLoginStatus(LoginCodeRequired); } else if (!error.isEmpty()) { qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << error.value(QLatin1String("message")).toString(); setLoginStatus(LoginFailed); } else { const QString token = root.value(QLatin1String("result")).toObject().value(QLatin1String("token")).toString(); mRocketChatAccount->settings()->setAuthToken(token); mRocketChatAccount->restApi()->setAuthToken(token); mRocketChatAccount->restApi()->setUserId(root.value(QLatin1String("id")).toString()); setLoginStatus(DDPClient::LoggedIn); } } } else if (messageType == QLatin1String("connected")) { qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << " Connected!"; m_connected = true; setLoginStatus(DDPClient::LoggingIn); Q_EMIT connectedChanged(); } else if (messageType == QLatin1String("error")) { qWarning() << mRocketChatAccount->accountName() << " ERROR!!" << message; } else if (messageType == QLatin1String("ping")) { qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "Ping - Pong"; pong(); } else if (messageType == QLatin1String("added")) { qCDebug(RUQOLA_DDPAPI_LOG) << mRocketChatAccount->accountName() << "ADDING element" <accountName() << "Changed element" <accountName() << "READY element" <accountName() << "REMOVED element" <accountName() << "Unsubscribe element" <accountName() << "Error unsubscribing from" << id; qWarning() << mRocketChatAccount->accountName() << "ERROR: " << errorObj[QStringLiteral("error")].toString(); qWarning() << mRocketChatAccount->accountName() << "Message: " << errorObj[QStringLiteral("message")].toString(); qWarning() << mRocketChatAccount->accountName() << "Reason: " << errorObj[QStringLiteral("reason")].toString(); qWarning() << mRocketChatAccount->accountName() << "-- Error found END --"; } } else { // The very first message we receive is {"server_id":"0"}, can't find it in the spec, just ignore it. if (messageType.isEmpty() && !root.value(QStringLiteral("server_id")).isUndefined()) { return; } qWarning() << mRocketChatAccount->accountName() << "received something unhandled:" << messageType << message; } } else { qWarning() << mRocketChatAccount->accountName() << "received something unhandled unknown " << message; } } quint64 DDPClient::loadHistory(const QJsonArray ¶ms) { return method(QStringLiteral("loadHistory"), QJsonDocument(params), process_backlog); } void DDPClient::login() { if (!mRocketChatAccount->settings()->authToken().isEmpty() && !mRocketChatAccount->settings()->tokenExpired()) { m_attemptedPasswordLogin = true; QJsonObject json; json[QStringLiteral("resume")] = mRocketChatAccount->settings()->authToken(); m_loginJob = method(QStringLiteral("login"), QJsonDocument(json)); } else if (!mRocketChatAccount->settings()->password().isEmpty()) { // If we have a password and we couldn't log in, let's stop here if (m_attemptedPasswordLogin) { setLoginStatus(LoginFailed); return; } m_attemptedPasswordLogin = true; //m_loginJob = login(mRocketChatAccount->settings()->userName(), mRocketChatAccount->settings()->password()); if (mRocketChatAccount->defaultAuthenticationInterface()) { mRocketChatAccount->defaultAuthenticationInterface()->login(); } else { qCWarning(RUQOLA_DDPAPI_LOG) <<"No plugins loaded. Please verify your installation."; setLoginStatus(FailedToLoginPluginProblem); } } else { setLoginStatus(LoginFailed); } } void DDPClient::onWSConnected() { qCDebug(RUQOLA_DDPAPI_LOG) << "Websocket connected at URL" << mUrl; QJsonArray supportedVersions; supportedVersions.append(QLatin1String("1")); QJsonObject protocol; protocol[QStringLiteral("msg")] = QStringLiteral("connect"); protocol[QStringLiteral("version")] = QStringLiteral("1"); protocol[QStringLiteral("support")] = supportedVersions; QByteArray serialize = QJsonDocument(protocol).toJson(QJsonDocument::Compact); qint64 bytes = mWebSocket->sendTextMessage(QString::fromUtf8(serialize)); if (bytes < serialize.length()) { qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "onWSConnected: ERROR! I couldn't send all of my message. This is a bug! (try again)"; qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << mWebSocket->isValid() << mWebSocket->error() << mWebSocket->requestUrl(); } else { qCDebug(RUQOLA_DDPAPI_COMMAND_LOG) << "Successfully sent " << serialize; } } void DDPClient::onSslErrors(const QList &errors) { qCDebug(RUQOLA_DDPAPI_LOG) << "SSL error" << errors.count(); for (const QSslError &err : errors) { qCDebug(RUQOLA_DDPAPI_LOG) << "error ssl type:" << err.errorString(); } mWebSocket->ignoreSslErrors(); } void DDPClient::onWSclosed() { const bool normalClose = mWebSocket->closeCode() == QWebSocketProtocol::CloseCodeNormal; if (!normalClose) { qCWarning(RUQOLA_DDPAPI_LOG) << "WebSocket CLOSED" << mWebSocket->closeReason() << mWebSocket->error() << mWebSocket->closeCode(); } setLoginStatus(NotConnected); if (normalClose) { Q_EMIT disconnectedByServer(); } } void DDPClient::pong() { QJsonObject pong; pong[QStringLiteral("msg")] = QStringLiteral("pong"); mWebSocket->sendBinaryMessage(QJsonDocument(pong).toJson(QJsonDocument::Compact)); } void DDPClient::executeSubsCallBack(const QJsonObject &root) { const QJsonArray subs = root[QStringLiteral("subs")].toArray(); if (!subs.isEmpty()) { const quint64 id = subs.at(0).toString().toULongLong(); if (m_callbackHash.contains(id)) { std::function callback = m_callbackHash.take(id); callback(root, mRocketChatAccount); } } else { qCWarning(RUQOLA_DDPAPI_LOG) << "Problem with subs json " << root; } } diff --git a/src/core/ddpapi/ddpclient.h b/src/core/ddpapi/ddpclient.h index 12ff0e14..4c5b438f 100644 --- a/src/core/ddpapi/ddpclient.h +++ b/src/core/ddpapi/ddpclient.h @@ -1,256 +1,251 @@ /* * Copyright 2016 Riccardo Iaconelli * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef DDPCLIENT_H #define DDPCLIENT_H #include "rocketchatmessage.h" #include "libruqolacore_export.h" #include #include #include #include class QJsonObject; class QJsonDocument; class RocketChatMessage; class AbstractWebSocket; class RocketChatAccount; class LIBRUQOLACORE_EXPORT DDPClient : public QObject { Q_OBJECT public: enum LoginStatus { NotConnected, LoggingIn, LoggedIn, LoginFailed, LoginCodeRequired, LoggedOut, FailedToLoginPluginProblem }; Q_ENUM(LoginStatus) enum MessageType { Persistent, Ephemeral }; explicit DDPClient(RocketChatAccount *account = nullptr, QObject *parent = nullptr); ~DDPClient() override; /** * @brief Call a method with name @param method and parameters @param params and @param messageType with an empty callback * * @param method The name of the method to call Rocket.Chat API for * @param params The parameters * @param messageType The type of message * @return unsigned int, the ID of the called method */ quint64 method(const QString &method, const QJsonDocument ¶ms, DDPClient::MessageType messageType = DDPClient::Ephemeral); /** * @brief Send message over network * * @param method The name of the method to call Rocket.Chat API for * @param params The parameters * @param callback The pointer to callback function * @param messageType The type of message * @return unsigned int, the ID of the called method */ quint64 method(const QString &method, const QJsonDocument ¶ms, std::function callback, DDPClient::MessageType messageType = DDPClient::Ephemeral); quint64 method(const RocketChatMessage::RocketChatMessageResult &result, std::function callback, DDPClient::MessageType messageType = DDPClient::Ephemeral); /** * @brief Subscribes to a collection with name @param collection and parameters @param params * * @param collection The name of the collection * @param params The parameters */ void subscribe(const QString &collection, const QJsonArray ¶ms); /** * @brief Calls method to log in the user with valid username and password */ Q_INVOKABLE void login(); - /** - * @brief Closes the websocket connection - */ - void logOut(); - /** * @brief Check whether websocket is connected at url * * @return true if connected, else false */ Q_REQUIRED_RESULT bool isConnected() const; /** * @brief Check whether user is logged in * * @return true if user is logged in, else false */ Q_REQUIRED_RESULT bool isLoggedIn() const; /** * @brief Reconnects the websocket to new url */ void onServerURLChange(); /** * @brief Returns the queue used to cache unsent messages * *@return QQueue>, The m_messageQueue object */ Q_REQUIRED_RESULT QQueue > messageQueue() const; /** * @brief Returns standard cache path * *@def QString path */ Q_REQUIRED_RESULT QString cachePath() const; Q_REQUIRED_RESULT quint64 leaveRoom(const QString &roomID); Q_REQUIRED_RESULT quint64 hideRoom(const QString &roomID); Q_REQUIRED_RESULT quint64 clearUnreadMessages(const QString &roomID); Q_REQUIRED_RESULT quint64 informTypingStatus(const QString &room, bool typing, const QString &userName); void setServerUrl(const QString &url); void start(); void setLoginJobId(quint64 jobid); Q_REQUIRED_RESULT LoginStatus loginStatus() const; Q_REQUIRED_RESULT quint64 toggleFavorite(const QString &roomID, bool favorite); Q_REQUIRED_RESULT quint64 createChannel(const QString &name, const QStringList &userList, bool readOnly); Q_REQUIRED_RESULT quint64 createPrivateGroup(const QString &name, const QStringList &userList); Q_REQUIRED_RESULT quint64 joinRoom(const QString &roomId, const QString &joinCode); Q_REQUIRED_RESULT quint64 openDirectChannel(const QString &userId); void subscribeRoomMessage(const QString &roomId); Q_REQUIRED_RESULT quint64 setDefaultStatus(User::PresenceStatus status); Q_REQUIRED_RESULT quint64 createJitsiConfCall(const QString &roomId); Q_REQUIRED_RESULT quint64 userAutocomplete(const QString &pattern, const QString &exception); Q_REQUIRED_RESULT quint64 deleteMessage(const QString &messageId); Q_REQUIRED_RESULT quint64 eraseRoom(const QString &roomID); Q_REQUIRED_RESULT quint64 setRoomName(const QString &roomId, const QString &name); Q_REQUIRED_RESULT quint64 setRoomTopic(const QString &roomId, const QString &topic); Q_REQUIRED_RESULT quint64 setRoomDescription(const QString &roomId, const QString &description); Q_REQUIRED_RESULT quint64 setRoomAnnouncement(const QString &roomId, const QString &announcement); Q_REQUIRED_RESULT quint64 starMessage(const QString &messageId, const QString &rid, bool starred); Q_REQUIRED_RESULT quint64 setRoomIsReadOnly(const QString &roomId, bool readOnly); Q_REQUIRED_RESULT quint64 archiveRoom(const QString &roomId); Q_REQUIRED_RESULT quint64 setReaction(const QString &emoji, const QString &messageId); Q_REQUIRED_RESULT quint64 getUsersOfRoom(const QString &roomId, bool showAll); Q_REQUIRED_RESULT quint64 loadHistory(const QJsonArray ¶ms); Q_REQUIRED_RESULT quint64 channelAndPrivateAutocomplete(const QString &pattern, const QString &exception); //Q_REQUIRED_RESULT quint64 roomFiles(const QString &roomId); Q_REQUIRED_RESULT quint64 addUserToRoom(const QString &userId, const QString &roomId); Q_REQUIRED_RESULT quint64 inputChannelAutocomplete(const QString &pattern, const QString &exceptions); Q_REQUIRED_RESULT quint64 inputUserAutocomplete(const QString &pattern, const QString &exceptions); Q_REQUIRED_RESULT quint64 login(const QString &username, const QString &password); Q_REQUIRED_RESULT quint64 loginProvider(const QString &credentialToken, const QString &credentialSecret); Q_REQUIRED_RESULT quint64 unBlockUser(const QString &rid, const QString &userId); Q_REQUIRED_RESULT quint64 blockUser(const QString &rid, const QString &userId); Q_REQUIRED_RESULT quint64 disableNotifications(const QString &roomId, bool disabled); Q_REQUIRED_RESULT quint64 hideUnreadStatus(const QString &roomId, bool disabled); Q_REQUIRED_RESULT quint64 audioNotifications(const QString &roomId, const QString &value); Q_REQUIRED_RESULT quint64 mobilePushNotifications(const QString &roomId, const QString &value); Q_REQUIRED_RESULT quint64 desktopNotifications(const QString &roomId, const QString &value); Q_REQUIRED_RESULT quint64 emailNotifications(const QString &roomId, const QString &value); Q_REQUIRED_RESULT quint64 unreadAlert(const QString &roomId, const QString &value); Q_REQUIRED_RESULT quint64 deleteFileMessage(const QString &roomId, const QString &fileid, const QString &channelType); Q_REQUIRED_RESULT quint64 setRoomType(const QString &roomId, bool privateChannel); Q_REQUIRED_RESULT quint64 ignoreUser(const QString &roomId, const QString &userId, bool ignore); Q_REQUIRED_RESULT quint64 setRoomEncrypted(const QString &roomId, bool encrypted); Q_SIGNALS: void connectedChanged(); void loginStatusChanged(); void added(const QJsonObject &item); void changed(const QJsonObject &item); void removed(const QJsonObject &item); void socketError(QAbstractSocket::SocketError error, const QString &errorString); void disconnectedByServer(); /** * @brief Emitted whenever a result is received * * @param id The ID received in the method() call * @param result The response sent by server */ void result(quint64 id, const QJsonDocument &result); private Q_SLOTS: void onWSConnected(); void onTextMessageReceived(const QString &message); void onWSclosed(); void onSslErrors(const QList &errors); private: Q_DISABLE_COPY(DDPClient) void initializeWebSocket(); QUrl adaptUrl(const QString &url); void setLoginStatus(LoginStatus l); void pong(); void executeSubsCallBack(const QJsonObject &root); QString mUrl; AbstractWebSocket *mWebSocket = nullptr; /** * @brief Unique message ID for each message sent over network */ quint64 m_uid = 0; /** * @brief Stores callback function associated with each message * * @def QHash unsigned messageID and std::function pointer to callback */ QHash > m_callbackHash; quint64 m_loginJob = 0; LoginStatus m_loginStatus; bool m_connected = false; bool m_attemptedPasswordLogin = false; /** * @brief Abstract queue for all requests regarding network management * * @def QPair QString method and QJsonDocument params */ QQueue > m_messageQueue; friend class Ruqola; RocketChatMessage *mRocketChatMessage = nullptr; RocketChatAccount *mRocketChatAccount = nullptr; }; #endif // DDPCLIENT_H diff --git a/src/core/rocketchataccount.cpp b/src/core/rocketchataccount.cpp index 119355b4..4af4159f 100644 --- a/src/core/rocketchataccount.cpp +++ b/src/core/rocketchataccount.cpp @@ -1,1980 +1,1977 @@ /* Copyright (c) 2017-2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "model/messagemodel.h" #include "rocketchataccount.h" #include "model/roommodel.h" #include "roomwrapper.h" #include "typingnotification.h" #include "model/usersmodel.h" #include "ruqola_debug.h" #include "ruqola.h" #include "messagequeue.h" #include "rocketchatbackend.h" #include "model/roomfilterproxymodel.h" #include "ruqolalogger.h" #include "ruqolaserverconfig.h" #include "model/usercompletermodel.h" #include "model/usercompleterfilterproxymodel.h" #include "model/statusmodel.h" #include "utils.h" #include "rocketchatcache.h" #include "fileattachments.h" #include "emoticons/emojimanager.h" #include "model/emoticonmodel.h" #include "otrmanager.h" #include "inputtextmanager.h" #include "model/usersforroommodel.h" #include "model/filesforroommodel.h" #include "model/searchchannelfilterproxymodel.h" #include "model/searchchannelmodel.h" #include "model/loginmethodmodel.h" #include "model/inputcompletermodel.h" #include "model/searchmessagemodel.h" #include "model/searchmessagefilterproxymodel.h" #include "model/discussionsmodel.h" #include "model/threadsmodel.h" #include "model/filesforroomfilterproxymodel.h" #include "model/discussionsfilterproxymodel.h" #include "model/threadsfilterproxymodel.h" #include "model/listmessagesmodel.h" #include "model/threadmessagemodel.h" #include "model/listmessagesmodelfilterproxymodel.h" #include "model/autotranslatelanguagesmodel.h" #include "managerdatapaths.h" #include "authenticationmanager.h" #include "ddpapi/ddpclient.h" #include "discussions.h" #include "receivetypingnotificationmanager.h" #include "restapirequest.h" #include "serverconfiginfo.h" #include "listmessages.h" #include "threads.h" #include #include #include #include #include #include "users/setstatusjob.h" #include "users/usersautocompletejob.h" #define USE_REASTAPI_JOB 1 RocketChatAccount::RocketChatAccount(const QString &accountFileName, QObject *parent) : QObject(parent) { mAccountRoomSettings = new AccountRoomSettings; qCDebug(RUQOLA_LOG) << " RocketChatAccount::RocketChatAccount(const QString &accountFileName, QObject *parent)"<accountName()); } mServerConfigInfo = new ServerConfigInfo(this, this); //Create it before loading settings mLoginMethodModel = new LoginMethodModel(this); mInputTextManager = new InputTextManager(this); connect(mInputTextManager, &InputTextManager::inputCompleter, this, &RocketChatAccount::inputAutocomplete); mInputThreadMessageTextManager = new InputTextManager(this); connect(mInputThreadMessageTextManager, &InputTextManager::inputCompleter, this, &RocketChatAccount::inputThreadMessageAutocomplete); mRuqolaServerConfig = new RuqolaServerConfig; mReceiveTypingNotificationManager = new ReceiveTypingNotificationManager(this); initializeAuthenticationPlugins(); mRocketChatBackend = new RocketChatBackend(this, this); mEmoticonModel = new EmoticonModel(this); //After loadSettings mEmojiManager = new EmojiManager(this); mEmojiManager->setServerUrl(mSettings->serverUrl()); mEmoticonModel->setEmoticons(mEmojiManager->unicodeEmojiList()); mOtrManager = new OtrManager(this); mRoomFilterProxyModel = new RoomFilterProxyModel(this); mUserCompleterModel = new UserCompleterModel(this); mUserCompleterFilterModelProxy = new UserCompleterFilterProxyModel(this); mUserCompleterFilterModelProxy->setSourceModel(mUserCompleterModel); mSearchChannelModel = new SearchChannelModel(this); mSearchChannelFilterProxyModel = new SearchChannelFilterProxyModel(this); mSearchChannelFilterProxyModel->setSourceModel(mSearchChannelModel); mSearchMessageModel = new SearchMessageModel(QString(), this, nullptr, this); mSearchMessageFilterProxyModel = new SearchMessageFilterProxyModel(mSearchMessageModel, this); mFilesModelForRoom = new FilesForRoomModel(this, this); mFilesModelForRoom->setObjectName(QStringLiteral("filesmodelforrooms")); mFilesForRoomFilterProxyModel = new FilesForRoomFilterProxyModel(mFilesModelForRoom, this); mFilesForRoomFilterProxyModel->setObjectName(QStringLiteral("filesforroomfiltermodelproxy")); mDiscussionsModel = new DiscussionsModel(this); mDiscussionsModel->setObjectName(QStringLiteral("discussionsmodel")); mDiscussionsFilterProxyModel = new DiscussionsFilterProxyModel(mDiscussionsModel, this); mDiscussionsFilterProxyModel->setObjectName(QStringLiteral("discussionsfilterproxymodel")); mThreadsModel = new ThreadsModel(this); mThreadsModel->setObjectName(QStringLiteral("threadsmodel")); mThreadsFilterProxyModel = new ThreadsFilterProxyModel(mThreadsModel, this); mThreadsFilterProxyModel->setObjectName(QStringLiteral("threadsfiltermodelproxy")); mThreadMessageModel = new ThreadMessageModel(QString(), this, nullptr, this); mThreadMessageModel->setObjectName(QStringLiteral("threadmessagemodel")); mListMessageModel = new ListMessagesModel(QString(), this, nullptr, this); mListMessageModel->setObjectName(QStringLiteral("listmessagemodel")); mListMessagesFilterProxyModel = new ListMessagesModelFilterProxyModel(mListMessageModel, this); mListMessagesFilterProxyModel->setObjectName(QStringLiteral("listmessagesfiltermodelproxy")); mAutoTranslateLanguagesModel = new AutotranslateLanguagesModel(this); mAutoTranslateLanguagesModel->setObjectName(QStringLiteral("autotranslatelanguagesmodel")); mStatusModel = new StatusModel(this); mRoomModel = new RoomModel(this, this); connect(mRoomModel, &RoomModel::needToUpdateNotification, this, &RocketChatAccount::slotNeedToUpdateNotification); mRoomFilterProxyModel->setSourceModel(mRoomModel); mUserModel = new UsersModel(this); connect(mUserModel, &UsersModel::userStatusChanged, this, &RocketChatAccount::userStatusChanged); mMessageQueue = new MessageQueue(this, this); //TODO fix mem leak ! mTypingNotification = new TypingNotification(this); mCache = new RocketChatCache(this, this); connect(mCache, &RocketChatCache::fileDownloaded, this, &RocketChatAccount::fileDownloaded); connect(mTypingNotification, &TypingNotification::informTypingStatus, this, &RocketChatAccount::slotInformTypingStatus); QTimer::singleShot(0, this, &RocketChatAccount::clearModels); } RocketChatAccount::~RocketChatAccount() { delete mCache; mCache = nullptr; delete mRuqolaServerConfig; delete mRuqolaLogger; delete mAccountRoomSettings; } void RocketChatAccount::removeSettings() { mSettings->removeSettings(); } void RocketChatAccount::loadSettings(const QString &accountFileName) { delete mSettings; mSettings = new RocketChatAccountSettings(accountFileName, this); connect(mSettings, &RocketChatAccountSettings::serverURLChanged, this, &RocketChatAccount::serverUrlChanged); connect(mSettings, &RocketChatAccountSettings::userIDChanged, this, &RocketChatAccount::userIDChanged); connect(mSettings, &RocketChatAccountSettings::userNameChanged, this, &RocketChatAccount::userNameChanged); connect(mSettings, &RocketChatAccountSettings::passwordChanged, this, &RocketChatAccount::passwordChanged); } void RocketChatAccount::slotNeedToUpdateNotification() { bool hasAlert = false; int nbUnread = 0; mRoomModel->getUnreadAlertFromAccount(hasAlert, nbUnread); Q_EMIT updateNotification(hasAlert, nbUnread, accountName()); } void RocketChatAccount::clearModels() { // Clear rooms data and refill it with data in the cache, if there is mRoomModel->reset(); mMessageQueue->loadCache(); //Try to send queue message mMessageQueue->processQueue(); } SearchChannelFilterProxyModel *RocketChatAccount::searchChannelFilterProxyModel() const { return mSearchChannelFilterProxyModel; } SearchChannelModel *RocketChatAccount::searchChannelModel() const { return mSearchChannelModel; } UserCompleterModel *RocketChatAccount::userCompleterModel() const { return mUserCompleterModel; } UserCompleterFilterProxyModel *RocketChatAccount::userCompleterFilterModelProxy() const { return mUserCompleterFilterModelProxy; } EmojiManager *RocketChatAccount::emojiManager() const { return mEmojiManager; } QString RocketChatAccount::userStatusIconFileName(const QString &name) { return mUserModel->userStatusIconFileName(name); } StatusModel *RocketChatAccount::statusModel() const { return mStatusModel; } RuqolaServerConfig *RocketChatAccount::ruqolaServerConfig() const { return mRuqolaServerConfig; } RuqolaLogger *RocketChatAccount::ruqolaLogger() const { return mRuqolaLogger; } RoomFilterProxyModel *RocketChatAccount::roomFilterProxyModel() const { return mRoomFilterProxyModel; } UsersForRoomFilterProxyModel *RocketChatAccount::usersForRoomFilterProxyModel(const QString &roomId) const { return mRoomModel->usersForRoomFilterProxyModel(roomId); } FilesForRoomFilterProxyModel *RocketChatAccount::filesForRoomFilterProxyModel() const { return mFilesForRoomFilterProxyModel; } RocketChatBackend *RocketChatAccount::rocketChatBackend() const { return mRocketChatBackend; } MessageQueue *RocketChatAccount::messageQueue() const { return mMessageQueue; } RocketChatAccountSettings *RocketChatAccount::settings() const { return mSettings; } void RocketChatAccount::slotInformTypingStatus(const QString &room, bool typing) { ddp()->informTypingStatus(room, typing, mSettings->userName()); } RoomModel *RocketChatAccount::roomModel() const { return mRoomModel; } UsersModel *RocketChatAccount::usersModel() const { return mUserModel; } Room *RocketChatAccount::getRoom(const QString &roomId) { return mRoomModel->findRoom(roomId); } DiscussionsFilterProxyModel *RocketChatAccount::discussionsFilterProxyModel() const { return mDiscussionsFilterProxyModel; } ThreadsFilterProxyModel *RocketChatAccount::threadsFilterProxyModel() const { return mThreadsFilterProxyModel; } RoomWrapper *RocketChatAccount::roomWrapper(const QString &roomId) { return mRoomModel->findRoomWrapper(roomId); } MessageModel *RocketChatAccount::messageModelForRoom(const QString &roomID) { return mRoomModel->messageModel(roomID); } void RocketChatAccount::changeDisplayAttachment(const QString &roomId, const QString &messageId, bool displayAttachment) { MessageModel *model = mRoomModel->messageModel(roomId); if (model) { model->changeDisplayAttachment(messageId, displayAttachment); } else { qCWarning(RUQOLA_LOG) << "impossible to find room: " << roomId; } //TODO } void RocketChatAccount::changeShowOriginalMessage(const QString &roomId, const QString &messageId, bool showOriginal) { MessageModel *model = mRoomModel->messageModel(roomId); if (model) { model->changeShowOriginalMessage(messageId, showOriginal); } else { qCWarning(RUQOLA_LOG) << "impossible to find room: " << roomId; } //TODO } QString RocketChatAccount::getUserCurrentMessage(const QString &roomId) { return mRoomModel->inputMessage(roomId); } void RocketChatAccount::setUserCurrentMessage(const QString &message, const QString &roomId) { mRoomModel->setInputMessage(roomId, message); } void RocketChatAccount::textEditing(const QString &roomId, bool clearNotification) { mTypingNotification->textNotificationChanged(roomId, clearNotification); } void RocketChatAccount::reactOnMessage(const QString &messageId, const QString &emoji, bool shouldReact) { restApi()->reactOnMessage(messageId, emoji, shouldReact); } void RocketChatAccount::replyToMessage(const QString &roomID, const QString &message, const QString &messageId) { restApi()->postMessage(roomID, message); } void RocketChatAccount::sendMessage(const QString &roomID, const QString &message) { restApi()->postMessage(roomID, message); } void RocketChatAccount::updateMessage(const QString &roomID, const QString &messageId, const QString &message) { restApi()->updateMessage(roomID, messageId, message); } void RocketChatAccount::replyOnThread(const QString &roomID, const QString &threadMessageId, const QString &message) { restApi()->sendMessage(roomID, message, QString(), threadMessageId); } QString RocketChatAccount::avatarUrlFromDirectChannel(const QString &rid) { return mCache->avatarUrl(Utils::userIdFromDirectChannel(rid, userID())); } void RocketChatAccount::deleteFileMessage(const QString &roomId, const QString &fileId, const QString &channelType) { ddp()->deleteFileMessage(roomId, fileId, channelType); } QString RocketChatAccount::avatarUrl(const QString &userId) { return mCache->avatarUrl(userId); } void RocketChatAccount::insertAvatarUrl(const QString &userId, const QUrl &url) { mCache->insertAvatarUrl(userId, url); } RocketChatRestApi::RestApiRequest *RocketChatAccount::restApi() { if (!mRestApi) { mRestApi = new RocketChatRestApi::RestApiRequest(this); connect(mRestApi, &RocketChatRestApi::RestApiRequest::setChannelJoinDone, this, &RocketChatAccount::setChannelJoinDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::missingChannelPassword, this, &RocketChatAccount::missingChannelPassword); connect(mRestApi, &RocketChatRestApi::RestApiRequest::loadEmojiCustomDone, this, &RocketChatAccount::loadEmoji); connect(mRestApi, &RocketChatRestApi::RestApiRequest::openArchivedRoom, this, &RocketChatAccount::openArchivedRoom); connect(mRestApi, &RocketChatRestApi::RestApiRequest::channelMembersDone, this, &RocketChatAccount::parseUsersForRooms); connect(mRestApi, &RocketChatRestApi::RestApiRequest::channelFilesDone, this, &RocketChatAccount::slotChannelFilesDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::channelRolesDone, this, &RocketChatAccount::slotChannelRolesDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::searchMessageDone, this, &RocketChatAccount::slotSearchMessages); connect(mRestApi, &RocketChatRestApi::RestApiRequest::failed, this, &RocketChatAccount::jobFailed); connect(mRestApi, &RocketChatRestApi::RestApiRequest::spotlightDone, this, &RocketChatAccount::slotSplotLightDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getThreadMessagesDone, this, &RocketChatAccount::slotGetThreadMessagesDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getThreadsDone, this, &RocketChatAccount::slotGetThreadsListDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getDiscussionsDone, this, &RocketChatAccount::slotGetDiscussionsListDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::channelGetAllUserMentionsDone, this, [this](const QJsonObject &obj, const QString &roomId) { slotGetListMessagesDone(obj, roomId, ListMessagesModel::ListMessageType::MentionsMessages); }); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getPinnedMessagesDone, this, [this](const QJsonObject &obj, const QString &roomId) { slotGetListMessagesDone(obj, roomId, ListMessagesModel::ListMessageType::PinnedMessages); }); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getSnippetedMessagesDone, this, [this](const QJsonObject &obj, const QString &roomId) { slotGetListMessagesDone(obj, roomId, ListMessagesModel::ListMessageType::SnipperedMessages); }); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getStarredMessagesDone, this, [this](const QJsonObject &obj, const QString &roomId) { slotGetListMessagesDone(obj, roomId, ListMessagesModel::ListMessageType::StarredMessages); }); connect(mRestApi, &RocketChatRestApi::RestApiRequest::getSupportedLanguagesDone, this, &RocketChatAccount::slotGetSupportedLanguagesDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::usersPresenceDone, this, &RocketChatAccount::slotUsersPresenceDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::usersAutocompleteDone, this, &RocketChatAccount::slotUserAutoCompleterDone); connect(mRestApi, &RocketChatRestApi::RestApiRequest::roomsAutoCompleteChannelAndPrivateDone, this, &RocketChatAccount::slotRoomsAutoCompleteChannelAndPrivateDone); mRestApi->setServerUrl(mSettings->serverUrl()); mRestApi->setRestApiLogger(mRuqolaLogger); } return mRestApi; } void RocketChatAccount::leaveRoom(const QString &roomId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->leaveChannel(roomId); } else if (channelType == QLatin1Char('p')) { restApi()->leaveGroups(roomId); } else { qCWarning(RUQOLA_LOG) << " unsupport leave room for type " << channelType; } } void RocketChatAccount::hideRoom(const QString &roomId, const QString &channelType) { restApi()->closeChannel(roomId, channelType); } DDPClient *RocketChatAccount::ddp() { if (!mDdp) { mDdp = new DDPClient(this, this); connect(mDdp, &DDPClient::loginStatusChanged, this, &RocketChatAccount::loginStatusChanged); connect(mDdp, &DDPClient::connectedChanged, this, &RocketChatAccount::connectedChanged); connect(mDdp, &DDPClient::changed, this, &RocketChatAccount::changed); connect(mDdp, &DDPClient::added, this, &RocketChatAccount::added); connect(mDdp, &DDPClient::removed, this, &RocketChatAccount::removed); connect(mDdp, &DDPClient::socketError, this, &RocketChatAccount::socketError); connect(mDdp, &DDPClient::disconnectedByServer, this, &RocketChatAccount::slotDisconnectedByServer); if (mSettings) { mDdp->setServerUrl(mSettings->serverUrl()); } mDdp->start(); } return mDdp; } bool RocketChatAccount::editingMode() const { return mEditingMode; } DDPClient::LoginStatus RocketChatAccount::loginStatus() { if (mDdp) { return ddp()->loginStatus(); } else { return DDPClient::LoggedOut; } } void RocketChatAccount::tryLogin() { qCDebug(RUQOLA_LOG) << "Attempting login" << mSettings->userName() << "on" << mSettings->serverUrl(); delete mDdp; mDdp = nullptr; // This creates a new ddp() object. // DDP will automatically try to connect and login. ddp(); // In the meantime, load cache... mRoomModel->reset(); } void RocketChatAccount::logOut() { mSettings->logout(); mRoomModel->clear(); #ifdef USE_REASTAPI_JOB restApi()->logout(); #else QJsonObject user; user[QStringLiteral("username")] = mSettings->userName(); QJsonObject json; json[QStringLiteral("user")] = user; ddp()->method(QStringLiteral("logout"), QJsonDocument(json)); #endif delete mDdp; mDdp = nullptr; Q_EMIT logoutDone(accountName()); Q_EMIT loginStatusChanged(); qCDebug(RUQOLA_LOG) << "Successfully logged out!"; } void RocketChatAccount::clearAllUnreadMessages() { for (int roomIdx = 0, nRooms = mRoomModel->rowCount(); roomIdx < nRooms; ++roomIdx) { const auto roomModelIndex = mRoomModel->index(roomIdx); const auto roomId = roomModelIndex.data(RoomModel::RoomID).toString(); const bool roomHasAlert = roomModelIndex.data(RoomModel::RoomAlert).toBool(); if (roomHasAlert) { clearUnreadMessages(roomId); } } } void RocketChatAccount::clearUnreadMessages(const QString &roomId) { restApi()->markAsRead(roomId); } void RocketChatAccount::changeFavorite(const QString &roomId, bool checked) { restApi()->markAsFavorite(roomId, checked); } void RocketChatAccount::openChannel(const QString &url, ChannelTypeInfo typeInfo) { RocketChatRestApi::ChannelBaseJob::ChannelInfo info; switch (typeInfo) { case ChannelTypeInfo::RoomId: info.channelInfoType = RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomId; break; case ChannelTypeInfo::RoomName: info.channelInfoType = RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomName; break; } info.channelInfoIdentifier = url; qCDebug(RUQOLA_LOG) << "opening channel" << url; restApi()->channelJoin(info, QString()); } void RocketChatAccount::setChannelJoinDone(const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo) { ddp()->subscribeRoomMessage(channelInfo.channelInfoIdentifier); //FIXME room is not added yet... switch(channelInfo.channelInfoType) { case RocketChatRestApi::ChannelBaseJob::ChannelInfoType::Unknown: qCWarning(RUQOLA_LOG) << "setChannelJoinDone : RocketChatRestApi::ChannelBaseJob::ChannelInfoType::Unknown"; break; case RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomId: Q_EMIT selectRoomByRoomIdRequested(channelInfo.channelInfoIdentifier); break; case RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomName: Q_EMIT selectRoomByRoomNameRequested(channelInfo.channelInfoIdentifier); break; } } void RocketChatAccount::openArchivedRoom(const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo) { //TODO } void RocketChatAccount::joinJitsiConfCall(const QString &roomId) { qCDebug(RUQOLA_LOG) << " void RocketChatAccount::joinJitsiConfCall(const QString &roomId)"<uniqueId() + roomId).toUtf8(), QCryptographicHash::Md5).toHex()); #if defined(Q_OS_IOS) || defined(Q_OS_ANDROID) const QString scheme = QStringLiteral("org.jitsi.meet://"); #else const QString scheme = QStringLiteral("https://"); #endif const QString url = scheme + mRuqolaServerConfig->jitsiMeetUrl() + QLatin1Char('/') + mRuqolaServerConfig->jitsiMeetPrefix() + hash; const QUrl clickedUrl = QUrl::fromUserInput(url); QDesktopServices::openUrl(clickedUrl); } void RocketChatAccount::eraseRoom(const QString &roomId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->channelDelete(roomId); } else if (channelType == QLatin1Char('p')) { restApi()->groupDelete(roomId); } else { qCWarning(RUQOLA_LOG) << " unsupport delete for type " << channelType; } } void RocketChatAccount::openDirectChannel(const QString &username) { //Laurent for the moment I didn't find a restapi method for it //TODO verify username vs userId //#ifdef USE_REASTAPI_JOB // restApi()->openDirectMessage(username); //#else qDebug() << "Open direct conversation channel with" << username; ddp()->openDirectChannel(username); //#endif } void RocketChatAccount::createNewChannel(const QString &name, bool readOnly, bool privateRoom, const QString &userNames, bool encryptedRoom, const QString &password, bool broadcast) { //TODO use encrypted room //TODO use broadcast if (!name.trimmed().isEmpty()) { const QStringList lstUsers = userNames.split(QLatin1Char(','), QString::SkipEmptyParts); if (privateRoom) { //TODO add password ??? restApi()->createGroups(name, readOnly, lstUsers); } else { restApi()->createChannels(name, readOnly, lstUsers, password); } } else { qCDebug(RUQOLA_LOG) << "Channel name can't be empty"; } } void RocketChatAccount::joinRoom(const QString &roomId, const QString &joinCode) { RocketChatRestApi::ChannelBaseJob::ChannelInfo info; info.channelInfoType = RocketChatRestApi::ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; restApi()->channelJoin(info, joinCode); } void RocketChatAccount::channelAndPrivateAutocomplete(const QString &pattern) { if (pattern.isEmpty()) { searchChannelModel()->clear(); } else { //Use restapi //Avoid to show own user #ifdef USE_REASTAPI_JOB restApi()->searchRoomUser(pattern); #else const QString addUserNameToException = userName(); ddp()->channelAndPrivateAutocomplete(pattern, addUserNameToException); #endif } } void RocketChatAccount::listEmojiCustom() { restApi()->listEmojiCustom(); } void RocketChatAccount::setDefaultStatus(User::PresenceStatus status, const QString &messageStatus) { #ifdef USE_REASTAPI_JOB RocketChatRestApi::SetStatusJob::StatusType type = RocketChatRestApi::SetStatusJob::Unknown; switch (status) { case User::PresenceStatus::PresenceOnline: type = RocketChatRestApi::SetStatusJob::OnLine; break; case User::PresenceStatus::PresenceBusy: type = RocketChatRestApi::SetStatusJob::Busy; break; case User::PresenceStatus::PresenceAway: type = RocketChatRestApi::SetStatusJob::Away; break; case User::PresenceStatus::PresenceOffline: type = RocketChatRestApi::SetStatusJob::Offline; break; case User::PresenceStatus::Unknown: type = RocketChatRestApi::SetStatusJob::Unknown; break; } restApi()->setUserStatus(userID(), type, messageStatus); #else Q_UNUSED(messageStatus); ddp()->setDefaultStatus(status); #endif } void RocketChatAccount::changeDefaultStatus(int index, const QString &messageStatus) { setDefaultStatus(mStatusModel->status(index), messageStatus); } void RocketChatAccount::loadEmoji(const QJsonObject &obj) { mEmojiManager->loadCustomEmoji(obj); } void RocketChatAccount::deleteMessage(const QString &messageId, const QString &roomId) { restApi()->deleteMessage(roomId, messageId); } void RocketChatAccount::insertCompleterUsers() { userCompleterModel()->insertUsers(rocketChatBackend()->users()); } void RocketChatAccount::userAutocomplete(const QString &searchText, const QString &exception) { userCompleterModel()->clear(); if (mRuqolaServerConfig->hasAtLeastVersion(2, 4, 0)) { if (!searchText.isEmpty()) { RocketChatRestApi::UsersAutocompleteJob::UsersAutocompleterInfo info; info.pattern = searchText; info.exception = exception; restApi()->usersAutocomplete(info); } } else { //Clear before to create new search rocketChatBackend()->clearUsersList(); if (!searchText.isEmpty()) { //Avoid to show own user QString addUserNameToException; if (exception.isEmpty()) { addUserNameToException = userName(); } else { addUserNameToException = exception + QLatin1Char(',') + userName(); } ddp()->userAutocomplete(searchText, addUserNameToException); } } } void RocketChatAccount::membersInRoom(const QString &roomId, const QString &roomType) { restApi()->membersInRoom(roomId, roomType); } void RocketChatAccount::parseUsersForRooms(const QJsonObject &obj, const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo) { //FIXME channelInfo const QString channelInfoIdentifier = channelInfo.channelInfoIdentifier; UsersForRoomModel *usersModelForRoom = roomModel()->usersModelForRoom(channelInfoIdentifier); if (usersModelForRoom) { usersModelForRoom->parseUsersForRooms(obj, mUserModel, true); } else { qCWarning(RUQOLA_LOG) << " Impossible to find room " << channelInfoIdentifier; } } void RocketChatAccount::loadAutoCompleteChannel(const QJsonObject &obj) { mSearchChannelModel->parseChannels(obj); } void RocketChatAccount::roomFiles(const QString &roomId, const QString &channelType) { mFilesModelForRoom->initialize(); restApi()->filesInRoom(roomId, channelType); } MessageModel *RocketChatAccount::threadMessageModel() const { return mThreadMessageModel; } ThreadsModel *RocketChatAccount::threadsModel() const { return mThreadsModel; } DiscussionsModel *RocketChatAccount::discussionsModel() const { return mDiscussionsModel; } FilesForRoomModel *RocketChatAccount::filesModelForRoom() const { return mFilesModelForRoom; } EmoticonModel *RocketChatAccount::emoticonModel() const { return mEmoticonModel; } ReceiveTypingNotificationManager *RocketChatAccount::receiveTypingNotificationManager() const { return mReceiveTypingNotificationManager; } void RocketChatAccount::slotChannelRolesDone(const QJsonObject &obj, const RocketChatRestApi::ChannelBaseJob::ChannelInfo &channelInfo) { Room *room = mRoomModel->findRoom(channelInfo.channelInfoIdentifier); if (room) { Roles r; r.parseRole(obj); room->setRolesForRooms(r); } else { qCWarning(RUQOLA_LOG) << " Impossible to find room " << channelInfo.channelInfoIdentifier; } } void RocketChatAccount::slotGetThreadMessagesDone(const QJsonObject &obj, const QString &threadMessageId) { if (mThreadMessageModel->threadMessageId() != threadMessageId) { mThreadMessageModel->setThreadMessageId(threadMessageId); mThreadMessageModel->parseThreadMessages(obj); } else { mThreadMessageModel->loadMoreThreadMessages(obj); } } void RocketChatAccount::slotGetDiscussionsListDone(const QJsonObject &obj, const QString &roomId) { if (mDiscussionsModel->roomId() != roomId) { mDiscussionsModel->parseDiscussions(obj, roomId); } else { mDiscussionsModel->addMoreDiscussions(obj); } mDiscussionsModel->setLoadMoreDiscussionsInProgress(false); } void RocketChatAccount::slotGetListMessagesDone(const QJsonObject &obj, const QString &roomId, ListMessagesModel::ListMessageType type) { if (mListMessageModel->roomId() != roomId || mListMessageModel->listMessageType() != type) { mListMessageModel->setRoomId(roomId); mListMessageModel->setListMessageType(type); mListMessageModel->parseListMessages(obj); } else { mListMessageModel->loadMoreListMessages(obj); } mListMessageModel->setLoadMoreListMessagesInProgress(false); } void RocketChatAccount::slotUserAutoCompleterDone(const QJsonObject &obj) { const QVector users = User::parseUsersList(obj); mUserCompleterModel->insertUsers(users); } void RocketChatAccount::slotRoomsAutoCompleteChannelAndPrivateDone(const QJsonObject &obj) { //TODO } AccountRoomSettings *RocketChatAccount::accountRoomSettings() const { return mAccountRoomSettings; } ListMessagesModelFilterProxyModel *RocketChatAccount::listMessagesFilterProxyModel() const { return mListMessagesFilterProxyModel; } ListMessagesModel *RocketChatAccount::listMessageModel() const { return mListMessageModel; } void RocketChatAccount::slotGetThreadsListDone(const QJsonObject &obj, const QString &roomId) { if (mThreadsModel->roomId() != roomId) { mThreadsModel->parseThreads(obj, roomId); } else { mThreadsModel->addMoreThreads(obj); } mThreadsModel->setLoadMoreThreadsInProgress(false); } void RocketChatAccount::slotSplotLightDone(const QJsonObject &obj) { //qDebug() << " void RocketChatAccount::slotSplotLightDone(const QJsonObject &obj)"<roomId() != channelInfo.channelInfoIdentifier) { mFilesModelForRoom->parseFileAttachments(obj, channelInfo.channelInfoIdentifier); } else { mFilesModelForRoom->addMoreFileAttachments(obj); } mFilesModelForRoom->setLoadMoreFilesInProgress(false); } void RocketChatAccount::loadMoreUsersInRoom(const QString &roomId, const QString &channelType) { UsersForRoomModel *usersModelForRoom = roomModel()->usersModelForRoom(roomId); const int offset = usersModelForRoom->usersCount(); if (offset < usersModelForRoom->total()) { restApi()->membersInRoom(roomId, channelType, offset, qMin(50, usersModelForRoom->total() - offset)); } } void RocketChatAccount::getMentionsMessages(const QString &roomId) { mListMessageModel->clear(); mListMessageModel->setRoomId(roomId); restApi()->channelGetAllUserMentions(roomId); } void RocketChatAccount::getPinnedMessages(const QString &roomId) { if (hasPinnedMessagesSupport()) { mListMessageModel->clear(); mListMessageModel->setRoomId(roomId); restApi()->getPinnedMessages(roomId); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::getPinnedMessages is not supported before server 2.0.0"; } } bool RocketChatAccount::hasPinnedMessagesSupport() const { return mRuqolaServerConfig->hasAtLeastVersion(1, 4, 0); } bool RocketChatAccount::hasStarredMessagesSupport() const { return mRuqolaServerConfig->hasAtLeastVersion(2, 3, 0); } void RocketChatAccount::getStarredMessages(const QString &roomId) { if (hasStarredMessagesSupport()) { mListMessageModel->clear(); mListMessageModel->setRoomId(roomId); restApi()->getStarredMessages(roomId); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::getStarredMessages is not supported before server 2.3.0"; } } bool RocketChatAccount::hasSnippetedMessagesSupport() const { return mRuqolaServerConfig->hasAtLeastVersion(2, 3, 0); } void RocketChatAccount::getSnippetedMessages(const QString &roomId) { if (hasSnippetedMessagesSupport()) { mListMessageModel->clear(); mListMessageModel->setRoomId(roomId); restApi()->getSnippetedMessages(roomId); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::getSnippetedMessages is not supported before server 2.3.0"; } } void RocketChatAccount::loadMoreFileAttachments(const QString &roomId, const QString &channelType) { if (!mFilesModelForRoom->loadMoreFilesInProgress()) { const int offset = mFilesModelForRoom->fileAttachments()->filesCount(); if (offset < mFilesModelForRoom->fileAttachments()->total()) { mFilesModelForRoom->setLoadMoreFilesInProgress(true); restApi()->filesInRoom(roomId, channelType, offset, qMin(50, mFilesModelForRoom->fileAttachments()->total() - offset)); } } } void RocketChatAccount::loadMoreDiscussions(const QString &roomId) { if (!mDiscussionsModel->loadMoreDiscussionsInProgress()) { const int offset = mDiscussionsModel->discussions()->discussionsCount(); if (offset < mDiscussionsModel->discussions()->total()) { mDiscussionsModel->setLoadMoreDiscussionsInProgress(true); restApi()->getDiscussions(roomId, offset, qMin(50, mDiscussionsModel->discussions()->total() - offset)); } } } void RocketChatAccount::updateThreadMessageList(const Message &m) { if (mThreadMessageModel->threadMessageId() == m.threadMessageId()) { mThreadMessageModel->addMessage(m); } } void RocketChatAccount::loadMoreThreads(const QString &roomId) { if (!mThreadsModel->loadMoreThreadsInProgress()) { const int offset = mThreadsModel->threads()->threadsCount(); if (offset < mThreadsModel->threads()->total()) { restApi()->getThreadsList(roomId, offset, qMin(50, mThreadsModel->threads()->total() - offset)); } } } void RocketChatAccount::getListMessages(const QString &roomId, ListMessagesModel::ListMessageType type) { mListMessageModel->setListMessageType(type); switch (type) { case ListMessagesModel::Unknown: qCWarning(RUQOLA_LOG) << " Error when using getListMessages"; break; case ListMessagesModel::StarredMessages: if (hasStarredMessagesSupport()) { getStarredMessages(roomId); } break; case ListMessagesModel::SnipperedMessages: if (hasSnippetedMessagesSupport()) { getSnippetedMessages(roomId); } break; case ListMessagesModel::PinnedMessages: getPinnedMessages(roomId); break; case ListMessagesModel::MentionsMessages: getMentionsMessages(roomId); break; } } QUrl RocketChatAccount::urlForLink(const QString &link) const { return mCache->urlForLink(link); } void RocketChatAccount::loadMoreListMessages(const QString &roomId) { if (!mListMessageModel->loadMoreListMessagesInProgress()) { const int offset = mListMessageModel->rowCount(); if (offset < mListMessageModel->total()) { switch (mListMessageModel->listMessageType()) { case ListMessagesModel::Unknown: qCWarning(RUQOLA_LOG) << " Error when using loadMoreListMessages"; break; case ListMessagesModel::StarredMessages: if (hasStarredMessagesSupport()) { restApi()->getStarredMessages(roomId, offset, qMin(50, mListMessageModel->total() - offset)); } break; case ListMessagesModel::SnipperedMessages: if (hasSnippetedMessagesSupport()) { restApi()->getSnippetedMessages(roomId, offset, qMin(50, mListMessageModel->total() - offset)); } break; case ListMessagesModel::PinnedMessages: restApi()->getPinnedMessages(roomId, offset, qMin(50, mListMessageModel->total() - offset)); break; case ListMessagesModel::MentionsMessages: restApi()->channelGetAllUserMentions(roomId, offset, qMin(50, mListMessageModel->total() - offset)); break; } } } } void RocketChatAccount::loadThreadMessagesHistory(const QString &threadMessageId) { restApi()->getThreadMessages(threadMessageId); } void RocketChatAccount::createJitsiConfCall(const QString &roomId) { //TODO use restapi ddp()->createJitsiConfCall(roomId); joinJitsiConfCall(roomId); } void RocketChatAccount::addUserToRoom(const QString &userId, const QString &roomId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->addUserInChannel(roomId, userId); } else if (channelType == QLatin1Char('p')) { restApi()->addUserInGroup(roomId, userId); } } void RocketChatAccount::clearSearchModel() { mSearchMessageModel->clear(); } void RocketChatAccount::messageSearch(const QString &pattern, const QString &rid) { if (pattern.isEmpty()) { clearSearchModel(); } else { restApi()->searchMessages(rid, pattern); } } void RocketChatAccount::slotSearchMessages(const QJsonObject &obj) { mSearchMessageModel->parse(obj); } void RocketChatAccount::starMessage(const QString &messageId, bool starred) { restApi()->starMessage(messageId, starred); } void RocketChatAccount::pinMessage(const QString &messageId, bool pinned) { restApi()->pinMessage(messageId, pinned); } void RocketChatAccount::uploadFile(const QString &roomId, const QString &description, const QString &messageText, const QUrl &fileUrl) { restApi()->uploadFile(roomId, description, messageText, fileUrl); } void RocketChatAccount::changeChannelSettings(const QString &roomId, RocketChatAccount::RoomInfoType infoType, const QVariant &newValue, const QString &channelType) { switch (infoType) { case Announcement: if (channelType == QLatin1Char('c')) { restApi()->changeChannelAnnouncement(roomId, newValue.toString()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsAnnouncement(roomId, newValue.toString()); } else { qCWarning(RUQOLA_LOG) << " unsupport change announcement for type " << channelType; } break; case Description: if (channelType == QLatin1Char('c')) { restApi()->changeChannelDescription(roomId, newValue.toString()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsDescription(roomId, newValue.toString()); } else { qCWarning(RUQOLA_LOG) << " unsupport change description for type " << channelType; } break; case Name: if (channelType == QLatin1Char('c')) { restApi()->changeChannelName(roomId, newValue.toString()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupName(roomId, newValue.toString()); } else { qCWarning(RUQOLA_LOG) << " unsupport change name for type " << channelType; } break; case Topic: if (channelType == QLatin1Char('c')) { restApi()->changeChannelTopic(roomId, newValue.toString()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsTopic(roomId, newValue.toString()); } else { //TODO : change topic in direct channel qCWarning(RUQOLA_LOG) << " unsupport change topic for type " << channelType; } break; case ReadOnly: if (channelType == QLatin1Char('c')) { restApi()->changeChannelReadOnly(roomId, newValue.toBool()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsReadOnly(roomId, newValue.toBool()); } else { qCWarning(RUQOLA_LOG) << " unsupport change readonly for type " << channelType; } break; case Archive: if (channelType == QLatin1Char('c')) { restApi()->archiveChannel(roomId, newValue.toBool()); } else if (channelType == QLatin1Char('p')) { restApi()->archiveGroups(roomId, newValue.toBool()); } else { qCWarning(RUQOLA_LOG) << " unsupport archiving for type " << channelType; } break; case RoomType: if (channelType == QLatin1Char('c')) { restApi()->setChannelType(roomId, newValue.toBool()); } else if (channelType == QLatin1Char('p')) { restApi()->setGroupType(roomId, newValue.toBool()); } else { qCWarning(RUQOLA_LOG) << " unsupport roomtype for type " << channelType; } break; case Encrypted: if (channelType == QLatin1Char('c')) { restApi()->changeChannelEncrypted(roomId, newValue.toBool()); } else if (channelType == QLatin1Char('p')) { restApi()->changeGroupsEncrypted(roomId, newValue.toBool()); } else { qCWarning(RUQOLA_LOG) << " unsupport encrypted mode for type " << channelType; } break; case Password: //FIXME channel type ??? //restApi()->setJoinCodeChannel(roomId, newValue.toString()); break; } } void RocketChatAccount::reportMessage(const QString &messageId, const QString &message) { restApi()->reportMessage(messageId, message); } void RocketChatAccount::getThreadMessages(const QString &threadMessageId) { mThreadMessageModel->clear(); restApi()->getThreadMessages(threadMessageId); } void RocketChatAccount::changeNotificationsSettings(const QString &roomId, RocketChatAccount::NotificationOptionsType notificationsType, const QVariant &newValue) { switch (notificationsType) { case DisableNotifications: restApi()->disableNotifications(roomId, newValue.toBool()); break; case HideUnreadStatus: restApi()->hideUnreadStatus(roomId, newValue.toBool()); break; case AudioNotifications: restApi()->audioNotifications(roomId, newValue.toString()); break; case DesktopNotifications: restApi()->desktopNotifications(roomId, newValue.toString()); break; case EmailNotifications: restApi()->emailNotifications(roomId, newValue.toString()); break; case MobilePushNotifications: restApi()->mobilePushNotifications(roomId, newValue.toString()); break; case UnreadAlert: restApi()->unreadAlert(roomId, newValue.toString()); break; case MuteGroupMentions: restApi()->muteGroupMentions(roomId, newValue.toBool()); break; case DesktopDurationNotifications: restApi()->desktopDurationNotifications(roomId, newValue.toInt()); break; case DesktopSoundNotifications: restApi()->desktopSoundNotifications(roomId, newValue.toString()); break; } } void RocketChatAccount::parsePublicSettings(const QJsonObject &obj) { QJsonArray configs = obj.value(QLatin1String("result")).toArray(); for (QJsonValueRef currentConfig : configs) { QJsonObject currentConfObject = currentConfig.toObject(); const QString id = currentConfObject[QStringLiteral("_id")].toString(); const QVariant value = currentConfObject[QStringLiteral("value")].toVariant(); if (id == QLatin1String("uniqueID")) { mRuqolaServerConfig->setUniqueId(value.toString()); } else if (id == QLatin1String("Jitsi_Enabled")) { mRuqolaServerConfig->setJitsiEnabled(value.toBool()); } else if (id == QLatin1String("Jitsi_Domain")) { mRuqolaServerConfig->setJitsiMeetUrl(value.toString()); } else if (id == QLatin1String("Jitsi_URL_Room_Prefix")) { mRuqolaServerConfig->setJitsiMeetPrefix(value.toString()); } else if (id == QLatin1String("FileUpload_Storage_Type")) { mRuqolaServerConfig->setFileUploadStorageType(value.toString()); } else if (id == QLatin1String("Message_AllowEditing")) { mRuqolaServerConfig->setAllowMessageEditing(value.toBool()); } else if (id == QLatin1String("Message_AllowEditing_BlockEditInMinutes")) { mRuqolaServerConfig->setBlockEditingMessageInMinutes(value.toInt()); } else if (id == QLatin1String("OTR_Enable")) { mRuqolaServerConfig->setOtrEnabled(value.toBool()); } else if (id.contains(QRegularExpression(QStringLiteral("^Accounts_OAuth_\\w+")))) { if (value.toBool()) { mRuqolaServerConfig->addOauthService(id); } } else if (id == QLatin1String("Site_Url")) { mRuqolaServerConfig->setSiteUrl(value.toString()); } else if (id == QLatin1String("Site_Name")) { mRuqolaServerConfig->setSiteName(value.toString()); } else if (id == QLatin1String("E2E_Enable")) { mRuqolaServerConfig->setEncryptionEnabled(value.toBool()); } else if (id == QLatin1String("Message_AllowPinning")) { mRuqolaServerConfig->setAllowMessagePinningEnabled(value.toBool()); } else if (id == QLatin1String("Message_AllowSnippeting")) { mRuqolaServerConfig->setAllowMessageSnippetingEnabled(value.toBool()); } else if (id == QLatin1String("Message_AllowStarring")) { mRuqolaServerConfig->setAllowMessageStarringEnabled(value.toBool()); } else if (id == QLatin1String("Message_AllowDeleting")) { mRuqolaServerConfig->setAllowMessageDeletingEnabled(value.toBool()); } else if (id == QLatin1String("Threads_enabled")) { mRuqolaServerConfig->setThreadsEnabled(value.toBool()); } else if (id == QLatin1String("Discussion_enabled")) { mRuqolaServerConfig->setDiscussionEnabled(value.toBool()); } else if (id == QLatin1String("AutoTranslate_Enabled")) { mRuqolaServerConfig->setAutoTranslateEnabled(value.toBool()); } else if (id == QLatin1String("AutoTranslate_GoogleAPIKey")) { mRuqolaServerConfig->setAutoTranslateGoogleKey(value.toString()); } else { qCDebug(RUQOLA_LOG) << "Other public settings id " << id << value; } //TODO add Accounts_AllowUserStatusMessageChange when we will have a RestAPI method for it. } fillOauthModel(); Q_EMIT publicSettingChanged(); } void RocketChatAccount::fillOauthModel() { QVector fillModel; for (int i = 0, total = mLstInfos.count(); i < total; ++i) { if (mRuqolaServerConfig->canShowOauthService(mLstInfos.at(i).oauthType())) { fillModel.append(mLstInfos.at(i)); } } mLoginMethodModel->setAuthenticationInfos(fillModel); } void RocketChatAccount::changeDefaultAuthentication(int index) { setDefaultAuthentication(mLoginMethodModel->loginType(index)); } void RocketChatAccount::setDefaultAuthentication(AuthenticationManager::OauthType type) { PluginAuthenticationInterface *interface = mLstPluginAuthenticationInterface.value(type); if (interface) { mDefaultAuthenticationInterface = interface; } else { qCWarning(RUQOLA_LOG) << "No interface defined for " << type; } } SearchMessageFilterProxyModel *RocketChatAccount::searchMessageFilterProxyModel() const { return mSearchMessageFilterProxyModel; } SearchMessageModel *RocketChatAccount::searchMessageModel() const { return mSearchMessageModel; } void RocketChatAccount::initializeAuthenticationPlugins() { //TODO change it when we change server //Clean up at the end. const QVector lstPlugins = AuthenticationManager::self()->pluginsList(); qCDebug(RUQOLA_LOG) <<" void RocketChatAccount::initializeAuthenticationPlugins()" << lstPlugins.count(); if (lstPlugins.isEmpty()) { qCWarning(RUQOLA_LOG) <<" No plugins loaded. Please verify your installation."; } mLstPluginAuthenticationInterface.clear(); mLstInfos.clear(); for (PluginAuthentication *abstractPlugin : lstPlugins) { AuthenticationInfo info; info.setIconName(abstractPlugin->iconName()); info.setName(abstractPlugin->name()); info.setOauthType(abstractPlugin->type()); if (info.isValid()) { mLstInfos.append(info); } PluginAuthenticationInterface *interface = abstractPlugin->createInterface(this); interface->setAccount(this); mRuqolaServerConfig->addRuqolaAuthenticationSupport(abstractPlugin->type()); mLstPluginAuthenticationInterface.insert(abstractPlugin->type(), interface); //For the moment initialize default interface if (abstractPlugin->type() == AuthenticationManager::OauthType::Password) { mDefaultAuthenticationInterface = interface; } qCDebug(RUQOLA_LOG) << " plugin type " << abstractPlugin->type(); } //TODO fill ??? or store QVector } PluginAuthenticationInterface *RocketChatAccount::defaultAuthenticationInterface() const { return mDefaultAuthenticationInterface; } LoginMethodModel *RocketChatAccount::loginMethodModel() const { return mLoginMethodModel; } QString RocketChatAccount::authToken() const { return settings()->authToken(); } QString RocketChatAccount::userName() const { return settings()->userName(); } void RocketChatAccount::setAccountName(const QString &accountname) { //Initialize new account room ManagerDataPaths::self()->initializeAccountPath(accountname); //qDebug() << "void RocketChatAccount::setAccountName(const QString &servername)"<accountConfigFileName(accountname)); settings()->setAccountName(accountname); } QString RocketChatAccount::accountName() const { return settings()->accountName(); } QString RocketChatAccount::userID() const { return settings()->userId(); } QString RocketChatAccount::password() const { return settings()->password(); } QString RocketChatAccount::twoFactorAuthenticationCode() const { return settings()->twoFactorAuthenticationCode(); } void RocketChatAccount::setAuthToken(const QString &token) { settings()->setAuthToken(token); } void RocketChatAccount::setPassword(const QString &password) { settings()->setPassword(password); } void RocketChatAccount::setTwoFactorAuthenticationCode(const QString &twoFactorAuthenticationCode) { settings()->setTwoFactorAuthenticationCode(twoFactorAuthenticationCode); } void RocketChatAccount::setAccountEnabled(bool enabled) { settings()->setAccountEnabled(enabled); } void RocketChatAccount::setUserName(const QString &username) { settings()->setUserName(username); } bool RocketChatAccount::accountEnabled() const { return settings()->accountEnabled(); } void RocketChatAccount::setUserID(const QString &userID) { settings()->setUserId(userID); } QString RocketChatAccount::serverUrl() const { return settings()->serverUrl(); } void RocketChatAccount::setServerUrl(const QString &serverURL) { settings()->setServerUrl(serverURL); restApi()->setServerUrl(serverURL); mEmojiManager->setServerUrl(serverURL); } QString RocketChatAccount::recordingVideoPath() const { return mCache->recordingVideoPath(accountName()); } QString RocketChatAccount::recordingImagePath() const { return mCache->recordingImagePath(accountName()); } void RocketChatAccount::downloadFile(const QString &downloadFileUrl, const QUrl &localFile) { mCache->downloadFile(downloadFileUrl, localFile, false); } QUrl RocketChatAccount::attachmentUrl(const QString &url) { return mCache->attachmentUrl(url); } void RocketChatAccount::loadHistory(const QString &roomID, const QString &channelType, bool initial) { //TODO port to restapi Q_UNUSED(channelType); MessageModel *roomModel = messageModelForRoom(roomID); if (roomModel) { //TODO add autotest for it ! QJsonArray params; params.append(QJsonValue(roomID)); // Load history const qint64 endDateTime = roomModel->lastTimestamp(); if (initial || roomModel->isEmpty()) { params.append(QJsonValue(QJsonValue::Null)); params.append(QJsonValue(50)); // Max number of messages to load; QJsonObject dateObject; //qDebug() << "roomModel->lastTimestamp()" << roomModel->lastTimestamp() << " ROOMID " << roomID; dateObject[QStringLiteral("$date")] = QJsonValue(endDateTime); params.append(dateObject); } else { const qint64 startDateTime = roomModel->generateNewStartTimeStamp(endDateTime); QJsonObject dateObjectEnd; dateObjectEnd[QStringLiteral("$date")] = QJsonValue(endDateTime); //qDebug() << " QDATE TIME END" << QDateTime::fromMSecsSinceEpoch(endDateTime) << " START " << QDateTime::fromMSecsSinceEpoch(startDateTime) << " ROOMID" << roomID; params.append(dateObjectEnd); params.append(QJsonValue(50)); // Max number of messages to load; QJsonObject dateObjectStart; //qDebug() << "roomModel->lastTimestamp()" << roomModel->lastTimestamp() << " ROOMID " << roomID; dateObjectStart[QStringLiteral("$date")] = QJsonValue(startDateTime); params.append(dateObjectStart); } ddp()->loadHistory(params); } else { qCWarning(RUQOLA_LOG) << "Room is not found " << roomID; } } void RocketChatAccount::setServerVersion(const QString &version) { qCDebug(RUQOLA_LOG) << " void RocketChatAccount::setServerVersion(const QString &version)" << version; mRuqolaServerConfig->setServerVersion(version); Q_EMIT serverVersionChanged(); } bool RocketChatAccount::needAdaptNewSubscriptionRC60() const { return mRuqolaServerConfig->needAdaptNewSubscriptionRC60(); } bool RocketChatAccount::otrEnabled() const { return mRuqolaServerConfig->otrEnabled(); } bool RocketChatAccount::encryptedEnabled() const { return mRuqolaServerConfig->encryptionEnabled(); } bool RocketChatAccount::allowMessagePinningEnabled() const { return mRuqolaServerConfig->allowMessagePinningEnabled(); } bool RocketChatAccount::allowMessageSnippetingEnabled() const { return mRuqolaServerConfig->allowMessageSnippetingEnabled(); } bool RocketChatAccount::allowMessageStarringEnabled() const { return mRuqolaServerConfig->allowMessageStarringEnabled(); } bool RocketChatAccount::allowMessageDeletingEnabled() const { return mRuqolaServerConfig->allowMessageDeletingEnabled(); } bool RocketChatAccount::threadsEnabled() const { return mRuqolaServerConfig->threadsEnabled(); } bool RocketChatAccount::autoTranslateEnabled() const { return mRuqolaServerConfig->autoTranslateEnabled(); } bool RocketChatAccount::discussionEnabled() const { return mRuqolaServerConfig->discussionEnabled(); } QString RocketChatAccount::serverVersionStr() const { return mRuqolaServerConfig->serverVersionStr(); } ServerConfigInfo *RocketChatAccount::serverConfigInfo() const { return mServerConfigInfo; } bool RocketChatAccount::jitsiEnabled() const { return mRuqolaServerConfig->jitsiEnabled(); } void RocketChatAccount::groupInfo(const QString &roomId) { restApi()->groupInfo(roomId); } void RocketChatAccount::switchEditingMode(bool b) { if (mEditingMode != b) { mEditingMode = b; Q_EMIT editingModeChanged(); } } void RocketChatAccount::setSortUnreadOnTop(bool b) { if (settings()->setShowUnreadOnTop(b)) { mRoomFilterProxyModel->invalidate(); Q_EMIT sortUnreadOnTopChanged(); } } bool RocketChatAccount::sortUnreadOnTop() const { return settings()->showUnreadOnTop(); } void RocketChatAccount::kickUser(const QString &roomId, const QString &userId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->channelKick(roomId, userId); } else if (channelType == QLatin1Char('p')) { restApi()->groupKick(roomId, userId); } else { qCWarning(RUQOLA_LOG) << " unsupport kickUser room for type " << channelType; } } void RocketChatAccount::rolesInRoom(const QString &roomId, const QString &channelType) { if (channelType == QLatin1Char('c')) { restApi()->getChannelRoles(roomId); } else if (channelType == QLatin1Char('p')) { restApi()->getGroupRoles(roomId); } else if (channelType == QLatin1Char('d')) { //No a problem here. } else { qCWarning(RUQOLA_LOG) << " unsupport get roles room for type " << channelType; } } void RocketChatAccount::switchingToRoom(const QString &roomID) { clearTypingNotification(); checkInitializedRoom(roomID); } void RocketChatAccount::changeRoles(const QString &roomId, const QString &userId, const QString &channelType, RocketChatAccount::RoleType roleType) { if (channelType == QLatin1Char('c')) { switch (roleType) { case RocketChatAccount::AddOwner: restApi()->channelAddOwner(roomId, userId); break; case RocketChatAccount::AddLeader: restApi()->channelAddLeader(roomId, userId); break; case RocketChatAccount::AddModerator: restApi()->channelAddModerator(roomId, userId); break; case RocketChatAccount::RemoveOwner: restApi()->channelRemoveOwner(roomId, userId); break; case RocketChatAccount::RemoveLeader: restApi()->channelRemoveLeader(roomId, userId); break; case RocketChatAccount::RemoveModerator: restApi()->channelRemoveModerator(roomId, userId); break; } } else if (channelType == QLatin1Char('p')) { switch (roleType) { case RocketChatAccount::AddOwner: restApi()->groupAddOwner(roomId, userId); break; case RocketChatAccount::AddLeader: restApi()->groupAddLeader(roomId, userId); break; case RocketChatAccount::AddModerator: restApi()->groupAddModerator(roomId, userId); break; case RocketChatAccount::RemoveOwner: restApi()->groupRemoveOwner(roomId, userId); break; case RocketChatAccount::RemoveLeader: restApi()->groupRemoveLeader(roomId, userId); break; case RocketChatAccount::RemoveModerator: restApi()->groupRemoveModerator(roomId, userId); break; } } else { qCWarning(RUQOLA_LOG) << " unsupport changeRoles room for type " << channelType; } } void RocketChatAccount::channelInfo(const QString &roomId) { restApi()->channelInfo(roomId); } bool RocketChatAccount::allowEditingMessages() const { return mRuqolaServerConfig->allowMessageEditing(); } void RocketChatAccount::parseOtr(const QJsonArray &contents) { qCWarning(RUQOLA_LOG) << " NOT IMPLEMENTED YET"; //const Otr t = mOtrManager->parseOtr(contents); //qDebug() << " void RocketChatAccount::parseOtr(const QJsonArray &contents)"<avatarUrlFromCacheOnly(sender); //qDebug() << " iconFileName"<inputChannelAutocomplete(pattern, exceptions); break; case InputTextManager::CompletionForType::User: ddp()->inputUserAutocomplete(pattern, exceptions); break; } } void RocketChatAccount::inputThreadMessageAutocomplete(const QString &pattern, const QString &exceptions, InputTextManager::CompletionForType type) { //qDebug() << " void RocketChatAccount::inputThreadMessageAutocomplete(const QString &pattern, const QString &exceptions, InputTextManager::CompletionForType type)" << pattern; switch (type) { case InputTextManager::CompletionForType::Channel: ddp()->inputChannelAutocomplete(pattern, exceptions); break; case InputTextManager::CompletionForType::User: ddp()->inputUserAutocomplete(pattern, exceptions); break; } } AutotranslateLanguagesModel *RocketChatAccount::autoTranslateLanguagesModel() const { return mAutoTranslateLanguagesModel; } void RocketChatAccount::updateUser(const QJsonObject &object) { mUserModel->updateUser(object); } void RocketChatAccount::userStatusChanged(const User &user) { if (user.userId() == userID()) { const User::PresenceStatus status = Utils::presenceStatusFromString(user.status()); statusModel()->setCurrentPresenceStatus(status); Q_EMIT userStatusUpdated(status); } mRoomModel->userStatusChanged(user); } void RocketChatAccount::ignoreUser(const QString &rid, const QString &userId, bool ignore) { restApi()->ignoreUser(rid, userId, ignore); } void RocketChatAccount::blockUser(const QString &rid, bool block) { //TODO use restapi if (rid.isEmpty()) { qCWarning(RUQOLA_LOG) << " void RocketChatAccount::blockUser EMPTY rid ! block " << block; } else { //qDebug() << " void RocketChatAccount::blockUser userId " << userId << " block " << block << " rid " << rid << " own userdId" << userID(); const QString userId = Utils::userIdFromDirectChannel(rid, userID()); if (block) { ddp()->blockUser(rid, userId); } else { ddp()->unBlockUser(rid, userId); } } } void RocketChatAccount::clearTypingNotification() { mReceiveTypingNotificationManager->clearTypingNotification(); } void RocketChatAccount::checkInitializedRoom(const QString &roomId) { Room *r = mRoomModel->findRoom(roomId); if (r && !r->wasInitialized()) { r->setWasInitialized(true); ddp()->subscribeRoomMessage(roomId); if (!r->archived()) { membersInRoom(r->roomId(), r->channelType()); rolesInRoom(r->roomId(), r->channelType()); } loadHistory(r->roomId(), QString(), true /*initial loading*/); } else if (!r) { qWarning() << " Room " << roomId << " was no found! Need to open it"; //openDirectChannel(roomId); } QMetaObject::invokeMethod(this, &RocketChatAccount::switchedRooms, Qt::QueuedConnection); } void RocketChatAccount::openDocumentation() { QDesktopServices::openUrl(QUrl(QStringLiteral("help:/"))); } void RocketChatAccount::rolesChanged(const QJsonArray &contents) { for (int i = 0; i < contents.count(); ++i) { const QJsonObject obj = contents.at(i).toObject(); const QString scope = obj[QLatin1String("scope")].toString(); Room *room = mRoomModel->findRoom(scope); if (room) { room->updateRoles(obj); } } } void RocketChatAccount::createDiscussion(const QString &parentRoomId, const QString &discussionName, const QString &replyMessage, const QString &messageId, const QStringList &users) { restApi()->createDiscussion(parentRoomId, discussionName, replyMessage, messageId, users); } void RocketChatAccount::threadsInRoom(const QString &roomId) { mThreadsModel->initialize(); restApi()->getThreadsList(roomId); } void RocketChatAccount::discussionsInRoom(const QString &roomId) { mDiscussionsModel->initialize(); restApi()->getDiscussions(roomId); } void RocketChatAccount::followMessage(const QString &messageId, bool follow) { if (follow) { restApi()->followMessage(messageId); } else { restApi()->unFollowMessage(messageId); } } void RocketChatAccount::getSupportedLanguages() { if (mRuqolaServerConfig->hasAtLeastVersion(1, 99, 0) && autoTranslateEnabled()) { restApi()->getSupportedLanguagesMessages(); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::getSupportedLanguages is not supported before server 2.0.0"; } } void RocketChatAccount::slotGetSupportedLanguagesDone(const QJsonObject &obj) { mAutoTranslateLanguagesModel->parseLanguages(obj); } void RocketChatAccount::autoTranslateSaveLanguageSettings(const QString &roomId, const QString &language) { if (mRuqolaServerConfig->hasAtLeastVersion(1, 99, 0)) { restApi()->autoTranslateSaveLanguageSettings(roomId, language); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::autoTranslateSaveLanguageSettings is not supported before server 2.0.0"; } } void RocketChatAccount::autoTranslateSaveAutoTranslateSettings(const QString &roomId, bool autoTranslate) { if (mRuqolaServerConfig->hasAtLeastVersion(1, 99, 0)) { restApi()->autoTranslateSaveAutoTranslateSettings(roomId, autoTranslate); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::autoTranslateSaveLanguageSettings is not supported before server 2.0.0"; } } void RocketChatAccount::slotUsersPresenceDone(const QJsonObject &obj) { qDebug() << " void RocketChatAccount::slotUsersPresenceDone(const QJsonObject &obj)" << obj; } void RocketChatAccount::slotDisconnectedByServer() { - //Laurent: disable it for the moment otherwise when we logout we are unable to add password in login page. Need to improve it first :) - - return; // This happens when we didn't react to pings for a while // (e.g. while stopped in gdb, or if network went down for a bit) // Let's try connecting in again // TODO: delay this more and more like RC+ ? QTimer::singleShot(100, this, [this]() { qCDebug(RUQOLA_LOG) << "Attempting to reconnect after the server disconnected us"; // Do the parts of logOut() that don't actually try talking to the server mRoomModel->clear(); delete mDdp; mDdp = nullptr; tryLogin(); }); } void RocketChatAccount::usersPresence() { restApi()->usersPresence(); } void RocketChatAccount::customUsersStatus() { if (mRuqolaServerConfig->hasAtLeastVersion(2, 4, 0)) { restApi()->customUserStatus(); } else { qCWarning(RUQOLA_LOG) << " RocketChatAccount::customUserStatus is not supported before server 2.4.0"; } } void RocketChatAccount::initializeAccount() { listEmojiCustom(); //load when necessary //account->usersPresence(); if (mRuqolaServerConfig->autoTranslateEnabled()) { getSupportedLanguages(); } //Force set online. //TODO don't reset message status ! ddp()->setDefaultStatus(User::PresenceStatus::PresenceOnline); //customUsersStatus(); Only for test } diff --git a/src/core/rocketchataccountsettings.cpp b/src/core/rocketchataccountsettings.cpp index 434989b8..ab8907e1 100644 --- a/src/core/rocketchataccountsettings.cpp +++ b/src/core/rocketchataccountsettings.cpp @@ -1,291 +1,290 @@ /* Copyright (c) 2017-2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "rocketchataccountsettings.h" #include "managerdatapaths.h" #include "ruqola_debug.h" #include #include #include #include #include #if HAVE_QT5KEYCHAIN #include using namespace QKeychain; #endif RocketChatAccountSettings::RocketChatAccountSettings(const QString &accountFileName, QObject *parent) : QObject(parent) { initializeSettings(accountFileName); } RocketChatAccountSettings::~RocketChatAccountSettings() { mSetting->sync(); delete mSetting; } void RocketChatAccountSettings::initializeSettings(const QString &accountFileName) { delete mSetting; mSetting = new QSettings(accountFileName, QSettings::IniFormat); qCDebug(RUQOLA_LOG) << "accountFileName "<value(QStringLiteral("serverURL"), QStringLiteral("open.rocket.chat")).toString(); mUserName = mSetting->value(QStringLiteral("username")).toString(); mUserId = mSetting->value(QStringLiteral("userID")).toString(); mAuthToken = mSetting->value(QStringLiteral("authToken")).toString(); mExpireToken = mSetting->value(QStringLiteral("expireToken")).toLongLong(); mAccountName = mSetting->value(QStringLiteral("accountName")).toString(); mShowUnreadOnTop = mSetting->value(QStringLiteral("showunreadontop")).toBool(); mAccountEnabled = mSetting->value(QStringLiteral("enabled"), true).toBool(); #if HAVE_QT5KEYCHAIN auto readJob = new ReadPasswordJob(QStringLiteral("Ruqola"), this); connect(readJob, &Job::finished, this, &RocketChatAccountSettings::slotPasswordRead); readJob->setKey(mAccountName); readJob->start(); #endif } void RocketChatAccountSettings::slotPasswordRead(QKeychain::Job *baseJob) { #if HAVE_QT5KEYCHAIN auto *job = qobject_cast(baseJob); Q_ASSERT(job); if (!job->error()) { mPassword = job->textData(); qCDebug(RUQOLA_LOG) << "OK, we have the password now"; Q_EMIT passwordChanged(); } #else Q_UNUSED(baseJob); #endif } void RocketChatAccountSettings::slotPasswordWritten(QKeychain::Job *baseJob) { #if HAVE_QT5KEYCHAIN if (baseJob->error()) { qCWarning(RUQOLA_LOG) << "Error writing password using QKeychain:" << baseJob->errorString(); } #endif } bool RocketChatAccountSettings::accountEnabled() const { return mAccountEnabled; } void RocketChatAccountSettings::setAccountEnabled(bool enabled) { if (mAccountEnabled != enabled) { mAccountEnabled = enabled; mSetting->setValue(QStringLiteral("enabled"), mAccountEnabled); mSetting->sync(); Q_EMIT enableAccountChanged(); } } qint64 RocketChatAccountSettings::expireToken() const { return mExpireToken; } void RocketChatAccountSettings::setExpireToken(const qint64 &expireToken) { if (mExpireToken != expireToken) { mExpireToken = expireToken; mSetting->setValue(QStringLiteral("expireToken"), mExpireToken); mSetting->sync(); } } bool RocketChatAccountSettings::tokenExpired() const { return mExpireToken < QDateTime::currentDateTime().toMSecsSinceEpoch(); } bool RocketChatAccountSettings::showUnreadOnTop() const { return mShowUnreadOnTop; } bool RocketChatAccountSettings::setShowUnreadOnTop(bool showUnreadOnTop) { if (mShowUnreadOnTop != showUnreadOnTop) { mShowUnreadOnTop = showUnreadOnTop; mSetting->setValue(QStringLiteral("showunreadontop"), mShowUnreadOnTop); mSetting->sync(); return true; } return false; } QString RocketChatAccountSettings::userId() const { return mUserId; } void RocketChatAccountSettings::setUserId(const QString &userId) { //Don't use if( m_userID != userID) as we need to Q_EMIT userIDChanged mUserId = userId; mSetting->setValue(QStringLiteral("userID"), userId); mSetting->sync(); Q_EMIT userIDChanged(); } QString RocketChatAccountSettings::authToken() const { return mAuthToken; } void RocketChatAccountSettings::setAuthToken(const QString &authToken) { if (mAuthToken != authToken) { qCDebug(RUQOLA_LOG) << "Setting token to" << authToken; mAuthToken = authToken; mSetting->setValue(QStringLiteral("authToken"), authToken); } } void RocketChatAccountSettings::logout() { mSetting->setValue(QStringLiteral("authToken"), QString()); mSetting->setValue(QStringLiteral("expireToken"), -1); mSetting->sync(); mAuthToken.clear(); mUserId.clear(); - mPassword.clear(); mExpireToken = -1; } QString RocketChatAccountSettings::password() const { return mPassword; } void RocketChatAccountSettings::setPassword(const QString &password) { mPassword = password; #if HAVE_QT5KEYCHAIN auto writeJob = new WritePasswordJob(QStringLiteral("Ruqola"), this); connect(writeJob, &Job::finished, this, &RocketChatAccountSettings::slotPasswordWritten); writeJob->setKey(mAccountName); writeJob->setTextData(mPassword); writeJob->start(); #endif Q_EMIT passwordChanged(); } QString RocketChatAccountSettings::twoFactorAuthenticationCode() const { return mTwoFactorAuthenticationCode; } void RocketChatAccountSettings::setTwoFactorAuthenticationCode(const QString &twoFactorAuthenticationCode) { if (mTwoFactorAuthenticationCode != twoFactorAuthenticationCode) { mTwoFactorAuthenticationCode = twoFactorAuthenticationCode; Q_EMIT twoFactorAuthenticationCodeChanged(); } } QString RocketChatAccountSettings::userName() const { return mUserName; } void RocketChatAccountSettings::setUserName(const QString &userName) { if (mUserName != userName) { mUserName = userName; mSetting->setValue(QStringLiteral("username"), mUserName); mSetting->sync(); Q_EMIT userNameChanged(); } } QString RocketChatAccountSettings::accountName() const { return mAccountName; } void RocketChatAccountSettings::setAccountName(const QString &accountName) { if (mAccountName == accountName) { return; } initializeSettings(ManagerDataPaths::self()->accountConfigFileName(accountName)); mSetting->setValue(QStringLiteral("accountName"), accountName); mSetting->sync(); mAccountName = accountName; Q_EMIT accountNameChanged(); } QString RocketChatAccountSettings::serverUrl() const { return mServerUrl; } void RocketChatAccountSettings::setServerUrl(const QString &serverUrl) { if (mServerUrl == serverUrl) { return; } mSetting->setValue(QStringLiteral("serverURL"), serverUrl); mSetting->sync(); mServerUrl = serverUrl; Q_EMIT serverURLChanged(); } QString RocketChatAccountSettings::cacheBasePath() { if (mServerUrl.isEmpty()) { return QString(); } if (mCachePath.isEmpty()) { mCachePath = ManagerDataPaths::self()->path(ManagerDataPaths::Cache, mAccountName); } return mCachePath; } void RocketChatAccountSettings::removeSettings() { //Delete password #if HAVE_QT5KEYCHAIN auto deleteJob = new DeletePasswordJob(QStringLiteral("Ruqola")); deleteJob->setKey(mAccountName); deleteJob->setAutoDelete(true); deleteJob->start(); #endif QFile f(mSetting->fileName()); if (!f.remove()) { qCWarning(RUQOLA_LOG) << "Impossible to delete config file: " << mSetting->fileName(); } } diff --git a/src/rocketchatrestapi-qt5/authentication/logoutjob.cpp b/src/rocketchatrestapi-qt5/authentication/logoutjob.cpp index cf5ddae4..70144fd0 100644 --- a/src/rocketchatrestapi-qt5/authentication/logoutjob.cpp +++ b/src/rocketchatrestapi-qt5/authentication/logoutjob.cpp @@ -1,86 +1,86 @@ /* Copyright (c) 2018-2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "logoutjob.h" #include "rocketchatqtrestapi_debug.h" #include "restapimethod.h" #include #include #include using namespace RocketChatRestApi; LogoutJob::LogoutJob(QObject *parent) : RestApiAbstractJob(parent) { } LogoutJob::~LogoutJob() { } bool LogoutJob::start() { if (!canStart()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start LogoutJob job"; deleteLater(); return false; } QNetworkReply *reply = mNetworkAccessManager->get(request()); addLoggerInfo("LogoutJob::start"); connect(reply, &QNetworkReply::finished, this, &LogoutJob::slotLogout); - return false; + return true; } void LogoutJob::slotLogout() { auto *reply = qobject_cast(sender()); if (reply) { const QByteArray data = reply->readAll(); addLoggerInfo("LogoutJob finished: " + data); const QJsonDocument replyJson = QJsonDocument::fromJson(data); const QJsonObject replyObject = replyJson.object(); if (replyObject[QStringLiteral("status")].toString() == QLatin1String("success")) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << " Logout"; - Q_EMIT logoutDone(); + Q_EMIT logoutDone(); // connected to RestApiRequest::slotLogout } else { emitFailedMessage(replyObject, reply); addLoggerWarning("Error during to logout" + data); } qCDebug(ROCKETCHATQTRESTAPI_LOG) << " void RestApiRequest::parseLogout(const QByteArray &data)" << data; reply->deleteLater(); } deleteLater(); } QNetworkRequest LogoutJob::request() const { const QUrl url = mRestApiMethod->generateUrl(RestApiUtil::RestApiUrlType::Logout); QNetworkRequest req(url); addAuthRawHeader(req); return req; } bool LogoutJob::requireHttpAuthentication() const { return true; } diff --git a/src/rocketchatrestapi-qt5/restapiabstractjob.cpp b/src/rocketchatrestapi-qt5/restapiabstractjob.cpp index fd42a72a..1b7603f7 100644 --- a/src/rocketchatrestapi-qt5/restapiabstractjob.cpp +++ b/src/rocketchatrestapi-qt5/restapiabstractjob.cpp @@ -1,468 +1,468 @@ /* Copyright (c) 2018-2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "restapiabstractjob.h" #include "rocketchatqtrestapi_debug.h" #include "abstractlogger.h" #include #include #include #include #include using namespace RocketChatRestApi; RestApiAbstractJob::RestApiAbstractJob(QObject *parent) : QObject(parent) { } QNetworkAccessManager *RestApiAbstractJob::networkAccessManager() const { return mNetworkAccessManager; } void RestApiAbstractJob::setNetworkAccessManager(QNetworkAccessManager *networkAccessManager) { mNetworkAccessManager = networkAccessManager; } RocketChatRestApi::RestApiMethod *RestApiAbstractJob::restApiMethod() const { return mRestApiMethod; } void RestApiAbstractJob::setRestApiMethod(RocketChatRestApi::RestApiMethod *restApiMethod) { mRestApiMethod = restApiMethod; } QString RestApiAbstractJob::authToken() const { return mAuthToken; } void RestApiAbstractJob::setAuthToken(const QString &authToken) { mAuthToken = authToken; } QString RestApiAbstractJob::userId() const { return mUserId; } void RestApiAbstractJob::setUserId(const QString &userId) { mUserId = userId; } bool RestApiAbstractJob::hasAuthenticationValue() const { return !mAuthToken.isEmpty() && !mUserId.isEmpty(); } bool RestApiAbstractJob::hasQueryParameterSupport() const { return false; } bool RestApiAbstractJob::canStart() const { if (!mNetworkAccessManager) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Network manager not defined"; return false; } if (!mRestApiMethod) { - qCWarning(ROCKETCHATQTRESTAPI_LOG) << "RestaApiMethod not defined"; + qCWarning(ROCKETCHATQTRESTAPI_LOG) << "RestApiMethod not defined"; return false; } if (requireHttpAuthentication() && !hasAuthenticationValue()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Auth settings is empty. It's a bug"; return false; } return true; } void RestApiAbstractJob::addRequestAttribute(QNetworkRequest &request) const { request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true); request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json")); } void RestApiAbstractJob::addAuthRawHeader(QNetworkRequest &request) const { request.setRawHeader(QByteArrayLiteral("X-Auth-Token"), mAuthToken.toLocal8Bit()); request.setRawHeader(QByteArrayLiteral("X-User-Id"), mUserId.toLocal8Bit()); } QueryParameters RestApiAbstractJob::queryParameters() const { return mQueryParameters; } void RestApiAbstractJob::setQueryParameters(const QueryParameters &queryParameters) { mQueryParameters = queryParameters; } void RestApiAbstractJob::addQueryParameter(QUrlQuery &urlQuery) const { if (hasQueryParameterSupport() && mQueryParameters.isValid()) { if (mQueryParameters.count() >= 0) { urlQuery.addQueryItem(QStringLiteral("count"), QString::number(mQueryParameters.count())); } if (mQueryParameters.offset() >= 0) { urlQuery.addQueryItem(QStringLiteral("offset"), QString::number(mQueryParameters.offset())); } if (!mQueryParameters.sorting().isEmpty()) { //example sort={"name" : -1,"status" : 1} QMapIterator i(mQueryParameters.sorting()); QString str; while (i.hasNext()) { i.next(); if (!str.isEmpty()) { str += QLatin1Char(','); } str += QLatin1Char('"') + i.key() + QLatin1Char('"') + QLatin1Char(':'); switch (i.value()) { case QueryParameters::SortOrder::Ascendant: str += QString::number(1); break; case QueryParameters::SortOrder::Descendant: str += QString::number(-1); break; case QueryParameters::SortOrder::NoSorting: qCWarning(ROCKETCHATQTRESTAPI_LOG) << "It's not a sorting attribute"; break; } } str = QStringLiteral("{%1}").arg(str); //It's ok for getAllMentions.... urlQuery.addQueryItem(QStringLiteral("sort"), str); } } //qDebug() << " urlQuery " << urlQuery.toString(); } RocketChatRestApi::AbstractLogger *RestApiAbstractJob::restApiLogger() const { return mRestApiLogger; } void RestApiAbstractJob::setRestApiLogger(RocketChatRestApi::AbstractLogger *ruqolaLogger) { mRestApiLogger = ruqolaLogger; } void RestApiAbstractJob::addLoggerInfo(const QByteArray &str) { if (mRestApiLogger) { // when $RUQOLA_LOGFILE is set mRestApiLogger->dataSent("RESTAPI: " + str); } else { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "RESTAPI: " << str; } } void RestApiAbstractJob::addLoggerWarning(const QByteArray &str) { if (mRestApiLogger) { mRestApiLogger->dataSent("WARNING RESTAPI: " + str); } else { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "RESTAPI: " << str; } } void RestApiAbstractJob::emitFailedMessage(const QJsonObject &replyObject, QNetworkReply *reply) { // HTTP-level error (e.g. host not found) if (reply->error() != QNetworkReply::NoError) { Q_EMIT failed(reply->errorString()); return; } // JSon-level error const QString errorType = replyObject[QStringLiteral("errorType")].toString(); if (!errorType.isEmpty()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "errorType" << errorType; const QString trStr = errorMessage(errorType); if (!trStr.isEmpty()) { Q_EMIT failed(trStr); } else { qCWarning(ROCKETCHATQTRESTAPI_LOG) << " errorType not defined as translated message: " << errorType; Q_EMIT failed(i18n("Unauthorized")); } } else { const QString error = replyObject[QStringLiteral("error")].toString(); qCWarning(ROCKETCHATQTRESTAPI_LOG) << "error " << error; Q_EMIT failed(generateErrorMessage(error)); } } QString RestApiAbstractJob::generateErrorMessage(const QString &errorStr) const { if (jobName().isEmpty()) { return errorStr; } return i18n("%1:%2", jobName(), errorStr); } QString RestApiAbstractJob::errorMessage(const QString &str) { if (str == QLatin1String("error-action-not-allowed")) { return i18n("__action__ is not allowed"); } else if (str == QLatin1String("error-application-not-found")) { return i18n("Application not found"); } else if (str == QLatin1String("error-archived-duplicate-name")) { return i18n("There's an archived channel with name '__room_name__'"); } else if (str == QLatin1String("error-avatar-invalid-url")) { return i18n("Invalid avatar URL: __url__"); } else if (str == QLatin1String("error-avatar-url-handling")) { return i18n("Error while handling avatar setting from a URL (__url__) for __username__"); } else if (str == QLatin1String("error-cant-invite-for-direct-room")) { return i18n("Can't invite user to direct rooms"); } else if (str == QLatin1String("error-channels-setdefault-is-same")) { return i18n("The channel default setting is the same as what it would be changed to."); } else if (str == QLatin1String("error-channels-setdefault-missing-default-param")) { return i18n("The bodyParam 'default' is required"); } else if (str == QLatin1String("error-could-not-change-email")) { return i18n("Could not change email"); } else if (str == QLatin1String("error-could-not-change-name")) { return i18n("Could not change name"); } else if (str == QLatin1String("error-could-not-change-username")) { return i18n("Could not change username"); } else if (str == QLatin1String("error-delete-protected-role")) { return i18n("Cannot delete a protected role"); } else if (str == QLatin1String("error-department-not-found")) { return i18n("Department not found"); } else if (str == QLatin1String("error-direct-message-file-upload-not-allowed")) { return i18n("File sharing not allowed in direct messages"); } else if (str == QLatin1String("error-duplicate-channel-name")) { return i18n("A channel with name '__channel_name__' exists"); } else if (str == QLatin1String("error-edit-permissions-not-allowed")) { return i18n("Editing permissions is not allowed"); } else if (str == QLatin1String("error-email-domain-blacklisted")) { return i18n("The email domain is blacklisted"); } else if (str == QLatin1String("error-email-send-failed")) { return i18n("Error trying to send email: __message__"); } else if (str == QLatin1String("error-field-unavailable")) { return i18n("__field__ is already in use :("); } else if (str == QLatin1String("error-file-too-large")) { return i18n("File is too large"); } else if (str == QLatin1String("error-importer-not-defined")) { return i18n("The importer was not defined correctly, it is missing the Import class."); } else if (str == QLatin1String("error-import-file-extract-error")) { return i18n("Failed to extract import file."); } else if (str == QLatin1String("error-import-file-is-empty")) { return i18n("Imported file seems to be empty."); } else if (str == QLatin1String("error-import-file-missing")) { return i18n("The file to be imported was not found on the specified path."); } else if (str == QLatin1String("error-input-is-not-a-valid-field")) { return i18n("__input__ is not a valid __field__"); } else if (str == QLatin1String("error-invalid-actionlink")) { return i18n("Invalid action link"); } else if (str == QLatin1String("error-invalid-account")) { return i18n("Invalid Account"); } else if (str == QLatin1String("error-invalid-arguments")) { return i18n("Invalid arguments"); } else if (str == QLatin1String("error-invalid-asset")) { return i18n("Invalid asset"); } else if (str == QLatin1String("error-invalid-channel")) { return i18n("Invalid channel."); } else if (str == QLatin1String("error-invalid-channel-start-with-chars")) { return i18n("Invalid channel. Start with @ or #"); } else if (str == QLatin1String("error-invalid-custom-field")) { return i18n("Invalid custom field"); } else if (str == QLatin1String("error-invalid-custom-field-name")) { return i18n("Invalid custom field name. Use only letters, numbers, hyphens and underscores."); } else if (str == QLatin1String("error-invalid-date")) { return i18n("Invalid date provided."); } else if (str == QLatin1String("error-invalid-description")) { return i18n("Invalid description"); } else if (str == QLatin1String("error-invalid-domain")) { return i18n("Invalid domain"); } else if (str == QLatin1String("error-invalid-email")) { return i18n("Invalid email __email__"); } else if (str == QLatin1String("error-invalid-email-address")) { return i18n("Invalid email address"); } else if (str == QLatin1String("error-invalid-file-height")) { return i18n("Invalid file height"); } else if (str == QLatin1String("error-invalid-file-type")) { return i18n("Invalid file type"); } else if (str == QLatin1String("error-invalid-file-width")) { return i18n("Invalid file width"); } else if (str == QLatin1String("error-invalid-from-address")) { return i18n("You informed an invalid FROM address."); } else if (str == QLatin1String("error-invalid-integration")) { return i18n("Invalid integration"); } else if (str == QLatin1String("error-invalid-message")) { return i18n("Invalid message"); } else if (str == QLatin1String("error-invalid-method")) { return i18n("Invalid method"); } else if (str == QLatin1String("error-invalid-name")) { return i18n("Invalid name"); } else if (str == QLatin1String("error-invalid-password")) { return i18n("Invalid password"); } else if (str == QLatin1String("error-invalid-permission")) { return i18n("Invalid permission"); } else if (str == QLatin1String("error-invalid-redirectUri")) { return i18n("Invalid redirectUri"); } else if (str == QLatin1String("error-invalid-role")) { return i18n("Invalid role"); } else if (str == QLatin1String("error-invalid-room")) { return i18n("Invalid room"); } else if (str == QLatin1String("error-invalid-room-name")) { return i18n("__room_name__ is not a valid room name"); } else if (str == QLatin1String("error-invalid-room-type")) { return i18n("__type__ is not a valid room type."); } else if (str == QLatin1String("error-invalid-settings")) { return i18n("Invalid settings provided"); } else if (str == QLatin1String("error-invalid-subscription")) { return i18n("Invalid subscription"); } else if (str == QLatin1String("error-invalid-token")) { return i18n("Invalid token"); } else if (str == QLatin1String("error-invalid-triggerWords")) { return i18n("Invalid triggerWords"); } else if (str == QLatin1String("error-invalid-urls")) { return i18n("Invalid URLs"); } else if (str == QLatin1String("error-invalid-user")) { return i18n("Invalid user"); } else if (str == QLatin1String("error-invalid-username")) { return i18n("Invalid username"); } else if (str == QLatin1String("error-invalid-webhook-response")) { return i18n("The webhook URL responded with a status other than 200"); } else if (str == QLatin1String("error-message-deleting-blocked")) { return i18n("Message deleting is blocked"); } else if (str == QLatin1String("error-message-editing-blocked")) { return i18n("Message editing is blocked"); } else if (str == QLatin1String("error-message-size-exceeded")) { return i18n("Message size exceeds Message_MaxAllowedSize"); } else if (str == QLatin1String("error-missing-unsubscribe-link")) { return i18n("You must provide the [unsubscribe] link."); } else if (str == QLatin1String("error-no-tokens-for-this-user")) { return i18n("There are no tokens for this user"); } else if (str == QLatin1String("error-not-allowed")) { return i18n("Not allowed"); } else if (str == QLatin1String("error-not-authorized")) { return i18n("Not authorized"); } else if (str == QLatin1String("error-password-policy-not-met")) { return i18n("Password does not meet the server's policy"); } else if (str == QLatin1String("error-password-policy-not-met-maxLength")) { return i18n("Password does not meet the server's policy of maximum length (password too long)"); } else if (str == QLatin1String("error-password-policy-not-met-minLength")) { return i18n("Password does not meet the server's policy of minimum length (password too short)"); } else if (str == QLatin1String("error-password-policy-not-met-oneLowercase")) { return i18n("Password does not meet the server's policy of at least one lowercase character"); } else if (str == QLatin1String("error-password-policy-not-met-oneNumber")) { return i18n("Password does not meet the server's policy of at least one numerical character"); } else if (str == QLatin1String("error-password-policy-not-met-oneSpecial")) { return i18n("Password does not meet the server's policy of at least one special character"); } else if (str == QLatin1String("error-password-policy-not-met-oneUppercase")) { return i18n("Password does not meet the server's policy of at least one uppercase character"); } else if (str == QLatin1String("error-password-policy-not-met-repeatingCharacters")) { return i18n("Password does not meet the server's policy of forbidden repeating characters (you have too many of the same characters next to each other)"); } else if (str == QLatin1String("error-push-disabled")) { return i18n("Push is disabled"); } else if (str == QLatin1String("error-remove-last-owner")) { return i18n("This is the last owner. Please set a new owner before removing this one."); } else if (str == QLatin1String("error-role-in-use")) { return i18n("Cannot delete role because it's in use"); } else if (str == QLatin1String("error-role-name-required")) { return i18n("Role name is required"); } else if (str == QLatin1String("error-room-is-not-closed")) { return i18n("Room is not closed"); } else if (str == QLatin1String("error-the-field-is-required")) { return i18n("The field __field__ is required."); } else if (str == QLatin1String("error-this-is-not-a-livechat-room")) { return i18n("This is not a Livechat room"); } else if (str == QLatin1String("error-personal-access-tokens-are-current-disabled")) { return i18n("Personal Access Tokens are currently disabled"); } else if (str == QLatin1String("error-token-already-exists")) { return i18n("A token with this name already exists"); } else if (str == QLatin1String("error-token-does-not-exists")) { return i18n("Token does not exists"); } else if (str == QLatin1String("error-too-many-requests")) { return i18n("Error, too many requests. Please slow down. You must wait __seconds__ seconds before trying again."); } else if (str == QLatin1String("error-user-has-no-roles")) { return i18n("User has no roles"); } else if (str == QLatin1String("error-user-is-not-activated")) { return i18n("User is not activated"); } else if (str == QLatin1String("error-user-limit-exceeded")) { return i18n("The number of users you are trying to invite to #channel_name exceeds the limit set by the administrator"); } else if (str == QLatin1String("error-user-not-in-room")) { return i18n("User is not in this room"); } else if (str == QLatin1String("error-logged-user-not-in-room")) { return i18n("You are not in the room `%s`"); } else if (str == QLatin1String("error-user-registration-disabled")) { return i18n("User registration is disabled"); } else if (str == QLatin1String("error-user-registration-secret")) { return i18n("User registration is only allowed via Secret URL"); } else if (str == QLatin1String("error-you-are-last-owner")) { return i18n("You are the last owner. Please set new owner before leaving the room."); } else if (str == QLatin1String("error-room-archived")) { return i18n("The private group is archived"); } else { qCWarning(ROCKETCHATQTRESTAPI_LOG) << " unknown error type " << str; return {}; } } QString RestApiAbstractJob::jobName() const { return {}; } QueryParameters::QueryParameters() { } int QueryParameters::offset() const { return mOffset; } void QueryParameters::setOffset(int offset) { mOffset = offset; } int QueryParameters::count() const { return mCount; } void QueryParameters::setCount(int count) { mCount = count; } bool QueryParameters::isValid() const { return (mCount >= 0) || (mOffset >= 0) || (!mSorting.isEmpty()); } QMap QueryParameters::sorting() const { return mSorting; } void QueryParameters::setSorting(const QMap &sorting) { mSorting = sorting; } diff --git a/src/rocketchatrestapi-qt5/restapirequest.cpp b/src/rocketchatrestapi-qt5/restapirequest.cpp index ef890693..2fccf1e1 100644 --- a/src/rocketchatrestapi-qt5/restapirequest.cpp +++ b/src/rocketchatrestapi-qt5/restapirequest.cpp @@ -1,1722 +1,1721 @@ /* Copyright (c) 2017-2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "restapimethod.h" #include "restapirequest.h" #include "rocketchatqtrestapi_debug.h" #include "serverinfojob.h" #include "uploadfilejob.h" #include "settings/privateinfojob.h" #include "channellistjob.h" #include "downloadfilejob.h" #include "spotlightjob.h" #include "users/getavatarjob.h" #include "users/setavatarjob.h" #include "users/forgotpasswordjob.h" #include "users/usersinfojob.h" #include "users/getpresencejob.h" #include "users/getusernamesuggestionjob.h" #include "users/setstatusjob.h" #include "users/userspresencejob.h" #include "misc/owninfojob.h" #include "emoji/loademojicustomjob.h" #include "authentication/logoutjob.h" #include "authentication/loginjob.h" #include "chat/starmessagejob.h" #include "chat/syncthreadmessagesjob.h" #include "chat/postmessagejob.h" #include "chat/deletemessagejob.h" #include "chat/updatemessagejob.h" #include "chat/reactonmessagejob.h" #include "chat/searchmessagejob.h" #include "chat/ignoreuserjob.h" #include "chat/reportmessagejob.h" #include "chat/pinmessagejob.h" #include "chat/followmessagejob.h" #include "chat/unfollowmessagejob.h" #include "chat/getthreadsjob.h" #include "chat/getthreadmessagesjob.h" #include "chat/sendmessagejob.h" #include "chat/getpinnedmessagesjob.h" #include "chat/getsnippetedmessagesjob.h" #include "chat/getstarredmessagesjob.h" #include "channels/changechanneltopicjob.h" #include "channels/changechannelannouncementjob.h" #include "channels/createchanneljob.h" #include "channels/leavechanneljob.h" #include "channels/channelclosejob.h" #include "channels/channelhistoryjob.h" #include "channels/changechanneldescriptionjob.h" #include "channels/archivechanneljob.h" #include "channels/channelfilesjob.h" #include "channels/channelinvitejob.h" #include "channels/setchanneltypejob.h" #include "channels/getchannelrolesjob.h" #include "channels/setjoincodechanneljob.h" #include "channels/channeljoinjob.h" #include "channels/channelinfojob.h" #include "channels/changechannelnamejob.h" #include "channels/channelgetallusermentionsjob.h" #include "channels/channelkickjob.h" #include "channels/channeladdownerjob.h" #include "channels/channelremoveownerjob.h" #include "channels/channeladdmoderatorjob.h" #include "channels/channelremovemoderatorjob.h" #include "channels/channeldeletejob.h" #include "channels/channelmembersjob.h" #include "channels/changechannelreadonlyjob.h" #include "channels/changechannelencryptedjob.h" #include "channels/channeladdleaderjob.h" #include "channels/channelremoveleaderjob.h" #include "groups/changegroupsannouncementjob.h" #include "groups/changegroupstopicjob.h" #include "groups/creategroupsjob.h" #include "groups/leavegroupsjob.h" #include "groups/changegroupsdescriptionjob.h" #include "groups/archivegroupsjob.h" #include "groups/groupsinvitejob.h" #include "groups/setgrouptypejob.h" #include "groups/getgrouprolesjob.h" #include "groups/changegroupsnamejob.h" #include "groups/groupsinfojob.h" #include "groups/groupskickjob.h" #include "groups/groupaddleaderjob.h" #include "groups/groupremoveleaderjob.h" #include "groups/groupaddownerjob.h" #include "groups/groupremoveownerjob.h" #include "groups/groupaddmoderatorjob.h" #include "groups/groupremovemoderatorjob.h" #include "groups/groupsdeletejob.h" #include "groups/changegroupsreadonlyjob.h" #include "groups/changegroupsencryptedjob.h" #include "rooms/getroomsjob.h" #include "rooms/roomfavoritejob.h" #include "rooms/savenotificationjob.h" #include "rooms/roomstartdiscussionjob.h" #include "rooms/getdiscussionsjob.h" #include "rooms/roomsautocompletechannelandprivatejob.h" #include "directmessage/createdmjob.h" #include "directmessage/opendmjob.h" #include "subscriptions/markroomasreadjob.h" #include "subscriptions/markroomasunreadjob.h" #include "permissions/listpermissionsjob.h" #include "commands/listcommandsjob.h" #include "e2e/fetchmykeysjob.h" #include "video-conference/videoconfupdatejitsitimeoutjob.h" #include "autotranslate/getsupportedlanguagesjob.h" #include "autotranslate/translatesavesettingsjob.h" #include "custom/customsoundsjob.h" #include "custom/customuserstatusjob.h" #include #include #include #include #include using namespace RocketChatRestApi; RestApiRequest::RestApiRequest(QObject *parent) : QObject(parent) { mRestApiMethod = new RestApiMethod; mCookieJar = new QNetworkCookieJar; mNetworkAccessManager = new QNetworkAccessManager(this); mNetworkAccessManager->setCookieJar(mCookieJar); connect(mNetworkAccessManager, &QNetworkAccessManager::finished, this, &RestApiRequest::slotResult); connect(mNetworkAccessManager, &QNetworkAccessManager::sslErrors, this, &RestApiRequest::slotSslErrors); } RestApiRequest::~RestApiRequest() { delete mRestApiMethod; } void RestApiRequest::setRestApiLogger(RocketChatRestApi::AbstractLogger *logger) { mRuqolaLogger = logger; } void RestApiRequest::initializeCookies() { QString url = serverUrl(); if (!url.isEmpty()) { QString host; QStringList lsthost = url.split(QStringLiteral("//")); if (lsthost.count() < 2) { host = url; } else { host = lsthost.at(1); } if (!mUserId.isEmpty()) { QNetworkCookie userIdCookie; userIdCookie.setDomain(host); userIdCookie.setName(QByteArrayLiteral("rc_uid")); userIdCookie.setValue(mUserId.toLocal8Bit()); mCookieJar->insertCookie(userIdCookie); } if (!mAuthToken.isEmpty()) { QNetworkCookie tokenCookie; tokenCookie.setDomain(host); tokenCookie.setName(QByteArrayLiteral("rc_token")); tokenCookie.setValue(mAuthToken.toLocal8Bit()); mCookieJar->insertCookie(tokenCookie); } } else { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "We can not initialize cookies as server url is empty."; } } void RestApiRequest::setAuthToken(const QString &authToken) { const bool isChanged = (mAuthToken != authToken); mAuthToken = authToken; if (isChanged) { if (!mAuthToken.isEmpty()) { initializeCookies(); } } } void RestApiRequest::setUserId(const QString &userId) { const bool isChanged = (mUserId != userId); mUserId = userId; if (isChanged) { if (!mUserId.isEmpty()) { initializeCookies(); } } } void RestApiRequest::slotResult(QNetworkReply *reply) { if (reply->error() != QNetworkReply::NoError) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << " Error reply - "<errorString(); } } void RestApiRequest::slotSslErrors(QNetworkReply *reply, const QList &error) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << " void RestApiRequest::slotSslErrors(QNetworkReply *reply, const QList &error)" << error.count(); reply->ignoreSslErrors(error); } void RestApiRequest::setPassword(const QString &password) { mPassword = password; } void RestApiRequest::setUserName(const QString &userName) { mUserName = userName; } QString RestApiRequest::serverUrl() const { return mRestApiMethod->serverUrl(); } void RestApiRequest::setServerUrl(const QString &serverUrl) { mRestApiMethod->setServerUrl(serverUrl); } QString RestApiRequest::authToken() const { return mAuthToken; } QString RestApiRequest::userId() const { return mUserId; } void RestApiRequest::login() { auto *job = new LoginJob(this); connect(job, &LoginJob::loginDone, this, &RestApiRequest::slotLogin); initializeRestApiJob(job); job->setPassword(mPassword); job->setUserName(mUserName); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::slotLogin(const QString &authToken, const QString &userId) { mAuthToken = authToken; mUserId = userId; } void RestApiRequest::slotLogout() { mUserId.clear(); mAuthToken.clear(); - Q_EMIT logoutDone(); } void RestApiRequest::initializeRestApiJob(RocketChatRestApi::RestApiAbstractJob *job) { connect(job, &RocketChatRestApi::RestApiAbstractJob::failed, this, &RestApiRequest::failed); job->setNetworkAccessManager(mNetworkAccessManager); job->setRestApiLogger(mRuqolaLogger); job->setRestApiMethod(mRestApiMethod); if (job->requireHttpAuthentication()) { job->setAuthToken(mAuthToken); job->setUserId(mUserId); } } void RestApiRequest::logout() { auto *job = new LogoutJob(this); connect(job, &LogoutJob::logoutDone, this, &RestApiRequest::slotLogout); initializeRestApiJob(job); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::channelList() { auto *job = new ChannelListJob(this); connect(job, &ChannelListJob::channelListDone, this, &RestApiRequest::channelListDone); initializeRestApiJob(job); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::getAvatar(const QString &userId) { auto *job = new GetAvatarJob(this); connect(job, &GetAvatarJob::avatar, this, &RestApiRequest::avatar); connect(job, &GetAvatarJob::redownloadAvatar, this, &RestApiRequest::redownloadAvatar); initializeRestApiJob(job); job->setAvatarUserId(userId); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::getPrivateSettings() { auto *job = new PrivateInfoJob(this); connect(job, &PrivateInfoJob::privateInfoDone, this, &RestApiRequest::privateInfoDone); initializeRestApiJob(job); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::getOwnInfo() { auto *job = new OwnInfoJob(this); connect(job, &OwnInfoJob::ownInfoDone, this, &RestApiRequest::getOwnInfoDone); initializeRestApiJob(job); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::starMessage(const QString &messageId, bool starred) { auto *job = new StarMessageJob(this); initializeRestApiJob(job); job->setMessageId(messageId); job->setStarMessage(starred); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::downloadFile(const QUrl &url, const QString &mimeType, bool storeInCache, const QUrl &localFileUrl) { auto *job = new DownloadFileJob(this); connect(job, &DownloadFileJob::downloadFileDone, this, &RestApiRequest::downloadFileDone); job->setUrl(url); job->setMimeType(mimeType); job->setLocalFileUrl(localFileUrl); job->setStoreInCache(storeInCache); initializeRestApiJob(job); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::serverInfo(bool useDeprecatedVersion) { auto *job = new ServerInfoJob(this); job->setUseDeprecatedVersion(useDeprecatedVersion); initializeRestApiJob(job); connect(job, &ServerInfoJob::serverInfoDone, this, &RestApiRequest::getServerInfoDone); connect(job, &ServerInfoJob::serverInfoFailed, this, &RestApiRequest::getServerInfoFailed); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::uploadFile(const QString &roomId, const QString &description, const QString &text, const QUrl &filename) { auto *job = new UploadFileJob(this); initializeRestApiJob(job); job->setDescription(description); job->setMessageText(text); job->setFilenameUrl(filename); job->setRoomId(roomId); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeChannelTopic(const QString &roomId, const QString &topic) { auto *job = new ChangeChannelTopicJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setTopic(topic); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeGroupsTopic(const QString &roomId, const QString &topic) { auto *job = new ChangeGroupsTopicJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setTopic(topic); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeChannelReadOnly(const QString &roomId, bool b) { auto *job = new ChangeChannelReadonlyJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setReadOnly(b); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeGroupsReadOnly(const QString &roomId, bool b) { auto *job = new ChangeGroupsReadonlyJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setReadOnly(b); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeChannelEncrypted(const QString &roomId, bool b) { auto *job = new ChangeChannelEncryptedJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setEncrypted(b); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeGroupsEncrypted(const QString &roomId, bool b) { auto *job = new ChangeGroupsEncryptedJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setEncrypted(b); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeChannelAnnouncement(const QString &roomId, const QString &announcement) { auto *job = new ChangeChannelAnnouncementJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setAnnouncement(announcement); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeGroupsAnnouncement(const QString &roomId, const QString &announcement) { auto *job = new ChangeGroupsAnnouncementJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setAnnouncement(announcement); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeChannelDescription(const QString &roomId, const QString &description) { auto *job = new ChangeChannelDescriptionJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setDescription(description); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeGroupsDescription(const QString &roomId, const QString &description) { auto *job = new ChangeGroupsDescriptionJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setDescription(description); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::postMessage(const QString &roomId, const QString &text) { auto *job = new PostMessageJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setText(text); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::deleteMessage(const QString &roomId, const QString &messageId) { auto *job = new DeleteMessageJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setMessageId(messageId); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::slotAddJoinCodeToChannel(const QString &channelId, const QString &password) { setJoinCodeChannel(channelId, password); } void RestApiRequest::createChannels(const QString &channelName, bool readOnly, const QStringList &members, const QString &password) { auto *job = new CreateChannelJob(this); connect(job, &CreateChannelJob::addJoinCodeToChannel, this, &RestApiRequest::slotAddJoinCodeToChannel); initializeRestApiJob(job); job->setChannelName(channelName); job->setReadOnly(readOnly); job->setMembers(members); job->setPassword(password); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::createGroups(const QString &channelName, bool readOnly, const QStringList &members) { auto *job = new CreateGroupsJob(this); initializeRestApiJob(job); job->setChannelName(channelName); job->setReadOnly(readOnly); job->setMembers(members); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::leaveChannel(const QString &roomId) { auto *job = new LeaveChannelJob(this); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::leaveGroups(const QString &roomId) { auto *job = new LeaveGroupsJob(this); initializeRestApiJob(job); job->setRoomId(roomId); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::archiveChannel(const QString &roomId, bool archive) { auto *job = new ArchiveChannelJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setArchive(archive); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::archiveGroups(const QString &roomId, bool archive) { auto *job = new ArchiveGroupsJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setArchive(archive); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::updateMessage(const QString &roomId, const QString &messageId, const QString &text) { auto *job = new UpdateMessageJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setMessageId(messageId); job->setUpdatedText(text); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::reactOnMessage(const QString &messageId, const QString &emoji, bool shouldReact) { auto *job = new ReactOnMessageJob(this); initializeRestApiJob(job); job->setMessageId(messageId); QString fixedEmoji = emoji; if (fixedEmoji.startsWith(QLatin1Char(':'))) { fixedEmoji.remove(0, 1); } if (fixedEmoji.endsWith(QLatin1Char(':'))) { fixedEmoji.chop(1); } job->setEmoji(fixedEmoji); job->setShouldReact(shouldReact); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::closeChannel(const QString &roomId, const QString &type) { auto *job = new ChannelCloseJob(this); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); if (type == QLatin1Char('d')) { job->setChannelType(ChannelCloseJob::Direct); } else if (type == QLatin1Char('p')) { job->setChannelType(ChannelCloseJob::Groups); } else if (type == QLatin1Char('c')) { job->setChannelType(ChannelCloseJob::Channel); } if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::historyChannel(const QString &roomId, const QString &type) { auto *job = new ChannelHistoryJob(this); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); if (type == QLatin1Char('d')) { job->setChannelType(ChannelHistoryJob::Direct); } else if (type == QLatin1Char('p')) { job->setChannelType(ChannelHistoryJob::Groups); } else if (type == QLatin1Char('c')) { job->setChannelType(ChannelHistoryJob::Channel); } if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::createDirectMessage(const QString &userName) { auto *job = new CreateDmJob(this); initializeRestApiJob(job); job->setUserName(userName); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::openDirectMessage(const QString &userId) { auto *job = new OpenDmJob(this); initializeRestApiJob(job); job->setDirectUserId(userId); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::filesInRoom(const QString &roomId, const QString &type, int offset, int count) { auto *job = new ChannelFilesJob(this); connect(job, &ChannelFilesJob::channelFilesDone, this, &RestApiRequest::channelFilesDone); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); QueryParameters parameters; parameters.setCount(count); parameters.setOffset(offset); job->setQueryParameters(parameters); if (type == QLatin1Char('d')) { job->setChannelType(ChannelFilesJob::Direct); } else if (type == QLatin1Char('p')) { job->setChannelType(ChannelFilesJob::Groups); } else if (type == QLatin1Char('c')) { job->setChannelType(ChannelFilesJob::Channel); } if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } //FIXME void RestApiRequest::membersInRoom(const QString &roomId, const QString &type, int offset, int count) { auto *job = new ChannelMembersJob(this); QueryParameters parameters; parameters.setCount(count); parameters.setOffset(offset); job->setQueryParameters(parameters); connect(job, &ChannelMembersJob::channelMembersDone, this, &RestApiRequest::channelMembersDone); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); if (type == QLatin1Char('d')) { job->setChannelType(ChannelMembersJob::Direct); } else if (type == QLatin1Char('p')) { job->setChannelType(ChannelMembersJob::Groups); } else if (type == QLatin1Char('c')) { job->setChannelType(ChannelMembersJob::Channel); } if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::addUserInChannel(const QString &roomId, const QString &userId) { auto *job = new ChannelInviteJob(this); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); job->setInviteUserId(userId); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::addUserInGroup(const QString &roomId, const QString &userId) { auto *job = new GroupsInviteJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setUserId(userId); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::listEmojiCustom() { auto *job = new LoadEmojiCustomJob(this); initializeRestApiJob(job); connect(job, &LoadEmojiCustomJob::loadEmojiCustomDone, this, &RestApiRequest::loadEmojiCustomDone); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::searchRoomUser(const QString &pattern) { auto *job = new SpotlightJob(this); job->setSearchPattern(pattern); initializeRestApiJob(job); connect(job, &SpotlightJob::spotlightDone, this, &RestApiRequest::spotlightDone); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::searchMessages(const QString &roomId, const QString &pattern) { auto *job = new SearchMessageJob(this); job->setRoomId(roomId); job->setSearchText(pattern); initializeRestApiJob(job); connect(job, &SearchMessageJob::searchMessageDone, this, &RestApiRequest::searchMessageDone); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::markAsRead(const QString &roomId) { auto *job = new MarkRoomAsReadJob(this); job->setRoomId(roomId); initializeRestApiJob(job); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::markRoomAsUnRead(const QString &roomId) { auto *job = new MarkRoomAsUnReadJob(this); job->setObjectId(roomId); job->setUnReadObject(MarkRoomAsUnReadJob::Room); initializeRestApiJob(job); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::markMessageAsUnReadFrom(const QString &messageId) { auto *job = new MarkRoomAsUnReadJob(this); job->setObjectId(messageId); job->setUnReadObject(MarkRoomAsUnReadJob::FromMessage); initializeRestApiJob(job); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::getRooms() { auto *job = new GetRoomsJob(this); initializeRestApiJob(job); connect(job, &GetRoomsJob::getRoomsDone, this, &RestApiRequest::getRoomsDone); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::markAsFavorite(const QString &roomId, bool favorite) { auto *job = new RoomFavoriteJob(this); initializeRestApiJob(job); job->setFavorite(favorite); job->setRoomId(roomId); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::disableNotifications(const QString &roomId, bool value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setDisableNotifications(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::muteGroupMentions(const QString &roomId, bool value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setMuteGroupMentions(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::desktopDurationNotifications(const QString &roomId, int value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setDesktopNotificationDuration(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::desktopSoundNotifications(const QString &roomId, const QString &value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setAudioNotificationValue(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeGroupName(const QString &roomId, const QString &newName) { auto *job = new ChangeGroupsNameJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setName(newName); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::changeChannelName(const QString &roomId, const QString &newName) { auto *job = new ChangeChannelNameJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setName(newName); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::channelInfo(const QString &roomId) { auto *job = new ChannelInfoJob(this); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::groupInfo(const QString &roomId) { auto *job = new GroupsInfoJob(this); initializeRestApiJob(job); job->setRoomId(roomId); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::hideUnreadStatus(const QString &roomId, bool value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setHideUnreadStatus(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::audioNotifications(const QString &roomId, const QString &value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setAudioNotifications(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::desktopNotifications(const QString &roomId, const QString &value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setDesktopNotifications(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::emailNotifications(const QString &roomId, const QString &value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setEmailNotifications(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::mobilePushNotifications(const QString &roomId, const QString &value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setMobilePushNotifications(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::unreadAlert(const QString &roomId, const QString &value) { auto *job = new SaveNotificationJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setUnreadAlert(value); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::setAvatar(const QString &avatarUrl) { auto *job = new SetAvatarJob(this); initializeRestApiJob(job); job->setAvatarUrl(avatarUrl); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::forgotPassword(const QString &email) { auto *job = new ForgotPasswordJob(this); initializeRestApiJob(job); job->setEmail(email); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::userInfo(const QString &identifier, bool userName) { auto *job = new UsersInfoJob(this); initializeRestApiJob(job); job->setIdentifier(identifier); job->setUseUserName(userName); connect(job, &UsersInfoJob::usersInfoDone, this, &RestApiRequest::usersInfoDone); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::ignoreUser(const QString &roomId, const QString &userId, bool ignore) { auto *job = new IgnoreUserJob(this); initializeRestApiJob(job); job->setIgnoreUserId(userId); job->setRoomId(roomId); job->setIgnore(ignore); connect(job, &IgnoreUserJob::ignoreUserDone, this, &RestApiRequest::ignoreUserDone); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::userPresence(const QString &userId) { auto *job = new GetPresenceJob(this); initializeRestApiJob(job); job->setPresenceUserId(userId); connect(job, &GetPresenceJob::getPresenceDone, this, &RestApiRequest::getPresenceDone); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::reportMessage(const QString &messageId, const QString &message) { auto *job = new ReportMessageJob(this); initializeRestApiJob(job); job->setMessageId(messageId); job->setReportMessage(message); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::setGroupType(const QString &roomId, bool isPrivate) { auto *job = new SetGroupTypeJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setType(isPrivate ? SetGroupTypeJob::Private : SetGroupTypeJob::Public); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::setChannelType(const QString &roomId, bool isPrivate) { auto *job = new SetChannelTypeJob(this); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); job->setType(isPrivate ? SetChannelTypeJob::Private : SetChannelTypeJob::Public); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::getGroupRoles(const QString &roomId) { auto *job = new GetGroupRolesJob(this); initializeRestApiJob(job); job->setRoomId(roomId); connect(job, &GetGroupRolesJob::groupRolesDone, this, &RestApiRequest::groupRolesDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getGroupRoles job"; } } void RestApiRequest::getChannelRoles(const QString &roomId) { auto *job = new GetChannelRolesJob(this); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &GetChannelRolesJob::channelRolesDone, this, &RestApiRequest::channelRolesDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start GetChannelRolesJob job"; } } void RestApiRequest::getUsernameSuggestion() { auto *job = new GetUsernameSuggestionJob(this); initializeRestApiJob(job); connect(job, &GetUsernameSuggestionJob::getUsernameSuggestionDone, this, &RestApiRequest::getUsernameSuggestionDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getUsernameSuggestion job"; } } void RestApiRequest::listPermissions() { auto *job = new ListPermissionsJob(this); initializeRestApiJob(job); connect(job, &ListPermissionsJob::listPermissionDone, this, &RestApiRequest::listPermissionDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ListPermissionsJob job"; } } void RestApiRequest::listCommands() { auto *job = new ListCommandsJob(this); initializeRestApiJob(job); connect(job, &ListCommandsJob::listCommandsDone, this, &RestApiRequest::listCommandsDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ListPermissionsJob job"; } } void RestApiRequest::fetchMyKeys() { auto *job = new FetchMyKeysJob(this); initializeRestApiJob(job); connect(job, &FetchMyKeysJob::fetchMyKeysDone, this, &RestApiRequest::fetchMyKeysDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start fetchmykeys job"; } } void RestApiRequest::setJoinCodeChannel(const QString &roomId, const QString &joinCode) { auto *job = new SetJoinCodeChannelJob(this); initializeRestApiJob(job); job->setJoinCode(joinCode); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &SetJoinCodeChannelJob::setJoinCodeDone, this, &RestApiRequest::setJoinCodeDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start setjoincode"; } } void RestApiRequest::updatejitsiTimeOut(const QString &roomId) { auto *job = new VideoConfUpdateJitsiTimeOutJob(this); initializeRestApiJob(job); job->setRoomId(roomId); connect(job, &VideoConfUpdateJitsiTimeOutJob::updateJitsiTimeOutDone, this, &RestApiRequest::updateJitsiTimeOutDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start VideoConfUpdateJitsiTimeOutJob"; } } void RestApiRequest::channelJoin(const ChannelBaseJob::ChannelInfo &channelInfo, const QString &joinCode) { auto *job = new ChannelJoinJob(this); initializeRestApiJob(job); job->setJoinCode(joinCode); job->setChannelInfo(channelInfo); connect(job, &ChannelJoinJob::setChannelJoinDone, this, &RestApiRequest::setChannelJoinDone); connect(job, &ChannelJoinJob::missingChannelPassword, this, &RestApiRequest::missingChannelPassword); connect(job, &ChannelJoinJob::openArchivedRoom, this, &RestApiRequest::openArchivedRoom); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start setChannelJoin"; } } void RestApiRequest::channelGetAllUserMentions(const QString &roomId, int offset, int count) { auto *job = new ChannelGetAllUserMentionsJob(this); initializeRestApiJob(job); job->setRoomId(roomId); QueryParameters parameters; QMap map; map.insert(QStringLiteral("_updatedAt"), QueryParameters::SortOrder::Descendant); parameters.setSorting(map); parameters.setCount(count); parameters.setOffset(offset); job->setQueryParameters(parameters); connect(job, &ChannelGetAllUserMentionsJob::channelGetAllUserMentionsDone, this, &RestApiRequest::channelGetAllUserMentionsDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start setChannelJoin"; } } void RestApiRequest::channelKick(const QString &roomId, const QString &userId) { auto *job = new ChannelKickJob(this); initializeRestApiJob(job); job->setKickUserId(userId); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &ChannelKickJob::kickUserDone, this, &RestApiRequest::channelKickUserDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelKick"; } } void RestApiRequest::groupKick(const QString &roomId, const QString &userId) { auto *job = new GroupsKickJob(this); initializeRestApiJob(job); job->setKickUserId(userId); job->setRoomId(roomId); connect(job, &GroupsKickJob::kickUserDone, this, &RestApiRequest::groupKickUserDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelKick"; } } void RestApiRequest::groupAddModerator(const QString &roomId, const QString &userId) { auto *job = new GroupAddModeratorJob(this); initializeRestApiJob(job); job->setAddModeratorUserId(userId); job->setRoomId(roomId); connect(job, &GroupAddModeratorJob::addModeratorDone, this, &RestApiRequest::addModeratorDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupAddModerator"; } } void RestApiRequest::groupRemoveModerator(const QString &roomId, const QString &userId) { auto *job = new GroupRemoveModeratorJob(this); initializeRestApiJob(job); job->setRemoveUserId(userId); job->setRoomId(roomId); connect(job, &GroupRemoveModeratorJob::removeModeratorDone, this, &RestApiRequest::removeModeratorDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupRemoveModerator"; } } void RestApiRequest::groupAddLeader(const QString &roomId, const QString &userId) { auto *job = new GroupAddLeaderJob(this); initializeRestApiJob(job); job->setAddLeaderUserId(userId); job->setRoomId(roomId); connect(job, &GroupAddLeaderJob::addLeaderDone, this, &RestApiRequest::addLeaderDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupAddLeader"; } } void RestApiRequest::groupRemoveLeader(const QString &roomId, const QString &userId) { auto *job = new GroupRemoveLeaderJob(this); initializeRestApiJob(job); job->setRemoveUserId(userId); job->setRoomId(roomId); connect(job, &GroupRemoveLeaderJob::removeLeaderDone, this, &RestApiRequest::removeLeaderDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupRemoveLeader"; } } void RestApiRequest::groupAddOwner(const QString &roomId, const QString &userId) { auto *job = new GroupAddOwnerJob(this); initializeRestApiJob(job); job->setAddownerUserId(userId); job->setRoomId(roomId); connect(job, &GroupAddOwnerJob::addOwnerDone, this, &RestApiRequest::addOwnerDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupAddOwner"; } } void RestApiRequest::groupRemoveOwner(const QString &roomId, const QString &userId) { auto *job = new GroupRemoveOwnerJob(this); initializeRestApiJob(job); job->setRemoveUserId(userId); job->setRoomId(roomId); connect(job, &GroupRemoveOwnerJob::removeOwnerDone, this, &RestApiRequest::removeOwnerDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start groupRemoveOwner"; } } void RestApiRequest::channelAddModerator(const QString &roomId, const QString &userId) { auto *job = new ChannelAddModeratorJob(this); initializeRestApiJob(job); job->setAddModeratorUserId(userId); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &ChannelAddModeratorJob::addModeratorDone, this, &RestApiRequest::addModeratorDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelAddModerator"; } } void RestApiRequest::channelRemoveModerator(const QString &roomId, const QString &userId) { auto *job = new ChannelRemoveModeratorJob(this); initializeRestApiJob(job); job->setRemoveUserId(userId); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &ChannelRemoveModeratorJob::removeModeratorDone, this, &RestApiRequest::removeModeratorDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelRemoveModeratorJob"; } } void RestApiRequest::channelAddLeader(const QString &roomId, const QString &userId) { auto *job = new ChannelAddLeaderJob(this); initializeRestApiJob(job); job->setAddLeaderUserId(userId); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &ChannelAddLeaderJob::addLeaderDone, this, &RestApiRequest::addLeaderDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelAddLeader"; } } void RestApiRequest::channelRemoveLeader(const QString &roomId, const QString &userId) { auto *job = new ChannelRemoveLeaderJob(this); initializeRestApiJob(job); job->setRemoveUserId(userId); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &ChannelRemoveLeaderJob::removeLeaderDone, this, &RestApiRequest::removeLeaderDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start channelRemoveLeader"; } } void RestApiRequest::channelAddOwner(const QString &roomId, const QString &userId) { auto *job = new ChannelAddOwnerJob(this); initializeRestApiJob(job); job->setAddownerUserId(userId); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &ChannelAddOwnerJob::addOwnerDone, this, &RestApiRequest::addOwnerDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelAddOwnerJob"; } } void RestApiRequest::channelRemoveOwner(const QString &roomId, const QString &userId) { auto *job = new ChannelRemoveOwnerJob(this); initializeRestApiJob(job); job->setRemoveUserId(userId); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &ChannelRemoveOwnerJob::removeOwnerDone, this, &RestApiRequest::removeOwnerDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelRemoveOwnerJob"; } } void RestApiRequest::channelDelete(const QString &roomId) { auto *job = new ChannelDeleteJob(this); initializeRestApiJob(job); ChannelBaseJob::ChannelInfo info; info.channelInfoType = ChannelBaseJob::ChannelInfoType::RoomId; info.channelInfoIdentifier = roomId; job->setChannelInfo(info); connect(job, &ChannelDeleteJob::deletechannelDone, this, &RestApiRequest::deletechannelDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start ChannelDeleteJob"; } } void RestApiRequest::groupDelete(const QString &roomId) { auto *job = new GroupsDeleteJob(this); initializeRestApiJob(job); job->setRoomId(roomId); connect(job, &GroupsDeleteJob::deleteGroupsDone, this, &RestApiRequest::deleteGroupsDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start GroupsDeleteJob"; } } void RestApiRequest::pinMessage(const QString &messageId, bool pinned) { auto *job = new PinMessageJob(this); initializeRestApiJob(job); job->setMessageId(messageId); job->setPinMessage(pinned); connect(job, &PinMessageJob::pinMessageDone, this, &RestApiRequest::pinMessageDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start PinMessageJob"; } } void RestApiRequest::followMessage(const QString &messageId) { auto *job = new FollowMessageJob(this); initializeRestApiJob(job); job->setMessageId(messageId); connect(job, &FollowMessageJob::followMessageDone, this, &RestApiRequest::followMessageDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start FollowMessageJob"; } } void RestApiRequest::unFollowMessage(const QString &messageId) { auto *job = new UnFollowMessageJob(this); initializeRestApiJob(job); job->setMessageId(messageId); connect(job, &UnFollowMessageJob::unFollowMessageDone, this, &RestApiRequest::unFollowMessageDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start unFollowMessageDone"; } } void RestApiRequest::createDiscussion(const QString &parentRoomId, const QString &discussionName, const QString &replyMessage, const QString &parentMessageId, const QStringList &users) { auto *job = new RoomStartDiscussionJob(this); initializeRestApiJob(job); job->setParentRoomId(parentRoomId); job->setDiscussionName(discussionName); job->setParentMessageId(parentMessageId); job->setReplyMessage(replyMessage); job->setUsers(users); connect(job, &RoomStartDiscussionJob::startDiscussionDone, this, &RestApiRequest::startDiscussionDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start roomStartDiscussion"; } } void RestApiRequest::getDiscussions(const QString &roomId, int offset, int count) { auto *job = new GetDiscussionsJob(this); initializeRestApiJob(job); QueryParameters parameters; parameters.setCount(count); parameters.setOffset(offset); job->setQueryParameters(parameters); job->setRoomId(roomId); connect(job, &GetDiscussionsJob::getDiscussionsDone, this, &RestApiRequest::getDiscussionsDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getDiscussions"; } } void RestApiRequest::getThreadsList(const QString &roomId, int offset, int count) { auto *job = new GetThreadsJob(this); initializeRestApiJob(job); job->setRoomId(roomId); QueryParameters parameters; QMap map; map.insert(QStringLiteral("_updatedAt"), QueryParameters::SortOrder::Descendant); parameters.setSorting(map); parameters.setCount(count); parameters.setOffset(offset); job->setQueryParameters(parameters); connect(job, &GetThreadsJob::getThreadsDone, this, &RestApiRequest::getThreadsDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getThreadsList"; } } void RestApiRequest::getPinnedMessages(const QString &roomId, int offset, int count) { auto *job = new GetPinnedMessagesJob(this); initializeRestApiJob(job); job->setRoomId(roomId); QueryParameters parameters; parameters.setCount(count); parameters.setOffset(offset); job->setQueryParameters(parameters); connect(job, &GetPinnedMessagesJob::getPinnedMessagesDone, this, &RestApiRequest::getPinnedMessagesDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getPinnedMessagesList"; } } void RestApiRequest::getStarredMessages(const QString &roomId, int offset, int count) { auto *job = new GetStarredMessagesJob(this); initializeRestApiJob(job); job->setRoomId(roomId); QueryParameters parameters; parameters.setCount(count); parameters.setOffset(offset); job->setQueryParameters(parameters); connect(job, &GetStarredMessagesJob::getStarredMessagesDone, this, &RestApiRequest::getStarredMessagesDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getStarredMessagesList"; } } void RestApiRequest::getSnippetedMessages(const QString &roomId, int offset, int count) { auto *job = new GetSnippetedMessagesJob(this); initializeRestApiJob(job); job->setRoomId(roomId); QueryParameters parameters; parameters.setCount(count); parameters.setOffset(offset); job->setQueryParameters(parameters); connect(job, &GetSnippetedMessagesJob::getSnippetedMessagesDone, this, &RestApiRequest::getSnippetedMessagesDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getSnippetedMessagesList"; } } void RestApiRequest::getThreadMessages(const QString &threadMessageId) { auto *job = new GetThreadMessagesJob(this); initializeRestApiJob(job); job->setThreadMessageId(threadMessageId); connect(job, &GetThreadMessagesJob::getThreadMessagesDone, this, &RestApiRequest::getThreadMessagesDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getThreadMessages"; } } void RestApiRequest::syncThreadMessages(const QString &threadMessageId, const QString ×tamp) { auto *job = new SyncThreadMessagesJob(this); initializeRestApiJob(job); job->setThreadMessageId(threadMessageId); job->setTimeStamp(timestamp); connect(job, &SyncThreadMessagesJob::syncThreadMessagesDone, this, &RestApiRequest::syncThreadMessagesDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start syncThreadMessages"; } } void RestApiRequest::sendMessage(const QString &roomId, const QString &text, const QString &messageId, const QString &threadMessageId) { auto *job = new SendMessageJob(this); initializeRestApiJob(job); SendMessageJob::SendMessageArguments args; args.roomId = roomId; args.message = text; args.messageId = messageId; args.threadMessageId = threadMessageId; job->setSendMessageArguments(args); if (!job->start()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start job"; } } void RestApiRequest::getSupportedLanguagesMessages() { auto *job = new GetSupportedLanguagesJob(this); initializeRestApiJob(job); connect(job, &GetSupportedLanguagesJob::getSupportedLanguagesDone, this, &RestApiRequest::getSupportedLanguagesDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start getSupportedLanguagesMessages"; } } void RestApiRequest::autoTranslateSaveLanguageSettings(const QString &roomId, const QString &language) { auto *job = new TranslateSaveSettingsJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setType(TranslateSaveSettingsJob::LanguageSetting); job->setLanguage(language); connect(job, &TranslateSaveSettingsJob::translateSavesettingsDone, this, &RestApiRequest::translateSavesettingsDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start autoTranslateSaveLanguageSettings"; } } void RestApiRequest::autoTranslateSaveAutoTranslateSettings(const QString &roomId, bool autoTranslate) { auto *job = new TranslateSaveSettingsJob(this); initializeRestApiJob(job); job->setRoomId(roomId); job->setType(TranslateSaveSettingsJob::AutoTranslateSetting); job->setAutoTranslate(autoTranslate); connect(job, &TranslateSaveSettingsJob::translateSavesettingsDone, this, &RestApiRequest::translateSavesettingsDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start autoTranslateSaveAutoTranslateSettings"; } } void RestApiRequest::setUserStatus(const QString &userId, SetStatusJob::StatusType status, const QString &message) { auto *job = new SetStatusJob(this); initializeRestApiJob(job); job->setStatusUserId(userId); job->setStatus(status); job->setStatusMessage(message); connect(job, &SetStatusJob::setStatusDone, this, &RestApiRequest::setStatusDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start SetStatusJob"; } } void RestApiRequest::usersPresence() { auto *job = new UsersPresenceJob(this); initializeRestApiJob(job); connect(job, &UsersPresenceJob::usersPresenceDone, this, &RestApiRequest::usersPresenceDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start usersPresenceJob"; } } void RestApiRequest::customUserStatus() { auto *job = new CustomUserStatusJob(this); initializeRestApiJob(job); connect(job, &CustomUserStatusJob::customUserStatusDone, this, &RestApiRequest::customUserStatusDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start CustomUserStatusJob"; } } void RestApiRequest::customSounds() { auto *job = new CustomSoundsJob(this); initializeRestApiJob(job); connect(job, &CustomSoundsJob::customSoundsDone, this, &RestApiRequest::customSoundsDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start CustomSoundsJob"; } } void RestApiRequest::usersAutocomplete(const UsersAutocompleteJob::UsersAutocompleterInfo &info) { auto *job = new UsersAutocompleteJob(this); job->setUsersCompleterInfo(info); initializeRestApiJob(job); connect(job, &UsersAutocompleteJob::usersAutocompleteDone, this, &RestApiRequest::usersAutocompleteDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start UsersAutocompleteJob"; } } void RestApiRequest::roomsAutocomplete(const RoomsAutocompleteChannelAndPrivateJob::RoomsAutocompleteChannelAndPrivateInfo &info) { auto *job = new RoomsAutocompleteChannelAndPrivateJob(this); job->setRoomsCompleterInfo(info); initializeRestApiJob(job); connect(job, &RoomsAutocompleteChannelAndPrivateJob::roomsAutoCompleteChannelAndPrivateDone, this, &RestApiRequest::roomsAutoCompleteChannelAndPrivateDone); if (!job->start()) { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "Impossible to start RoomsAutocompleteChannelAndPrivateJob"; } } diff --git a/src/rocketchatrestapi-qt5/restapirequest.h b/src/rocketchatrestapi-qt5/restapirequest.h index 7d10ac86..39d6cf25 100644 --- a/src/rocketchatrestapi-qt5/restapirequest.h +++ b/src/rocketchatrestapi-qt5/restapirequest.h @@ -1,266 +1,265 @@ /* Copyright (c) 2017-2020 Laurent Montel This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef RESTAPIREQUEST_H #define RESTAPIREQUEST_H #include #include #include #include "channels/channelbasejob.h" #include "rooms/roomsautocompletechannelandprivatejob.h" #include "restapiutil.h" #include "users/setstatusjob.h" #include "users/usersautocompletejob.h" #include "librocketchatrestapi-qt5_export.h" class QNetworkAccessManager; class QNetworkReply; class QNetworkCookieJar; namespace RocketChatRestApi { class RestApiAbstractJob; class AbstractLogger; class LIBROCKETCHATRESTAPI_QT5_EXPORT RestApiRequest : public QObject { Q_OBJECT public: explicit RestApiRequest(QObject *parent = nullptr); ~RestApiRequest() override; void setRestApiLogger(RocketChatRestApi::AbstractLogger *logger); Q_REQUIRED_RESULT QString userId() const; Q_REQUIRED_RESULT QString authToken() const; void setUserId(const QString &userId); void setAuthToken(const QString &authToken); //Assign/get server url QString serverUrl() const; void setServerUrl(const QString &serverUrl); void setUserName(const QString &userName); void setPassword(const QString &password); void login(); void logout(); void channelList(); void getAvatar(const QString &userId); void serverInfo(bool useDeprecatedVersion); void getPrivateSettings(); void getOwnInfo(); void starMessage(const QString &messageId, bool starred); void uploadFile(const QString &roomId, const QString &description, const QString &text, const QUrl &filename); void downloadFile(const QUrl &url, const QString &mimeType = QStringLiteral("text/plain"), bool storeInCache = true, const QUrl &localFileUrl = QUrl()); void changeChannelTopic(const QString &roomId, const QString &topic); void changeGroupsTopic(const QString &roomId, const QString &topic); void changeChannelAnnouncement(const QString &roomId, const QString &announcement); void changeGroupsAnnouncement(const QString &roomId, const QString &announcement); void postMessage(const QString &roomId, const QString &text); void deleteMessage(const QString &roomId, const QString &messageId); void createChannels(const QString &channelName, bool readOnly, const QStringList &members, const QString &password); void createGroups(const QString &channelName, bool readOnly, const QStringList &members); void leaveChannel(const QString &roomId); void leaveGroups(const QString &roomId); void updateMessage(const QString &roomId, const QString &messageId, const QString &text); void reactOnMessage(const QString &messageId, const QString &emoji, bool shouldReact); void closeChannel(const QString &roomId, const QString &type); void createDirectMessage(const QString &userName); void historyChannel(const QString &roomId, const QString &type); void changeChannelDescription(const QString &roomId, const QString &description); void changeGroupsDescription(const QString &roomId, const QString &description); void archiveChannel(const QString &roomId, bool archive); void archiveGroups(const QString &roomId, bool archive); void filesInRoom(const QString &roomId, const QString &type, int offset = 0, int count = 50); void addUserInChannel(const QString &roomId, const QString &userId); void listEmojiCustom(); void searchRoomUser(const QString &pattern); void searchMessages(const QString &roomId, const QString &pattern); void markAsRead(const QString &roomId); void getRooms(); void markAsFavorite(const QString &roomId, bool favorite); void addUserInGroup(const QString &roomId, const QString &userId); void disableNotifications(const QString &roomId, bool value); void hideUnreadStatus(const QString &roomId, bool value); void audioNotifications(const QString &roomId, const QString &value); void desktopNotifications(const QString &roomId, const QString &value); void emailNotifications(const QString &roomId, const QString &value); void mobilePushNotifications(const QString &roomId, const QString &value); void unreadAlert(const QString &roomId, const QString &value); void setAvatar(const QString &avatarUrl); void markRoomAsUnRead(const QString &roomId); void markMessageAsUnReadFrom(const QString &messageId); void forgotPassword(const QString &email); void userInfo(const QString &identifier, bool userName = false); void ignoreUser(const QString &roomId, const QString &userId, bool ignore); void userPresence(const QString &userId); void reportMessage(const QString &messageId, const QString &message); void setGroupType(const QString &roomId, bool isPrivate); void setChannelType(const QString &roomId, bool isPrivate); void getGroupRoles(const QString &roomId); void getChannelRoles(const QString &roomId); void getUsernameSuggestion(); void listPermissions(); void listCommands(); void fetchMyKeys(); void setJoinCodeChannel(const QString &roomId, const QString &joinCode); void channelJoin(const ChannelBaseJob::ChannelInfo &channelInfo, const QString &joinCode); void muteGroupMentions(const QString &roomId, bool value); void channelInfo(const QString &roomId); void syncThreadMessages(const QString &threadMessageId, const QString ×tamp); void changeChannelName(const QString &roomId, const QString &newName); void changeGroupName(const QString &roomId, const QString &newName); void groupInfo(const QString &roomId); void channelGetAllUserMentions(const QString &roomId, int offset = 0, int count = 50); void updatejitsiTimeOut(const QString &roomId); void openDirectMessage(const QString &userId); void channelKick(const QString &roomId, const QString &userId); void groupKick(const QString &roomId, const QString &userId); void groupAddModerator(const QString &roomId, const QString &userId); void groupRemoveModerator(const QString &roomId, const QString &userId); void groupAddLeader(const QString &roomId, const QString &userId); void groupRemoveLeader(const QString &roomId, const QString &userId); void groupAddOwner(const QString &roomId, const QString &userId); void groupRemoveOwner(const QString &roomId, const QString &userId); void channelAddModerator(const QString &roomId, const QString &userId); void channelRemoveModerator(const QString &roomId, const QString &userId); void channelAddOwner(const QString &roomId, const QString &userId); void channelRemoveOwner(const QString &roomId, const QString &userId); void channelDelete(const QString &roomId); void groupDelete(const QString &roomId); void membersInRoom(const QString &roomId, const QString &type, int offset = 0, int count = 50); void changeChannelReadOnly(const QString &roomId, bool b); void changeGroupsReadOnly(const QString &roomId, bool b); void channelAddLeader(const QString &roomId, const QString &userId); void channelRemoveLeader(const QString &roomId, const QString &userId); void changeChannelEncrypted(const QString &roomId, bool b); void changeGroupsEncrypted(const QString &roomId, bool b); void pinMessage(const QString &messageId, bool pinned); void desktopDurationNotifications(const QString &roomId, int value); void desktopSoundNotifications(const QString &roomId, const QString &value); void followMessage(const QString &messageId); void unFollowMessage(const QString &messageId); void createDiscussion(const QString &parentRoomId, const QString &discussionName, const QString &replyMessage, const QString &parentMessageId, const QStringList &users); void getDiscussions(const QString &roomId, int offset = 0, int count = 50); void getThreadsList(const QString &roomId, int offset = 0, int count = 50); void getThreadMessages(const QString &threadMessageId); void sendMessage(const QString &roomId, const QString &text, const QString &messageId = QString(), const QString &threadMessageId = QString()); void getPinnedMessages(const QString &roomId, int offset = 0, int count = 50); void getSupportedLanguagesMessages(); void autoTranslateSaveLanguageSettings(const QString &roomId, const QString &language); void autoTranslateSaveAutoTranslateSettings(const QString &roomId, bool autoTranslate); void setUserStatus(const QString &userId, SetStatusJob::StatusType status, const QString &message = QString()); void usersPresence(); void getStarredMessages(const QString &roomId, int offset = 0, int count = 50); void getSnippetedMessages(const QString &roomId, int offset = 0, int count = 50); void customUserStatus(); void customSounds(); void usersAutocomplete(const UsersAutocompleteJob::UsersAutocompleterInfo &info); void roomsAutocomplete(const RoomsAutocompleteChannelAndPrivateJob::RoomsAutocompleteChannelAndPrivateInfo &info); Q_SIGNALS: void avatar(const QString &userId, const QString &url); void redownloadAvatar(); - void logoutDone(); void loginDone(const QString &authToken, const QString &userId); void downloadFileDone(const QByteArray &data, const QUrl &url, bool useCache, const QUrl &localFileUrl); void getServerInfoDone(const QString &version); void getServerInfoFailed(bool useDeprecatedVersion); void getOwnInfoDone(const QJsonObject &data); void privateInfoDone(const QByteArray &data); void channelFilesDone(const QJsonObject &obj, const ChannelBaseJob::ChannelInfo &channelInfo); void channelMembersDone(const QJsonObject &obj, const ChannelBaseJob::ChannelInfo &channelInfo); void syncThreadMessagesDone(const QJsonObject &obj, const QString &threadMessageId); void loadEmojiCustomDone(const QJsonObject &obj); void spotlightDone(const QJsonObject &obj); void channelListDone(const QJsonObject &obj); void searchMessageDone(const QJsonObject &obj); void getRoomsDone(const QJsonObject &obj); void usersInfoDone(const QJsonObject &obj); void channelRolesDone(const QJsonObject &obj, const ChannelBaseJob::ChannelInfo &channelInfo); void getUsernameSuggestionDone(const QString &username); void getPresenceDone(const QString &presence); void listPermissionDone(const QJsonObject &obj); void listCommandsDone(const QJsonObject &obj); void fetchMyKeysDone(); void setJoinCodeDone(); void setChannelJoinDone(const ChannelBaseJob::ChannelInfo &channelInfo); void missingChannelPassword(const ChannelBaseJob::ChannelInfo &channelInfo); void openArchivedRoom(const ChannelBaseJob::ChannelInfo &channelInfo); void channelGetAllUserMentionsDone(const QJsonObject &obj, const QString &roomId); void updateJitsiTimeOutDone(const QString &datetime); void channelKickUserDone(const QJsonObject &obj); void groupKickUserDone(const QJsonObject &obj); void addModeratorDone(); void removeModeratorDone(); void addLeaderDone(); void removeLeaderDone(); void addOwnerDone(); void removeOwnerDone(); void deletechannelDone(); void deleteGroupsDone(); void pinMessageDone(); void ignoreUserDone(const QJsonObject &obj, const QString &roomId); void groupRolesDone(const QJsonObject &obj, const QString &roomId); void followMessageDone(); void unFollowMessageDone(); void startDiscussionDone(); void getDiscussionsDone(const QJsonObject &obj, const QString &roomId); void getThreadsDone(const QJsonObject &obj, const QString &roomId); void getThreadMessagesDone(const QJsonObject &obj, const QString &threadMessageId); void getPinnedMessagesDone(const QJsonObject &obj, const QString &roomId); void getStarredMessagesDone(const QJsonObject &obj, const QString &roomId); void getSnippetedMessagesDone(const QJsonObject &obj, const QString &roomId); void getSupportedLanguagesDone(const QJsonObject &obj); void translateSavesettingsDone(); void setStatusDone(); void usersPresenceDone(const QJsonObject &obj); void customUserStatusDone(const QByteArray &); //TODO QByteArray or QJson ? void customSoundsDone(const QByteArray &); //TODO QByteArray or QJson ? void usersAutocompleteDone(const QJsonObject &obj); void roomsAutoCompleteChannelAndPrivateDone(const QJsonObject &obj); void failed(const QString &str); private: Q_DISABLE_COPY(RestApiRequest) void initializeCookies(); void slotResult(QNetworkReply *reply); void slotSslErrors(QNetworkReply *reply, const QList &error); void slotLogout(); void slotLogin(const QString &authToken, const QString &userId); void slotAddJoinCodeToChannel(const QString &channelId, const QString &password); void initializeRestApiJob(RocketChatRestApi::RestApiAbstractJob *job); QNetworkAccessManager *mNetworkAccessManager = nullptr; QNetworkCookieJar *mCookieJar = nullptr; RestApiMethod *mRestApiMethod = nullptr; RocketChatRestApi::AbstractLogger *mRuqolaLogger = nullptr; QString mUserId; QString mAuthToken; QString mUserName; QString mPassword; }; } #endif // RESTAPIREQUEST_H