added insecure credential store

This commit is contained in:
fourtf 2019-09-13 19:26:52 +02:00
parent eadf5355ee
commit 7c6f744e73
8 changed files with 118 additions and 74 deletions

View file

@ -179,7 +179,6 @@ SOURCES += \
src/widgets/AttachedWindow.cpp \
src/widgets/dialogs/EmotePopup.cpp \
src/widgets/dialogs/IrcConnectionEditor.cpp \
src/widgets/dialogs/IrcConnectionPopup.cpp \
src/widgets/dialogs/LastRunCrashDialog.cpp \
src/widgets/dialogs/LoginDialog.cpp \
src/widgets/dialogs/LogsPopup.cpp \
@ -360,7 +359,6 @@ HEADERS += \
src/widgets/AttachedWindow.hpp \
src/widgets/dialogs/EmotePopup.hpp \
src/widgets/dialogs/IrcConnectionEditor.hpp \
src/widgets/dialogs/IrcConnectionPopup.hpp \
src/widgets/dialogs/LastRunCrashDialog.hpp \
src/widgets/dialogs/LoginDialog.hpp \
src/widgets/dialogs/LogsPopup.hpp \

View file

@ -2,6 +2,10 @@
#include "keychain.h"
#include "singletons/Paths.hpp"
#include "singletons/Settings.hpp"
#include "util/CombinePath.hpp"
#include <QSaveFile>
#define FORMAT_NAME \
([&] { \
@ -11,6 +15,65 @@
namespace chatterino {
namespace {
bool useKeyring()
{
if (getPaths()->isPortable())
{
return false;
}
else
{
#ifdef Q_OS_LINUX
return getSettings()->useKeyring;
#else
return true;
#endif
}
}
// Insecure storage:
QString insecurePath()
{
return combinePath(getPaths()->settingsDirectory, "credentials.json");
}
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();
}
QJsonDocument &insecureInstance()
{
static auto store = loadInsecure();
return store;
}
void queueInsecureSave()
{
static bool isQueued = false;
if (!isQueued)
{
isQueued = true;
QTimer::singleShot(200, qApp, [] {
storeInsecure(insecureInstance());
isQueued = false;
});
}
}
} // namespace
Credentials &Credentials::getInstance()
{
static Credentials creds;
@ -24,15 +87,11 @@ Credentials::Credentials()
QString Credentials::get(const QString &provider, const QString &name_,
std::function<void(QString)> &&onLoaded)
{
assertInGuiThread();
auto name = FORMAT_NAME;
if (getPaths()->isPortable())
{
assert(false);
return {};
}
else
if (useKeyring())
{
auto job = new QKeychain::ReadPasswordJob("chatterino");
job->setAutoDelete(true);
@ -45,44 +104,69 @@ QString Credentials::get(const QString &provider, const QString &name_,
return job->textData();
}
else
{
auto &instance = insecureInstance();
return instance.object().find(name).value().toString();
}
}
void Credentials::set(const QString &provider, const QString &name_,
const QString &credential)
{
assertInGuiThread();
/// On linux, we try to use a keychain but show a message to disable it when it fails.
/// XXX: add said message
auto name = FORMAT_NAME;
if (getPaths()->isPortable())
{
assert(false);
}
else
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) {});
//QObject::connect(job, &QKeychain::Job::finished, qApp, [](auto) {});
job->start();
}
else
{
auto &instance = insecureInstance();
instance.object()[name] = credential;
queueInsecureSave();
}
}
void Credentials::erase(const QString &provider, const QString &name_)
{
assertInGuiThread();
auto name = FORMAT_NAME;
if (getPaths()->isPortable())
{
assert(false);
}
else
if (useKeyring())
{
auto job = new QKeychain::DeletePasswordJob("chatterino");
job->setAutoDelete(true);
job->setKey(name);
QObject::connect(job, &QKeychain::Job::finished, qApp, [](auto) {});
//QObject::connect(job, &QKeychain::Job::finished, qApp, [](auto) {});
job->start();
}
else
{
auto &instance = insecureInstance();
if (auto it = instance.object().find(name);
it != instance.object().end())
{
instance.object().erase(it);
}
queueInsecureSave();
}
}
} // namespace chatterino

View file

@ -199,6 +199,10 @@ public:
/// Misc
BoolSetting betaUpdates = {"/misc/beta", false};
#ifdef Q_OS_LINUX
BoolSetting useKeyring = {"/misc/useKeyring", true};
#endif
IntSetting startUpNotification = {"/misc/startUpNotification", 0};
QStringSetting currentVersion = {"/misc/currentVersion", ""};
BoolSetting loadTwitchMessageHistoryOnConnect = {

View file

@ -1,6 +1,7 @@
#include "widgets/Window.hpp"
#include "Application.hpp"
#include "common/Credentials.hpp"
#include "common/Version.hpp"
#include "controllers/accounts/AccountController.hpp"
#include "providers/twitch/TwitchServer.hpp"
@ -103,7 +104,7 @@ bool Window::event(QEvent *event)
break;
default:;
};
}
return BaseWindow::event(event);
}

View file

@ -1,38 +0,0 @@
#include "IrcConnectionPopup.hpp"
#include "providers/irc/Irc2.hpp"
#include "util/LayoutHelper.hpp"
#include "widgets/helper/EditableModelView.hpp"
#include <QHBoxLayout>
#include <QTableView>
namespace chatterino {
IrcConnectionPopup::IrcConnectionPopup(QWidget *parent)
: BaseWindow(parent, BaseWindow::Flags::EnableCustomFrame)
{
this->setWindowTitle("Edit Irc Connections");
// view
auto view =
new EditableModelView(Irc::getInstance().newConnectionModel(this));
view->setTitles({"host", "port", "ssl", "user", "nick", "password"});
view->getTableView()->horizontalHeader()->resizeSection(0, 140);
view->getTableView()->horizontalHeader()->resizeSection(1, 30);
view->getTableView()->horizontalHeader()->resizeSection(2, 30);
this->setScaleIndependantSize(800, 500);
view->addButtonPressed.connect([] {
auto unique = IrcServerData{};
unique.id = Irc::getInstance().uniqueId();
Irc::getInstance().connections.appendItem(unique);
});
// init layout
this->getLayoutContainer()->setLayout(makeLayout<QHBoxLayout>({view}));
}
} // namespace chatterino

View file

@ -1,13 +0,0 @@
#pragma once
#include "widgets/BaseWindow.hpp"
namespace chatterino {
class IrcConnectionPopup : public BaseWindow
{
public:
IrcConnectionPopup(QWidget *parent);
};
} // namespace chatterino

View file

@ -6,7 +6,6 @@
#include "util/LayoutCreator.hpp"
#include "widgets/Notebook.hpp"
#include "widgets/dialogs/IrcConnectionEditor.hpp"
#include "widgets/dialogs/IrcConnectionPopup.hpp"
#include "widgets/helper/NotebookTab.hpp"
#include <QDialogButtonBox>

View file

@ -377,6 +377,15 @@ void GeneralPage::initLayout(SettingsLayout &layout)
layout.addTitle("Miscellaneous");
#ifdef Q_OS_LINUX
if (!getPaths()->isPortable())
{
layout.addCheckbox(
"Use libsecret/KWallet/Gnome keychain to secure passwords",
s.useKeyring);
}
#endif
layout.addCheckbox("Show moderation messages", s.hideModerationActions,
true);
layout.addCheckbox("Random username color for users who never set a color",