Update auth configi and tests

This commit is contained in:
badaix 2025-02-10 22:03:34 +01:00
parent e2feac1d75
commit 4c9d377816
3 changed files with 89 additions and 41 deletions

View file

@ -20,9 +20,11 @@
// local headers
#include "common/snap_exception.hpp"
#include "common/utils/string_utils.hpp"
// standard headers
#include <algorithm>
#include <cstdint>
#include <filesystem>
#include <memory>
@ -71,6 +73,35 @@ struct ServerSettings
/// Authorization settings
struct Authorization
{
/// c'tor
Authorization() = default;
/// c'tor
Authorization(const std::vector<std::string>& conf_roles, const std::vector<std::string>& conf_users)
{
for (const auto& role : conf_roles)
roles.emplace_back(std::make_shared<ServerSettings::Authorization::Role>(role));
auto empty_role = std::make_shared<ServerSettings::Authorization::Role>();
for (const auto& conf_user : conf_users)
{
users.emplace_back(conf_user);
ServerSettings::Authorization::User& user = users.back();
if (user.role_name.empty())
{
user.role = empty_role;
}
else
{
const auto& role_iter = std::find_if(roles.begin(), roles.end(), [&](const auto& role) { return role->role == user.role_name; });
if (role_iter != roles.end())
user.role = *role_iter;
}
if (user.role == nullptr)
throw SnapException("Role '" + user.role_name + "' for user '" + user.name + "' not found");
}
}
/// Role settings
struct Role
{

View file

@ -324,34 +324,20 @@ int main(int argc, char* argv[])
if (settings.auth.enabled)
{
std::vector<std::string> roles;
for (size_t n = 0; n < roles_value->count(); ++n)
{
settings.auth.roles.emplace_back(std::make_shared<ServerSettings::Authorization::Role>(roles_value->value(n)));
const auto& role = settings.auth.roles.back();
LOG(DEBUG, LOG_TAG) << "Role: " << role->role << ", permissions: " << utils::string::container_to_string(role->permissions) << "\n";
}
auto empty_role = std::make_shared<ServerSettings::Authorization::Role>();
roles.push_back(roles_value->value(n));
std::vector<std::string> users;
for (size_t n = 0; n < users_value->count(); ++n)
{
settings.auth.users.emplace_back(users_value->value(n));
ServerSettings::Authorization::User& user = settings.auth.users.back();
if (user.role_name.empty())
{
user.role = empty_role;
}
else
{
const auto& role_iter =
find_if(settings.auth.roles.begin(), settings.auth.roles.end(), [&](const auto& role) { return role->role == user.role_name; });
if (role_iter != settings.auth.roles.end())
user.role = *role_iter;
}
if (user.role == nullptr)
throw SnapException("Role '" + user.role_name + "' for user '" + user.name + "' not found");
users.push_back(users_value->value(n));
settings.auth = ServerSettings::Authorization(roles, users);
for (const auto& role : settings.auth.roles)
LOG(DEBUG, LOG_TAG) << "Role: " << role->role << ", permissions: " << utils::string::container_to_string(role->permissions) << "\n";
for (const auto& user : settings.auth.users)
LOG(DEBUG, LOG_TAG) << "User: " << user.name << ", pw: " << user.password << ", role: " << user.role_name << "\n";
}
}
#ifdef HAS_DAEMON

View file

@ -19,10 +19,13 @@
// prototype/interface header file
// local headers
#include "common/base64.h"
#include "common/error_code.hpp"
#include "common/stream_uri.hpp"
#include "common/utils/string_utils.hpp"
// #include "server/jwt.hpp"
#include "server/authinfo.hpp"
#include "server/server_settings.hpp"
#include "server/streamreader/control_error.hpp"
#include "server/streamreader/properties.hpp"
@ -30,6 +33,7 @@
#include <catch2/catch_test_macros.hpp>
// standard headers
#include <cstddef>
#include <iostream>
#include <regex>
#include <system_error>
@ -717,17 +721,19 @@ TEST_CASE("WildcardMatch")
REQUIRE(!wildcardMatch("*get*erver*", "Server.getToken"));
}
#if 0
TEST_CASE("Auth")
{
{
ServerSettings settings;
ServerSettings::User user("badaix:*:secret");
REQUIRE(user.permissions.size() == 1);
REQUIRE(user.permissions[0] == "*");
settings.users.push_back(user);
ServerSettings::Authorization auth_settings({"admin:*"}, {"badaix:secret:admin"});
auth_settings.enabled = true;
REQUIRE(auth_settings.users.size() == 1);
REQUIRE(auth_settings.roles.size() == 1);
REQUIRE(auth_settings.users.front().role->role == "admin");
REQUIRE(auth_settings.users.front().role->permissions.size() == 1);
REQUIRE(auth_settings.users.front().role->permissions.front() == "*");
AuthInfo auth(settings);
AuthInfo auth(auth_settings);
auto ec = auth.authenticateBasic(base64_encode("badaix:secret"));
REQUIRE(!ec);
REQUIRE(auth.isAuthenticated());
@ -735,12 +741,14 @@ TEST_CASE("Auth")
}
{
ServerSettings settings;
ServerSettings::User user("badaix::secret");
REQUIRE(user.permissions.empty());
settings.users.push_back(user);
ServerSettings::Authorization auth_settings({"admin:"}, {"badaix:secret:admin"});
auth_settings.enabled = true;
REQUIRE(auth_settings.users.size() == 1);
REQUIRE(auth_settings.roles.size() == 1);
REQUIRE(auth_settings.users.front().role->role == "admin");
REQUIRE(auth_settings.users.front().role->permissions.empty());
AuthInfo auth(settings);
AuthInfo auth(auth_settings);
auto ec = auth.authenticateBasic(base64_encode("badaix:secret"));
REQUIRE(!ec);
REQUIRE(auth.isAuthenticated());
@ -748,11 +756,29 @@ TEST_CASE("Auth")
}
{
ServerSettings settings;
ServerSettings::User user("badaix:*:secret");
settings.users.push_back(user);
ServerSettings::Authorization auth_settings({}, {"badaix:secret:"});
auth_settings.enabled = true;
REQUIRE(auth_settings.users.size() == 1);
REQUIRE(auth_settings.roles.empty());
REQUIRE(auth_settings.users.front().role->permissions.empty());
AuthInfo auth(settings);
AuthInfo auth(auth_settings);
auto ec = auth.authenticateBasic(base64_encode("badaix:secret"));
REQUIRE(!ec);
REQUIRE(auth.isAuthenticated());
REQUIRE(!auth.hasPermission("stream"));
}
{
ServerSettings::Authorization auth_settings({"admin:xxx,stream"}, {"badaix:secret:admin"});
auth_settings.enabled = true;
REQUIRE(auth_settings.users.size() == 1);
REQUIRE(auth_settings.roles.size() == 1);
REQUIRE(auth_settings.users.front().role->permissions.size() == 2);
REQUIRE(auth_settings.users.front().role->permissions[0] == "xxx");
REQUIRE(auth_settings.users.front().role->permissions[1] == "stream");
AuthInfo auth(auth_settings);
auto ec = auth.authenticateBasic(base64_encode("badaix:wrong_password"));
REQUIRE(ec == AuthErrc::wrong_password);
REQUIRE(!auth.isAuthenticated());
@ -762,6 +788,11 @@ TEST_CASE("Auth")
REQUIRE(ec == AuthErrc::unknown_user);
REQUIRE(!auth.isAuthenticated());
REQUIRE(!auth.hasPermission("stream"));
ec = auth.authenticateBasic(base64_encode("badaix:secret"));
REQUIRE(!ec);
REQUIRE(auth.isAuthenticated());
REQUIRE(auth.hasPermission("stream"));
REQUIRE(!auth.hasPermission("play"));
}
}
#endif