add and remove priv commands
This commit is contained in:
parent
5b19afa0a4
commit
5f0eb57e83
162
priv_thread.cpp
162
priv_thread.cpp
|
@ -6,7 +6,10 @@
|
||||||
|
|
||||||
#include <toml++/toml.hpp>
|
#include <toml++/toml.hpp>
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
PrivThread::PrivThread(Connection& connection, std::string config_path)
|
PrivThread::PrivThread(Connection& connection, std::string config_path)
|
||||||
: connection_{connection}
|
: connection_{connection}
|
||||||
|
@ -18,11 +21,11 @@ auto PrivThread::check_command(CommandEvent& event, std::string priv) -> bool
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
(not event.account.empty() &&
|
(not event.account.empty() &&
|
||||||
(check(account_privs, priv, "") ||
|
(check(account_privs_, priv, wildcard) ||
|
||||||
check(account_privs, priv, std::string{event.account}))) ||
|
check(account_privs_, priv, std::string{event.account}))) ||
|
||||||
(not event.oper.empty() &&
|
(not event.oper.empty() &&
|
||||||
(check(oper_privs, priv, "") ||
|
(check(oper_privs_, priv, wildcard) ||
|
||||||
check(oper_privs, priv, std::string{event.oper})));
|
check(oper_privs_, priv, std::string{event.oper})));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PrivThread::check(
|
auto PrivThread::check(
|
||||||
|
@ -35,40 +38,131 @@ auto PrivThread::check(
|
||||||
return cursor != privs.end() && cursor->second.contains(priv);
|
return cursor != privs.end() && cursor->second.contains(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto PrivThread::list_privs(std::string_view nick) -> void
|
||||||
|
{
|
||||||
|
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_, 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_, nick, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto PrivThread::on_command(CommandEvent& event) -> void
|
auto PrivThread::on_command(CommandEvent& event) -> void
|
||||||
{
|
{
|
||||||
if (event.command == "list_privs" && check_command(event, PrivThread::owner_priv))
|
if ("list_privs" == event.command)
|
||||||
{
|
{
|
||||||
for (auto const& [oper, privset] : oper_privs)
|
if (check_command(event, PrivThread::owner_priv))
|
||||||
{
|
{
|
||||||
std::string message = "Oper ";
|
list_privs(event.nick);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ("add_priv" == event.command)
|
||||||
|
{
|
||||||
|
if (check_command(event, PrivThread::owner_priv))
|
||||||
|
{
|
||||||
|
auto in = std::istringstream{std::string{event.arg}};
|
||||||
|
std::string kind, name, priv;
|
||||||
|
if (in >> kind >> name >> priv)
|
||||||
|
{
|
||||||
|
if ("oper" == kind)
|
||||||
|
{
|
||||||
|
oper_privs_[name].insert(priv);
|
||||||
|
save_config();
|
||||||
|
send_notice(connection_, event.nick, "ack");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ("account" == kind)
|
||||||
|
{
|
||||||
|
account_privs_[name].insert(priv);
|
||||||
|
save_config();
|
||||||
|
send_notice(connection_, event.nick, "ack");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send_notice(connection_, event.nick, "nak");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ("remove_priv" == event.command)
|
||||||
|
{
|
||||||
|
if (check_command(event, PrivThread::owner_priv))
|
||||||
|
{
|
||||||
|
auto in = std::istringstream{std::string{event.arg}};
|
||||||
|
std::string kind, name, priv;
|
||||||
|
if (in >> kind >> name >> priv)
|
||||||
|
{
|
||||||
|
if ("oper" == kind)
|
||||||
|
{
|
||||||
|
oper_privs_[name].erase(priv);
|
||||||
|
if (oper_privs_[name].empty()) oper_privs_.erase(name);
|
||||||
|
save_config();
|
||||||
|
send_notice(connection_, event.nick, "ack");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ("account" == kind)
|
||||||
|
{
|
||||||
|
account_privs_[name].erase(priv);
|
||||||
|
if (account_privs_[name].empty()) account_privs_.erase(name);
|
||||||
|
save_config();
|
||||||
|
send_notice(connection_, event.nick, "ack");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
send_notice(connection_, event.nick, "nak");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PrivThread::save_config() -> void
|
||||||
|
{
|
||||||
|
auto serialize_table = [](auto map) {
|
||||||
|
auto tab = toml::table{};
|
||||||
|
for (auto const& [oper, privs] : map)
|
||||||
|
{
|
||||||
|
auto privset = toml::array{};
|
||||||
|
for (auto const& priv : privs)
|
||||||
|
{
|
||||||
|
privset.push_back(priv);
|
||||||
|
}
|
||||||
|
tab.insert(oper, privset);
|
||||||
|
}
|
||||||
|
return tab;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto config = toml::table{};
|
||||||
|
if (not oper_privs_.empty()) {
|
||||||
|
config.insert("oper", serialize_table(oper_privs_));
|
||||||
|
}
|
||||||
|
if (not account_privs_.empty()) {
|
||||||
|
config.insert("account", serialize_table(account_privs_));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string tmp = config_path_ + ".tmp";
|
||||||
|
std::ofstream{tmp} << config;
|
||||||
|
std::filesystem::rename(tmp, config_path_);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto PrivThread::load_config() -> void
|
auto PrivThread::load_config() -> void
|
||||||
|
@ -81,7 +175,7 @@ auto PrivThread::load_config() -> void
|
||||||
{
|
{
|
||||||
for (auto const [oper, privs] : *config["oper"].as_table())
|
for (auto const [oper, privs] : *config["oper"].as_table())
|
||||||
{
|
{
|
||||||
auto& privset = oper_privs[std::string{oper.str()}];
|
auto& privset = oper_privs_[std::string{oper.str()}];
|
||||||
for (auto const& priv : *privs.as_array())
|
for (auto const& priv : *privs.as_array())
|
||||||
{
|
{
|
||||||
privset.insert(priv.as_string()->get());
|
privset.insert(priv.as_string()->get());
|
||||||
|
@ -93,7 +187,7 @@ auto PrivThread::load_config() -> void
|
||||||
{
|
{
|
||||||
for (auto const [account, privs] : *config["account"].as_table())
|
for (auto const [account, privs] : *config["account"].as_table())
|
||||||
{
|
{
|
||||||
auto& privset = account_privs[std::string{account.str()}];
|
auto& privset = account_privs_[std::string{account.str()}];
|
||||||
for (auto const& priv : *privs.as_array())
|
for (auto const& priv : *privs.as_array())
|
||||||
{
|
{
|
||||||
privset.insert(priv.as_string()->get());
|
privset.insert(priv.as_string()->get());
|
||||||
|
|
|
@ -13,8 +13,8 @@ class PrivThread : std::enable_shared_from_this<PrivThread>
|
||||||
Connection& connection_;
|
Connection& connection_;
|
||||||
std::string config_path_;
|
std::string config_path_;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::unordered_set<std::string>> oper_privs;
|
std::unordered_map<std::string, std::unordered_set<std::string>> oper_privs_;
|
||||||
std::unordered_map<std::string, std::unordered_set<std::string>> account_privs;
|
std::unordered_map<std::string, std::unordered_set<std::string>> account_privs_;
|
||||||
|
|
||||||
auto on_command(CommandEvent&) -> void;
|
auto on_command(CommandEvent&) -> void;
|
||||||
|
|
||||||
|
@ -24,12 +24,15 @@ class PrivThread : std::enable_shared_from_this<PrivThread>
|
||||||
std::string const& name) -> bool;
|
std::string const& name) -> bool;
|
||||||
|
|
||||||
auto load_config() -> void;
|
auto load_config() -> void;
|
||||||
|
auto save_config() -> void;
|
||||||
|
auto list_privs(std::string_view nick) -> void;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PrivThread(Connection&, std::string config_path);
|
PrivThread(Connection&, std::string config_path);
|
||||||
auto check_command(CommandEvent& event, std::string priv) -> bool;
|
auto check_command(CommandEvent& event, std::string priv) -> bool;
|
||||||
|
|
||||||
static constexpr char const* owner_priv = "owner";
|
static constexpr char const* owner_priv = "owner";
|
||||||
|
static constexpr char const* wildcard = "*";
|
||||||
|
|
||||||
static auto start(Connection&, std::string config_path) -> std::shared_ptr<PrivThread>;
|
static auto start(Connection&, std::string config_path) -> std::shared_ptr<PrivThread>;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user