From 9bbc4f8a5e6e06c8f4506edadd7ca664ec1bbca4 Mon Sep 17 00:00:00 2001 From: fourtf Date: Sat, 14 Sep 2019 22:58:53 +0200 Subject: [PATCH] queue for erase/set credentials --- chatterino.pro | 1 + src/common/Credentials.cpp | 81 ++++++++++++++++++--- src/providers/irc/Irc2.cpp | 4 +- src/providers/irc/Irc2.hpp | 5 +- src/util/Overloaded.hpp | 13 ++++ src/widgets/dialogs/IrcConnectionEditor.cpp | 22 +++++- src/widgets/dialogs/IrcConnectionEditor.ui | 11 ++- src/widgets/dialogs/SelectChannelDialog.cpp | 3 +- 8 files changed, 122 insertions(+), 18 deletions(-) create mode 100644 src/util/Overloaded.hpp diff --git a/chatterino.pro b/chatterino.pro index 0f74a6030..3d3da9041 100644 --- a/chatterino.pro +++ b/chatterino.pro @@ -346,6 +346,7 @@ HEADERS += \ src/util/IsBigEndian.hpp \ src/util/JsonQuery.hpp \ src/util/LayoutCreator.hpp \ + src/util/Overloaded.hpp \ src/util/QObjectRef.hpp \ src/util/QStringHash.hpp \ src/util/rangealgorithm.hpp \ diff --git a/src/common/Credentials.cpp b/src/common/Credentials.cpp index 37727de6d..26f9231ce 100644 --- a/src/common/Credentials.cpp +++ b/src/common/Credentials.cpp @@ -5,8 +5,10 @@ #include "singletons/Paths.hpp" #include "singletons/Settings.hpp" #include "util/CombinePath.hpp" +#include "util/Overloaded.hpp" #include +#include #define FORMAT_NAME \ ([&] { \ @@ -73,6 +75,70 @@ namespace { }); } } + + // QKeychain runs jobs asyncronously, so we have to assure that set/erase + // jobs gets executed in order. + struct SetJob { + QString name; + QString credential; + }; + + struct EraseJob { + QString name; + }; + + using Job = std::variant; + + static std::queue &jobQueue() + { + static std::queue jobs; + return jobs; + } + + static void runNextJob() + { + auto &&queue = jobQueue(); + + if (!queue.empty()) + { + std::visit( + Overloaded{ + [](const SetJob &set) { + qDebug() << "set"; + auto job = + new QKeychain::WritePasswordJob("chatterino"); + job->setAutoDelete(true); + job->setKey(set.name); + job->setTextData(set.credential); + QObject::connect(job, &QKeychain::Job::finished, qApp, + [](auto) { runNextJob(); }); + job->start(); + }, + [](const EraseJob &erase) { + qDebug() << "erase"; + auto job = + new QKeychain::DeletePasswordJob("chatterino"); + job->setAutoDelete(true); + job->setKey(erase.name); + QObject::connect(job, &QKeychain::Job::finished, qApp, + [](auto) { runNextJob(); }); + job->start(); + }}, + queue.front()); + queue.pop(); + } + } + + static void queueJob(Job &&job) + { + auto &&queue = jobQueue(); + + queue.push(std::move(job)); + if (queue.size() == 1) + { + runNextJob(); + } + } } // namespace Credentials &Credentials::getInstance() @@ -125,12 +191,8 @@ void Credentials::set(const QString &provider, const QString &name_, if (useKeyring()) { - auto job = new QKeychain::WritePasswordJob("chatterino"); - job->setAutoDelete(true); - job->setKey(name); - job->setTextData(credential); - //QObject::connect(job, &QKeychain::Job::finished, qApp, [](auto) {}); - job->start(); + qDebug() << "queue set"; + queueJob(SetJob{name, credential}); } else { @@ -150,11 +212,8 @@ void Credentials::erase(const QString &provider, const QString &name_) if (useKeyring()) { - auto job = new QKeychain::DeletePasswordJob("chatterino"); - job->setAutoDelete(true); - job->setKey(name); - //QObject::connect(job, &QKeychain::Job::finished, qApp, [](auto) {}); - job->start(); + qDebug() << "queue erase"; + queueJob(EraseJob{name}); } else { diff --git a/src/providers/irc/Irc2.cpp b/src/providers/irc/Irc2.cpp index 9f0a746e9..5a985803f 100644 --- a/src/providers/irc/Irc2.cpp +++ b/src/providers/irc/Irc2.cpp @@ -128,8 +128,10 @@ Irc::Irc() this->abandonedChannels_[args.item.id] = abandoned; this->servers_.erase(server); + } - // delete password + if (args.caller != Irc::noEraseCredentialCaller) + { Credentials::getInstance().erase("irc", getCredentialName(args.item)); } diff --git a/src/providers/irc/Irc2.hpp b/src/providers/irc/Irc2.hpp index 639c1bd2f..6ca6b0c8b 100644 --- a/src/providers/irc/Irc2.hpp +++ b/src/providers/irc/Irc2.hpp @@ -10,7 +10,7 @@ class QAbstractTableModel; namespace chatterino { -//enum IrcAuthType { Anonymous, /*Sals,*/ Pass, MsgNickServ, NickServ }; +enum class IrcAuthType { Anonymous, Custom, Pass }; struct IrcServerData { QString host; @@ -38,6 +38,9 @@ public: static Irc &getInstance(); + static inline void *const noEraseCredentialCaller = + reinterpret_cast(1); + UnsortedSignalVector connections; QAbstractTableModel *newConnectionModel(QObject *parent); diff --git a/src/util/Overloaded.hpp b/src/util/Overloaded.hpp new file mode 100644 index 000000000..7deb38a67 --- /dev/null +++ b/src/util/Overloaded.hpp @@ -0,0 +1,13 @@ +#pragma once + +namespace chatterino { + +template +struct Overloaded : Ts... { + using Ts::operator()...; +}; + +template +Overloaded(Ts...)->Overloaded; + +} // namespace chatterino diff --git a/src/widgets/dialogs/IrcConnectionEditor.cpp b/src/widgets/dialogs/IrcConnectionEditor.cpp index 53f2cd19f..0fbf46208 100644 --- a/src/widgets/dialogs/IrcConnectionEditor.cpp +++ b/src/widgets/dialogs/IrcConnectionEditor.cpp @@ -33,10 +33,30 @@ IrcConnectionEditor::IrcConnectionEditor(const IrcServerData &data, bool isAdd, this->ui_->passwordLineEdit->setText(password); }); + QObject::connect(this->ui_->loginMethodComboBox, + qOverload(&QComboBox::currentIndexChanged), this, + [this](int index) { + IrcAuthType type; + + switch (index) + { + case 0: // anonymous + type = IrcAuthType::Anonymous; + break; + case 1: // custom + this->ui_->connectCommandsEditor->setFocus(); + type = IrcAuthType::Custom; + break; + case 2: // PASS + type = IrcAuthType::Pass; + break; + } + }); + QFont font("Monospace"); font.setStyleHint(QFont::TypeWriter); this->ui_->connectCommandsEditor->setFont(font); -} // namespace chatterino +} IrcConnectionEditor::~IrcConnectionEditor() { diff --git a/src/widgets/dialogs/IrcConnectionEditor.ui b/src/widgets/dialogs/IrcConnectionEditor.ui index db1c6124f..e054ac557 100644 --- a/src/widgets/dialogs/IrcConnectionEditor.ui +++ b/src/widgets/dialogs/IrcConnectionEditor.ui @@ -142,7 +142,7 @@ - + Anonymous @@ -150,7 +150,12 @@ - PASS + Custom + + + + + Server Password (/PASS $password) @@ -210,7 +215,7 @@ on connect: userNameLineEdit nickNameLineEdit realNameLineEdit - comboBox + loginMethodComboBox passwordLineEdit diff --git a/src/widgets/dialogs/SelectChannelDialog.cpp b/src/widgets/dialogs/SelectChannelDialog.cpp index 1333e86e6..8dcc42bee 100644 --- a/src/widgets/dialogs/SelectChannelDialog.cpp +++ b/src/widgets/dialogs/SelectChannelDialog.cpp @@ -174,7 +174,8 @@ SelectChannelDialog::SelectChannelDialog(QWidget *parent) { if (conn.id == data.id) { - Irc::getInstance().connections.removeItem(i); + Irc::getInstance().connections.removeItem( + i, Irc::noEraseCredentialCaller); Irc::getInstance().connections.insertItem(data, i); }