#include "priv_thread.hpp" #include "command_thread.hpp" #include "connection.hpp" #include "write_irc.hpp" #include #include PrivThread::PrivThread(Connection& connection, std::string config_path) : connection_{connection} , config_path_{std::move(config_path)} { } auto PrivThread::check_command(CommandEvent& event, std::string priv) -> bool { return (not event.account.empty() && (check(account_privs, priv, "") || check(account_privs, priv, std::string{event.account}))) || (not event.oper.empty() && (check(oper_privs, priv, "") || check(oper_privs, priv, std::string{event.oper}))); } auto PrivThread::check( std::unordered_map> const& privs, std::string const& priv, std::string const& name ) -> bool { auto const cursor = privs.find(name); return cursor != privs.end() && cursor->second.contains(priv); } auto PrivThread::on_command(CommandEvent& event) -> void { if (event.command == "list_privs" && check_command(event, PrivThread::owner_priv)) { for (auto const& [oper, privset] : oper_privs) { std::string message = "Oper "; message += oper; message += ":"; for (auto const& priv : privset) { message += " "; message += priv; } send_notice(connection_, event.nick, message); } for (auto const& [account, privset] : account_privs) { std::string message = "Account "; message += account; message += ":"; for (auto const& priv : privset) { message += " "; message += priv; } send_notice(connection_, event.nick, message); } } } auto PrivThread::load_config() -> void { if (auto in = std::ifstream{config_path_}) { auto const config = toml::parse(in); if (config.contains("oper")) { for (auto const [oper, privs] : *config["oper"].as_table()) { auto& privset = oper_privs[std::string{oper.str()}]; for (auto const& priv : *privs.as_array()) { privset.insert(priv.as_string()->get()); } } } if (config.contains("account")) { for (auto const [account, privs] : *config["account"].as_table()) { auto& privset = account_privs[std::string{account.str()}]; for (auto const& priv : *privs.as_array()) { privset.insert(priv.as_string()->get()); } } } } } auto PrivThread::start(Connection& connection, std::string config_path) -> std::shared_ptr { auto thread = std::make_shared(connection, config_path); thread->load_config(); connection.add_listener([thread](CommandEvent& event) { thread->on_command(event); }); return thread; }