account connect/disconnect now activate/deactivate, it's a bit less contraversial; async account password asking new concept

This commit is contained in:
Blue 2022-04-12 23:33:10 +03:00
parent 2c26c7e264
commit f64e5c2df0
Signed by untrusted user: blue
GPG key ID: 9B203B252A63EE38
13 changed files with 248 additions and 200 deletions

View file

@ -26,8 +26,8 @@ Core::Squawk::Squawk(QObject* parent):
QObject(parent),
accounts(),
amap(),
state(Shared::Availability::offline),
network(),
waitingForAccounts(0),
isInitialized(false)
#ifdef WITH_KWALLET
,kwallet()
@ -42,7 +42,7 @@ Core::Squawk::Squawk(QObject* parent):
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);
connect(&kwallet, &PSE::KWallet::responsePassword, this, &Squawk::responsePassword);
Shared::Global::setSupported("KWallet", true);
}
@ -97,6 +97,7 @@ void Core::Squawk::stop()
settings.setValue("password", password);
settings.setValue("resource", acc->getResource());
settings.setValue("passwordType", static_cast<int>(ap));
settings.setValue("active", acc->getActive());
}
settings.endArray();
settings.endGroup();
@ -124,8 +125,9 @@ void Core::Squawk::newAccountRequest(const QMap<QString, QVariant>& map)
QString password = map.value("password").toString();
QString resource = map.value("resource").toString();
int passwordType = map.value("passwordType").toInt();
bool active = map.value("active").toBool();
addAccount(login, server, password, name, resource, Shared::Global::fromInt<Shared::AccountPassword>(passwordType));
addAccount(login, server, password, name, resource, active, Shared::Global::fromInt<Shared::AccountPassword>(passwordType));
}
void Core::Squawk::addAccount(
@ -133,13 +135,13 @@ void Core::Squawk::addAccount(
const QString& server,
const QString& password,
const QString& name,
const QString& resource,
Shared::AccountPassword passwordType
)
const QString& resource,
bool active,
Shared::AccountPassword passwordType)
{
QSettings settings;
Account* acc = new Account(login, server, password, name, &network);
Account* acc = new Account(login, server, password, name, active, &network);
acc->setResource(resource);
acc->setPasswordType(passwordType);
accounts.push_back(acc);
@ -148,6 +150,8 @@ void Core::Squawk::addAccount(
connect(acc, &Account::connectionStateChanged, this, &Squawk::onAccountConnectionStateChanged);
connect(acc, &Account::changed, this, &Squawk::onAccountChanged);
connect(acc, &Account::error, this, &Squawk::onAccountError);
connect(acc, &Account::needPassword, this, &Squawk::onAccountNeedPassword);
connect(acc, &Account::availabilityChanged, this, &Squawk::onAccountAvailabilityChanged);
connect(acc, &Account::addContact, this, &Squawk::onAccountAddContact);
connect(acc, &Account::addGroup, this, &Squawk::onAccountAddGroup);
@ -185,20 +189,42 @@ void Core::Squawk::addAccount(
{"offline", QVariant::fromValue(Shared::Availability::offline)},
{"error", ""},
{"avatarPath", acc->getAvatarPath()},
{"passwordType", QVariant::fromValue(passwordType)}
{"passwordType", QVariant::fromValue(passwordType)},
{"active", active}
};
emit newAccount(map);
switch (passwordType) {
case Shared::AccountPassword::alwaysAsk:
case Shared::AccountPassword::kwallet:
acc->invalidatePassword();
break;
default:
break;
}
if (state != Shared::Availability::offline) {
acc->setAvailability(state);
if (acc->getActive()) {
acc->connect();
}
}
}
void Core::Squawk::changeState(Shared::Availability p_state)
{
if (state != p_state) {
for (std::deque<Account*>::iterator itr = accounts.begin(), end = accounts.end(); itr != end; ++itr) {
Account* acc = *itr;
acc->setAvailability(p_state);
if (state == Shared::Availability::offline && acc->getActive()) {
acc->connect();
}
}
state = p_state;
}
for (std::deque<Account*>::iterator itr = accounts.begin(), end = accounts.end(); itr != end; ++itr) {
(*itr)->setAvailability(state);
emit stateChanged(p_state);
}
}
@ -209,7 +235,10 @@ void Core::Squawk::connectAccount(const QString& account)
qDebug("An attempt to connect non existing account, skipping");
return;
}
itr->second->connect();
itr->second->setActive(true);
if (state != Shared::Availability::offline) {
itr->second->connect();
}
}
void Core::Squawk::disconnectAccount(const QString& account)
@ -220,6 +249,7 @@ void Core::Squawk::disconnectAccount(const QString& account)
return;
}
itr->second->setActive(false);
itr->second->disconnect();
}
@ -227,7 +257,7 @@ void Core::Squawk::onAccountConnectionStateChanged(Shared::ConnectionState p_sta
{
Account* acc = static_cast<Account*>(sender());
emit changeAccount(acc->getName(), {{"state", QVariant::fromValue(p_state)}});
#ifdef WITH_KWALLET
if (p_state == Shared::ConnectionState::connected) {
if (acc->getPasswordType() == Shared::AccountPassword::kwallet && kwallet.supportState() == PSE::KWallet::success) {
@ -235,33 +265,6 @@ void Core::Squawk::onAccountConnectionStateChanged(Shared::ConnectionState p_sta
}
}
#endif
Accounts::const_iterator itr = accounts.begin();
bool es = true;
bool ea = true;
Shared::ConnectionState cs = (*itr)->getState();
Shared::Availability av = (*itr)->getAvailability();
itr++;
for (Accounts::const_iterator end = accounts.end(); itr != end; itr++) {
Account* item = *itr;
if (item->getState() != cs) {
es = false;
}
if (item->getAvailability() != av) {
ea = false;
}
}
if (es) {
if (cs == Shared::ConnectionState::disconnected) {
state = Shared::Availability::offline;
emit stateChanged(state);
} else if (ea) {
state = av;
emit stateChanged(state);
}
}
}
void Core::Squawk::onAccountAddContact(const QString& jid, const QString& group, const QMap<QString, QVariant>& data)
@ -416,8 +419,15 @@ void Core::Squawk::modifyAccountRequest(const QString& name, const QMap<QString,
}
}
if (needToReconnect && st != Shared::ConnectionState::disconnected) {
acc->reconnect();
bool activeChanged = false;
mItr = map.find("active");
if (mItr == map.end() || mItr->toBool() == acc->getActive()) {
if (needToReconnect && st != Shared::ConnectionState::disconnected) {
acc->reconnect();
}
} else {
acc->setActive(mItr->toBool());
activeChanged = true;
}
mItr = map.find("login");
@ -454,6 +464,10 @@ void Core::Squawk::modifyAccountRequest(const QString& name, const QMap<QString,
}
#endif
if (activeChanged && acc->getActive() && state != Shared::Availability::offline) {
acc->connect();
}
emit changeAccount(name, map);
}
@ -675,85 +689,62 @@ void Core::Squawk::uploadVCard(const QString& account, const Shared::VCard& card
itr->second->uploadVCard(card);
}
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);
emit changeAccount(account, {{"password", password}});
accountReady();
}
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(
Shared::AccountPassword passwordType =
Shared::Global::fromInt<Shared::AccountPassword>(
settings.value("passwordType", static_cast<int>(Shared::AccountPassword::plain)).toInt()
);
QString password = settings.value("password", "").toString();
if (passwordType == Shared::AccountPassword::jammed) {
SimpleCrypt crypto(passwordHash);
password = crypto.decryptToString(password);
}
addAccount(
settings.value("login").toString(),
settings.value("server").toString(),
settings.value("password", "").toString(),
password,
settings.value("name").toString(),
settings.value("resource").toString(),
Shared::Global::fromInt<Shared::AccountPassword>(settings.value("passwordType", static_cast<int>(Shared::AccountPassword::plain)).toInt())
settings.value("active").toBool(),
passwordType
);
}
settings.endArray();
settings.endGroup();
qDebug() << "Squawk core is ready";
emit ready();
}
void Core::Squawk::accountReady()
void Core::Squawk::onAccountNeedPassword()
{
--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;
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);
Account* acc = static_cast<Account*>(sender());
switch (acc->getPasswordType()) {
case Shared::AccountPassword::alwaysAsk:
emit requestPassword(acc->getName());
break;
case Shared::AccountPassword::kwallet: {
addAccount(login, server, QString(), name, resource, passwordType);
#ifdef WITH_KWALLET
if (kwallet.supportState() == PSE::KWallet::success) {
kwallet.requestReadPassword(name);
kwallet.requestReadPassword(acc->getName());
} else {
#endif
emit requestPassword(name);
emit requestPassword(acc->getName());
#ifdef WITH_KWALLET
}
#endif
break;
}
default:
break; //should never happen;
}
}
@ -762,16 +753,19 @@ void Core::Squawk::onWalletRejectPassword(const QString& login)
emit requestPassword(login);
}
void Core::Squawk::onWalletResponsePassword(const QString& login, const QString& password)
void Core::Squawk::responsePassword(const QString& account, const QString& password)
{
AccountsMap::const_iterator itr = amap.find(login);
AccountsMap::const_iterator itr = amap.find(account);
if (itr == amap.end()) {
qDebug() << "An attempt to set password to non existing account" << login << ", skipping";
qDebug() << "An attempt to set password to non existing account" << account << ", skipping";
return;
}
itr->second->setPassword(password);
emit changeAccount(login, {{"password", password}});
accountReady();
Account* acc = itr->second;
acc->setPassword(password);
emit changeAccount(account, {{"password", password}});
if (state != Shared::Availability::offline && acc->getActive()) {
acc->connect();
}
}
void Core::Squawk::onAccountUploadFileError(const QString& jid, const QString id, const QString& errorText)