summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLorenDB <computersemiexpert@outlook.com>2020-11-09 21:28:41 -0500
committerLoren Burkholder <computersemiexpert@outlook.com>2020-12-24 21:16:46 -0500
commit53f45bdb1c9ee2b42b88ca4587775756f8daa124 (patch)
treeab8b89b8016d37dfb4a1e9e0aaae50a9d86b2d6f /src
parent100b5e0371f9485ec6fbbdc69a0efd9aa84d26d3 (diff)
Switch profile code to a more flexible method
This introduces a new version of SingleApplication as well.
Diffstat (limited to 'src')
-rw-r--r--src/Cache.cpp43
-rw-r--r--src/MainWindow.cpp41
-rw-r--r--src/MainWindow.h4
-rw-r--r--src/UserSettingsPage.cpp72
-rw-r--r--src/UserSettingsPage.h28
-rw-r--r--src/main.cpp64
6 files changed, 179 insertions, 73 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp
index 674b5793..986de221 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -21,6 +21,7 @@
#include <QByteArray>
#include <QCoreApplication>
+#include <QCryptographicHash>
#include <QFile>
#include <QHash>
#include <QMap>
@@ -41,6 +42,7 @@
#include "Logging.h"
#include "MatrixClient.h"
#include "Olm.h"
+#include "UserSettingsPage.h"
#include "Utils.h"
//! Should be changed when a breaking change occurs in the cache format.
@@ -165,17 +167,15 @@ Cache::Cache(const QString &userId, QObject *parent)
void
Cache::setup()
{
- nhlog::db()->debug("setting up cache");
+ UserSettings settings;
- auto statePath = QString("%1/%2")
- .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
- .arg(QString::fromUtf8(localUserId_.toUtf8().toHex()));
+ nhlog::db()->debug("setting up cache");
- cacheDirectory_ = QString("%1/%2")
+ cacheDirectory_ = QString("%1/%2%3")
.arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
- .arg(QString::fromUtf8(localUserId_.toUtf8().toHex()));
+ .arg(QString::fromUtf8(localUserId_.toUtf8().toHex())).arg(QString::fromUtf8(settings.profile().toUtf8().toHex()));
- bool isInitial = !QFile::exists(statePath);
+ bool isInitial = !QFile::exists(cacheDirectory_);
env_ = lmdb::env::create();
env_.set_mapsize(DB_SIZE);
@@ -184,9 +184,9 @@ Cache::setup()
if (isInitial) {
nhlog::db()->info("initializing LMDB");
- if (!QDir().mkpath(statePath)) {
+ if (!QDir().mkpath(cacheDirectory_)) {
throw std::runtime_error(
- ("Unable to create state directory:" + statePath).toStdString().c_str());
+ ("Unable to create state directory:" + cacheDirectory_).toStdString().c_str());
}
}
@@ -194,7 +194,7 @@ Cache::setup()
// NOTE(Nico): We may want to use (MDB_MAPASYNC | MDB_WRITEMAP) in the future, but
// it can really mess up our database, so we shouldn't. For now, hopefully
// NOMETASYNC is fast enough.
- env_.open(statePath.toStdString().c_str(), MDB_NOMETASYNC | MDB_NOSYNC);
+ env_.open(cacheDirectory_.toStdString().c_str(), MDB_NOMETASYNC | MDB_NOSYNC);
} catch (const lmdb::error &e) {
if (e.code() != MDB_VERSION_MISMATCH && e.code() != MDB_INVALID) {
throw std::runtime_error("LMDB initialization failed" +
@@ -203,15 +203,14 @@ Cache::setup()
nhlog::db()->warn("resetting cache due to LMDB version mismatch: {}", e.what());
- QDir stateDir(statePath);
+ QDir stateDir(cacheDirectory_);
for (const auto &file : stateDir.entryList(QDir::NoDotAndDotDot)) {
if (!stateDir.remove(file))
throw std::runtime_error(
("Unable to delete file " + file).toStdString().c_str());
}
-
- env_.open(statePath.toStdString().c_str());
+ env_.open(cacheDirectory_.toStdString().c_str());
}
auto txn = lmdb::txn::begin(env_);
@@ -577,10 +576,14 @@ Cache::restoreOlmAccount()
void
Cache::storeSecret(const std::string &name, const std::string &secret)
{
+ UserSettings settings;
QKeychain::WritePasswordJob job(QCoreApplication::applicationName());
job.setAutoDelete(false);
job.setInsecureFallback(true);
- job.setKey(QString::fromStdString(name));
+ job.setKey(
+ "matrix." +
+ QString(QCryptographicHash::hash(settings.profile().toUtf8(), QCryptographicHash::Sha256)) +
+ "." + name.c_str());
job.setTextData(QString::fromStdString(secret));
QEventLoop loop;
job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
@@ -598,10 +601,14 @@ Cache::storeSecret(const std::string &name, const std::string &secret)
void
Cache::deleteSecret(const std::string &name)
{
+ UserSettings settings;
QKeychain::DeletePasswordJob job(QCoreApplication::applicationName());
job.setAutoDelete(false);
job.setInsecureFallback(true);
- job.setKey(QString::fromStdString(name));
+ job.setKey(
+ "matrix." +
+ QString(QCryptographicHash::hash(settings.profile().toUtf8(), QCryptographicHash::Sha256)) +
+ "." + name.c_str());
QEventLoop loop;
job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
job.start();
@@ -613,10 +620,14 @@ Cache::deleteSecret(const std::string &name)
std::optional<std::string>
Cache::secret(const std::string &name)
{
+ UserSettings settings;
QKeychain::ReadPasswordJob job(QCoreApplication::applicationName());
job.setAutoDelete(false);
job.setInsecureFallback(true);
- job.setKey(QString::fromStdString(name));
+ job.setKey(
+ "matrix." +
+ QString(QCryptographicHash::hash(settings.profile().toUtf8(), QCryptographicHash::Sha256)) +
+ "." + name.c_str());
QEventLoop loop;
job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit);
job.start();
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index d056aca6..ffd0e30b 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -55,9 +55,9 @@
MainWindow *MainWindow::instance_ = nullptr;
-MainWindow::MainWindow(const QString profile, QWidget *parent)
- : QMainWindow(parent)
- , profile_{profile}
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent),
+ userSettings_{QSharedPointer<UserSettings>{new UserSettings}}
{
setWindowTitle(0);
setObjectName("MainWindow");
@@ -70,8 +70,7 @@ MainWindow::MainWindow(const QString profile, QWidget *parent)
font.setStyleStrategy(QFont::PreferAntialias);
setFont(font);
- userSettings_ = QSharedPointer<UserSettings>(new UserSettings);
- trayIcon_ = new TrayIcon(":/logos/nheko.svg", this);
+ trayIcon_ = new TrayIcon(":/logos/nheko.svg", this);
welcome_page_ = new WelcomePage(this);
login_page_ = new LoginPage(this);
@@ -150,15 +149,13 @@ MainWindow::MainWindow(const QString profile, QWidget *parent)
chat_page_->showQuickSwitcher();
});
- QSettings settings;
-
trayIcon_->setVisible(userSettings_->tray());
if (hasActiveUser()) {
- QString token = settings.value("auth/access_token").toString();
- QString home_server = settings.value("auth/home_server").toString();
- QString user_id = settings.value("auth/user_id").toString();
- QString device_id = settings.value("auth/device_id").toString();
+ QString token = userSettings_->accessToken();
+ QString home_server = userSettings_->homeserver();
+ QString user_id = userSettings_->userId();
+ QString device_id = userSettings_->deviceId();
http::client()->set_access_token(token.toStdString());
http::client()->set_server(home_server.toStdString());
@@ -184,8 +181,9 @@ void
MainWindow::setWindowTitle(int notificationCount)
{
QString name = "nheko";
- if (!profile_.isEmpty())
- name += " | " + profile_;
+
+ if (!userSettings_.data()->profile().isEmpty())
+ name += " | " + userSettings_.data()->profile();
if (notificationCount > 0) {
name.append(QString{" (%1)"}.arg(notificationCount));
}
@@ -279,11 +277,10 @@ MainWindow::showChatPage()
std::to_string(http::client()->port()));
auto token = QString::fromStdString(http::client()->access_token());
- QSettings settings;
- settings.setValue("auth/access_token", token);
- settings.setValue("auth/home_server", homeserver);
- settings.setValue("auth/user_id", userid);
- settings.setValue("auth/device_id", device_id);
+ userSettings_.data()->setUserId(userid);
+ userSettings_.data()->setAccessToken(token);
+ userSettings_.data()->setDeviceId(device_id);
+ userSettings_.data()->setHomeserver(homeserver);
showOverlayProgressBar();
@@ -341,9 +338,13 @@ bool
MainWindow::hasActiveUser()
{
QSettings settings;
+ QString prefix;
+ if (userSettings_->profile() != "")
+ prefix = "profile/" + userSettings_->profile() + "/";
- return settings.contains("auth/access_token") && settings.contains("auth/home_server") &&
- settings.contains("auth/user_id");
+ return settings.contains(prefix + "auth/access_token") &&
+ settings.contains(prefix + "auth/home_server") &&
+ settings.contains(prefix + "auth/user_id");
}
void
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 2f9ff897..0915a849 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -62,7 +62,7 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
- explicit MainWindow(const QString name, QWidget *parent = nullptr);
+ explicit MainWindow(QWidget *parent = nullptr);
static MainWindow *instance() { return instance_; };
void saveCurrentWindowSize();
@@ -149,6 +149,4 @@ private:
LoadingIndicator *spinner_ = nullptr;
JdenticonInterface *jdenticonInteface_ = nullptr;
-
- QString profile_;
};
diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp
index 708fb7fd..55f666c1 100644
--- a/src/UserSettingsPage.cpp
+++ b/src/UserSettingsPage.cpp
@@ -89,6 +89,14 @@ UserSettings::load()
cameraResolution_ = settings.value("user/camera_resolution", QString()).toString();
cameraFrameRate_ = settings.value("user/camera_frame_rate", QString()).toString();
useStunServer_ = settings.value("user/use_stun_server", false).toBool();
+ profile_ = settings.value("user/currentProfile", "").toString();
+
+ QString prefix =
+ (profile_ != "" && profile_ != "default") ? "profile/" + profile_ + "/" : "";
+ accessToken_ = settings.value(prefix + "auth/access_token", "").toString();
+ homeserver_ = settings.value(prefix + "auth/home_server", "").toString();
+ userId_ = settings.value(prefix + "auth/user_id", "").toString();
+ deviceId_ = settings.value(prefix + "auth/device_id", "").toString();
applyTheme();
}
@@ -373,6 +381,56 @@ UserSettings::setCameraFrameRate(QString frameRate)
}
void
+UserSettings::setProfile(QString profile)
+{
+ if (profile == profile_)
+ return;
+ profile_ = profile;
+ emit profileChanged(profile_);
+ save();
+}
+
+void
+UserSettings::setUserId(QString userId)
+{
+ if (userId == userId_)
+ return;
+ userId_ = userId;
+ emit userIdChanged(userId_);
+ save();
+}
+
+void
+UserSettings::setAccessToken(QString accessToken)
+{
+ if (accessToken == accessToken_)
+ return;
+ accessToken_ = accessToken;
+ emit accessTokenChanged(accessToken_);
+ save();
+}
+
+void
+UserSettings::setDeviceId(QString deviceId)
+{
+ if (deviceId == deviceId_)
+ return;
+ deviceId_ = deviceId;
+ emit deviceIdChanged(deviceId_);
+ save();
+}
+
+void
+UserSettings::setHomeserver(QString homeserver)
+{
+ if (homeserver == homeserver_)
+ return;
+ homeserver_ = homeserver;
+ emit homeserverChanged(homeserver_);
+ save();
+}
+
+void
UserSettings::applyTheme()
{
QFile stylefile;
@@ -436,14 +494,14 @@ UserSettings::save()
settings.beginGroup("window");
settings.setValue("tray", tray_);
settings.setValue("start_in_tray", startInTray_);
- settings.endGroup();
+ settings.endGroup(); // window
settings.beginGroup("timeline");
settings.setValue("buttons", buttonsInTimeline_);
settings.setValue("message_hover_highlight", messageHoverHighlight_);
settings.setValue("enlarge_emoji_only_msg", enlargeEmojiOnlyMessages_);
settings.setValue("max_width", timelineMaxWidth_);
- settings.endGroup();
+ settings.endGroup(); // timeline
settings.setValue("avatar_circles", avatarCircles_);
settings.setValue("decrypt_sidebar", decryptSidebar_);
@@ -467,8 +525,16 @@ UserSettings::save()
settings.setValue("camera_resolution", cameraResolution_);
settings.setValue("camera_frame_rate", cameraFrameRate_);
settings.setValue("use_stun_server", useStunServer_);
+ settings.setValue("currentProfile", profile_);
+
+ QString prefix =
+ (profile_ != "" && profile_ != "default") ? "profile/" + profile_ + "/" : "";
+ settings.setValue(prefix + "auth/access_token", accessToken_);
+ settings.setValue(prefix + "auth/home_server", homeserver_);
+ settings.setValue(prefix + "auth/user_id", userId_);
+ settings.setValue(prefix + "auth/device_id", deviceId_);
- settings.endGroup();
+ settings.endGroup(); // user
settings.sync();
}
diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h
index c699fd59..dd1e26d9 100644
--- a/src/UserSettingsPage.h
+++ b/src/UserSettingsPage.h
@@ -84,6 +84,12 @@ class UserSettings : public QObject
bool useStunServer READ useStunServer WRITE setUseStunServer NOTIFY useStunServerChanged)
Q_PROPERTY(bool shareKeysWithTrustedUsers READ shareKeysWithTrustedUsers WRITE
setShareKeysWithTrustedUsers NOTIFY shareKeysWithTrustedUsersChanged)
+ Q_PROPERTY(QString profile READ profile WRITE setProfile NOTIFY profileChanged)
+ Q_PROPERTY(QString userId READ userId WRITE setUserId NOTIFY userIdChanged)
+ Q_PROPERTY(
+ QString accessToken READ accessToken WRITE setAccessToken NOTIFY accessTokenChanged)
+ Q_PROPERTY(QString deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged)
+ Q_PROPERTY(QString homeserver READ homeserver WRITE setHomeserver NOTIFY homeserverChanged)
public:
UserSettings();
@@ -95,7 +101,7 @@ public:
Unavailable,
Offline,
};
- Q_ENUM(Presence);
+ Q_ENUM(Presence)
void save();
void load();
@@ -128,6 +134,11 @@ public:
void setCameraFrameRate(QString frameRate);
void setUseStunServer(bool state);
void setShareKeysWithTrustedUsers(bool state);
+ void setProfile(QString profile);
+ void setUserId(QString userId);
+ void setAccessToken(QString accessToken);
+ void setDeviceId(QString deviceId);
+ void setHomeserver(QString homeserver);
QString theme() const { return !theme_.isEmpty() ? theme_ : defaultTheme_; }
bool messageHoverHighlight() const { return messageHoverHighlight_; }
@@ -161,6 +172,11 @@ public:
QString cameraFrameRate() const { return cameraFrameRate_; }
bool useStunServer() const { return useStunServer_; }
bool shareKeysWithTrustedUsers() const { return shareKeysWithTrustedUsers_; }
+ QString profile() const { return profile_; }
+ QString userId() const { return userId_; }
+ QString accessToken() const { return accessToken_; }
+ QString deviceId() const { return deviceId_; }
+ QString homeserver() const { return homeserver_; }
signals:
void groupViewStateChanged(bool state);
@@ -191,6 +207,11 @@ signals:
void cameraFrameRateChanged(QString frameRate);
void useStunServerChanged(bool state);
void shareKeysWithTrustedUsersChanged(bool state);
+ void profileChanged(QString profile);
+ void userIdChanged(QString userId);
+ void accessTokenChanged(QString accessToken);
+ void deviceIdChanged(QString deviceId);
+ void homeserverChanged(QString homeserver);
private:
// Default to system theme if QT_QPA_PLATFORMTHEME var is set.
@@ -226,6 +247,11 @@ private:
QString cameraResolution_;
QString cameraFrameRate_;
bool useStunServer_;
+ QString profile_;
+ QString userId_;
+ QString accessToken_;
+ QString deviceId_;
+ QString homeserver_;
};
class HorizontalLine : public QFrame
diff --git a/src/main.cpp b/src/main.cpp
index 5eeebb82..58bdda34 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -107,29 +107,7 @@ main(int argc, char *argv[])
// needed for settings so need to register before any settings are read to prevent warnings
qRegisterMetaType<UserSettings::Presence>();
- // This is some hacky programming, but it's necessary (AFAIK?) to get the unique config name
- // parsed before the app name is set.
- QString appName{"nheko"};
- for (int i = 0; i < argc; ++i) {
- if (QString{argv[i]}.startsWith("--profile=")) {
- QString q{argv[i]};
- q.remove("--profile=");
- appName += "-" + q;
- } else if (QString{argv[i]}.startsWith("--p=")) {
- QString q{argv[i]};
- q.remove("-p=");
- appName += "-" + q;
- } else if (QString{argv[i]} == "--profile" || QString{argv[i]} == "-p") {
- if (i < argc - 1) // if i is less than argc - 1, we still have a parameter
- // left to process as the name
- {
- ++i; // the next arg is the name, so increment
- appName += "-" + QString{argv[i]};
- }
- }
- }
-
- QCoreApplication::setApplicationName(appName);
+ QCoreApplication::setApplicationName("nheko");
QCoreApplication::setApplicationVersion(nheko::version);
QCoreApplication::setOrganizationName("nheko");
QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
@@ -147,12 +125,36 @@ main(int argc, char *argv[])
}
#endif
+ // This is some hacky programming, but it's necessary (AFAIK?) to get the unique config name
+ // parsed before the SingleApplication userdata is set.
+ QString userdata{""};
+ for (int i = 0; i < argc; ++i) {
+ if (QString{argv[i]}.startsWith("--profile=")) {
+ QString q{argv[i]};
+ q.remove("--profile=");
+ userdata = q;
+ } else if (QString{argv[i]}.startsWith("--p=")) {
+ QString q{argv[i]};
+ q.remove("-p=");
+ userdata = q;
+ } else if (QString{argv[i]} == "--profile" || QString{argv[i]} == "-p") {
+ if (i < argc - 1) // if i is less than argc - 1, we still have a parameter
+ // left to process as the name
+ {
+ ++i; // the next arg is the name, so increment
+ userdata = QString{argv[i]};
+ }
+ }
+ }
+
SingleApplication app(argc,
argv,
false,
SingleApplication::Mode::User |
SingleApplication::Mode::ExcludeAppPath |
- SingleApplication::Mode::ExcludeAppVersion);
+ SingleApplication::Mode::ExcludeAppVersion,
+ 100,
+ userdata);
QCommandLineParser parser;
parser.addHelpOption();
@@ -194,14 +196,17 @@ main(int argc, char *argv[])
std::exit(1);
}
- QSettings settings;
+ UserSettings settings;
+
+ if (parser.isSet(configName))
+ settings.setProfile(parser.value(configName));
QFont font;
- QString userFontFamily = settings.value("user/font_family", "").toString();
+ QString userFontFamily = settings.font();
if (!userFontFamily.isEmpty()) {
font.setFamily(userFontFamily);
}
- font.setPointSizeF(settings.value("user/font_size", font.pointSizeF()).toDouble());
+ font.setPointSizeF(settings.fontSize());
app.setFont(font);
@@ -216,13 +221,12 @@ main(int argc, char *argv[])
appTranslator.load(QLocale(), "nheko", "_", ":/translations");
app.installTranslator(&appTranslator);
- MainWindow w{(appName == "nheko" ? "" : appName.remove("nheko-"))};
+ MainWindow w;
// Move the MainWindow to the center
w.move(screenCenter(w.width(), w.height()));
- if (!settings.value("user/window/start_in_tray", false).toBool() ||
- !settings.value("user/window/tray", true).toBool())
+ if (!settings.startInTray() && !settings.tray())
w.show();
QObject::connect(&app, &QApplication::aboutToQuit, &w, [&w]() {