mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 00:30:05 +00:00 
			
		
		
		
	Merge pull request #324 from AdenKoperczak/high_privilege_warning
High privilege warning
This commit is contained in:
		
						commit
						6ef24bf4ed
					
				
					 7 changed files with 210 additions and 14 deletions
				
			
		|  | @ -51,9 +51,11 @@ find_package(Qt${QT_VERSION_MAJOR} | |||
| set(SRC_EXE_MAIN source/scwx/qt/main/main.cpp) | ||||
| 
 | ||||
| set(HDR_MAIN source/scwx/qt/main/application.hpp | ||||
|              source/scwx/qt/main/check_privilege.hpp | ||||
|              source/scwx/qt/main/main_window.hpp | ||||
|              source/scwx/qt/main/process_validation.hpp) | ||||
| set(SRC_MAIN source/scwx/qt/main/application.cpp | ||||
|              source/scwx/qt/main/check_privilege.cpp | ||||
|              source/scwx/qt/main/main_window.cpp | ||||
|              source/scwx/qt/main/process_validation.cpp) | ||||
| set(UI_MAIN  source/scwx/qt/main/main_window.ui) | ||||
|  |  | |||
							
								
								
									
										136
									
								
								scwx-qt/source/scwx/qt/main/check_privilege.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								scwx-qt/source/scwx/qt/main/check_privilege.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,136 @@ | |||
| #include <scwx/qt/settings/general_settings.hpp> | ||||
| #include <scwx/qt/main/check_privilege.hpp> | ||||
| #include <QtGlobal> | ||||
| #include <QStandardPaths> | ||||
| #include <filesystem> | ||||
| #include <QObject> | ||||
| #include <QMessageBox> | ||||
| #include <QCheckBox> | ||||
| 
 | ||||
| #ifdef _WIN32 | ||||
| #   include <windows.h> | ||||
| #else | ||||
| #   include <unistd.h> | ||||
| #endif | ||||
| 
 | ||||
| namespace scwx::qt::main | ||||
| { | ||||
| 
 | ||||
| bool is_high_privilege() | ||||
| { | ||||
| #if defined(_WIN32) | ||||
|    bool            isAdmin = false; | ||||
|    HANDLE          token   = NULL; | ||||
|    TOKEN_ELEVATION elevation; | ||||
|    DWORD           elevationSize = sizeof(TOKEN_ELEVATION); | ||||
| 
 | ||||
|    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) | ||||
|    { | ||||
|       return false; | ||||
|    } | ||||
|    if (!GetTokenInformation( | ||||
|           token, TokenElevation, &elevation, elevationSize, &elevationSize)) | ||||
|    { | ||||
|       CloseHandle(token); | ||||
|       return false; | ||||
|    } | ||||
|    isAdmin = elevation.TokenIsElevated; | ||||
|    CloseHandle(token); | ||||
|    return isAdmin; | ||||
| #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 | ||||
| } | ||||
| 
 | ||||
| #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_.setDefaultButton(QMessageBox::No); | ||||
|       dialog_.setCheckBox(checkBox_); | ||||
|    }; | ||||
| 
 | ||||
|    bool hasAppData_; | ||||
|    bool firstCheckCheckBoxState_ {true}; | ||||
|    bool highPrivilege_; | ||||
| 
 | ||||
|    QMessageBox dialog_; | ||||
|    QCheckBox*  checkBox_; | ||||
| }; | ||||
| 
 | ||||
| PrivilegeChecker::PrivilegeChecker() : | ||||
|     p(std::make_unique<PrivilegeChecker::Impl>()) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| PrivilegeChecker::~PrivilegeChecker() = default; | ||||
| 
 | ||||
| bool PrivilegeChecker::pre_settings_check() | ||||
| { | ||||
|    if (p->hasAppData_ || !p->highPrivilege_) | ||||
|    { | ||||
|       return false; | ||||
|    } | ||||
| 
 | ||||
|    const int result            = p->dialog_.exec(); | ||||
|    p->firstCheckCheckBoxState_ = p->checkBox_->isChecked(); | ||||
| 
 | ||||
|    return result != QMessageBox::Yes; | ||||
| } | ||||
| 
 | ||||
| bool PrivilegeChecker::post_settings_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::main
 | ||||
							
								
								
									
										30
									
								
								scwx-qt/source/scwx/qt/main/check_privilege.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								scwx-qt/source/scwx/qt/main/check_privilege.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | |||
| #pragma once | ||||
| 
 | ||||
| #include <memory> | ||||
| 
 | ||||
| namespace scwx::qt::main | ||||
| { | ||||
| 
 | ||||
| bool is_high_privilege(); | ||||
| 
 | ||||
| class PrivilegeChecker | ||||
| { | ||||
| public: | ||||
|    explicit PrivilegeChecker(); | ||||
|    ~PrivilegeChecker(); | ||||
| 
 | ||||
|    PrivilegeChecker(const PrivilegeChecker&)             = delete; | ||||
|    PrivilegeChecker& operator=(const PrivilegeChecker&)  = delete; | ||||
|    PrivilegeChecker(const PrivilegeChecker&&)            = delete; | ||||
|    PrivilegeChecker& operator=(const PrivilegeChecker&&) = delete; | ||||
| 
 | ||||
|    // returning true means check failed.
 | ||||
|    bool pre_settings_check(); | ||||
|    bool post_settings_check(); | ||||
| 
 | ||||
| private: | ||||
|    class Impl; | ||||
|    std::unique_ptr<Impl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace scwx::qt::main
 | ||||
|  | @ -13,6 +13,7 @@ | |||
| #include <scwx/qt/settings/general_settings.hpp> | ||||
| #include <scwx/qt/types/qt_types.hpp> | ||||
| #include <scwx/qt/ui/setup/setup_wizard.hpp> | ||||
| #include <scwx/qt/main/check_privilege.hpp> | ||||
| #include <scwx/network/cpr.hpp> | ||||
| #include <scwx/util/environment.hpp> | ||||
| #include <scwx/util/logger.hpp> | ||||
|  | @ -78,6 +79,13 @@ int main(int argc, char* argv[]) | |||
|       QStandardPaths::setTestModeEnabled(true); | ||||
|    } | ||||
| 
 | ||||
|    // Test to see if scwx was run with high privilege
 | ||||
|    scwx::qt::main::PrivilegeChecker privilegeChecker; | ||||
|    if (privilegeChecker.pre_settings_check()) | ||||
|    { | ||||
|       return 0; | ||||
|    } | ||||
| 
 | ||||
|    // Start the io_context main loop
 | ||||
|    boost::asio::io_context& ioContext = scwx::util::io_context(); | ||||
|    auto                     work      = boost::asio::make_work_guard(ioContext); | ||||
|  | @ -117,6 +125,13 @@ int main(int argc, char* argv[]) | |||
|    // Check process modules for compatibility
 | ||||
|    scwx::qt::main::CheckProcessModules(); | ||||
| 
 | ||||
|    int result = 0; | ||||
|    if (privilegeChecker.post_settings_check()) | ||||
|    { | ||||
|       result = 1; | ||||
|    } | ||||
|    else | ||||
|    { | ||||
|       // Run initial setup if required
 | ||||
|       if (scwx::qt::ui::setup::SetupWizard::IsSetupRequired()) | ||||
|       { | ||||
|  | @ -126,12 +141,12 @@ int main(int argc, char* argv[]) | |||
|       } | ||||
| 
 | ||||
|       // Run Qt main loop
 | ||||
|    int result; | ||||
|       { | ||||
|          scwx::qt::main::MainWindow w; | ||||
|          w.show(); | ||||
|          result = a.exec(); | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    // Deinitialize application
 | ||||
|    scwx::qt::manager::RadarProductManager::Cleanup(); | ||||
|  |  | |||
|  | @ -80,6 +80,7 @@ public: | |||
|       warningsProvider_.SetDefault(defaultWarningsProviderValue); | ||||
|       cursorIconAlwaysOn_.SetDefault(false); | ||||
|       radarSiteThreshold_.SetDefault(0.0); | ||||
|       highPrivilegeWarningEnabled_.SetDefault(true); | ||||
| 
 | ||||
|       fontSizes_.SetElementMinimum(1); | ||||
|       fontSizes_.SetElementMaximum(72); | ||||
|  | @ -175,6 +176,8 @@ public: | |||
|    SettingsVariable<std::string> warningsProvider_ {"warnings_provider"}; | ||||
|    SettingsVariable<bool>        cursorIconAlwaysOn_ {"cursor_icon_always_on"}; | ||||
|    SettingsVariable<double>      radarSiteThreshold_ {"radar_site_threshold"}; | ||||
|    SettingsVariable<bool>        highPrivilegeWarningEnabled_ { | ||||
|       "high_privilege_warning_enabled"}; | ||||
| }; | ||||
| 
 | ||||
| GeneralSettings::GeneralSettings() : | ||||
|  | @ -210,7 +213,8 @@ GeneralSettings::GeneralSettings() : | |||
|                       &p->updateNotificationsEnabled_, | ||||
|                       &p->warningsProvider_, | ||||
|                       &p->cursorIconAlwaysOn_, | ||||
|                       &p->radarSiteThreshold_}); | ||||
|                       &p->radarSiteThreshold_, | ||||
|                       &p->highPrivilegeWarningEnabled_}); | ||||
|    SetDefaults(); | ||||
| } | ||||
| GeneralSettings::~GeneralSettings() = default; | ||||
|  | @ -375,6 +379,11 @@ SettingsVariable<double>& GeneralSettings::radar_site_threshold() const | |||
|    return p->radarSiteThreshold_; | ||||
| } | ||||
| 
 | ||||
| SettingsVariable<bool>& GeneralSettings::high_privilege_warning_enabled() const | ||||
| { | ||||
|    return p->highPrivilegeWarningEnabled_; | ||||
| } | ||||
| 
 | ||||
| bool GeneralSettings::Shutdown() | ||||
| { | ||||
|    bool dataChanged = false; | ||||
|  | @ -385,6 +394,7 @@ bool GeneralSettings::Shutdown() | |||
|    dataChanged |= p->loopTime_.Commit(); | ||||
|    dataChanged |= p->processModuleWarningsEnabled_.Commit(); | ||||
|    dataChanged |= p->trackLocation_.Commit(); | ||||
|    dataChanged |= p->highPrivilegeWarningEnabled_.Commit(); | ||||
| 
 | ||||
|    return dataChanged; | ||||
| } | ||||
|  | @ -429,7 +439,9 @@ bool operator==(const GeneralSettings& lhs, const GeneralSettings& rhs) | |||
|               rhs.p->updateNotificationsEnabled_ && | ||||
|            lhs.p->warningsProvider_ == rhs.p->warningsProvider_ && | ||||
|            lhs.p->cursorIconAlwaysOn_ == rhs.p->cursorIconAlwaysOn_ && | ||||
|            lhs.p->radarSiteThreshold_ == rhs.p->radarSiteThreshold_); | ||||
|            lhs.p->radarSiteThreshold_ == rhs.p->radarSiteThreshold_ && | ||||
|            lhs.p->highPrivilegeWarningEnabled_ == | ||||
|               rhs.p->highPrivilegeWarningEnabled_); | ||||
| } | ||||
| 
 | ||||
| } // namespace settings
 | ||||
|  |  | |||
|  | @ -56,6 +56,7 @@ public: | |||
|    SettingsVariable<std::string>& warnings_provider() const; | ||||
|    SettingsVariable<bool>&        cursor_icon_always_on() const; | ||||
|    SettingsVariable<double>&      radar_site_threshold() const; | ||||
|    SettingsVariable<bool>&        high_privilege_warning_enabled() const; | ||||
| 
 | ||||
|    static GeneralSettings& Instance(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1 +1 @@ | |||
| Subproject commit 24ececcd183d3b8961e5638da89f0eb36309cd6b | ||||
| Subproject commit 1f3e1259130a5eb4a6df37d721fe6c8301213e7e | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat