queue for erase/set credentials

This commit is contained in:
fourtf 2019-09-14 22:58:53 +02:00
parent 13d1fab303
commit 9bbc4f8a5e
8 changed files with 122 additions and 18 deletions

View file

@ -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 \

View file

@ -5,8 +5,10 @@
#include "singletons/Paths.hpp"
#include "singletons/Settings.hpp"
#include "util/CombinePath.hpp"
#include "util/Overloaded.hpp"
#include <QSaveFile>
#include <variant>
#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<SetJob, EraseJob>;
static std::queue<Job> &jobQueue()
{
static std::queue<Job> 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
{

View file

@ -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));
}

View file

@ -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<void *>(1);
UnsortedSignalVector<IrcServerData> connections;
QAbstractTableModel *newConnectionModel(QObject *parent);

13
src/util/Overloaded.hpp Normal file
View file

@ -0,0 +1,13 @@
#pragma once
namespace chatterino {
template <class... Ts>
struct Overloaded : Ts... {
using Ts::operator()...;
};
template <class... Ts>
Overloaded(Ts...)->Overloaded<Ts...>;
} // namespace chatterino

View file

@ -33,10 +33,30 @@ IrcConnectionEditor::IrcConnectionEditor(const IrcServerData &data, bool isAdd,
this->ui_->passwordLineEdit->setText(password);
});
QObject::connect(this->ui_->loginMethodComboBox,
qOverload<int>(&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()
{

View file

@ -142,7 +142,7 @@
</spacer>
</item>
<item row="8" column="1">
<widget class="QComboBox" name="comboBox">
<widget class="QComboBox" name="loginMethodComboBox">
<item>
<property name="text">
<string>Anonymous</string>
@ -150,7 +150,12 @@
</item>
<item>
<property name="text">
<string>PASS</string>
<string>Custom</string>
</property>
</item>
<item>
<property name="text">
<string>Server Password (/PASS $password)</string>
</property>
</item>
</widget>
@ -210,7 +215,7 @@ on connect:</string>
<tabstop>userNameLineEdit</tabstop>
<tabstop>nickNameLineEdit</tabstop>
<tabstop>realNameLineEdit</tabstop>
<tabstop>comboBox</tabstop>
<tabstop>loginMethodComboBox</tabstop>
<tabstop>passwordLineEdit</tabstop>
</tabstops>
<resources/>

View file

@ -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);
}