diff --git a/common/utils/string_utils.cpp b/common/utils/string_utils.cpp index 72dfea36..960599f4 100644 --- a/common/utils/string_utils.cpp +++ b/common/utils/string_utils.cpp @@ -43,13 +43,13 @@ static constexpr auto LOG_TAG = "StringUtils"; bool wildcardMatch(const std::string& pattern, const std::string& text) { - LOG(INFO, LOG_TAG) << "wildcardMatch '" << pattern << "', text: '" << text << "'\n"; + LOG(DEBUG, LOG_TAG) << "wildcardMatch '" << pattern << "', text: '" << text << "'\n"; std::vector parts = utils::string::split(pattern, '*'); size_t pos = 0; for (size_t n = 0; n < parts.size(); ++n) { const std::string& part = parts[n]; - LOG(INFO, LOG_TAG) << "Matching '" << part << "', pos: " << pos << "\n"; + LOG(DEBUG, LOG_TAG) << "Matching '" << part << "', pos: " << pos << "\n"; pos = text.find(part, pos); if (pos == std::string::npos) return false; diff --git a/server/authinfo.cpp b/server/authinfo.cpp index 9126404d..cb62d277 100644 --- a/server/authinfo.cpp +++ b/server/authinfo.cpp @@ -269,11 +269,28 @@ bool AuthInfo::hasPermission(const std::string& resource) const return false; const auto& role = user_iter->role; - auto perm_iter = std::find_if(role->permissions.begin(), role->permissions.end(), - [&](const std::string& permission) { return utils::string::wildcardMatch(permission, resource); }); + auto perm_iter = std::find_if(role->permissions.begin(), role->permissions.end(), [&](const std::string& permission) + { + if (!permission.empty() && (permission[0] == '-')) + return false; + return utils::string::wildcardMatch(permission, resource); + }); if (perm_iter != role->permissions.end()) { + auto not_perm_iter = std::find_if(role->permissions.begin(), role->permissions.end(), [&](const std::string& permission) + { + if (!permission.empty() && (permission[0] != '-')) + return false; + return utils::string::wildcardMatch(permission.substr(1), resource); + }); + + if (not_perm_iter != role->permissions.end()) + { + LOG(DEBUG, LOG_TAG) << "Found non-permission for ressource '" << resource << "': '" << *perm_iter << "'\n"; + return false; + } + LOG(DEBUG, LOG_TAG) << "Found permission for ressource '" << resource << "': '" << *perm_iter << "'\n"; return true; } diff --git a/test/test_main.cpp b/test/test_main.cpp index 3b286d32..41150a51 100644 --- a/test/test_main.cpp +++ b/test/test_main.cpp @@ -793,4 +793,20 @@ TEST_CASE("Auth") REQUIRE(auth.hasPermission("stream")); REQUIRE(!auth.hasPermission("play")); } + + { + auth_settings.init({"admin:Client.*,Group.*,-Group.Set*"}, {"badaix:secret:admin"}); + REQUIRE(auth_settings.users.size() == 1); + REQUIRE(auth_settings.roles.size() == 1); + REQUIRE(auth_settings.users.front().role->permissions.size() == 3); + + AuthInfo auth(auth_settings); + auto ec = auth.authenticateBasic(base64_encode("badaix:secret")); + REQUIRE(!ec); + REQUIRE(auth.hasPermission("Client.SetVolume")); + REQUIRE(auth.hasPermission("Client.SetName")); + REQUIRE(auth.hasPermission("Group.GetStatus")); + REQUIRE(!auth.hasPermission("Group.SetName")); + REQUIRE(!auth.hasPermission("Server.GetStatus")); + } }