119 lines
3.1 KiB
C++
119 lines
3.1 KiB
C++
#include "priv_thread.hpp"
|
|
|
|
#include "command_thread.hpp"
|
|
#include "connection.hpp"
|
|
#include "write_irc.hpp"
|
|
|
|
#include <toml++/toml.hpp>
|
|
|
|
#include <fstream>
|
|
|
|
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<std::string, std::unordered_set<std::string>> 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<PrivThread>
|
|
{
|
|
auto thread = std::make_shared<PrivThread>(connection, config_path);
|
|
|
|
thread->load_config();
|
|
|
|
connection.add_listener<CommandEvent>([thread](CommandEvent& event)
|
|
{
|
|
thread->on_command(event);
|
|
});
|
|
|
|
return thread;
|
|
}
|