2019-08-14 14:54:46 +00:00
|
|
|
/*
|
|
|
|
* Squawk messenger.
|
|
|
|
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
|
|
|
|
*
|
|
|
|
* 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 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2019-03-29 14:54:34 +00:00
|
|
|
#include "squawk.h"
|
2019-03-30 20:13:13 +00:00
|
|
|
#include <QDebug>
|
2019-04-02 21:58:43 +00:00
|
|
|
#include <QSettings>
|
2019-05-29 15:05:54 +00:00
|
|
|
#include <QDir>
|
|
|
|
#include <QStandardPaths>
|
2019-03-29 14:54:34 +00:00
|
|
|
|
2019-03-30 20:13:13 +00:00
|
|
|
Core::Squawk::Squawk(QObject* parent):
|
2019-03-29 14:54:34 +00:00
|
|
|
QObject(parent),
|
2019-03-31 21:05:09 +00:00
|
|
|
accounts(),
|
2019-09-11 15:03:52 +00:00
|
|
|
amap(),
|
2020-04-04 16:40:32 +00:00
|
|
|
network(),
|
2020-04-10 22:15:08 +00:00
|
|
|
waitingForAccounts(0)
|
|
|
|
#ifdef WITH_KWALLET
|
|
|
|
,kwallet()
|
|
|
|
#endif
|
2019-03-29 14:54:34 +00:00
|
|
|
{
|
2019-10-16 19:38:35 +00:00
|
|
|
connect(&network, &NetworkAccess::fileLocalPathResponse, this, &Squawk::fileLocalPathResponse);
|
|
|
|
connect(&network, &NetworkAccess::downloadFileProgress, this, &Squawk::downloadFileProgress);
|
|
|
|
connect(&network, &NetworkAccess::downloadFileError, this, &Squawk::downloadFileError);
|
2019-11-09 09:54:30 +00:00
|
|
|
connect(&network, &NetworkAccess::uploadFileProgress, this, &Squawk::uploadFileProgress);
|
|
|
|
connect(&network, &NetworkAccess::uploadFileError, this, &Squawk::uploadFileError);
|
2020-04-09 22:48:08 +00:00
|
|
|
|
2020-04-10 22:15:08 +00:00
|
|
|
#ifdef WITH_KWALLET
|
2020-04-09 22:48:08 +00:00
|
|
|
if (kwallet.supportState() == PSE::KWallet::success) {
|
|
|
|
connect(&kwallet, &PSE::KWallet::opened, this, &Squawk::onWalletOpened);
|
|
|
|
connect(&kwallet, &PSE::KWallet::rejectPassword, this, &Squawk::onWalletRejectPassword);
|
|
|
|
connect(&kwallet, &PSE::KWallet::responsePassword, this, &Squawk::onWalletResponsePassword);
|
2020-04-10 22:15:08 +00:00
|
|
|
|
|
|
|
Shared::Global::setSupported("KWallet", true);
|
2020-04-09 22:48:08 +00:00
|
|
|
}
|
2020-04-10 22:15:08 +00:00
|
|
|
#endif
|
2019-03-29 14:54:34 +00:00
|
|
|
}
|
|
|
|
|
2019-03-30 20:13:13 +00:00
|
|
|
Core::Squawk::~Squawk()
|
2019-03-29 14:54:34 +00:00
|
|
|
{
|
2019-03-30 20:13:13 +00:00
|
|
|
Accounts::const_iterator itr = accounts.begin();
|
|
|
|
Accounts::const_iterator end = accounts.end();
|
|
|
|
for (; itr != end; ++itr) {
|
2019-04-02 21:58:43 +00:00
|
|
|
delete (*itr);
|
2019-03-30 20:13:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-09 22:48:08 +00:00
|
|
|
void Core::Squawk::onWalletOpened(bool success)
|
|
|
|
{
|
|
|
|
qDebug() << "KWallet opened: " << success;
|
|
|
|
}
|
|
|
|
|
2019-04-02 21:58:43 +00:00
|
|
|
void Core::Squawk::stop()
|
|
|
|
{
|
|
|
|
qDebug("Stopping squawk core..");
|
2019-09-17 15:16:09 +00:00
|
|
|
network.stop();
|
2019-04-02 21:58:43 +00:00
|
|
|
QSettings settings;
|
|
|
|
settings.beginGroup("core");
|
|
|
|
settings.beginWriteArray("accounts");
|
2020-04-07 20:33:03 +00:00
|
|
|
SimpleCrypt crypto(passwordHash);
|
2019-11-17 10:24:12 +00:00
|
|
|
for (std::deque<Account*>::size_type i = 0; i < accounts.size(); ++i) {
|
2019-04-02 21:58:43 +00:00
|
|
|
settings.setArrayIndex(i);
|
|
|
|
Account* acc = accounts[i];
|
2020-04-07 20:33:03 +00:00
|
|
|
|
|
|
|
Shared::AccountPassword ap = acc->getPasswordType();
|
|
|
|
QString password;
|
|
|
|
|
|
|
|
switch (ap) {
|
|
|
|
case Shared::AccountPassword::plain:
|
|
|
|
password = acc->getPassword();
|
|
|
|
break;
|
|
|
|
case Shared::AccountPassword::jammed:
|
|
|
|
password = crypto.encryptToString(acc->getPassword());
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2019-04-02 21:58:43 +00:00
|
|
|
settings.setValue("name", acc->getName());
|
|
|
|
settings.setValue("server", acc->getServer());
|
|
|
|
settings.setValue("login", acc->getLogin());
|
2020-04-07 20:33:03 +00:00
|
|
|
settings.setValue("password", password);
|
2019-04-12 05:51:36 +00:00
|
|
|
settings.setValue("resource", acc->getResource());
|
2020-04-07 20:33:03 +00:00
|
|
|
settings.setValue("passwordType", static_cast<int>(ap));
|
2019-04-02 21:58:43 +00:00
|
|
|
}
|
|
|
|
settings.endArray();
|
|
|
|
settings.endGroup();
|
|
|
|
|
|
|
|
settings.sync();
|
|
|
|
|
|
|
|
emit quit();
|
|
|
|
}
|
|
|
|
|
2019-03-30 20:13:13 +00:00
|
|
|
void Core::Squawk::start()
|
|
|
|
{
|
2019-04-02 21:58:43 +00:00
|
|
|
qDebug("Starting squawk core..");
|
|
|
|
|
2020-04-04 16:40:32 +00:00
|
|
|
readSettings();
|
2019-09-17 15:16:09 +00:00
|
|
|
network.start();
|
2019-03-30 20:13:13 +00:00
|
|
|
}
|
2019-03-29 14:54:34 +00:00
|
|
|
|
2019-03-30 20:13:13 +00:00
|
|
|
void Core::Squawk::newAccountRequest(const QMap<QString, QVariant>& map)
|
|
|
|
{
|
|
|
|
QString name = map.value("name").toString();
|
|
|
|
QString login = map.value("login").toString();
|
|
|
|
QString server = map.value("server").toString();
|
|
|
|
QString password = map.value("password").toString();
|
2019-04-12 05:51:36 +00:00
|
|
|
QString resource = map.value("resource").toString();
|
2019-03-30 20:13:13 +00:00
|
|
|
|
2020-04-04 16:40:32 +00:00
|
|
|
addAccount(login, server, password, name, resource, Shared::AccountPassword::plain);
|
2019-03-30 20:13:13 +00:00
|
|
|
}
|
|
|
|
|
2020-04-04 16:40:32 +00:00
|
|
|
void Core::Squawk::addAccount(
|
|
|
|
const QString& login,
|
|
|
|
const QString& server,
|
|
|
|
const QString& password,
|
|
|
|
const QString& name,
|
|
|
|
const QString& resource,
|
|
|
|
Shared::AccountPassword passwordType
|
|
|
|
)
|
2019-03-30 20:13:13 +00:00
|
|
|
{
|
2019-10-01 08:47:40 +00:00
|
|
|
QSettings settings;
|
|
|
|
|
2019-11-09 14:04:27 +00:00
|
|
|
Account* acc = new Account(login, server, password, name, &network);
|
2019-04-12 05:51:36 +00:00
|
|
|
acc->setResource(resource);
|
2020-04-04 16:40:32 +00:00
|
|
|
acc->setPasswordType(passwordType);
|
2019-03-30 20:13:13 +00:00
|
|
|
accounts.push_back(acc);
|
2019-03-31 21:05:09 +00:00
|
|
|
amap.insert(std::make_pair(name, acc));
|
|
|
|
|
2019-10-16 19:38:35 +00:00
|
|
|
connect(acc, &Account::connectionStateChanged, this, &Squawk::onAccountConnectionStateChanged);
|
|
|
|
connect(acc, &Account::changed, this, &Squawk::onAccountChanged);
|
|
|
|
connect(acc, &Account::error, this, &Squawk::onAccountError);
|
|
|
|
connect(acc, &Account::availabilityChanged, this, &Squawk::onAccountAvailabilityChanged);
|
|
|
|
connect(acc, &Account::addContact, this, &Squawk::onAccountAddContact);
|
|
|
|
connect(acc, &Account::addGroup, this, &Squawk::onAccountAddGroup);
|
|
|
|
connect(acc, &Account::removeGroup, this, &Squawk::onAccountRemoveGroup);
|
2020-04-04 16:40:32 +00:00
|
|
|
connect(acc, qOverload<const QString&, const QString&>(&Account::removeContact),
|
|
|
|
this, qOverload<const QString&, const QString&>(&Squawk::onAccountRemoveContact));
|
|
|
|
connect(acc, qOverload<const QString&>(&Account::removeContact),
|
|
|
|
this, qOverload<const QString&>(&Squawk::onAccountRemoveContact));
|
2019-10-16 19:38:35 +00:00
|
|
|
connect(acc, &Account::changeContact, this, &Squawk::onAccountChangeContact);
|
|
|
|
connect(acc, &Account::addPresence, this, &Squawk::onAccountAddPresence);
|
|
|
|
connect(acc, &Account::removePresence, this, &Squawk::onAccountRemovePresence);
|
|
|
|
connect(acc, &Account::message, this, &Squawk::onAccountMessage);
|
2020-03-25 15:28:36 +00:00
|
|
|
connect(acc, &Account::changeMessage, this, &Squawk::onAccountChangeMessage);
|
2019-10-16 19:38:35 +00:00
|
|
|
connect(acc, &Account::responseArchive, this, &Squawk::onAccountResponseArchive);
|
|
|
|
|
|
|
|
connect(acc, &Account::addRoom, this, &Squawk::onAccountAddRoom);
|
|
|
|
connect(acc, &Account::changeRoom, this, &Squawk::onAccountChangeRoom);
|
|
|
|
connect(acc, &Account::removeRoom, this, &Squawk::onAccountRemoveRoom);
|
2019-07-11 08:51:52 +00:00
|
|
|
|
2019-10-16 19:38:35 +00:00
|
|
|
connect(acc, &Account::addRoomParticipant, this, &Squawk::onAccountAddRoomPresence);
|
|
|
|
connect(acc, &Account::changeRoomParticipant, this, &Squawk::onAccountChangeRoomPresence);
|
|
|
|
connect(acc, &Account::removeRoomParticipant, this, &Squawk::onAccountRemoveRoomPresence);
|
2019-09-02 11:17:28 +00:00
|
|
|
|
2019-10-22 15:13:56 +00:00
|
|
|
connect(acc, &Account::receivedVCard, this, &Squawk::responseVCard);
|
2019-07-11 08:51:52 +00:00
|
|
|
|
2019-11-14 11:43:43 +00:00
|
|
|
connect(acc, &Account::uploadFileError, this, &Squawk::uploadFileError);
|
|
|
|
|
2019-03-30 20:13:13 +00:00
|
|
|
QMap<QString, QVariant> map = {
|
|
|
|
{"login", login},
|
|
|
|
{"server", server},
|
|
|
|
{"name", name},
|
|
|
|
{"password", password},
|
2019-04-12 05:51:36 +00:00
|
|
|
{"resource", resource},
|
2020-04-03 22:28:15 +00:00
|
|
|
{"state", QVariant::fromValue(Shared::ConnectionState::disconnected)},
|
|
|
|
{"offline", QVariant::fromValue(Shared::Availability::offline)},
|
2019-10-16 19:38:35 +00:00
|
|
|
{"error", ""},
|
2020-04-04 16:40:32 +00:00
|
|
|
{"avatarPath", acc->getAvatarPath()},
|
|
|
|
{"passwordType", QVariant::fromValue(passwordType)}
|
2019-03-30 20:13:13 +00:00
|
|
|
};
|
2019-10-16 19:38:35 +00:00
|
|
|
|
2019-03-30 20:13:13 +00:00
|
|
|
emit newAccount(map);
|
2019-03-29 14:54:34 +00:00
|
|
|
}
|
2019-03-31 21:05:09 +00:00
|
|
|
|
2020-04-03 22:28:15 +00:00
|
|
|
void Core::Squawk::changeState(Shared::Availability p_state)
|
2019-04-07 20:14:15 +00:00
|
|
|
{
|
2020-04-03 22:28:15 +00:00
|
|
|
if (state != p_state) {
|
|
|
|
state = p_state;
|
2019-04-07 20:14:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (std::deque<Account*>::iterator itr = accounts.begin(), end = accounts.end(); itr != end; ++itr) {
|
|
|
|
(*itr)->setAvailability(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-31 21:05:09 +00:00
|
|
|
void Core::Squawk::connectAccount(const QString& account)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to connect non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->connect();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::disconnectAccount(const QString& account)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to connect non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-02 15:46:18 +00:00
|
|
|
itr->second->disconnect();
|
2019-03-31 21:05:09 +00:00
|
|
|
}
|
|
|
|
|
2020-04-03 22:28:15 +00:00
|
|
|
void Core::Squawk::onAccountConnectionStateChanged(Shared::ConnectionState p_state)
|
2019-03-31 21:05:09 +00:00
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
2020-04-03 22:28:15 +00:00
|
|
|
emit changeAccount(acc->getName(), {{"state", QVariant::fromValue(p_state)}});
|
2019-05-23 20:19:53 +00:00
|
|
|
|
2020-04-09 22:48:08 +00:00
|
|
|
switch (p_state) {
|
|
|
|
case Shared::ConnectionState::disconnected: {
|
|
|
|
bool equals = true;
|
|
|
|
for (Accounts::const_iterator itr = accounts.begin(), end = accounts.end(); itr != end; itr++) {
|
|
|
|
if ((*itr)->getState() != Shared::ConnectionState::disconnected) {
|
|
|
|
equals = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (equals && state != Shared::Availability::offline) {
|
|
|
|
state = Shared::Availability::offline;
|
|
|
|
emit stateChanged(state);
|
|
|
|
}
|
2019-05-23 20:19:53 +00:00
|
|
|
}
|
2020-04-09 22:48:08 +00:00
|
|
|
break;
|
|
|
|
case Shared::ConnectionState::connected:
|
2020-04-10 22:15:08 +00:00
|
|
|
#ifdef WITH_KWALLET
|
2020-04-09 22:48:08 +00:00
|
|
|
if (acc->getPasswordType() == Shared::AccountPassword::kwallet && kwallet.supportState() == PSE::KWallet::success) {
|
|
|
|
kwallet.requestWritePassword(acc->getName(), acc->getPassword(), true);
|
|
|
|
}
|
2020-04-10 22:15:08 +00:00
|
|
|
#endif
|
2020-04-09 22:48:08 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2019-05-23 20:19:53 +00:00
|
|
|
}
|
2019-03-31 21:05:09 +00:00
|
|
|
}
|
|
|
|
|
2019-04-07 20:14:15 +00:00
|
|
|
void Core::Squawk::onAccountAddContact(const QString& jid, const QString& group, const QMap<QString, QVariant>& data)
|
2019-04-03 21:23:51 +00:00
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
2019-04-07 20:14:15 +00:00
|
|
|
emit addContact(acc->getName(), jid, group, data);
|
2019-04-03 21:23:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountAddGroup(const QString& name)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit addGroup(acc->getName(), name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountRemoveGroup(const QString& name)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit removeGroup(acc->getName(), name);
|
|
|
|
}
|
2019-04-06 10:14:32 +00:00
|
|
|
|
2019-04-07 20:14:15 +00:00
|
|
|
void Core::Squawk::onAccountChangeContact(const QString& jid, const QMap<QString, QVariant>& data)
|
2019-04-06 10:14:32 +00:00
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
2019-04-07 20:14:15 +00:00
|
|
|
emit changeContact(acc->getName(), jid, data);
|
2019-04-06 10:14:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountRemoveContact(const QString& jid)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit removeContact(acc->getName(), jid);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountRemoveContact(const QString& jid, const QString& group)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit removeContact(acc->getName(), jid, group);
|
|
|
|
}
|
2019-04-07 14:02:41 +00:00
|
|
|
|
|
|
|
void Core::Squawk::onAccountAddPresence(const QString& jid, const QString& name, const QMap<QString, QVariant>& data)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit addPresence(acc->getName(), jid, name, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountRemovePresence(const QString& jid, const QString& name)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit removePresence(acc->getName(), jid, name);
|
|
|
|
}
|
2019-04-07 20:14:15 +00:00
|
|
|
|
2020-04-03 22:28:15 +00:00
|
|
|
void Core::Squawk::onAccountAvailabilityChanged(Shared::Availability state)
|
2019-04-07 20:14:15 +00:00
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
2020-04-03 22:28:15 +00:00
|
|
|
emit changeAccount(acc->getName(), {{"availability", QVariant::fromValue(state)}});
|
2019-04-07 20:14:15 +00:00
|
|
|
}
|
2019-04-09 22:01:25 +00:00
|
|
|
|
2019-10-16 19:38:35 +00:00
|
|
|
void Core::Squawk::onAccountChanged(const QMap<QString, QVariant>& data)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit changeAccount(acc->getName(), data);
|
|
|
|
}
|
|
|
|
|
2019-04-11 14:58:59 +00:00
|
|
|
void Core::Squawk::onAccountMessage(const Shared::Message& data)
|
2019-04-09 22:01:25 +00:00
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit accountMessage(acc->getName(), data);
|
|
|
|
}
|
2019-04-10 20:53:42 +00:00
|
|
|
|
2019-04-11 14:58:59 +00:00
|
|
|
void Core::Squawk::sendMessage(const QString& account, const Shared::Message& data)
|
2019-04-10 20:53:42 +00:00
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to send a message with non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
itr->second->sendMessage(data);
|
|
|
|
}
|
2019-04-13 20:38:20 +00:00
|
|
|
|
2019-09-23 12:09:15 +00:00
|
|
|
void Core::Squawk::sendMessage(const QString& account, const Shared::Message& data, const QString& path)
|
|
|
|
{
|
2019-11-09 14:04:27 +00:00
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to send a message with non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
2019-09-23 12:09:15 +00:00
|
|
|
|
2019-11-09 14:04:27 +00:00
|
|
|
itr->second->sendMessage(data, path);
|
2019-09-23 12:09:15 +00:00
|
|
|
}
|
|
|
|
|
2019-05-15 17:36:37 +00:00
|
|
|
void Core::Squawk::requestArchive(const QString& account, const QString& jid, int count, const QString& before)
|
2019-04-13 20:38:20 +00:00
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to request an archive of non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
2019-05-15 17:36:37 +00:00
|
|
|
itr->second->requestArchive(jid, count, before);
|
2019-04-13 20:38:20 +00:00
|
|
|
}
|
2019-05-15 17:36:37 +00:00
|
|
|
|
|
|
|
void Core::Squawk::onAccountResponseArchive(const QString& jid, const std::list<Shared::Message>& list)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit responseArchive(acc->getName(), jid, list);
|
|
|
|
}
|
|
|
|
|
2019-05-24 14:46:34 +00:00
|
|
|
void Core::Squawk::modifyAccountRequest(const QString& name, const QMap<QString, QVariant>& map)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(name);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to modify non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Core::Account* acc = itr->second;
|
|
|
|
Shared::ConnectionState st = acc->getState();
|
2020-04-07 20:33:03 +00:00
|
|
|
QMap<QString, QVariant>::const_iterator mItr;
|
|
|
|
bool needToReconnect = false;
|
|
|
|
|
|
|
|
mItr = map.find("login");
|
|
|
|
if (mItr != map.end()) {
|
|
|
|
needToReconnect = acc->getLogin() != mItr->toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!needToReconnect) {
|
|
|
|
mItr = map.find("password");
|
|
|
|
if (mItr != map.end()) {
|
|
|
|
needToReconnect = acc->getPassword() != mItr->toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!needToReconnect) {
|
|
|
|
mItr = map.find("server");
|
|
|
|
if (mItr != map.end()) {
|
|
|
|
needToReconnect = acc->getServer() != mItr->toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!needToReconnect) {
|
|
|
|
mItr = map.find("resource");
|
|
|
|
if (mItr != map.end()) {
|
|
|
|
needToReconnect = acc->getResource() != mItr->toString();
|
|
|
|
}
|
|
|
|
}
|
2019-05-24 14:46:34 +00:00
|
|
|
|
2020-04-07 20:33:03 +00:00
|
|
|
if (needToReconnect && st != Shared::ConnectionState::disconnected) {
|
2019-05-24 14:46:34 +00:00
|
|
|
acc->reconnect();
|
|
|
|
}
|
|
|
|
|
|
|
|
mItr = map.find("login");
|
|
|
|
if (mItr != map.end()) {
|
|
|
|
acc->setLogin(mItr->toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
mItr = map.find("password");
|
|
|
|
if (mItr != map.end()) {
|
|
|
|
acc->setPassword(mItr->toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
mItr = map.find("resource");
|
|
|
|
if (mItr != map.end()) {
|
|
|
|
acc->setResource(mItr->toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
mItr = map.find("server");
|
|
|
|
if (mItr != map.end()) {
|
|
|
|
acc->setServer(mItr->toString());
|
|
|
|
}
|
|
|
|
|
2020-04-07 20:33:03 +00:00
|
|
|
mItr = map.find("passwordType");
|
|
|
|
if (mItr != map.end()) {
|
|
|
|
acc->setPasswordType(Shared::Global::fromInt<Shared::AccountPassword>(mItr->toInt()));
|
|
|
|
}
|
|
|
|
|
2020-04-10 22:15:08 +00:00
|
|
|
#ifdef WITH_KWALLET
|
2020-04-09 22:48:08 +00:00
|
|
|
if (acc->getPasswordType() == Shared::AccountPassword::kwallet
|
|
|
|
&& kwallet.supportState() == PSE::KWallet::success
|
|
|
|
&& !needToReconnect
|
|
|
|
) {
|
|
|
|
kwallet.requestWritePassword(acc->getName(), acc->getPassword(), true);
|
|
|
|
}
|
2020-04-10 22:15:08 +00:00
|
|
|
#endif
|
2020-04-09 22:48:08 +00:00
|
|
|
|
2019-05-24 14:46:34 +00:00
|
|
|
emit changeAccount(name, map);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountError(const QString& text)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit changeAccount(acc->getName(), {{"error", text}});
|
|
|
|
}
|
2019-05-29 15:05:54 +00:00
|
|
|
|
|
|
|
void Core::Squawk::removeAccountRequest(const QString& name)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(name);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug() << "An attempt to remove non existing account " << name << " from core, skipping";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Account* acc = itr->second;
|
2020-04-03 22:28:15 +00:00
|
|
|
if (acc->getState() != Shared::ConnectionState::disconnected) {
|
2019-05-30 09:36:21 +00:00
|
|
|
acc->disconnect();
|
|
|
|
}
|
2019-05-29 15:05:54 +00:00
|
|
|
|
|
|
|
for (Accounts::const_iterator aItr = accounts.begin(); aItr != accounts.end(); ++aItr) {
|
|
|
|
if (*aItr == acc) {
|
|
|
|
accounts.erase(aItr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
amap.erase(itr);
|
|
|
|
|
|
|
|
QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
|
|
|
|
path += "/" + name;
|
|
|
|
QDir dir(path);
|
|
|
|
dir.removeRecursively();
|
|
|
|
|
|
|
|
emit removeAccount(name);
|
2019-05-30 09:36:21 +00:00
|
|
|
acc->deleteLater();
|
2019-05-29 15:05:54 +00:00
|
|
|
}
|
2019-06-12 17:18:18 +00:00
|
|
|
|
|
|
|
void Core::Squawk::subscribeContact(const QString& account, const QString& jid, const QString& reason)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to subscribe to the contact with non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
itr->second->subscribeToContact(jid, reason);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::unsubscribeContact(const QString& account, const QString& jid, const QString& reason)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to subscribe to the contact with non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
itr->second->unsubscribeFromContact(jid, reason);
|
|
|
|
}
|
2019-06-14 16:36:04 +00:00
|
|
|
|
|
|
|
void Core::Squawk::removeContactRequest(const QString& account, const QString& jid)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to remove contact from non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
itr->second->removeContactRequest(jid);
|
|
|
|
}
|
2019-06-15 15:29:15 +00:00
|
|
|
|
|
|
|
void Core::Squawk::addContactRequest(const QString& account, const QString& jid, const QString& name, const QSet<QString>& groups)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug("An attempt to add contact to a non existing account, skipping");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
itr->second->addContactRequest(jid, name, groups);
|
|
|
|
}
|
2019-07-11 08:51:52 +00:00
|
|
|
|
|
|
|
void Core::Squawk::onAccountAddRoom(const QString jid, const QMap<QString, QVariant>& data)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit addRoom(acc->getName(), jid, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountChangeRoom(const QString jid, const QMap<QString, QVariant>& data)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit changeRoom(acc->getName(), jid, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountRemoveRoom(const QString jid)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit removeRoom(acc->getName(), jid);
|
|
|
|
}
|
2019-08-29 14:19:35 +00:00
|
|
|
|
|
|
|
void Core::Squawk::setRoomJoined(const QString& account, const QString& jid, bool joined)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
2019-08-31 20:50:05 +00:00
|
|
|
qDebug() << "An attempt to set jouned to the room" << jid << "of non existing account" << account << ", skipping";
|
2019-08-29 14:19:35 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->setRoomJoined(jid, joined);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::setRoomAutoJoin(const QString& account, const QString& jid, bool joined)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug() << "An attempt to set autoJoin to the room" << jid << "of non existing account" << account << ", skipping";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->setRoomAutoJoin(jid, joined);
|
|
|
|
}
|
|
|
|
|
2019-09-01 19:46:12 +00:00
|
|
|
void Core::Squawk::onAccountAddRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit addRoomParticipant(acc->getName(), jid, nick, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountChangeRoomPresence(const QString& jid, const QString& nick, const QMap<QString, QVariant>& data)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit changeRoomParticipant(acc->getName(), jid, nick, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onAccountRemoveRoomPresence(const QString& jid, const QString& nick)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit removeRoomParticipant(acc->getName(), jid, nick);
|
|
|
|
}
|
2019-09-03 20:28:58 +00:00
|
|
|
|
2020-03-25 15:28:36 +00:00
|
|
|
void Core::Squawk::onAccountChangeMessage(const QString& jid, const QString& id, const QMap<QString, QVariant>& data)
|
|
|
|
{
|
|
|
|
Account* acc = static_cast<Account*>(sender());
|
|
|
|
emit changeMessage(acc->getName(), jid, id, data);
|
|
|
|
}
|
|
|
|
|
2019-09-03 20:28:58 +00:00
|
|
|
void Core::Squawk::removeRoomRequest(const QString& account, const QString& jid)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug() << "An attempt to remove the room" << jid << "of non existing account" << account << ", skipping";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->removeRoomRequest(jid);
|
|
|
|
}
|
2019-09-04 16:38:52 +00:00
|
|
|
|
|
|
|
void Core::Squawk::addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug() << "An attempt to add the room" << jid << "to non existing account" << account << ", skipping";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->addRoomRequest(jid, nick, password, autoJoin);
|
|
|
|
}
|
|
|
|
|
2019-09-11 15:03:52 +00:00
|
|
|
void Core::Squawk::fileLocalPathRequest(const QString& messageId, const QString& url)
|
|
|
|
{
|
2019-09-17 15:16:09 +00:00
|
|
|
network.fileLocalPathRequest(messageId, url);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::downloadFileRequest(const QString& messageId, const QString& url)
|
|
|
|
{
|
|
|
|
network.downladFileRequest(messageId, url);
|
2019-09-11 15:03:52 +00:00
|
|
|
}
|
2019-09-28 14:30:16 +00:00
|
|
|
|
|
|
|
void Core::Squawk::addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
2019-10-22 15:13:56 +00:00
|
|
|
qDebug() << "An attempt to add contact" << jid << "of non existing account" << account << "to the group" << groupName << ", skipping";
|
2019-09-28 14:30:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->addContactToGroupRequest(jid, groupName);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::removeContactFromGroupRequest(const QString& account, const QString& jid, const QString& groupName)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
2019-10-22 15:13:56 +00:00
|
|
|
qDebug() << "An attempt to add contact" << jid << "of non existing account" << account << "to the group" << groupName << ", skipping";
|
2019-09-28 14:30:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->removeContactFromGroupRequest(jid, groupName);
|
|
|
|
}
|
2019-10-01 08:47:40 +00:00
|
|
|
|
|
|
|
void Core::Squawk::renameContactRequest(const QString& account, const QString& jid, const QString& newName)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
2019-10-22 15:13:56 +00:00
|
|
|
qDebug() << "An attempt to rename contact" << jid << "of non existing account" << account << ", skipping";
|
2019-10-01 08:47:40 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->renameContactRequest(jid, newName);
|
|
|
|
}
|
2019-10-22 15:13:56 +00:00
|
|
|
|
|
|
|
void Core::Squawk::requestVCard(const QString& account, const QString& jid)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug() << "An attempt to request" << jid << "vcard of non existing account" << account << ", skipping";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->requestVCard(jid);
|
|
|
|
}
|
2019-10-24 09:42:38 +00:00
|
|
|
|
|
|
|
void Core::Squawk::uploadVCard(const QString& account, const Shared::VCard& card)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug() << "An attempt to upload vcard to non existing account" << account << ", skipping";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->uploadVCard(card);
|
|
|
|
}
|
2020-03-25 15:28:36 +00:00
|
|
|
|
2020-04-07 20:33:03 +00:00
|
|
|
void Core::Squawk::responsePassword(const QString& account, const QString& password)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(account);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug() << "An attempt to set password to non existing account" << account << ", skipping";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
itr->second->setPassword(password);
|
2020-05-21 15:42:40 +00:00
|
|
|
emit changeAccount(account, {{"password", password}});
|
2020-04-07 20:33:03 +00:00
|
|
|
accountReady();
|
|
|
|
}
|
|
|
|
|
2020-04-04 16:40:32 +00:00
|
|
|
void Core::Squawk::readSettings()
|
|
|
|
{
|
|
|
|
QSettings settings;
|
|
|
|
settings.beginGroup("core");
|
|
|
|
int size = settings.beginReadArray("accounts");
|
|
|
|
waitingForAccounts = size;
|
|
|
|
for (int i = 0; i < size; ++i) {
|
|
|
|
settings.setArrayIndex(i);
|
|
|
|
parseAccount(
|
|
|
|
settings.value("login").toString(),
|
|
|
|
settings.value("server").toString(),
|
|
|
|
settings.value("password", "").toString(),
|
|
|
|
settings.value("name").toString(),
|
|
|
|
settings.value("resource").toString(),
|
|
|
|
Shared::Global::fromInt<Shared::AccountPassword>(settings.value("passwordType", static_cast<int>(Shared::AccountPassword::plain)).toInt())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
settings.endArray();
|
|
|
|
settings.endGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::accountReady()
|
|
|
|
{
|
|
|
|
--waitingForAccounts;
|
|
|
|
|
|
|
|
if (waitingForAccounts == 0) {
|
|
|
|
emit ready();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::parseAccount(
|
|
|
|
const QString& login,
|
|
|
|
const QString& server,
|
|
|
|
const QString& password,
|
|
|
|
const QString& name,
|
|
|
|
const QString& resource,
|
|
|
|
Shared::AccountPassword passwordType
|
|
|
|
)
|
|
|
|
{
|
|
|
|
switch (passwordType) {
|
|
|
|
case Shared::AccountPassword::plain:
|
|
|
|
addAccount(login, server, password, name, resource, passwordType);
|
|
|
|
accountReady();
|
|
|
|
break;
|
2020-04-07 20:33:03 +00:00
|
|
|
case Shared::AccountPassword::jammed: {
|
|
|
|
SimpleCrypt crypto(passwordHash);
|
|
|
|
QString decrypted = crypto.decryptToString(password);
|
|
|
|
addAccount(login, server, decrypted, name, resource, passwordType);
|
|
|
|
accountReady();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case Shared::AccountPassword::alwaysAsk:
|
|
|
|
addAccount(login, server, QString(), name, resource, passwordType);
|
|
|
|
emit requestPassword(name);
|
|
|
|
break;
|
2020-04-09 22:48:08 +00:00
|
|
|
case Shared::AccountPassword::kwallet: {
|
|
|
|
addAccount(login, server, QString(), name, resource, passwordType);
|
2020-04-10 22:15:08 +00:00
|
|
|
#ifdef WITH_KWALLET
|
2020-04-09 22:48:08 +00:00
|
|
|
if (kwallet.supportState() == PSE::KWallet::success) {
|
|
|
|
kwallet.requestReadPassword(name);
|
|
|
|
} else {
|
2020-04-10 22:15:08 +00:00
|
|
|
#endif
|
2020-04-09 22:48:08 +00:00
|
|
|
emit requestPassword(name);
|
2020-04-10 22:15:08 +00:00
|
|
|
#ifdef WITH_KWALLET
|
2020-04-09 22:48:08 +00:00
|
|
|
}
|
2020-04-10 22:15:08 +00:00
|
|
|
#endif
|
2020-04-09 22:48:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onWalletRejectPassword(const QString& login)
|
|
|
|
{
|
|
|
|
emit requestPassword(login);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Core::Squawk::onWalletResponsePassword(const QString& login, const QString& password)
|
|
|
|
{
|
|
|
|
AccountsMap::const_iterator itr = amap.find(login);
|
|
|
|
if (itr == amap.end()) {
|
|
|
|
qDebug() << "An attempt to set password to non existing account" << login << ", skipping";
|
|
|
|
return;
|
2020-04-04 16:40:32 +00:00
|
|
|
}
|
2020-04-09 22:48:08 +00:00
|
|
|
itr->second->setPassword(password);
|
2020-05-21 15:42:40 +00:00
|
|
|
emit changeAccount(login, {{"password", password}});
|
2020-04-09 22:48:08 +00:00
|
|
|
accountReady();
|
2020-04-04 16:40:32 +00:00
|
|
|
}
|