diff --git a/scwx-qt/source/scwx/qt/main/main.cpp b/scwx-qt/source/scwx/qt/main/main.cpp index 468aa1e6..4212050e 100644 --- a/scwx-qt/source/scwx/qt/main/main.cpp +++ b/scwx-qt/source/scwx/qt/main/main.cpp @@ -46,9 +46,6 @@ static void OverrideDefaultStyle(const std::vector& args); int main(int argc, char* argv[]) { - bool disableHighPrivilegeWarning = false; - bool highPrivilegeChecked = false; - // Store arguments std::vector args {}; for (int i = 0; i < argc; ++i) @@ -85,27 +82,10 @@ int main(int argc, char* argv[]) } // Test to see if scwx was run with high privilege - const std::string appDataPath { - QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) - .toStdString()}; - - // Check if high privilege before writing settings, assuming no settings - // have been written - if (!std::filesystem::exists(appDataPath) && - scwx::qt::util::is_high_privilege()) + scwx::qt::util::PrivilegeChecker privilegeChecker; + if (privilegeChecker.first_check()) { - auto dialog = - scwx::qt::ui::HighPrivilegeDialog(); // TODO does this need cleaned up? - const int result = dialog.exec(); - - disableHighPrivilegeWarning = dialog.disable_high_privilege_message(); - highPrivilegeChecked = true; - - if (result == QDialog::Rejected) - { - // TODO any other cleanup needed here? - return 0; - } + return 0; } // Start the io_context main loop @@ -146,61 +126,28 @@ int main(int argc, char* argv[]) // Check process modules for compatibility scwx::qt::main::CheckProcessModules(); - auto& generalSettings = scwx::qt::settings::GeneralSettings::Instance(); - if (!highPrivilegeChecked && - generalSettings.high_privilege_warning_enabled().GetValue() && - scwx::qt::util::is_high_privilege()) + int result = 0; + if (privilegeChecker.second_check()) { - auto dialog = - scwx::qt::ui::HighPrivilegeDialog(); // TODO does this need cleaned up? - const int result = dialog.exec(); - - disableHighPrivilegeWarning = dialog.disable_high_privilege_message(); - - if (result == QDialog::Rejected) + result = 1; + } + else + { + // Run initial setup if required + if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired()) { - // Deinitialize application - scwx::qt::manager::RadarProductManager::Cleanup(); - - // Stop Qt Threads - scwx::qt::manager::ThreadManager::Instance().StopThreads(); - - // Gracefully stop the io_context main loop - work.reset(); - threadPool.join(); - - // Shutdown application - scwx::qt::manager::ResourceManager::Shutdown(); - scwx::qt::manager::SettingsManager::Instance().Shutdown(); - - // Shutdown AWS SDK - Aws::ShutdownAPI(awsSdkOptions); - return 0; + scwx::qt::ui::setup::SetupWizard w; + w.show(); + a.exec(); } - } - // Save high privilege settings - if (disableHighPrivilegeWarning) - { - generalSettings.high_privilege_warning_enabled().SetValue(false); - scwx::qt::manager::SettingsManager::Instance().SaveSettings(); - } - - // Run initial setup if required - if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired()) - { - scwx::qt::ui::setup::SetupWizard w; - w.show(); - a.exec(); - } - - // Run Qt main loop - int result; - { - scwx::qt::main::MainWindow w; - w.show(); - result = a.exec(); + // Run Qt main loop + { + scwx::qt::main::MainWindow w; + w.show(); + result = a.exec(); + } } // Deinitialize application diff --git a/scwx-qt/source/scwx/qt/settings/general_settings.cpp b/scwx-qt/source/scwx/qt/settings/general_settings.cpp index 0abb45e9..6f254c6b 100644 --- a/scwx-qt/source/scwx/qt/settings/general_settings.cpp +++ b/scwx-qt/source/scwx/qt/settings/general_settings.cpp @@ -394,6 +394,7 @@ bool GeneralSettings::Shutdown() dataChanged |= p->loopTime_.Commit(); dataChanged |= p->processModuleWarningsEnabled_.Commit(); dataChanged |= p->trackLocation_.Commit(); + dataChanged |= p->highPrivilegeWarningEnabled_.Commit(); return dataChanged; } diff --git a/scwx-qt/source/scwx/qt/util/check_privilege.cpp b/scwx-qt/source/scwx/qt/util/check_privilege.cpp index 2d7d1227..62a4c4d0 100644 --- a/scwx-qt/source/scwx/qt/util/check_privilege.cpp +++ b/scwx-qt/source/scwx/qt/util/check_privilege.cpp @@ -1,5 +1,11 @@ +#include "scwx/qt/settings/general_settings.hpp" #include "scwx/qt/util/check_privilege.hpp" #include +#include +#include +#include +#include +#include #ifdef _WIN32 # include @@ -7,11 +13,7 @@ # include #endif -namespace scwx -{ -namespace qt -{ -namespace util +namespace scwx::qt::util { bool is_high_privilege() @@ -38,9 +40,95 @@ bool is_high_privilege() #elif defined(Q_OS_UNIX) // On UNIX root is always uid 0. On Linux this is enforced by the kernel. return geteuid() == 0; +#else + return false; #endif } -} // namespace util -} // namespace qt -} // namespace scwx +#if defined(_WIN32) +static const QString message = QObject::tr( + "Supercell Wx has been run with administrator permissions. It is " + "recommended to run it without administrator permissions Do you wish to " + "continue?"); +#elif defined(Q_OS_UNIX) +static const QString message = QObject::tr( + "Supercell Wx has been run as root. It is recommended to run it as a normal " + "user. Do you wish to continue?"); +#else +static const QString message = QObject::tr(""); +#endif + +static const QString title = QObject::tr("Supercell Wx"); +static const QString checkBoxText = + QObject::tr("Do not show this warning again."); + +class PrivilegeChecker::Impl +{ +public: + explicit Impl() : + highPrivilege_ {is_high_privilege()}, + dialog_ {QMessageBox::Icon::Warning, title, message}, + checkBox_(new QCheckBox(checkBoxText, &dialog_)) + { + const std::string appDataPath { + QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + .toStdString()}; + hasAppData_ = std::filesystem::exists(appDataPath); + + dialog_.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + dialog_.setCheckBox(checkBox_); + }; + + bool hasAppData_; + bool firstCheckCheckBoxState_ {true}; + bool highPrivilege_; + + QMessageBox dialog_; + QCheckBox* checkBox_; +}; + +PrivilegeChecker::PrivilegeChecker() : p(std::make_unique()) +{ +} + +PrivilegeChecker::~PrivilegeChecker() = default; + +bool PrivilegeChecker::first_check() +{ + if (p->hasAppData_ || !p->highPrivilege_) + { + return false; + } + + int result = p->dialog_.exec(); + p->firstCheckCheckBoxState_ = p->checkBox_->isChecked(); + + return result != QMessageBox::Yes; +} + +bool PrivilegeChecker::second_check() +{ + auto& highPrivilegeWarningEnabled = + settings::GeneralSettings::Instance().high_privilege_warning_enabled(); + if (!highPrivilegeWarningEnabled.GetValue() || !p->highPrivilege_) + { + return false; + } + else if (!p->hasAppData_) + { + highPrivilegeWarningEnabled.StageValue(!p->firstCheckCheckBoxState_); + return false; + } + + switch (p->dialog_.exec()) + { + case QMessageBox::Yes: + highPrivilegeWarningEnabled.StageValue(!p->checkBox_->isChecked()); + return false; + case QMessageBox::No: + default: + return true; + } +} + +} // namespace scwx::qt::util diff --git a/scwx-qt/source/scwx/qt/util/check_privilege.hpp b/scwx-qt/source/scwx/qt/util/check_privilege.hpp index 7a44a070..7935e54a 100644 --- a/scwx-qt/source/scwx/qt/util/check_privilege.hpp +++ b/scwx-qt/source/scwx/qt/util/check_privilege.hpp @@ -1,14 +1,25 @@ #pragma once -namespace scwx -{ -namespace qt -{ -namespace util +#include + +namespace scwx::qt::util { bool is_high_privilege(); -} // namespace util -} // namespace qt -} // namespace scwx +class PrivilegeChecker +{ +public: + explicit PrivilegeChecker(); + ~PrivilegeChecker(); + + // returning true means check failed. + bool first_check(); + bool second_check(); + +private: + class Impl; + std::unique_ptr p; +}; + +} // namespace scwx::qt::util