Skip to content

Commit

Permalink
refactor: common/Credentials (#4979)
Browse files Browse the repository at this point in the history
Use full path in includes
Sort includes
Move anon namespace out of chatterino namespace
Use auto * where possible
Disable convert-member-function-to-static check for all member functions
Don't use else after return
Removed empty constructor
Replace use of `boost::variant` with `std::variant`

Co-authored-by: nerix <nerixdev@outlook.de>
  • Loading branch information
pajlada and Nerixyz authored Nov 26, 2023
1 parent 5b741a8 commit 1f09035
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 119 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
- Dev: Removed direct dependency on Qt 5 compatibility module. (#4906)
- Dev: Refactor `Emoji`'s EmojiMap into a vector. (#4980)
- Dev: Refactor `DebugCount` and add copy button to debug popup. (#4921)
- Dev: Refactor `common/Credentials`. (#4979)
- Dev: Changed lifetime of context menus. (#4924)
- Dev: Refactor `ChannelView`, removing a bunch of clang-tidy warnings. (#4926)
- Dev: Refactor `IrcMessageHandler`, removing a bunch of clang-tidy warnings & changing its public API. (#4927)
Expand Down
239 changes: 121 additions & 118 deletions src/common/Credentials.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#include "Credentials.hpp"
#include "common/Credentials.hpp"

#include "debug/AssertInGuiThread.hpp"
#include "singletons/Paths.hpp"
#include "singletons/Settings.hpp"
#include "util/CombinePath.hpp"
#include "util/Overloaded.hpp"
#include "util/Variant.hpp"

#include <QJsonDocument>
#include <QJsonObject>
#include <QSaveFile>

#include <variant>

#ifndef NO_QTKEYCHAIN
# ifdef CMAKE_BUILD
Expand All @@ -20,161 +24,158 @@
# include "keychain.h"
# endif
#endif
#include <boost/variant.hpp>
#include <QSaveFile>

#define FORMAT_NAME \
([&] { \
assert(!provider.contains(":")); \
return QString("chatterino:%1:%2").arg(provider).arg(name_); \
})()

namespace chatterino {

namespace {
bool useKeyring()
{

using namespace chatterino;

bool useKeyring()
{
#ifdef NO_QTKEYCHAIN
return false;
return false;
#endif
if (getPaths()->isPortable())
{
return false;
}
else
{
if (getPaths()->isPortable())
{
return false;
}

#ifdef Q_OS_LINUX
return getSettings()->useKeyring;
return getSettings()->useKeyring;
#else
return true;
return true;
#endif
}
}
}

// Insecure storage:
QString insecurePath()
{
return combinePath(getPaths()->settingsDirectory, "credentials.json");
}
// Insecure storage:
QString insecurePath()
{
return combinePath(getPaths()->settingsDirectory, "credentials.json");
}

QJsonDocument loadInsecure()
{
QFile file(insecurePath());
file.open(QIODevice::ReadOnly);
return QJsonDocument::fromJson(file.readAll());
}
QJsonDocument loadInsecure()
{
QFile file(insecurePath());
file.open(QIODevice::ReadOnly);
return QJsonDocument::fromJson(file.readAll());
}

void storeInsecure(const QJsonDocument &doc)
{
QSaveFile file(insecurePath());
file.open(QIODevice::WriteOnly);
file.write(doc.toJson());
file.commit();
}
void storeInsecure(const QJsonDocument &doc)
{
QSaveFile file(insecurePath());
file.open(QIODevice::WriteOnly);
file.write(doc.toJson());
file.commit();
}

QJsonDocument &insecureInstance()
{
static auto store = loadInsecure();
return store;
}
QJsonDocument &insecureInstance()
{
static auto store = loadInsecure();
return store;
}

void queueInsecureSave()
{
static bool isQueued = false;
void queueInsecureSave()
{
static bool isQueued = false;

if (!isQueued)
{
isQueued = true;
QTimer::singleShot(200, qApp, [] {
storeInsecure(insecureInstance());
isQueued = false;
});
}
if (!isQueued)
{
isQueued = true;
QTimer::singleShot(200, qApp, [] {
storeInsecure(insecureInstance());
isQueued = false;
});
}
}

// QKeychain runs jobs asyncronously, so we have to assure that set/erase
// jobs gets executed in order.
struct SetJob {
QString name;
QString credential;
};
// 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;
};
struct EraseJob {
QString name;
};

using Job = boost::variant<SetJob, EraseJob>;
using Job = std::variant<SetJob, EraseJob>;

static std::queue<Job> &jobQueue()
{
static std::queue<Job> jobs;
return jobs;
}
std::queue<Job> &jobQueue()
{
static std::queue<Job> jobs;
return jobs;
}

static void runNextJob()
{
void runNextJob()
{
#ifndef NO_QTKEYCHAIN
auto &&queue = jobQueue();
auto &&queue = jobQueue();

if (!queue.empty())
{
// we were gonna use std::visit here but macos is shit

auto &&item = queue.front();

if (item.which() == 0) // set job
{
auto set = boost::get<SetJob>(item);
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();
}
else // erase job
{
auto erase = boost::get<EraseJob>(item);
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.pop();
}
#endif
if (!queue.empty())
{
// we were gonna use std::visit here but macos is shit

auto &&item = queue.front();

std::visit(
variant::Overloaded{
[](const SetJob &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) {
auto *job = new QKeychain::DeletePasswordJob("chatterino");
job->setAutoDelete(true);
job->setKey(erase.name);
QObject::connect(job, &QKeychain::Job::finished, qApp,
[](auto) {
runNextJob();
});
job->start();
},
},
item);

queue.pop();
}
#endif
}

static void queueJob(Job &&job)
{
auto &&queue = jobQueue();
void queueJob(Job &&job)
{
auto &&queue = jobQueue();

queue.push(std::move(job));
if (queue.size() == 1)
{
runNextJob();
}
queue.push(std::move(job));
if (queue.size() == 1)
{
runNextJob();
}
}

} // namespace

namespace chatterino {

Credentials &Credentials::instance()
{
static Credentials creds;
return creds;
}

Credentials::Credentials()
{
}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
void Credentials::get(const QString &provider, const QString &name_,
QObject *receiver,
std::function<void(const QString &)> &&onLoaded)
Expand All @@ -187,7 +188,7 @@ void Credentials::get(const QString &provider, const QString &name_,
{
#ifndef NO_QTKEYCHAIN
// if NO_QTKEYCHAIN is set, then this code is never used either way
auto job = new QKeychain::ReadPasswordJob("chatterino");
auto *job = new QKeychain::ReadPasswordJob("chatterino");
job->setAutoDelete(true);
job->setKey(name);
QObject::connect(
Expand All @@ -207,6 +208,7 @@ void Credentials::get(const QString &provider, const QString &name_,
}
}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
void Credentials::set(const QString &provider, const QString &name_,
const QString &credential)
{
Expand All @@ -233,6 +235,7 @@ void Credentials::set(const QString &provider, const QString &name_,
}
}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
void Credentials::erase(const QString &provider, const QString &name_)
{
assertInGuiThread();
Expand Down
2 changes: 1 addition & 1 deletion src/common/Credentials.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Credentials
void erase(const QString &provider, const QString &name);

private:
Credentials();
Credentials() = default;
};

} // namespace chatterino

0 comments on commit 1f09035

Please sign in to comment.