Add reset settings menu action and env var (#7435)
* Add reset settings menu action and env var * Delete profile and config dirs, reduce duplication with TLS dir and various other paths, fixed bug in new client dialog, move TLS arg to server * Better filename * Make method const * Update ChangeLog * Remove include * Make param const * Stop core process on reset * Fixed: reset menu action causes config to be pulled from app/server config * Center main window in middle of screen
This commit is contained in:
parent
c4510bf093
commit
3e4cb4a1c7
37 changed files with 559 additions and 228 deletions
|
|
@ -21,6 +21,9 @@
|
||||||
# Enable verbose logging in the GUI (always off by default)
|
# Enable verbose logging in the GUI (always off by default)
|
||||||
# SYNERGY_GUI_VERBOSE=true
|
# SYNERGY_GUI_VERBOSE=true
|
||||||
|
|
||||||
|
# Reset all settings and delete all data on startup
|
||||||
|
# SYNERGY_RESET_ALL=true
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build
|
# Build
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ Enhancements:
|
||||||
- #7431 Improve handling of Qt-related warnings and errors
|
- #7431 Improve handling of Qt-related warnings and errors
|
||||||
- #7432 Only show close to tray reminder when not quitting the app
|
- #7432 Only show close to tray reminder when not quitting the app
|
||||||
- #7434 Show dark logo in dark mode and improve .env loader
|
- #7434 Show dark logo in dark mode and improve .env loader
|
||||||
|
- #7435 Add reset settings menu action and env var
|
||||||
|
|
||||||
# 1.14.6
|
# 1.14.6
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,14 @@
|
||||||
#include "AboutDialog.h"
|
#include "AboutDialog.h"
|
||||||
#include "ActivationDialog.h"
|
#include "ActivationDialog.h"
|
||||||
#include "ServerConfigDialog.h"
|
#include "ServerConfigDialog.h"
|
||||||
|
#include "common/constants.h"
|
||||||
#include "gui/Logger.h"
|
#include "gui/Logger.h"
|
||||||
#include "gui/TrayIcon.h"
|
#include "gui/TrayIcon.h"
|
||||||
#include "gui/VersionChecker.h"
|
#include "gui/VersionChecker.h"
|
||||||
#include "gui/config/ConfigScopes.h"
|
#include "gui/config/ConfigScopes.h"
|
||||||
#include "gui/constants.h"
|
#include "gui/constants.h"
|
||||||
#include "gui/core/CoreProcess.h"
|
#include "gui/core/CoreProcess.h"
|
||||||
|
#include "gui/diagnostic.h"
|
||||||
#include "gui/dialogs/SettingsDialog.h"
|
#include "gui/dialogs/SettingsDialog.h"
|
||||||
#include "gui/license/LicenseHandler.h"
|
#include "gui/license/LicenseHandler.h"
|
||||||
#include "gui/license/license_notices.h"
|
#include "gui/license/license_notices.h"
|
||||||
|
|
@ -76,13 +78,15 @@ MainWindow::MainWindow(ConfigScopes &configScopes, AppConfig &appConfig)
|
||||||
: m_ConfigScopes(configScopes),
|
: m_ConfigScopes(configScopes),
|
||||||
m_AppConfig(appConfig),
|
m_AppConfig(appConfig),
|
||||||
m_ServerConfig(appConfig, *this),
|
m_ServerConfig(appConfig, *this),
|
||||||
m_CoreProcess(appConfig, m_ServerConfig),
|
m_CoreProcess(appConfig, m_ServerConfig, m_LicenseHandler.license()),
|
||||||
m_ServerConnection(this, appConfig, m_ServerConfig),
|
m_ServerConnection(
|
||||||
|
this, appConfig, m_ServerConfig, m_ServerConfigDialogState),
|
||||||
m_ClientConnection(this, appConfig),
|
m_ClientConnection(this, appConfig),
|
||||||
m_TlsUtility(appConfig, m_LicenseHandler.license()),
|
m_TlsUtility(appConfig, m_LicenseHandler.license()),
|
||||||
m_WindowSaveTimer(this) {
|
m_WindowSaveTimer(this) {
|
||||||
|
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
createMenuBar();
|
||||||
setupControls();
|
setupControls();
|
||||||
connectSlots();
|
connectSlots();
|
||||||
|
|
||||||
|
|
@ -90,15 +94,7 @@ MainWindow::MainWindow(ConfigScopes &configScopes, AppConfig &appConfig)
|
||||||
emit created();
|
emit created();
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow() {
|
MainWindow::~MainWindow() { m_CoreProcess.cleanup(); }
|
||||||
try {
|
|
||||||
saveWindow();
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
qFatal("failed to save window on main window close: %s", e.what());
|
|
||||||
}
|
|
||||||
|
|
||||||
m_CoreProcess.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::restoreWindow() {
|
void MainWindow::restoreWindow() {
|
||||||
|
|
||||||
|
|
@ -112,6 +108,11 @@ void MainWindow::restoreWindow() {
|
||||||
if (windowPosition.has_value()) {
|
if (windowPosition.has_value()) {
|
||||||
qDebug("restoring main window position");
|
qDebug("restoring main window position");
|
||||||
move(windowPosition.value());
|
move(windowPosition.value());
|
||||||
|
} else {
|
||||||
|
// center main window in middle of screen
|
||||||
|
const auto screen = QGuiApplication::primaryScreen();
|
||||||
|
QRect screenGeometry = screen->geometry();
|
||||||
|
move(screenGeometry.center() - rect().center());
|
||||||
}
|
}
|
||||||
|
|
||||||
// give the window chance to restore its size and position before the window
|
// give the window chance to restore its size and position before the window
|
||||||
|
|
@ -144,7 +145,6 @@ void MainWindow::setupControls() {
|
||||||
m_pActionActivate->setVisible(false);
|
m_pActionActivate->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
createMenuBar();
|
|
||||||
secureSocket(false);
|
secureSocket(false);
|
||||||
updateLocalFingerprint();
|
updateLocalFingerprint();
|
||||||
|
|
||||||
|
|
@ -273,7 +273,11 @@ void MainWindow::connectSlots() {
|
||||||
[this]() { showAndActivate(); });
|
[this]() { showAndActivate(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::onAppAboutToQuit() { m_ConfigScopes.save(); }
|
void MainWindow::onAppAboutToQuit() {
|
||||||
|
if (m_SaveOnExit) {
|
||||||
|
m_ConfigScopes.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::onCreated() {
|
void MainWindow::onCreated() {
|
||||||
|
|
||||||
|
|
@ -398,6 +402,19 @@ void MainWindow::on_m_pActionTestCriticalError_triggered() const {
|
||||||
qCritical("test critical error");
|
qCritical("test critical error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_m_pActionClearSettings_triggered() {
|
||||||
|
if (!messages::showClearSettings(this)) {
|
||||||
|
qDebug("clear settings cancelled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_CoreProcess.stop();
|
||||||
|
|
||||||
|
m_Quitting = true;
|
||||||
|
m_SaveOnExit = false;
|
||||||
|
diagnostic::clearSettings(m_ConfigScopes, true);
|
||||||
|
}
|
||||||
|
|
||||||
bool MainWindow::on_m_pActionSave_triggered() {
|
bool MainWindow::on_m_pActionSave_triggered() {
|
||||||
QString fileName =
|
QString fileName =
|
||||||
QFileDialog::getSaveFileName(this, QString("Save configuration as..."));
|
QFileDialog::getSaveFileName(this, QString("Save configuration as..."));
|
||||||
|
|
@ -505,10 +522,12 @@ void MainWindow::on_m_pButtonConnectToClient_clicked() {
|
||||||
void MainWindow::onWindowSaveTimerTimeout() { saveWindow(); }
|
void MainWindow::onWindowSaveTimerTimeout() { saveWindow(); }
|
||||||
|
|
||||||
void MainWindow::onServerConnectionConfigureClient(const QString &clientName) {
|
void MainWindow::onServerConnectionConfigureClient(const QString &clientName) {
|
||||||
|
m_ServerConfigDialogState.setVisible(true);
|
||||||
ServerConfigDialog dialog(this, m_ServerConfig, m_AppConfig);
|
ServerConfigDialog dialog(this, m_ServerConfig, m_AppConfig);
|
||||||
if (dialog.addClient(clientName) && dialog.exec() == QDialog::Accepted) {
|
if (dialog.addClient(clientName) && dialog.exec() == QDialog::Accepted) {
|
||||||
m_CoreProcess.restart();
|
m_CoreProcess.restart();
|
||||||
}
|
}
|
||||||
|
m_ServerConfigDialogState.setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -592,22 +611,21 @@ void MainWindow::createMenuBar() {
|
||||||
m_pMenuFile->addAction(m_pActionSave);
|
m_pMenuFile->addAction(m_pActionSave);
|
||||||
m_pMenuFile->addSeparator();
|
m_pMenuFile->addSeparator();
|
||||||
m_pMenuFile->addAction(m_pActionQuit);
|
m_pMenuFile->addAction(m_pActionQuit);
|
||||||
|
|
||||||
m_pMenuEdit->addAction(m_pActionSettings);
|
m_pMenuEdit->addAction(m_pActionSettings);
|
||||||
|
|
||||||
m_pMenuWindow->addAction(m_pActionMinimize);
|
m_pMenuWindow->addAction(m_pActionMinimize);
|
||||||
m_pMenuWindow->addAction(m_pActionRestore);
|
m_pMenuWindow->addAction(m_pActionRestore);
|
||||||
|
|
||||||
m_pMenuHelp->addAction(m_pActionAbout);
|
m_pMenuHelp->addAction(m_pActionAbout);
|
||||||
m_pMenuHelp->addAction(m_pActionHelp);
|
m_pMenuHelp->addAction(m_pActionHelp);
|
||||||
|
m_pMenuFile->addSeparator();
|
||||||
|
m_pMenuHelp->addAction(m_pActionClearSettings);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
// always enable test menu in debug mode.
|
|
||||||
const auto enableTestMenu = true;
|
|
||||||
#else
|
|
||||||
// only enable test menu in release build if env var is true.
|
|
||||||
const auto enableTestMenu =
|
const auto enableTestMenu =
|
||||||
strToTrue(qEnvironmentVariable("SYNERGY_TEST_MENU"));
|
strToTrue(qEnvironmentVariable("SYNERGY_TEST_MENU"));
|
||||||
#endif
|
|
||||||
|
|
||||||
if (enableTestMenu) {
|
if (enableTestMenu || kDebugBuild) {
|
||||||
auto testMenu = new QMenu("Test", m_pMenuBar);
|
auto testMenu = new QMenu("Test", m_pMenuBar);
|
||||||
m_pMenuBar->addMenu(testMenu);
|
m_pMenuBar->addMenu(testMenu);
|
||||||
testMenu->addAction(m_pActionTestFatalError);
|
testMenu->addAction(m_pActionTestFatalError);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
#include "gui/VersionChecker.h"
|
#include "gui/VersionChecker.h"
|
||||||
#include "gui/config/AppConfig.h"
|
#include "gui/config/AppConfig.h"
|
||||||
#include "gui/config/ConfigScopes.h"
|
#include "gui/config/ConfigScopes.h"
|
||||||
|
#include "gui/config/ServerConfigDialogState.h"
|
||||||
#include "gui/core/ClientConnection.h"
|
#include "gui/core/ClientConnection.h"
|
||||||
#include "gui/core/CoreProcess.h"
|
#include "gui/core/CoreProcess.h"
|
||||||
#include "gui/core/ServerConnection.h"
|
#include "gui/core/ServerConnection.h"
|
||||||
|
|
@ -130,6 +131,7 @@ private slots:
|
||||||
void on_m_pActionStopCore_triggered();
|
void on_m_pActionStopCore_triggered();
|
||||||
void on_m_pActionTestFatalError_triggered() const;
|
void on_m_pActionTestFatalError_triggered() const;
|
||||||
void on_m_pActionTestCriticalError_triggered() const;
|
void on_m_pActionTestCriticalError_triggered() const;
|
||||||
|
void on_m_pActionClearSettings_triggered();
|
||||||
void on_m_pLineEditHostname_returnPressed();
|
void on_m_pLineEditHostname_returnPressed();
|
||||||
void on_m_pLineEditClientIp_returnPressed();
|
void on_m_pLineEditClientIp_returnPressed();
|
||||||
void on_m_pLineEditHostname_textChanged(const QString &text);
|
void on_m_pLineEditHostname_textChanged(const QString &text);
|
||||||
|
|
@ -194,6 +196,8 @@ private:
|
||||||
bool m_SaveWindow = false;
|
bool m_SaveWindow = false;
|
||||||
LicenseHandler m_LicenseHandler;
|
LicenseHandler m_LicenseHandler;
|
||||||
bool m_Quitting = false;
|
bool m_Quitting = false;
|
||||||
|
synergy::gui::config::ServerConfigDialogState m_ServerConfigDialogState;
|
||||||
|
bool m_SaveOnExit = true;
|
||||||
|
|
||||||
synergy::gui::ConfigScopes &m_ConfigScopes;
|
synergy::gui::ConfigScopes &m_ConfigScopes;
|
||||||
AppConfig &m_AppConfig;
|
AppConfig &m_AppConfig;
|
||||||
|
|
|
||||||
|
|
@ -667,6 +667,14 @@
|
||||||
<enum>QAction::TextHeuristicRole</enum>
|
<enum>QAction::TextHeuristicRole</enum>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="m_pActionClearSettings">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear settings</string>
|
||||||
|
</property>
|
||||||
|
<property name="menuRole">
|
||||||
|
<enum>QAction::TextHeuristicRole</enum>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,10 @@
|
||||||
#include "gui/Logger.h"
|
#include "gui/Logger.h"
|
||||||
#include "gui/config/AppConfig.h"
|
#include "gui/config/AppConfig.h"
|
||||||
#include "gui/config/ConfigScopes.h"
|
#include "gui/config/ConfigScopes.h"
|
||||||
|
#include "gui/diagnostic.h"
|
||||||
#include "gui/dotenv.h"
|
#include "gui/dotenv.h"
|
||||||
#include "gui/messages.h"
|
#include "gui/messages.h"
|
||||||
|
#include "gui/string_utils.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
@ -34,6 +36,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QtCore>
|
#include <QtCore>
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
|
#include <qglobal.h>
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
|
|
@ -53,6 +56,11 @@ QString getSystemSettingPath();
|
||||||
bool checkMacAssistiveDevices();
|
bool checkMacAssistiveDevices();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool hasArg(const QString &arg, const QStringList &args) {
|
||||||
|
return std::ranges::any_of(
|
||||||
|
args, [&arg](const QString &a) { return a == arg; });
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
|
|
@ -96,6 +104,15 @@ int main(int argc, char *argv[]) {
|
||||||
qRegisterMetaType<Edition>("Edition");
|
qRegisterMetaType<Edition>("Edition");
|
||||||
|
|
||||||
ConfigScopes configScopes;
|
ConfigScopes configScopes;
|
||||||
|
|
||||||
|
// --no-reset
|
||||||
|
QStringList arguments = QCoreApplication::arguments();
|
||||||
|
const auto noReset = hasArg("--no-reset", arguments);
|
||||||
|
const auto resetEnvVar = strToTrue(qEnvironmentVariable("SYNERGY_RESET_ALL"));
|
||||||
|
if (resetEnvVar && !noReset) {
|
||||||
|
diagnostic::clearSettings(configScopes, false);
|
||||||
|
}
|
||||||
|
|
||||||
AppConfig appConfig(configScopes);
|
AppConfig appConfig(configScopes);
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
|
|
|
||||||
|
|
@ -30,3 +30,9 @@ const auto kVersionGitSha = GIT_SHA_SHORT;
|
||||||
#else
|
#else
|
||||||
const auto kVersionGitSha = "";
|
const auto kVersionGitSha = "";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
const auto kDebugBuild = true;
|
||||||
|
#else
|
||||||
|
const auto kDebugBuild = false;
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,8 @@ AppConfig::AppConfig(
|
||||||
synergy::gui::IConfigScopes &scopes, std::shared_ptr<Deps> deps)
|
synergy::gui::IConfigScopes &scopes, std::shared_ptr<Deps> deps)
|
||||||
: m_Scopes(scopes),
|
: m_Scopes(scopes),
|
||||||
m_pDeps(deps),
|
m_pDeps(deps),
|
||||||
m_ScreenName(deps->hostname()) {
|
m_ScreenName(deps->hostname()),
|
||||||
|
m_TlsCertPath(deps->defaultTlsCertPath()) {
|
||||||
determineScope();
|
determineScope();
|
||||||
recall();
|
recall();
|
||||||
}
|
}
|
||||||
|
|
@ -314,13 +315,6 @@ void AppConfig::recallElevateMode() {
|
||||||
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
|
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AppConfig::defaultTlsCertPath() const {
|
|
||||||
QDir path(m_pDeps->profileDir());
|
|
||||||
path = path.filePath("SSL");
|
|
||||||
path = path.filePath("Synergy.pem");
|
|
||||||
return path.absolutePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString AppConfig::settingName(Setting name) {
|
QString AppConfig::settingName(Setting name) {
|
||||||
auto index = static_cast<int>(name);
|
auto index = static_cast<int>(name);
|
||||||
return m_SettingsName[index];
|
return m_SettingsName[index];
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#include "ElevateMode.h"
|
#include "ElevateMode.h"
|
||||||
#include "IAppConfig.h"
|
#include "IAppConfig.h"
|
||||||
#include "IConfigScopes.h"
|
#include "IConfigScopes.h"
|
||||||
#include "gui/core/CoreTool.h"
|
#include "gui/paths.h"
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QHostInfo>
|
#include <QHostInfo>
|
||||||
|
|
@ -116,11 +116,10 @@ private:
|
||||||
public:
|
public:
|
||||||
struct Deps {
|
struct Deps {
|
||||||
virtual ~Deps() = default;
|
virtual ~Deps() = default;
|
||||||
virtual QString profileDir() const { return m_coreTool.getProfileDir(); }
|
virtual QString defaultTlsCertPath() const {
|
||||||
|
return synergy::gui::paths::defaultTlsCertPath();
|
||||||
|
}
|
||||||
virtual QString hostname() const { return QHostInfo::localHostName(); }
|
virtual QString hostname() const { return QHostInfo::localHostName(); }
|
||||||
|
|
||||||
private:
|
|
||||||
[[no_unique_address]] CoreTool m_coreTool;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit AppConfig(
|
explicit AppConfig(
|
||||||
|
|
@ -293,9 +292,16 @@ private:
|
||||||
*/
|
*/
|
||||||
QString defaultTlsCertPath() const;
|
QString defaultTlsCertPath() const;
|
||||||
|
|
||||||
synergy::gui::IConfigScopes &m_Scopes;
|
static const char m_CoreServerName[];
|
||||||
std::shared_ptr<Deps> m_pDeps;
|
static const char m_CoreClientName[];
|
||||||
QString m_ScreenName;
|
static const char m_LogDir[];
|
||||||
|
|
||||||
|
/// @brief Contains the string values of the settings names that will be saved
|
||||||
|
static const char *const m_SettingsName[];
|
||||||
|
|
||||||
|
/// @brief Core config filename (not the Qt settings filename)
|
||||||
|
static const char m_ConfigFilename[];
|
||||||
|
|
||||||
int m_Port = 24800;
|
int m_Port = 24800;
|
||||||
QString m_Interface = "";
|
QString m_Interface = "";
|
||||||
int m_LogLevel = 0;
|
int m_LogLevel = 0;
|
||||||
|
|
@ -324,7 +330,6 @@ private:
|
||||||
bool m_EnableService =
|
bool m_EnableService =
|
||||||
synergy::gui::kDefaultProcessMode == ProcessMode::kService;
|
synergy::gui::kDefaultProcessMode == ProcessMode::kService;
|
||||||
bool m_CloseToTray = true;
|
bool m_CloseToTray = true;
|
||||||
QString m_TlsCertPath = defaultTlsCertPath();
|
|
||||||
int m_TlsKeyLength = synergy::gui::kDefaultTlsKeyLength;
|
int m_TlsKeyLength = synergy::gui::kDefaultTlsKeyLength;
|
||||||
std::optional<QSize> m_MainWindowSize;
|
std::optional<QSize> m_MainWindowSize;
|
||||||
std::optional<QPoint> m_MainWindowPosition;
|
std::optional<QPoint> m_MainWindowPosition;
|
||||||
|
|
@ -338,15 +343,10 @@ private:
|
||||||
*/
|
*/
|
||||||
bool m_TlsChanged = false;
|
bool m_TlsChanged = false;
|
||||||
|
|
||||||
static const char m_CoreServerName[];
|
synergy::gui::IConfigScopes &m_Scopes;
|
||||||
static const char m_CoreClientName[];
|
std::shared_ptr<Deps> m_pDeps;
|
||||||
static const char m_LogDir[];
|
QString m_ScreenName;
|
||||||
|
QString m_TlsCertPath;
|
||||||
/// @brief Contains the string values of the settings names that will be saved
|
|
||||||
static const char *const m_SettingsName[];
|
|
||||||
|
|
||||||
/// @brief Core config filename (not the Qt settings filename)
|
|
||||||
static const char m_ConfigFilename[];
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void tlsChanged();
|
void tlsChanged();
|
||||||
|
|
|
||||||
|
|
@ -54,11 +54,18 @@ ConfigScopes::ConfigScopes(std::shared_ptr<Deps> deps)
|
||||||
m_pSystemSettingsProxy->loadSystem();
|
m_pSystemSettingsProxy->loadSystem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigScopes::clear() const {
|
||||||
|
m_pUserSettingsProxy->clear();
|
||||||
|
m_pSystemSettingsProxy->clear();
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigScopes::signalReady() { emit ready(); }
|
void ConfigScopes::signalReady() { emit ready(); }
|
||||||
|
|
||||||
void ConfigScopes::save() {
|
void ConfigScopes::save(bool emitSaving) {
|
||||||
qDebug("emitting config saving signal");
|
if (emitSaving) {
|
||||||
emit saving();
|
qDebug("emitting config saving signal");
|
||||||
|
emit saving();
|
||||||
|
}
|
||||||
|
|
||||||
qDebug("writing config to filesystem");
|
qDebug("writing config to filesystem");
|
||||||
m_pUserSettingsProxy->sync();
|
m_pUserSettingsProxy->sync();
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,10 @@ public:
|
||||||
explicit ConfigScopes(std::shared_ptr<Deps> deps = std::make_shared<Deps>());
|
explicit ConfigScopes(std::shared_ptr<Deps> deps = std::make_shared<Deps>());
|
||||||
~ConfigScopes() override = default;
|
~ConfigScopes() override = default;
|
||||||
|
|
||||||
|
void clear() const;
|
||||||
|
|
||||||
void signalReady() override;
|
void signalReady() override;
|
||||||
void save() override;
|
void save(bool emitSaving = true) override;
|
||||||
bool scopeContains(
|
bool scopeContains(
|
||||||
const QString &name, Scope scope = Scope::Current) const override;
|
const QString &name, Scope scope = Scope::Current) const override;
|
||||||
bool isActiveScopeWritable() const override;
|
bool isActiveScopeWritable() const override;
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,10 @@ public:
|
||||||
* @brief Signals to listeners to save and calls `sync` on underlying Qt
|
* @brief Signals to listeners to save and calls `sync` on underlying Qt
|
||||||
* config.
|
* config.
|
||||||
*
|
*
|
||||||
|
* @param emitSaving Whether to emit the saving signal which typically
|
||||||
|
* triggers listeners to write their current state to the config.
|
||||||
*/
|
*/
|
||||||
virtual void save() = 0;
|
virtual void save(bool emitSaving = true) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check a scope for a config value (default is current scope).
|
* @brief Check a scope for a config value (default is current scope).
|
||||||
|
|
|
||||||
38
src/lib/gui/config/ServerConfigDialogState.h
Normal file
38
src/lib/gui/config/ServerConfigDialogState.h
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2021 Symless Ltd.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace synergy::gui::config {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Represents the state of the server config dialog.
|
||||||
|
*
|
||||||
|
* Future design consideration: Once moving the server config dialog to the GUI
|
||||||
|
* lib, we can probably just pass a reference to that rather than needing an
|
||||||
|
* object to track it's state.
|
||||||
|
*/
|
||||||
|
class ServerConfigDialogState {
|
||||||
|
public:
|
||||||
|
bool isVisible() const { return m_isVisible; }
|
||||||
|
void setVisible(bool isVisible) { m_isVisible = isVisible; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_isVisible = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace synergy::gui::config
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "gui/config/IAppConfig.h"
|
#include "gui/config/IAppConfig.h"
|
||||||
#include "gui/core/CoreTool.h"
|
#include "gui/core/CoreTool.h"
|
||||||
|
#include "gui/paths.h"
|
||||||
|
#include "tls/TlsUtility.h"
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
#include "OSXHelpers.h"
|
#include "OSXHelpers.h"
|
||||||
|
|
@ -37,7 +39,7 @@
|
||||||
namespace synergy::gui {
|
namespace synergy::gui {
|
||||||
|
|
||||||
const int kRetryDelay = 1000;
|
const int kRetryDelay = 1000;
|
||||||
const auto kLastConfigFilename = "LastConfig.cfg";
|
const auto kServerConfigFilename = "synergy-server.conf";
|
||||||
const auto kLineSplitRegex = QRegularExpression("\r|\n|\r\n");
|
const auto kLineSplitRegex = QRegularExpression("\r|\n|\r\n");
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -135,9 +137,10 @@ QString CoreProcess::Deps::getProfileRoot() const {
|
||||||
|
|
||||||
CoreProcess::CoreProcess(
|
CoreProcess::CoreProcess(
|
||||||
IAppConfig &appConfig, IServerConfig &serverConfig,
|
IAppConfig &appConfig, IServerConfig &serverConfig,
|
||||||
std::shared_ptr<Deps> deps)
|
const license::ILicense &license, std::shared_ptr<Deps> deps)
|
||||||
: m_appConfig(appConfig),
|
: m_appConfig(appConfig),
|
||||||
m_serverConfig(serverConfig),
|
m_serverConfig(serverConfig),
|
||||||
|
m_license(license),
|
||||||
m_pDeps(deps) {
|
m_pDeps(deps) {
|
||||||
|
|
||||||
connect(
|
connect(
|
||||||
|
|
@ -339,65 +342,19 @@ void CoreProcess::start(std::optional<ProcessMode> processModeOption) {
|
||||||
|
|
||||||
setConnectionState(ConnectionState::Connecting);
|
setConnectionState(ConnectionState::Connecting);
|
||||||
|
|
||||||
QString app;
|
|
||||||
QStringList args;
|
|
||||||
|
|
||||||
args << "-f"
|
|
||||||
<< "--no-tray"
|
|
||||||
<< "--debug" << m_appConfig.logLevelText();
|
|
||||||
|
|
||||||
args << "--name" << m_appConfig.screenName();
|
|
||||||
|
|
||||||
if (processMode == ProcessMode::kDesktop) {
|
if (processMode == ProcessMode::kDesktop) {
|
||||||
m_pDeps->process().create();
|
m_pDeps->process().create();
|
||||||
} else {
|
|
||||||
// tell client/server to talk to daemon through ipc.
|
|
||||||
args << "--ipc";
|
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
// tell the client/server to shut down when a ms windows desk
|
|
||||||
// is switched; this is because we may need to elevate or not
|
|
||||||
// based on which desk the user is in (login always needs
|
|
||||||
// elevation, where as default desk does not).
|
|
||||||
// Note that this is only enabled when synergy is set to elevate
|
|
||||||
// 'as needed' (e.g. on a UAC dialog popup) in order to prevent
|
|
||||||
// unnecessary restarts when synergy was started elevated or
|
|
||||||
// when it is not allowed to elevate. In these cases restarting
|
|
||||||
// the server is fruitless.
|
|
||||||
if (m_appConfig.elevateMode() == ElevateMode::kAutomatic) {
|
|
||||||
args << "--stop-on-desk-switch";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef Q_OS_LINUX
|
QString app;
|
||||||
|
QStringList args;
|
||||||
|
addGenericArgs(args, processMode);
|
||||||
|
|
||||||
if (m_serverConfig.enableDragAndDrop()) {
|
if (mode() == Mode::Server && !addServerArgs(args, app)) {
|
||||||
args << "--enable-drag-drop";
|
qDebug("failed to add server args for core process, aborting start");
|
||||||
}
|
return;
|
||||||
|
} else if (mode() == Mode::Client && !addClientArgs(args, app)) {
|
||||||
#endif
|
qDebug("failed to add client args for core process, aborting start");
|
||||||
|
|
||||||
if (m_appConfig.tlsEnabled()) {
|
|
||||||
args << "--enable-crypto";
|
|
||||||
args << "--tls-cert" << m_appConfig.tlsCertPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
// on windows, the profile directory changes depending on the user that
|
|
||||||
// launched the process (e.g. when launched with elevation). setting the
|
|
||||||
// profile dir on launch ensures it uses the same profile dir is used
|
|
||||||
// no matter how its relaunched.
|
|
||||||
args << "--profile-dir" << m_pDeps->getProfileRoot();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (m_appConfig.preventSleep()) {
|
|
||||||
args << "--prevent-sleep";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((mode() == Mode::Client && !clientArgs(args, app)) ||
|
|
||||||
(mode() == Mode::Server && !serverArgs(args, app))) {
|
|
||||||
qDebug("failed to get args for core process, aborting start");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -483,7 +440,62 @@ void CoreProcess::cleanup() {
|
||||||
m_pDeps->ipcClient().disconnectFromHost();
|
m_pDeps->ipcClient().disconnectFromHost();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CoreProcess::serverArgs(QStringList &args, QString &app) {
|
bool CoreProcess::addGenericArgs(
|
||||||
|
QStringList &args, const ProcessMode processMode) const {
|
||||||
|
args << "-f"
|
||||||
|
<< "--no-tray"
|
||||||
|
<< "--debug" << m_appConfig.logLevelText();
|
||||||
|
|
||||||
|
args << "--name" << m_appConfig.screenName();
|
||||||
|
|
||||||
|
if (processMode != ProcessMode::kDesktop) {
|
||||||
|
// tell client/server to talk to daemon through ipc.
|
||||||
|
args << "--ipc";
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
// tell the client/server to shut down when a ms windows desk
|
||||||
|
// is switched; this is because we may need to elevate or not
|
||||||
|
// based on which desk the user is in (login always needs
|
||||||
|
// elevation, where as default desk does not).
|
||||||
|
// Note that this is only enabled when synergy is set to elevate
|
||||||
|
// 'as needed' (e.g. on a UAC dialog popup) in order to prevent
|
||||||
|
// unnecessary restarts when synergy was started elevated or
|
||||||
|
// when it is not allowed to elevate. In these cases restarting
|
||||||
|
// the server is fruitless.
|
||||||
|
if (m_appConfig.elevateMode() == ElevateMode::kAutomatic) {
|
||||||
|
args << "--stop-on-desk-switch";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef Q_OS_LINUX
|
||||||
|
|
||||||
|
if (m_serverConfig.enableDragAndDrop()) {
|
||||||
|
args << "--enable-drag-drop";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (m_appConfig.tlsEnabled()) {
|
||||||
|
args << "--enable-crypto";
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN)
|
||||||
|
// on windows, the profile directory changes depending on the user that
|
||||||
|
// launched the process (e.g. when launched with elevation). setting the
|
||||||
|
// profile dir on launch ensures it uses the same profile dir is used
|
||||||
|
// no matter how its relaunched.
|
||||||
|
args << "--profile-dir" << m_pDeps->getProfileRoot();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (m_appConfig.preventSleep()) {
|
||||||
|
args << "--prevent-sleep";
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CoreProcess::addServerArgs(QStringList &args, QString &app) {
|
||||||
app = m_pDeps->appPath(m_appConfig.coreServerName());
|
app = m_pDeps->appPath(m_appConfig.coreServerName());
|
||||||
|
|
||||||
if (!m_pDeps->fileExists(app)) {
|
if (!m_pDeps->fileExists(app)) {
|
||||||
|
|
@ -497,7 +509,7 @@ bool CoreProcess::serverArgs(QStringList &args, QString &app) {
|
||||||
args << "--log" << m_appConfig.logFilename();
|
args << "--log" << m_appConfig.logFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString configFilename = persistConfig();
|
QString configFilename = persistServerConfig();
|
||||||
if (configFilename.isEmpty()) {
|
if (configFilename.isEmpty()) {
|
||||||
qFatal("config file name empty for server args");
|
qFatal("config file name empty for server args");
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -526,10 +538,22 @@ bool CoreProcess::serverArgs(QStringList &args, QString &app) {
|
||||||
args << "--serial-key" << m_appConfig.serialKey();
|
args << "--serial-key" << m_appConfig.serialKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bizarrely, the tls cert path arg was being given to the core client.
|
||||||
|
// since it's not clear why (it is only needed for the server), this has now
|
||||||
|
// been moved to server args.
|
||||||
|
if (m_appConfig.tlsEnabled()) {
|
||||||
|
TlsUtility tlsUtility(m_appConfig, m_license);
|
||||||
|
if (!tlsUtility.persistCertificate()) {
|
||||||
|
qCritical("failed to persist tls certificate");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
args << "--tls-cert" << m_appConfig.tlsCertPath();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CoreProcess::clientArgs(QStringList &args, QString &app) {
|
bool CoreProcess::addClientArgs(QStringList &args, QString &app) {
|
||||||
app = m_pDeps->appPath(m_appConfig.coreClientName());
|
app = m_pDeps->appPath(m_appConfig.coreClientName());
|
||||||
|
|
||||||
if (!m_pDeps->fileExists(app)) {
|
if (!m_pDeps->fileExists(app)) {
|
||||||
|
|
@ -568,35 +592,25 @@ bool CoreProcess::clientArgs(QStringList &args, QString &app) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CoreProcess::persistConfig() const {
|
QString CoreProcess::persistServerConfig() const {
|
||||||
QString configFullPath;
|
QString configFullPath;
|
||||||
if (m_appConfig.useExternalConfig()) {
|
if (m_appConfig.useExternalConfig()) {
|
||||||
return m_appConfig.configFile();
|
return m_appConfig.configFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto path :
|
const auto configDir = paths::configDir(true);
|
||||||
{QStandardPaths::AppDataLocation, QStandardPaths::AppConfigLocation}) {
|
const auto configDirPath = configDir.absolutePath();
|
||||||
auto configDirPath = QStandardPaths::writableLocation(path);
|
|
||||||
if (!QDir().mkpath(configDirPath)) {
|
|
||||||
qWarning("failed to create config folder: %s", qPrintable(configDirPath));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile configFile(configDirPath + "/" + kLastConfigFilename);
|
QFile configFile(configDirPath + "/" + kServerConfigFilename);
|
||||||
if (!configFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
if (!configFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||||
qWarning(
|
qFatal(
|
||||||
"failed to open core config file: %s",
|
"failed to open core config file for write: %s",
|
||||||
qPrintable(configFile.fileName()));
|
qPrintable(configFile.fileName()));
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_serverConfig.save(configFile);
|
|
||||||
configFile.close();
|
|
||||||
return configFile.fileName();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qFatal("failed to persist config file");
|
m_serverConfig.save(configFile);
|
||||||
return "";
|
configFile.close();
|
||||||
|
return configFile.fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CoreProcess::modeString() const {
|
QString CoreProcess::modeString() const {
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "gui/config/IServerConfig.h"
|
#include "gui/config/IServerConfig.h"
|
||||||
#include "gui/ipc/QIpcClient.h"
|
#include "gui/ipc/QIpcClient.h"
|
||||||
#include "gui/proxy/QProcessProxy.h"
|
#include "gui/proxy/QProcessProxy.h"
|
||||||
|
#include "license/License.h"
|
||||||
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
@ -58,6 +59,7 @@ public:
|
||||||
|
|
||||||
explicit CoreProcess(
|
explicit CoreProcess(
|
||||||
IAppConfig &appConfig, IServerConfig &serverConfig,
|
IAppConfig &appConfig, IServerConfig &serverConfig,
|
||||||
|
const license::ILicense &license,
|
||||||
std::shared_ptr<Deps> deps = std::make_shared<Deps>());
|
std::shared_ptr<Deps> deps = std::make_shared<Deps>());
|
||||||
|
|
||||||
void extracted(QString &app, QStringList &args);
|
void extracted(QString &app, QStringList &args);
|
||||||
|
|
@ -98,9 +100,10 @@ private:
|
||||||
void startService(const QString &app, const QStringList &args);
|
void startService(const QString &app, const QStringList &args);
|
||||||
void stopDesktop() const;
|
void stopDesktop() const;
|
||||||
void stopService();
|
void stopService();
|
||||||
bool serverArgs(QStringList &args, QString &app);
|
bool addGenericArgs(QStringList &args, const ProcessMode processMode) const;
|
||||||
bool clientArgs(QStringList &args, QString &app);
|
bool addServerArgs(QStringList &args, QString &app);
|
||||||
QString persistConfig() const;
|
bool addClientArgs(QStringList &args, QString &app);
|
||||||
|
QString persistServerConfig() const;
|
||||||
QString modeString() const;
|
QString modeString() const;
|
||||||
QString processModeString() const;
|
QString processModeString() const;
|
||||||
void setConnectionState(ConnectionState state);
|
void setConnectionState(ConnectionState state);
|
||||||
|
|
@ -117,6 +120,7 @@ private:
|
||||||
|
|
||||||
IAppConfig &m_appConfig;
|
IAppConfig &m_appConfig;
|
||||||
IServerConfig &m_serverConfig;
|
IServerConfig &m_serverConfig;
|
||||||
|
const license::ILicense &m_license;
|
||||||
std::shared_ptr<Deps> m_pDeps;
|
std::shared_ptr<Deps> m_pDeps;
|
||||||
QString m_address;
|
QString m_address;
|
||||||
ProcessState m_processState = ProcessState::Stopped;
|
ProcessState m_processState = ProcessState::Stopped;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include "ServerConnection.h"
|
#include "ServerConnection.h"
|
||||||
|
|
||||||
#include "ServerMessage.h"
|
#include "ServerMessage.h"
|
||||||
|
#include "gui/config/ServerConfigDialogState.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
@ -40,10 +41,12 @@ messages::NewClientPromptResult ServerConnection::Deps::showNewClientPrompt(
|
||||||
|
|
||||||
ServerConnection::ServerConnection(
|
ServerConnection::ServerConnection(
|
||||||
QWidget *parent, IAppConfig &appConfig, IServerConfig &serverConfig,
|
QWidget *parent, IAppConfig &appConfig, IServerConfig &serverConfig,
|
||||||
|
const config::ServerConfigDialogState &serverConfigDialogState,
|
||||||
std::shared_ptr<Deps> deps)
|
std::shared_ptr<Deps> deps)
|
||||||
: m_pParent(parent),
|
: m_pParent(parent),
|
||||||
m_appConfig(appConfig),
|
m_appConfig(appConfig),
|
||||||
m_serverConfig(serverConfig),
|
m_serverConfig(serverConfig),
|
||||||
|
m_serverConfigDialogState(serverConfigDialogState),
|
||||||
m_pDeps(deps) {}
|
m_pDeps(deps) {}
|
||||||
|
|
||||||
void ServerConnection::handleLogLine(const QString &logLine) {
|
void ServerConnection::handleLogLine(const QString &logLine) {
|
||||||
|
|
@ -53,6 +56,16 @@ void ServerConnection::handleLogLine(const QString &logLine) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_messageShowing) {
|
||||||
|
qDebug("new client message already shown, skipping for now");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_serverConfigDialogState.isVisible()) {
|
||||||
|
qDebug("server config dialog visible, skipping new client prompt");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_appConfig.useExternalConfig()) {
|
if (m_appConfig.useExternalConfig()) {
|
||||||
qDebug("external config enabled, skipping new client prompt");
|
qDebug("external config enabled, skipping new client prompt");
|
||||||
return;
|
return;
|
||||||
|
|
@ -75,11 +88,6 @@ void ServerConnection::handleNewClient(const QString &clientName) {
|
||||||
|
|
||||||
m_receivedClients.append(clientName);
|
m_receivedClients.append(clientName);
|
||||||
|
|
||||||
if (m_messageShowing) {
|
|
||||||
qDebug("new client message already shown, skipping");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_serverConfig.isFull()) {
|
if (m_serverConfig.isFull()) {
|
||||||
qDebug(
|
qDebug(
|
||||||
"server config full, skipping new client prompt for: %s",
|
"server config full, skipping new client prompt for: %s",
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "gui/config/IAppConfig.h"
|
#include "gui/config/IAppConfig.h"
|
||||||
#include "gui/config/IServerConfig.h"
|
#include "gui/config/IServerConfig.h"
|
||||||
|
#include "gui/config/ServerConfigDialogState.h"
|
||||||
#include "gui/messages.h"
|
#include "gui/messages.h"
|
||||||
|
|
||||||
namespace synergy::gui {
|
namespace synergy::gui {
|
||||||
|
|
@ -39,6 +40,7 @@ public:
|
||||||
|
|
||||||
explicit ServerConnection(
|
explicit ServerConnection(
|
||||||
QWidget *parent, IAppConfig &appConfig, IServerConfig &serverConfig,
|
QWidget *parent, IAppConfig &appConfig, IServerConfig &serverConfig,
|
||||||
|
const config::ServerConfigDialogState &serverConfigDialogState,
|
||||||
std::shared_ptr<Deps> deps = std::make_shared<Deps>());
|
std::shared_ptr<Deps> deps = std::make_shared<Deps>());
|
||||||
void handleLogLine(const QString &logLine);
|
void handleLogLine(const QString &logLine);
|
||||||
|
|
||||||
|
|
@ -52,6 +54,7 @@ private:
|
||||||
QWidget *m_pParent;
|
QWidget *m_pParent;
|
||||||
IAppConfig &m_appConfig;
|
IAppConfig &m_appConfig;
|
||||||
IServerConfig &m_serverConfig;
|
IServerConfig &m_serverConfig;
|
||||||
|
const config::ServerConfigDialogState &m_serverConfigDialogState;
|
||||||
std::shared_ptr<Deps> m_pDeps;
|
std::shared_ptr<Deps> m_pDeps;
|
||||||
QStringList m_receivedClients;
|
QStringList m_receivedClients;
|
||||||
bool m_messageShowing = false;
|
bool m_messageShowing = false;
|
||||||
|
|
|
||||||
67
src/lib/gui/diagnostic.cpp
Normal file
67
src/lib/gui/diagnostic.cpp
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2024 Symless Ltd.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "diagnostic.h"
|
||||||
|
|
||||||
|
#include "config/ConfigScopes.h"
|
||||||
|
#include "paths.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
|
namespace synergy::gui::diagnostic {
|
||||||
|
|
||||||
|
void restart() {
|
||||||
|
QString program = QCoreApplication::applicationFilePath();
|
||||||
|
QStringList arguments = QCoreApplication::arguments();
|
||||||
|
|
||||||
|
// prevent infinite reset loop when env var set.
|
||||||
|
arguments << "--no-reset";
|
||||||
|
|
||||||
|
qInfo("launching new process: %s", qPrintable(program));
|
||||||
|
QProcess::startDetached(program, arguments);
|
||||||
|
|
||||||
|
qDebug("exiting current process");
|
||||||
|
QApplication::exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearSettings(ConfigScopes &scopes, bool enableRestart) {
|
||||||
|
qDebug("clearing settings");
|
||||||
|
scopes.clear();
|
||||||
|
|
||||||
|
// save but do not emit saving signal which will prevent the current state of
|
||||||
|
// the app config and server configs from being applied.
|
||||||
|
scopes.save(false);
|
||||||
|
|
||||||
|
auto configDir = paths::configDir();
|
||||||
|
qDebug("removing config dir: %s", qPrintable(configDir.absolutePath()));
|
||||||
|
configDir.removeRecursively();
|
||||||
|
|
||||||
|
auto profileDir = paths::coreProfileDir();
|
||||||
|
qDebug("removing profile dir: %s", qPrintable(profileDir.absolutePath()));
|
||||||
|
profileDir.removeRecursively();
|
||||||
|
|
||||||
|
if (enableRestart) {
|
||||||
|
qDebug("restarting");
|
||||||
|
restart();
|
||||||
|
} else {
|
||||||
|
qDebug("skipping restart");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace synergy::gui::diagnostic
|
||||||
26
src/lib/gui/diagnostic.h
Normal file
26
src/lib/gui/diagnostic.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2024 Symless Ltd.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "gui/config/ConfigScopes.h"
|
||||||
|
|
||||||
|
namespace synergy::gui::diagnostic {
|
||||||
|
|
||||||
|
void clearSettings(ConfigScopes &scopes, bool enableRestart);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#include "dotenv.h"
|
#include "dotenv.h"
|
||||||
|
|
||||||
|
#include "paths.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
@ -55,17 +57,10 @@ void dotenv(const QString &filename) {
|
||||||
"no %s file in dir: %s", qPrintable(filename),
|
"no %s file in dir: %s", qPrintable(filename),
|
||||||
qPrintable(fileInfo.absolutePath()));
|
qPrintable(fileInfo.absolutePath()));
|
||||||
|
|
||||||
// if nothing in current dir, then try the app data dir.
|
// if nothing in current dir, then try the config dir.
|
||||||
// this makes it a bit easier for engineers in the field to have an easily
|
// this makes it a bit easier for engineers in the field to have an easily
|
||||||
// predictable location for the .env file.
|
// predictable location for the .env file.
|
||||||
QDir configDir(
|
const auto orgDir = paths::configDir();
|
||||||
QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation));
|
|
||||||
|
|
||||||
// HACK: since we have the org name set to the app name, the config dir is
|
|
||||||
// confusing. make this simple by using the org dir instead.
|
|
||||||
// use `filePath("..")` instead of `cdUp` to avoid the existence check.
|
|
||||||
QDir orgDir = configDir.filePath("..");
|
|
||||||
orgDir = orgDir.absolutePath();
|
|
||||||
|
|
||||||
filePath = orgDir.filePath(filename);
|
filePath = orgDir.filePath(filename);
|
||||||
if (!open(file, filePath)) {
|
if (!open(file, filePath)) {
|
||||||
|
|
|
||||||
|
|
@ -249,4 +249,17 @@ showNewClientPrompt(QWidget *parent, const QString &clientName) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool showClearSettings(QWidget *parent) {
|
||||||
|
QMessageBox message(parent);
|
||||||
|
message.addButton(QObject::tr("Cancel"), QMessageBox::RejectRole);
|
||||||
|
const auto clear =
|
||||||
|
message.addButton(QObject::tr("Clear settings"), QMessageBox::AcceptRole);
|
||||||
|
message.setText(
|
||||||
|
"<p>Are you sure you want to clear all settings and restart Synergy?</p>"
|
||||||
|
"<p>This action cannot be undone.</p>");
|
||||||
|
message.exec();
|
||||||
|
|
||||||
|
return message.clickedButton() == clear;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace synergy::gui::messages
|
} // namespace synergy::gui::messages
|
||||||
|
|
|
||||||
|
|
@ -46,4 +46,6 @@ void showClientConnectError(
|
||||||
NewClientPromptResult
|
NewClientPromptResult
|
||||||
showNewClientPrompt(QWidget *parent, const QString &clientName);
|
showNewClientPrompt(QWidget *parent, const QString &clientName);
|
||||||
|
|
||||||
|
bool showClearSettings(QWidget *parent);
|
||||||
|
|
||||||
} // namespace synergy::gui::messages
|
} // namespace synergy::gui::messages
|
||||||
|
|
|
||||||
67
src/lib/gui/paths.h
Normal file
67
src/lib/gui/paths.h
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2024 Symless Ltd.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/CoreTool.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
const auto kCertificateFilename = "Synergy.pem";
|
||||||
|
const auto kSslDir = "SSL";
|
||||||
|
|
||||||
|
namespace synergy::gui::paths {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the org config dir (parent of app config dir).
|
||||||
|
*/
|
||||||
|
inline QDir configDir(const bool persist = false) {
|
||||||
|
const QDir configDir(
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation));
|
||||||
|
|
||||||
|
// HACK: since we have the org name set to the app name, the config dir is
|
||||||
|
// confusing. make this simple by using the org dir instead.
|
||||||
|
// use `filePath("..")` instead of `cdUp` to avoid the existence check.
|
||||||
|
const QDir orgDir = configDir.filePath("..");
|
||||||
|
|
||||||
|
if (persist) {
|
||||||
|
const auto orgDirPath = orgDir.absolutePath();
|
||||||
|
if (!QDir().mkpath(orgDirPath)) {
|
||||||
|
qFatal("failed to persist config dir: %s", qPrintable(orgDirPath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return orgDir.absolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Uses the Core tool to get the profile dir.
|
||||||
|
*/
|
||||||
|
inline QDir coreProfileDir() {
|
||||||
|
CoreTool coreTool;
|
||||||
|
return QDir(coreTool.getProfileDir());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QString defaultTlsCertPath() {
|
||||||
|
const auto root = coreProfileDir();
|
||||||
|
const auto sslDirPath = QDir(root.filePath(kSslDir));
|
||||||
|
return sslDirPath.filePath(kCertificateFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace synergy::gui::paths
|
||||||
|
|
@ -29,7 +29,7 @@ public:
|
||||||
|
|
||||||
virtual void loadUser();
|
virtual void loadUser();
|
||||||
virtual void loadSystem();
|
virtual void loadSystem();
|
||||||
|
virtual void clear() { m_pSettings->clear(); }
|
||||||
virtual void sync() { m_pSettings->sync(); }
|
virtual void sync() { m_pSettings->sync(); }
|
||||||
virtual int beginReadArray(const QString &prefix);
|
virtual int beginReadArray(const QString &prefix);
|
||||||
virtual void beginWriteArray(const QString &prefix);
|
virtual void beginWriteArray(const QString &prefix);
|
||||||
|
|
|
||||||
|
|
@ -18,18 +18,16 @@
|
||||||
#include "TlsCertificate.h"
|
#include "TlsCertificate.h"
|
||||||
|
|
||||||
#include "TlsFingerprint.h"
|
#include "TlsFingerprint.h"
|
||||||
|
#include "gui/paths.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
static const char *const kCertificateKeyLength = "rsa:";
|
static const char *const kCertificateKeyLength = "rsa:";
|
||||||
static const char *const kCertificateHashAlgorithm = "-sha256";
|
static const char *const kCertificateHashAlgorithm = "-sha256";
|
||||||
static const char *const kCertificateLifetime = "365";
|
static const char *const kCertificateLifetime = "365";
|
||||||
static const char *const kCertificateSubjectInfo = "/CN=Synergy";
|
static const char *const kCertificateSubjectInfo = "/CN=Synergy";
|
||||||
static const char *const kCertificateFilename = "Synergy.pem";
|
|
||||||
static const char *const kSslDir = "SSL";
|
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
static const char *const kWinOpenSslDir = "OpenSSL";
|
static const char *const kWinOpenSslDir = "OpenSSL";
|
||||||
|
|
@ -39,6 +37,8 @@ static const char *const kConfigFile = "synergy.conf";
|
||||||
static const char *const kUnixOpenSslCommand = "openssl";
|
static const char *const kUnixOpenSslCommand = "openssl";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using namespace synergy::gui;
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
|
|
||||||
namespace synergy::gui {
|
namespace synergy::gui {
|
||||||
|
|
@ -87,12 +87,7 @@ using namespace synergy::gui;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TlsCertificate::TlsCertificate(QObject *parent) : QObject(parent) {
|
TlsCertificate::TlsCertificate(QObject *parent) : QObject(parent) {}
|
||||||
m_profileDir = m_coreTool.getProfileDir();
|
|
||||||
if (m_profileDir.isEmpty()) {
|
|
||||||
qCritical("empty profile directory result");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TlsCertificate::runTool(const QStringList &args) {
|
bool TlsCertificate::runTool(const QStringList &args) {
|
||||||
QString program;
|
QString program;
|
||||||
|
|
@ -157,21 +152,17 @@ bool TlsCertificate::runTool(const QStringList &args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TlsCertificate::generateCertificate(const QString &path, int keyLength) {
|
bool TlsCertificate::generateCertificate(const QString &path, int keyLength) {
|
||||||
QString sslDirPath =
|
qDebug("generating tls certificate: %s", qUtf8Printable(path));
|
||||||
QString("%1%2%3").arg(m_profileDir).arg(QDir::separator()).arg(kSslDir);
|
|
||||||
|
|
||||||
QString defaultPath = QString("%1%2%3")
|
QFileInfo info(path);
|
||||||
.arg(sslDirPath)
|
QDir dir(info.absolutePath());
|
||||||
.arg(QDir::separator())
|
if (!dir.exists() && !dir.mkpath(".")) {
|
||||||
.arg(kCertificateFilename);
|
qCritical("failed to create directory for tls certificate");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QString keySize = kCertificateKeyLength + QString::number(keyLength);
|
QString keySize = kCertificateKeyLength + QString::number(keyLength);
|
||||||
|
|
||||||
const QString pathToUse =
|
|
||||||
QDir::cleanPath(path.isEmpty() ? defaultPath : path);
|
|
||||||
|
|
||||||
qDebug("generating tls certificate: %s", qUtf8Printable(pathToUse));
|
|
||||||
|
|
||||||
QStringList arguments;
|
QStringList arguments;
|
||||||
|
|
||||||
// self signed certificate
|
// self signed certificate
|
||||||
|
|
@ -179,7 +170,7 @@ bool TlsCertificate::generateCertificate(const QString &path, int keyLength) {
|
||||||
arguments.append("-x509");
|
arguments.append("-x509");
|
||||||
arguments.append("-nodes");
|
arguments.append("-nodes");
|
||||||
|
|
||||||
// valide duration
|
// valid duration
|
||||||
arguments.append("-days");
|
arguments.append("-days");
|
||||||
arguments.append(kCertificateLifetime);
|
arguments.append(kCertificateLifetime);
|
||||||
|
|
||||||
|
|
@ -193,22 +184,18 @@ bool TlsCertificate::generateCertificate(const QString &path, int keyLength) {
|
||||||
arguments.append("-newkey");
|
arguments.append("-newkey");
|
||||||
arguments.append(keySize);
|
arguments.append(keySize);
|
||||||
|
|
||||||
if (QDir sslDir(sslDirPath); !sslDir.exists()) {
|
|
||||||
sslDir.mkpath(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
// key output filename
|
// key output filename
|
||||||
arguments.append("-keyout");
|
arguments.append("-keyout");
|
||||||
arguments.append(pathToUse);
|
arguments.append(path);
|
||||||
|
|
||||||
// certificate output filename
|
// certificate output filename
|
||||||
arguments.append("-out");
|
arguments.append("-out");
|
||||||
arguments.append(pathToUse);
|
arguments.append(path);
|
||||||
|
|
||||||
if (runTool(arguments)) {
|
if (runTool(arguments)) {
|
||||||
qDebug("tls certificate generated");
|
qDebug("tls certificate generated");
|
||||||
|
|
||||||
return generateFingerprint(pathToUse);
|
return generateFingerprint(path);
|
||||||
} else {
|
} else {
|
||||||
qCritical("failed to generate tls certificate");
|
qCritical("failed to generate tls certificate");
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ private:
|
||||||
bool generateFingerprint(const QString &certificateFilename);
|
bool generateFingerprint(const QString &certificateFilename);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_profileDir;
|
|
||||||
QString m_toolStdout;
|
QString m_toolStdout;
|
||||||
[[no_unique_address]] CoreTool m_coreTool;
|
[[no_unique_address]] CoreTool m_coreTool;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,13 @@
|
||||||
#include "TlsCertificate.h"
|
#include "TlsCertificate.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
namespace synergy::gui {
|
namespace synergy::gui {
|
||||||
|
|
||||||
TlsUtility::TlsUtility(
|
TlsUtility::TlsUtility(
|
||||||
const IAppConfig &appConfig, const license::License &license)
|
const IAppConfig &appConfig, const license::ILicense &license)
|
||||||
: m_appConfig(appConfig),
|
: m_appConfig(appConfig),
|
||||||
m_license(license) {}
|
m_license(license) {}
|
||||||
|
|
||||||
|
|
@ -48,10 +49,20 @@ bool TlsUtility::generateCertificate() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto path = m_appConfig.tlsCertPath();
|
|
||||||
auto length = m_appConfig.tlsKeyLength();
|
auto length = m_appConfig.tlsKeyLength();
|
||||||
|
|
||||||
return m_certificate.generateCertificate(path, length);
|
return m_certificate.generateCertificate(m_appConfig.tlsCertPath(), length);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TlsUtility::persistCertificate() {
|
||||||
|
qDebug("persisting tls certificate");
|
||||||
|
|
||||||
|
if (QFile::exists(m_appConfig.tlsCertPath())) {
|
||||||
|
qDebug("tls certificate already exists");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return generateCertificate();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace synergy::gui
|
} // namespace synergy::gui
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,10 @@ class TlsUtility : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TlsUtility(
|
explicit TlsUtility(
|
||||||
const IAppConfig &appConfig, const license::License &license);
|
const IAppConfig &appConfig, const license::ILicense &license);
|
||||||
|
|
||||||
bool generateCertificate();
|
bool generateCertificate();
|
||||||
|
bool persistCertificate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Combines the availability and the enabled status of TLS.
|
* @brief Combines the availability and the enabled status of TLS.
|
||||||
|
|
@ -51,7 +52,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const IAppConfig &m_appConfig;
|
const IAppConfig &m_appConfig;
|
||||||
const license::License &m_license;
|
const license::ILicense &m_license;
|
||||||
TlsCertificate m_certificate;
|
TlsCertificate m_certificate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
32
src/lib/license/ILicense.h
Normal file
32
src/lib/license/ILicense.h
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* synergy -- mouse and keyboard sharing utility
|
||||||
|
* Copyright (C) 2016 Symless Ltd.
|
||||||
|
*
|
||||||
|
* This package is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* found in the file LICENSE that should have accompanied this file.
|
||||||
|
*
|
||||||
|
* This package is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class Server;
|
||||||
|
class LicenseHandler;
|
||||||
|
class LicenseTests;
|
||||||
|
|
||||||
|
namespace synergy::license {
|
||||||
|
|
||||||
|
class ILicense {
|
||||||
|
public:
|
||||||
|
virtual ~ILicense() = default;
|
||||||
|
virtual bool isTlsAvailable() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace synergy::license
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "ILicense.h"
|
||||||
#include "SerialKey.h"
|
#include "SerialKey.h"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
@ -30,7 +31,7 @@ class LicenseTests;
|
||||||
|
|
||||||
namespace synergy::license {
|
namespace synergy::license {
|
||||||
|
|
||||||
class License {
|
class License : public ILicense {
|
||||||
friend class ::Server;
|
friend class ::Server;
|
||||||
friend class ::LicenseHandler;
|
friend class ::LicenseHandler;
|
||||||
friend class ::LicenseTests;
|
friend class ::LicenseTests;
|
||||||
|
|
@ -44,18 +45,20 @@ class License {
|
||||||
public:
|
public:
|
||||||
explicit License(const SerialKey &serialKey);
|
explicit License(const SerialKey &serialKey);
|
||||||
explicit License(const std::string &hexString);
|
explicit License(const std::string &hexString);
|
||||||
|
~License() override = default;
|
||||||
|
|
||||||
friend bool operator==(License const &lhs, License const &rhs) {
|
friend bool operator==(License const &lhs, License const &rhs) {
|
||||||
return lhs.m_serialKey == rhs.m_serialKey;
|
return lhs.m_serialKey == rhs.m_serialKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isTlsAvailable() const override;
|
||||||
|
|
||||||
bool isValid() const { return m_serialKey.isValid; }
|
bool isValid() const { return m_serialKey.isValid; }
|
||||||
bool isExpiringSoon() const;
|
bool isExpiringSoon() const;
|
||||||
bool isExpired() const;
|
bool isExpired() const;
|
||||||
bool isTrial() const;
|
bool isTrial() const;
|
||||||
bool isSubscription() const;
|
bool isSubscription() const;
|
||||||
bool isTimeLimited() const;
|
bool isTimeLimited() const;
|
||||||
bool isTlsAvailable() const;
|
|
||||||
days daysLeft() const;
|
days daysLeft() const;
|
||||||
Edition productEdition() const;
|
Edition productEdition() const;
|
||||||
std::string productName() const;
|
std::string productName() const;
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ IDataSocket *SecureServerSocket::accept() {
|
||||||
socket->initSsl(true);
|
socket->initSsl(true);
|
||||||
setListeningJob();
|
setListeningJob();
|
||||||
|
|
||||||
auto certificateFilename = getCertifcateFileName();
|
auto certificateFilename = getCertificateFileName();
|
||||||
if (socket->loadCertificates(certificateFilename)) {
|
if (socket->loadCertificates(certificateFilename)) {
|
||||||
socket->secureAccept();
|
socket->secureAccept();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -64,7 +64,7 @@ IDataSocket *SecureServerSocket::accept() {
|
||||||
return dynamic_cast<IDataSocket *>(socket);
|
return dynamic_cast<IDataSocket *>(socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SecureServerSocket::getCertifcateFileName() const {
|
std::string SecureServerSocket::getCertificateFileName() const {
|
||||||
// if the tls cert option is set use that for the certificate file
|
// if the tls cert option is set use that for the certificate file
|
||||||
auto certificateFilename = ArgParser::argsBase().m_tlsCertFile;
|
auto certificateFilename = ArgParser::argsBase().m_tlsCertFile;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,5 +27,5 @@ public:
|
||||||
IDataSocket *accept() override;
|
IDataSocket *accept() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string getCertifcateFileName() const;
|
std::string getCertificateFileName() const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -48,12 +48,12 @@ public:
|
||||||
MOCK_METHOD(bool, isActiveScopeWritable, (), (const, override));
|
MOCK_METHOD(bool, isActiveScopeWritable, (), (const, override));
|
||||||
MOCK_METHOD(const QSettingsProxy &, activeSettings, (), (const, override));
|
MOCK_METHOD(const QSettingsProxy &, activeSettings, (), (const, override));
|
||||||
MOCK_METHOD(QSettingsProxy &, activeSettings, (), (override));
|
MOCK_METHOD(QSettingsProxy &, activeSettings, (), (override));
|
||||||
MOCK_METHOD(void, save, (), (override));
|
MOCK_METHOD(void, save, (bool), (override));
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DepsMock : public AppConfig::Deps {
|
struct DepsMock : public AppConfig::Deps {
|
||||||
DepsMock() {
|
DepsMock() {
|
||||||
ON_CALL(*this, profileDir()).WillByDefault(Return("stub"));
|
ON_CALL(*this, defaultTlsCertPath()).WillByDefault(Return("stub"));
|
||||||
ON_CALL(*this, hostname()).WillByDefault(Return("stub"));
|
ON_CALL(*this, hostname()).WillByDefault(Return("stub"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ struct DepsMock : public AppConfig::Deps {
|
||||||
return std::make_shared<NiceMock<DepsMock>>();
|
return std::make_shared<NiceMock<DepsMock>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
MOCK_METHOD(QString, profileDir, (), (const, override));
|
MOCK_METHOD(QString, defaultTlsCertPath, (), (const, override));
|
||||||
MOCK_METHOD(QString, hostname, (), (const, override));
|
MOCK_METHOD(QString, hostname, (), (const, override));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,7 @@ struct DepsMock : public ConfigScopes::Deps {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST(ConfigScopesTests, ctor_callsMakeUserSettings) {
|
TEST(ConfigScopesTests, ctor_callsMakeUserSettings) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
EXPECT_CALL(*deps, makeUserSettings()).Times(1);
|
EXPECT_CALL(*deps, makeUserSettings()).Times(1);
|
||||||
|
|
||||||
|
|
@ -72,8 +71,7 @@ TEST(ConfigScopesTests, ctor_callsMakeUserSettings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ConfigScopesTests, ctor_callsMakeSystemSettings) {
|
TEST(ConfigScopesTests, ctor_callsMakeSystemSettings) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
EXPECT_CALL(*deps, makeSystemSettings()).Times(1);
|
EXPECT_CALL(*deps, makeSystemSettings()).Times(1);
|
||||||
|
|
||||||
|
|
@ -81,8 +79,7 @@ TEST(ConfigScopesTests, ctor_callsMakeSystemSettings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ConfigScopesTests, save_syncsBothScopes) {
|
TEST(ConfigScopesTests, save_syncsBothScopes) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
ConfigScopes configScopes(deps);
|
ConfigScopes configScopes(deps);
|
||||||
|
|
||||||
|
|
@ -93,8 +90,7 @@ TEST(ConfigScopesTests, save_syncsBothScopes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ConfigScopesTests, activeSettings_returnsUserSettingsByDefault) {
|
TEST(ConfigScopesTests, activeSettings_returnsUserSettingsByDefault) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
ConfigScopes configScopes(deps);
|
ConfigScopes configScopes(deps);
|
||||||
|
|
||||||
|
|
@ -102,8 +98,7 @@ TEST(ConfigScopesTests, activeSettings_returnsUserSettingsByDefault) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ConfigScopesTests, activeSettings_returnsSystemSettingsWhenSystemScope) {
|
TEST(ConfigScopesTests, activeSettings_returnsSystemSettingsWhenSystemScope) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
ConfigScopes configScopes(deps);
|
ConfigScopes configScopes(deps);
|
||||||
configScopes.setActiveScope(ConfigScopes::Scope::System);
|
configScopes.setActiveScope(ConfigScopes::Scope::System);
|
||||||
|
|
@ -112,8 +107,7 @@ TEST(ConfigScopesTests, activeSettings_returnsSystemSettingsWhenSystemScope) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ConfigScopesTests, setActiveScope_setsCurrentScope) {
|
TEST(ConfigScopesTests, setActiveScope_setsCurrentScope) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
ConfigScopes configScopes(deps);
|
ConfigScopes configScopes(deps);
|
||||||
|
|
||||||
|
|
@ -125,8 +119,7 @@ TEST(ConfigScopesTests, setActiveScope_setsCurrentScope) {
|
||||||
TEST(
|
TEST(
|
||||||
ConfigScopesTests,
|
ConfigScopesTests,
|
||||||
isActiveScopeWritable_returnsTrueWhenUserSettingsWritable) {
|
isActiveScopeWritable_returnsTrueWhenUserSettingsWritable) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
ConfigScopes configScopes(deps);
|
ConfigScopes configScopes(deps);
|
||||||
|
|
||||||
|
|
@ -138,8 +131,7 @@ TEST(
|
||||||
TEST(
|
TEST(
|
||||||
ConfigScopesTests,
|
ConfigScopesTests,
|
||||||
scopeContains_byDefault_returnsTrueWhenUserSettingsContainsKey) {
|
scopeContains_byDefault_returnsTrueWhenUserSettingsContainsKey) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
ON_CALL(*deps->m_pUserSettings, contains(_)).WillByDefault(Return(true));
|
ON_CALL(*deps->m_pUserSettings, contains(_)).WillByDefault(Return(true));
|
||||||
|
|
||||||
|
|
@ -151,8 +143,7 @@ TEST(
|
||||||
TEST(
|
TEST(
|
||||||
ConfigScopesTests,
|
ConfigScopesTests,
|
||||||
scopeContains_userScope_returnsTrueWhenUserSettingsContainsKey) {
|
scopeContains_userScope_returnsTrueWhenUserSettingsContainsKey) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
ON_CALL(*deps->m_pUserSettings, contains(_)).WillByDefault(Return(true));
|
ON_CALL(*deps->m_pUserSettings, contains(_)).WillByDefault(Return(true));
|
||||||
|
|
||||||
|
|
@ -164,8 +155,7 @@ TEST(
|
||||||
TEST(
|
TEST(
|
||||||
ConfigScopesTests,
|
ConfigScopesTests,
|
||||||
scopeContains_systemScope_returnsTrueWhenSystemSettingsContainsKey) {
|
scopeContains_systemScope_returnsTrueWhenSystemSettingsContainsKey) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
ON_CALL(*deps->m_pSystemSettings, contains(_)).WillByDefault(Return(true));
|
ON_CALL(*deps->m_pSystemSettings, contains(_)).WillByDefault(Return(true));
|
||||||
|
|
||||||
|
|
@ -175,8 +165,7 @@ TEST(
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ConfigScopesTests, activeFilePath_returnsUserSettingsFileNameByDefault) {
|
TEST(ConfigScopesTests, activeFilePath_returnsUserSettingsFileNameByDefault) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
ON_CALL(*deps->m_pUserSettings, fileName()).WillByDefault(Return("test"));
|
ON_CALL(*deps->m_pUserSettings, fileName()).WillByDefault(Return("test"));
|
||||||
|
|
||||||
ConfigScopes configScopes(deps);
|
ConfigScopes configScopes(deps);
|
||||||
|
|
@ -185,8 +174,7 @@ TEST(ConfigScopesTests, activeFilePath_returnsUserSettingsFileNameByDefault) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ConfigScopesTests, getFromScope_byDefault_returnsValueFromActiveSettings) {
|
TEST(ConfigScopesTests, getFromScope_byDefault_returnsValueFromActiveSettings) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
ON_CALL(*deps->m_pUserSettings, value(_, _)).WillByDefault(Return("test"));
|
ON_CALL(*deps->m_pUserSettings, value(_, _)).WillByDefault(Return("test"));
|
||||||
|
|
||||||
ConfigScopes configScopes(deps);
|
ConfigScopes configScopes(deps);
|
||||||
|
|
@ -195,8 +183,7 @@ TEST(ConfigScopesTests, getFromScope_byDefault_returnsValueFromActiveSettings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ConfigScopesTests, setInScope_byDefault_setsValueInActiveSettings) {
|
TEST(ConfigScopesTests, setInScope_byDefault_setsValueInActiveSettings) {
|
||||||
std::shared_ptr<NiceMock<DepsMock>> deps =
|
auto deps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
|
||||||
|
|
||||||
ConfigScopes configScopes(deps);
|
ConfigScopes configScopes(deps);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "gui/core/CoreProcess.h"
|
#include "gui/core/CoreProcess.h"
|
||||||
#include "gui/ipc/IQIpcClient.h"
|
#include "gui/ipc/IQIpcClient.h"
|
||||||
#include "gui/proxy/QProcessProxy.h"
|
#include "gui/proxy/QProcessProxy.h"
|
||||||
|
#include "license/ILicense.h"
|
||||||
#include "shared/gui/mocks/AppConfigMock.h"
|
#include "shared/gui/mocks/AppConfigMock.h"
|
||||||
#include "shared/gui/mocks/ServerConfigMock.h"
|
#include "shared/gui/mocks/ServerConfigMock.h"
|
||||||
|
|
||||||
|
|
@ -27,10 +28,8 @@
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
using namespace synergy::gui;
|
using namespace synergy::gui;
|
||||||
using ::testing::_;
|
using namespace synergy::license;
|
||||||
using ::testing::NiceMock;
|
using namespace testing;
|
||||||
using ::testing::Return;
|
|
||||||
using ::testing::ReturnRef;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
@ -92,12 +91,23 @@ public:
|
||||||
NiceMock<QIpcClientMock> m_ipcClient;
|
NiceMock<QIpcClientMock> m_ipcClient;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CoreProcessTests : public ::testing::Test {
|
class LicenseMock : public ILicense {
|
||||||
public:
|
public:
|
||||||
CoreProcessTests() : m_coreProcess(m_appConfig, m_serverConfig, m_pDeps) {}
|
LicenseMock() {
|
||||||
|
ON_CALL(*this, isTlsAvailable()).WillByDefault(Return(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
MOCK_METHOD(bool, isTlsAvailable, (), (const, override));
|
||||||
|
};
|
||||||
|
|
||||||
|
class CoreProcessTests : public Test {
|
||||||
|
public:
|
||||||
|
CoreProcessTests()
|
||||||
|
: m_coreProcess(m_appConfig, m_serverConfig, m_license, m_pDeps) {}
|
||||||
|
|
||||||
NiceMock<AppConfigMock> m_appConfig;
|
NiceMock<AppConfigMock> m_appConfig;
|
||||||
NiceMock<ServerConfigMock> m_serverConfig;
|
NiceMock<ServerConfigMock> m_serverConfig;
|
||||||
|
NiceMock<LicenseMock> m_license;
|
||||||
std::shared_ptr<NiceMock<DepsMock>> m_pDeps =
|
std::shared_ptr<NiceMock<DepsMock>> m_pDeps =
|
||||||
std::make_shared<NiceMock<DepsMock>>();
|
std::make_shared<NiceMock<DepsMock>>();
|
||||||
CoreProcess m_coreProcess;
|
CoreProcess m_coreProcess;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "gui/config/ServerConfigDialogState.h"
|
||||||
#include "gui/core/ServerConnection.h"
|
#include "gui/core/ServerConnection.h"
|
||||||
|
|
||||||
#include "shared/gui/mocks/AppConfigMock.h"
|
#include "shared/gui/mocks/AppConfigMock.h"
|
||||||
|
|
@ -45,11 +46,12 @@ public:
|
||||||
std::shared_ptr<DepsMock> m_pDeps = std::make_shared<NiceMock<DepsMock>>();
|
std::shared_ptr<DepsMock> m_pDeps = std::make_shared<NiceMock<DepsMock>>();
|
||||||
NiceMock<AppConfigMock> m_appConfig;
|
NiceMock<AppConfigMock> m_appConfig;
|
||||||
NiceMock<ServerConfigMock> m_serverConfig;
|
NiceMock<ServerConfigMock> m_serverConfig;
|
||||||
|
config::ServerConfigDialogState m_serverConfigDialogState;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(ServerConnectionTests, handleLogLine_newClient_shouldShowPrompt) {
|
TEST_F(ServerConnectionTests, handleLogLine_newClient_shouldShowPrompt) {
|
||||||
ServerConnection serverConnection(
|
ServerConnection serverConnection(
|
||||||
nullptr, m_appConfig, m_serverConfig, m_pDeps);
|
nullptr, m_appConfig, m_serverConfig, m_serverConfigDialogState, m_pDeps);
|
||||||
|
|
||||||
QString clientName = "test client";
|
QString clientName = "test client";
|
||||||
EXPECT_CALL(*m_pDeps, showNewClientPrompt(_, clientName));
|
EXPECT_CALL(*m_pDeps, showNewClientPrompt(_, clientName));
|
||||||
|
|
@ -59,7 +61,7 @@ TEST_F(ServerConnectionTests, handleLogLine_newClient_shouldShowPrompt) {
|
||||||
|
|
||||||
TEST_F(ServerConnectionTests, handleLogLine_ignoredClient_shouldNotShowPrompt) {
|
TEST_F(ServerConnectionTests, handleLogLine_ignoredClient_shouldNotShowPrompt) {
|
||||||
ServerConnection serverConnection(
|
ServerConnection serverConnection(
|
||||||
nullptr, m_appConfig, m_serverConfig, m_pDeps);
|
nullptr, m_appConfig, m_serverConfig, m_serverConfigDialogState, m_pDeps);
|
||||||
ON_CALL(*m_pDeps, showNewClientPrompt(_, _))
|
ON_CALL(*m_pDeps, showNewClientPrompt(_, _))
|
||||||
.WillByDefault(testing::Return(messages::NewClientPromptResult::Ignore));
|
.WillByDefault(testing::Return(messages::NewClientPromptResult::Ignore));
|
||||||
serverConnection.handleLogLine(R"(unrecognised client name "stub")");
|
serverConnection.handleLogLine(R"(unrecognised client name "stub")");
|
||||||
|
|
@ -72,7 +74,7 @@ TEST_F(ServerConnectionTests, handleLogLine_ignoredClient_shouldNotShowPrompt) {
|
||||||
TEST_F(
|
TEST_F(
|
||||||
ServerConnectionTests, handleLogLine_serverConfigFull_shouldNotShowPrompt) {
|
ServerConnectionTests, handleLogLine_serverConfigFull_shouldNotShowPrompt) {
|
||||||
ServerConnection serverConnection(
|
ServerConnection serverConnection(
|
||||||
nullptr, m_appConfig, m_serverConfig, m_pDeps);
|
nullptr, m_appConfig, m_serverConfig, m_serverConfigDialogState, m_pDeps);
|
||||||
ON_CALL(m_serverConfig, isFull()).WillByDefault(testing::Return(true));
|
ON_CALL(m_serverConfig, isFull()).WillByDefault(testing::Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(*m_pDeps, showNewClientPrompt(_, _)).Times(0);
|
EXPECT_CALL(*m_pDeps, showNewClientPrompt(_, _)).Times(0);
|
||||||
|
|
@ -82,7 +84,7 @@ TEST_F(
|
||||||
|
|
||||||
TEST_F(ServerConnectionTests, handleLogLine_screenExists_shouldNotShowPrompt) {
|
TEST_F(ServerConnectionTests, handleLogLine_screenExists_shouldNotShowPrompt) {
|
||||||
ServerConnection serverConnection(
|
ServerConnection serverConnection(
|
||||||
nullptr, m_appConfig, m_serverConfig, m_pDeps);
|
nullptr, m_appConfig, m_serverConfig, m_serverConfigDialogState, m_pDeps);
|
||||||
ON_CALL(m_serverConfig, screenExists(_)).WillByDefault(testing::Return(true));
|
ON_CALL(m_serverConfig, screenExists(_)).WillByDefault(testing::Return(true));
|
||||||
|
|
||||||
EXPECT_CALL(*m_pDeps, showNewClientPrompt(_, _)).Times(0);
|
EXPECT_CALL(*m_pDeps, showNewClientPrompt(_, _)).Times(0);
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ TEST(SettingsDialogTests, ctor_getsScreenName) {
|
||||||
serialKey.isValid = true;
|
serialKey.isValid = true;
|
||||||
License license(serialKey);
|
License license(serialKey);
|
||||||
auto cpDeps = std::make_shared<CoreProcess::Deps>();
|
auto cpDeps = std::make_shared<CoreProcess::Deps>();
|
||||||
CoreProcess coreProcess(appConfig, serverConfig, cpDeps);
|
CoreProcess coreProcess(appConfig, serverConfig, license, cpDeps);
|
||||||
|
|
||||||
EXPECT_CALL(appConfig, screenName()).Times(1);
|
EXPECT_CALL(appConfig, screenName()).Times(1);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue