From 0fb63c68e9c5112815d168cb283324dd9136e691 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Wed, 18 Jun 2025 22:42:52 +0200 Subject: [PATCH] permissions: properly print config requests for plugins --- .../permissions/DynamicPermissionManager.cpp | 43 ++++++++++++++----- .../permissions/DynamicPermissionManager.hpp | 6 +++ src/plugins/PluginSystem.cpp | 8 ++-- src/plugins/PluginSystem.hpp | 3 +- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/managers/permissions/DynamicPermissionManager.cpp b/src/managers/permissions/DynamicPermissionManager.cpp index c015adfe..bfb14c59 100644 --- a/src/managers/permissions/DynamicPermissionManager.cpp +++ b/src/managers/permissions/DynamicPermissionManager.cpp @@ -69,6 +69,13 @@ static const char* permissionToHumanString(eDynamicPermissionType type) { return "error"; } +static const char* specialPidToString(eSpecialPidTypes type) { + switch (type) { + case SPECIAL_PID_TYPE_CONFIG: return "config"; + default: return ""; + } +} + static std::expected binaryNameForPid(pid_t pid) { if (pid <= 0) return std::unexpected("No pid for client"); @@ -198,17 +205,26 @@ eDynamicPermissionAllowMode CDynamicPermissionManager::clientPermissionModeWithS if (*PPERM == 0) return PERMISSION_RULE_ALLOW_MODE_ALLOW; - const auto LOOKUP = binaryNameForPid(pid); + std::optional binaryName; + std::expected lookup; - Debug::log(TRACE, "CDynamicPermissionManager::clientHasPermission: checking permission {} for key {} (binary {})", permissionToString(permission), str, - LOOKUP.has_value() ? LOOKUP.value() : "lookup failed: " + LOOKUP.error()); + if (pid > 0) { + lookup = binaryNameForPid(pid); + + Debug::log(TRACE, "CDynamicPermissionManager::clientHasPermission: checking permission {} for key {} (binary {})", permissionToString(permission), str, + lookup.has_value() ? lookup.value() : "lookup failed: " + lookup.error()); + + if (lookup.has_value()) + binaryName = *lookup; + } else + binaryName = specialPidToString((eSpecialPidTypes)pid); // first, check if we have the client + perm combo in our cache. auto it = std::ranges::find_if(m_rules, [str, permission, pid](const auto& e) { return e->m_keyString == str && pid && pid == e->m_pid && e->m_type == permission; }); if (it == m_rules.end()) { Debug::log(TRACE, "CDynamicPermissionManager::clientHasPermission: permission not cached, checking key"); - it = std::ranges::find_if(m_rules, [key = str, permission, &LOOKUP](const auto& e) { + it = std::ranges::find_if(m_rules, [key = str, permission, &lookup](const auto& e) { if (e->m_type != permission) return false; // wrong perm @@ -216,7 +232,7 @@ eDynamicPermissionAllowMode CDynamicPermissionManager::clientPermissionModeWithS return false; // no regex // regex match - if (RE2::FullMatch(key, *e->m_binaryRegex) || (LOOKUP.has_value() && RE2::FullMatch(LOOKUP.value(), *e->m_binaryRegex))) + if (RE2::FullMatch(key, *e->m_binaryRegex) || (lookup.has_value() && RE2::FullMatch(lookup.value(), *e->m_binaryRegex))) return true; return false; @@ -277,16 +293,23 @@ void CDynamicPermissionManager::askForPermission(wl_client* client, const std::s else if (client) { std::string binaryName = binaryPath.contains("/") ? binaryPath.substr(binaryPath.find_last_of('/') + 1) : binaryPath; description = std::format(std::runtime_format(permissionToHumanString(type)), std::format("{} ({})", binaryName, binaryPath)); - } else if (pid >= 0) { + } else { + std::string lookup = ""; + if (pid < 0) + lookup = specialPidToString((eSpecialPidTypes)pid); + else { + const auto LOOKUP = binaryNameForPid(pid); + lookup = LOOKUP.value_or("Unknown"); + } + if (type == PERMISSION_TYPE_PLUGIN) { const auto LOOKUP = binaryNameForPid(pid); - description = std::format(std::runtime_format(permissionToHumanString(type)), LOOKUP.value_or("Unknown"), binaryPath); + description = std::format(std::runtime_format(permissionToHumanString(type)), lookup, binaryPath); } else { const auto LOOKUP = binaryNameForPid(pid); - description = std::format(std::runtime_format(permissionToHumanString(type)), LOOKUP.value_or("Unknown"), binaryPath); + description = std::format(std::runtime_format(permissionToHumanString(type)), lookup, binaryPath); } - } else - description = std::format(std::runtime_format(permissionToHumanString(type)), binaryPath); + } std::vector options; diff --git a/src/managers/permissions/DynamicPermissionManager.hpp b/src/managers/permissions/DynamicPermissionManager.hpp index a61f256e..4de1eb32 100644 --- a/src/managers/permissions/DynamicPermissionManager.hpp +++ b/src/managers/permissions/DynamicPermissionManager.hpp @@ -34,6 +34,12 @@ enum eDynamicPermissionAllowMode : uint8_t { PERMISSION_RULE_ALLOW_MODE_PENDING, // popup is open }; +// NOLINTNEXTLINE +enum eSpecialPidTypes : int { + SPECIAL_PID_TYPE_CONFIG = -3, + SPECIAL_PID_TYPE_NONE = -2, +}; + class CDynamicPermissionRule; struct SDynamicPermissionRuleDestroyWrapper { diff --git a/src/plugins/PluginSystem.cpp b/src/plugins/PluginSystem.cpp index bfa3710f..cd36702e 100644 --- a/src/plugins/PluginSystem.cpp +++ b/src/plugins/PluginSystem.cpp @@ -14,15 +14,15 @@ CPluginSystem::CPluginSystem() { g_pFunctionHookSystem = makeUnique(); } -SP> CPluginSystem::loadPlugin(const std::string& path) { +SP> CPluginSystem::loadPlugin(const std::string& path, eSpecialPidTypes pidType) { pid_t pid = 0; if (g_pHyprCtl->m_currentRequestParams.pid > 0) pid = g_pHyprCtl->m_currentRequestParams.pid; - return CPromise::make([path, pid, this](SP> resolver) { - const auto PERM = g_pDynamicPermissionManager->clientPermissionModeWithString(pid, path, PERMISSION_TYPE_PLUGIN); + return CPromise::make([path, pid, pidType, this](SP> resolver) { + const auto PERM = g_pDynamicPermissionManager->clientPermissionModeWithString(pidType != SPECIAL_PID_TYPE_NONE ? pidType : pid, path, PERMISSION_TYPE_PLUGIN); if (PERM == PERMISSION_RULE_ALLOW_MODE_PENDING) { Debug::log(LOG, "CPluginSystem: Waiting for user confirmation to load {}", path); @@ -220,7 +220,7 @@ void CPluginSystem::updateConfigPlugins(const std::vector& plugins, changed = true; - loadPlugin(path)->then([path](SP> result) { + loadPlugin(path, SPECIAL_PID_TYPE_CONFIG)->then([path](SP> result) { if (result->hasError()) { const auto NAME = path.contains('/') ? path.substr(path.find_last_of('/') + 1) : path; Debug::log(ERR, "CPluginSystem::updateConfigPlugins: failed to load plugin {}: {}", NAME, result->error()); diff --git a/src/plugins/PluginSystem.hpp b/src/plugins/PluginSystem.hpp index 816569d2..7d062a9b 100644 --- a/src/plugins/PluginSystem.hpp +++ b/src/plugins/PluginSystem.hpp @@ -3,6 +3,7 @@ #include "../defines.hpp" #include "../helpers/defer/Promise.hpp" #include "PluginAPI.hpp" +#include "../managers/permissions/DynamicPermissionManager.hpp" #include #include @@ -32,7 +33,7 @@ class CPluginSystem { public: CPluginSystem(); - SP> loadPlugin(const std::string& path); + SP> loadPlugin(const std::string& path, eSpecialPidTypes pidType = SPECIAL_PID_TYPE_NONE); void unloadPlugin(const CPlugin* plugin, bool eject = false); void unloadAllPlugins(); void updateConfigPlugins(const std::vector& plugins, bool& changed);