Mercurial > irccd
changeset 643:eff84e503c26
Irccd: implement rule_util, #771
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 21 Mar 2018 19:45:55 +0100 |
parents | d3ea56d7a126 |
children | aae6d5a2b28d |
files | libirccd/CMakeLists.txt libirccd/irccd/daemon/command/rule_add_command.cpp libirccd/irccd/daemon/command/rule_edit_command.cpp libirccd/irccd/daemon/command/rule_info_command.cpp libirccd/irccd/daemon/command/rule_list_command.cpp libirccd/irccd/daemon/command/rule_move_command.cpp libirccd/irccd/daemon/command/rule_remove_command.cpp libirccd/irccd/daemon/rule_util.cpp libirccd/irccd/daemon/rule_util.hpp libirccd/irccd/daemon/service/rule_service.cpp libirccd/irccd/daemon/service/rule_service.hpp |
diffstat | 11 files changed, 275 insertions(+), 167 deletions(-) [+] |
line wrap: on
line diff
--- a/libirccd/CMakeLists.txt Wed Mar 21 12:51:25 2018 +0100 +++ b/libirccd/CMakeLists.txt Wed Mar 21 19:45:55 2018 +0100 @@ -61,6 +61,7 @@ ${libirccd_SOURCE_DIR}/irccd/daemon/logger.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/plugin.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/rule.hpp + ${libirccd_SOURCE_DIR}/irccd/daemon/rule_util.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/server.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/server_util.hpp ${libirccd_SOURCE_DIR}/irccd/daemon/service/plugin_service.hpp @@ -108,6 +109,7 @@ ${libirccd_SOURCE_DIR}/irccd/daemon/logger.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/plugin.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/rule.cpp + ${libirccd_SOURCE_DIR}/irccd/daemon/rule_util.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/server.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/server_util.cpp ${libirccd_SOURCE_DIR}/irccd/daemon/service/plugin_service.cpp
--- a/libirccd/irccd/daemon/command/rule_add_command.cpp Wed Mar 21 12:51:25 2018 +0100 +++ b/libirccd/irccd/daemon/command/rule_add_command.cpp Wed Mar 21 19:45:55 2018 +0100 @@ -20,6 +20,7 @@ #include <irccd/daemon/irccd.hpp> #include <irccd/daemon/transport_client.hpp> +#include <irccd/daemon/rule_util.hpp> #include <irccd/daemon/service/rule_service.hpp> @@ -41,7 +42,7 @@ if (index > irccd.rules().length()) throw rule_error(rule_error::error::invalid_index); - irccd.rules().insert(rule_service::from_json(args), *index); + irccd.rules().insert(rule_util::from_json(args), *index); client.success("rule-add"); }
--- a/libirccd/irccd/daemon/command/rule_edit_command.cpp Wed Mar 21 12:51:25 2018 +0100 +++ b/libirccd/irccd/daemon/command/rule_edit_command.cpp Wed Mar 21 19:45:55 2018 +0100 @@ -16,7 +16,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <irccd/json_util.hpp> + #include <irccd/daemon/irccd.hpp> +#include <irccd/daemon/rule_util.hpp> #include <irccd/daemon/transport_client.hpp> #include <irccd/daemon/service/rule_service.hpp> @@ -46,8 +49,12 @@ }; // Create a copy to avoid incomplete edition in case of errors. - auto index = irccd.rules().get_index(args); - auto rule = irccd.rules().require(index); + const auto index = json_util::get_uint(args, "/index"_json_pointer); + + if (!index) + throw rule_error(rule_error::invalid_index); + + auto rule = irccd.rules().require(*index); updateset(rule.get_channels(), args, "channels"); updateset(rule.get_events(), args, "events"); @@ -69,7 +76,7 @@ } // All done, sync the rule. - irccd.rules().require(index) = rule; + irccd.rules().require(*index) = rule; client.success("rule-edit"); }
--- a/libirccd/irccd/daemon/command/rule_info_command.cpp Wed Mar 21 12:51:25 2018 +0100 +++ b/libirccd/irccd/daemon/command/rule_info_command.cpp Wed Mar 21 19:45:55 2018 +0100 @@ -16,7 +16,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <irccd/json_util.hpp> + #include <irccd/daemon/irccd.hpp> +#include <irccd/daemon/rule_util.hpp> #include <irccd/daemon/transport_client.hpp> #include <irccd/daemon/service/rule_service.hpp> @@ -32,7 +35,12 @@ void rule_info_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - auto json = rule_service::to_json(irccd.rules().require(irccd.rules().get_index(args))); + const auto index = json_util::get_uint(args, "/index"_json_pointer); + + if (!index) + throw rule_error(rule_error::invalid_index); + + auto json = rule_util::to_json(irccd.rules().require(*index)); json.push_back({"command", "rule-info"}); client.send(std::move(json));
--- a/libirccd/irccd/daemon/command/rule_list_command.cpp Wed Mar 21 12:51:25 2018 +0100 +++ b/libirccd/irccd/daemon/command/rule_list_command.cpp Wed Mar 21 19:45:55 2018 +0100 @@ -17,6 +17,7 @@ */ #include <irccd/daemon/irccd.hpp> +#include <irccd/daemon/rule_util.hpp> #include <irccd/daemon/transport_client.hpp> #include <irccd/daemon/service/rule_service.hpp> @@ -35,7 +36,7 @@ auto array = nlohmann::json::array(); for (const auto& rule : irccd.rules().list()) - array.push_back(rule_service::to_json(rule)); + array.push_back(rule_util::to_json(rule)); client.send({ { "command", "rule-list" },
--- a/libirccd/irccd/daemon/command/rule_move_command.cpp Wed Mar 21 12:51:25 2018 +0100 +++ b/libirccd/irccd/daemon/command/rule_move_command.cpp Wed Mar 21 19:45:55 2018 +0100 @@ -16,7 +16,10 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <irccd/json_util.hpp> + #include <irccd/daemon/irccd.hpp> +#include <irccd/daemon/rule_util.hpp> #include <irccd/daemon/transport_client.hpp> #include <irccd/daemon/service/rule_service.hpp> @@ -32,8 +35,11 @@ void rule_move_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - auto from = rule_service::get_index(args, "from"); - auto to = rule_service::get_index(args, "to"); + const auto from = json_util::get_uint(args, "/from"_json_pointer); + const auto to = json_util::get_uint(args, "/to"_json_pointer); + + if (!from || !to) + throw rule_error(rule_error::invalid_index); /* * Examples of moves @@ -66,18 +72,18 @@ */ // Ignore dumb input. - if (from == to) { + if (*from == *to) { client.success("rule-move"); return; } - if (from >= irccd.rules().length()) + if (*from >= irccd.rules().length()) throw rule_error(rule_error::error::invalid_index); - auto save = irccd.rules().list()[from]; + const auto save = irccd.rules().list()[*from]; - irccd.rules().remove(from); - irccd.rules().insert(save, to > irccd.rules().length() ? irccd.rules().length() : to); + irccd.rules().remove(*from); + irccd.rules().insert(save, *to > irccd.rules().length() ? irccd.rules().length() : *to); client.success("rule-move"); }
--- a/libirccd/irccd/daemon/command/rule_remove_command.cpp Wed Mar 21 12:51:25 2018 +0100 +++ b/libirccd/irccd/daemon/command/rule_remove_command.cpp Wed Mar 21 19:45:55 2018 +0100 @@ -16,6 +16,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <irccd/json_util.hpp> + #include <irccd/daemon/irccd.hpp> #include <irccd/daemon/transport_client.hpp> @@ -32,12 +34,12 @@ void rule_remove_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - auto index = rule_service::get_index(args); + const auto index = json_util::get_uint(args, "/index"_json_pointer); - if (index >= irccd.rules().length()) + if (!index || *index >= irccd.rules().length()) throw rule_error(rule_error::invalid_index); - irccd.rules().remove(index); + irccd.rules().remove(*index); client.success("rule-remove"); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd/irccd/daemon/rule_util.cpp Wed Mar 21 19:45:55 2018 +0100 @@ -0,0 +1,152 @@ +/* + * rule_util.cpp -- rule utilities + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <unordered_set> + +#include <irccd/ini.hpp> + +#include <irccd/daemon/rule.hpp> + +#include "rule_util.hpp" + +namespace irccd { + +namespace rule_util { + +rule from_config(const ini::section& sc) +{ + // Simple converter from std::vector to std::unordered_set. + const auto toset = [] (const auto& v) { + return std::unordered_set<std::string>(v.begin(), v.end()); + }; + + rule::set servers, channels, origins, plugins, events; + rule::action action = rule::action::accept; + + // Get the sets. + ini::section::const_iterator it; + + if ((it = sc.find("servers")) != sc.end()) + servers = toset(*it); + if ((it = sc.find("channels")) != sc.end()) + channels = toset(*it); + if ((it = sc.find("origins")) != sc.end()) + origins = toset(*it); + if ((it = sc.find("plugins")) != sc.end()) + plugins = toset(*it); + if ((it = sc.find("channels")) != sc.end()) + channels = toset(*it); + + // Get the action. + auto actionstr = sc.get("action").value(); + + if (actionstr == "drop") + action = rule::action::drop; + else if (actionstr == "accept") + action = rule::action::accept; + else + throw rule_error(rule_error::invalid_action); + + return { + std::move(servers), + std::move(channels), + std::move(origins), + std::move(plugins), + std::move(events), + action + }; +} + +rule from_json(const nlohmann::json& json) +{ + const auto toset = [] (auto object, auto name) { + rule::set result; + + for (const auto& s : object[name]) + if (s.is_string()) + result.insert(s.template get<std::string>()); + + return result; + }; + const auto toaction = [] (const auto& object, const auto& name) { + const auto v = object.find(name); + + if (v == object.end() || !v->is_string()) + throw rule_error(rule_error::invalid_action); + + const auto s = v->template get<std::string>(); + + if (s == "accept") + return rule::action::accept; + if (s == "drop") + return rule::action::drop; + + throw rule_error(rule_error::invalid_action); + }; + + return { + toset(json, "servers"), + toset(json, "channels"), + toset(json, "origins"), + toset(json, "plugins"), + toset(json, "events"), + toaction(json, "action") + }; +} + +unsigned get_index(const nlohmann::json& json, const std::string& key) +{ + const auto index = json.find(key); + + if (index == json.end() || !index->is_number_integer() || index->get<int>() < 0) + throw rule_error(rule_error::invalid_index); + + return index->get<int>(); +} + +nlohmann::json to_json(const rule& rule) +{ + const auto join = [] (const auto& set) { + auto array = nlohmann::json::array(); + + for (const auto& entry : set) + array.push_back(entry); + + return array; + }; + const auto str = [] (auto action) { + switch (action) { + case rule::action::accept: + return "accept"; + default: + return "drop"; + } + }; + + return { + { "servers", join(rule.get_servers()) }, + { "channels", join(rule.get_channels()) }, + { "plugins", join(rule.get_plugins()) }, + { "events", join(rule.get_events()) }, + { "action", str(rule.get_action()) } + }; +} + +} // !rule_util + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libirccd/irccd/daemon/rule_util.hpp Wed Mar 21 19:45:55 2018 +0100 @@ -0,0 +1,78 @@ +/* + * rule_util.hpp -- rule utilities + * + * Copyright (c) 2013-2018 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_DAEMON_RULE_UTIL_HPP +#define IRCCD_DAEMON_RULE_UTIL_HPP + +/** + * \file rule_util.hpp + * \brief Rule utilities. + */ + +#include <json.hpp> + +namespace irccd { + +namespace ini { + +class section; + +} // !ini + +class config; +class rule; + +/** + * \brief Rule utilities. + */ +namespace rule_util { + +/** + * Load a rule from a JSON object. + * + * For possible use in transport commands or Javascript API. + * + * \pre json.is_object() + * \param json the JSON object + * \return the new rule + * \throw rule_error on errors + */ +rule from_json(const nlohmann::json& json); + +/** + * Load a rule from a INI section. + * + * \param sc the ini section + * \return the rule + * \throw rule_error on errors + */ +rule from_config(const ini::section& sc); + +/** + * Convert a rule into a JSON object. + * + * \param rule the rule + * \throw the JSON representation + */ +nlohmann::json to_json(const rule& rule); + +} // !rule_util + +} // !irccd + +#endif // !IRCCD_DAEMON_RULE_UTIL_HPP
--- a/libirccd/irccd/daemon/service/rule_service.cpp Wed Mar 21 12:51:25 2018 +0100 +++ b/libirccd/irccd/daemon/service/rule_service.cpp Wed Mar 21 19:45:55 2018 +0100 @@ -23,6 +23,7 @@ #include <irccd/daemon/irccd.hpp> #include <irccd/daemon/logger.hpp> +#include <irccd/daemon/rule_util.hpp> #include <irccd/daemon/service/rule_service.hpp> @@ -30,128 +31,9 @@ namespace { -rule load_rule(const ini::section& sc) -{ - assert(sc.key() == "rule"); - - // Simple converter from std::vector to std::unordered_set. - auto toset = [] (const auto& v) { - return std::unordered_set<std::string>(v.begin(), v.end()); - }; - - rule::set servers, channels, origins, plugins, events; - rule::action action = rule::action::accept; - - // Get the sets. - ini::section::const_iterator it; - - if ((it = sc.find("servers")) != sc.end()) - servers = toset(*it); - if ((it = sc.find("channels")) != sc.end()) - channels = toset(*it); - if ((it = sc.find("origins")) != sc.end()) - origins = toset(*it); - if ((it = sc.find("plugins")) != sc.end()) - plugins = toset(*it); - if ((it = sc.find("channels")) != sc.end()) - channels = toset(*it); - - // Get the action. - auto actionstr = sc.get("action").value(); - - if (actionstr == "drop") - action = rule::action::drop; - else if (actionstr == "accept") - action = rule::action::accept; - else - throw rule_error(rule_error::invalid_action); - - return { - std::move(servers), - std::move(channels), - std::move(origins), - std::move(plugins), - std::move(events), - action - }; -} } // !namespace -rule rule_service::from_json(const nlohmann::json& json) -{ - auto toset = [] (auto object, auto name) { - rule::set result; - - for (const auto& s : object[name]) - if (s.is_string()) - result.insert(s.template get<std::string>()); - - return result; - }; - auto toaction = [] (auto object, auto name) { - auto v = object[name]; - - if (!v.is_string()) - throw rule_error(rule_error::invalid_action); - - auto s = v.template get<std::string>(); - if (s == "accept") - return rule::action::accept; - if (s == "drop") - return rule::action::drop; - - throw rule_error(rule_error::invalid_action); - }; - - return { - toset(json, "servers"), - toset(json, "channels"), - toset(json, "origins"), - toset(json, "plugins"), - toset(json, "events"), - toaction(json, "action") - }; -} - -unsigned rule_service::get_index(const nlohmann::json& json, const std::string& key) -{ - auto index = json.find(key); - - if (index == json.end() || !index->is_number_integer() || index->get<int>() < 0) - throw rule_error(rule_error::invalid_index); - - return index->get<int>(); -} - -nlohmann::json rule_service::to_json(const rule& rule) -{ - auto join = [] (const auto& set) { - auto array = nlohmann::json::array(); - - for (const auto& entry : set) - array.push_back(entry); - - return array; - }; - auto str = [] (auto action) { - switch (action) { - case rule::action::accept: - return "accept"; - default: - return "drop"; - } - }; - - return { - { "servers", join(rule.get_servers()) }, - { "channels", join(rule.get_channels()) }, - { "plugins", join(rule.get_plugins()) }, - { "events", join(rule.get_events()) }, - { "action", str(rule.get_action()) } - }; -} - rule_service::rule_service(irccd &irccd) : irccd_(irccd) { @@ -231,7 +113,7 @@ continue; try { - rules_.push_back(load_rule(section)); + rules_.push_back(rule_util::from_config(section)); } catch (const std::exception& ex) { irccd_.log().warning() << "rule: " << ex.what() << std::endl; }
--- a/libirccd/irccd/daemon/service/rule_service.hpp Wed Mar 21 12:51:25 2018 +0100 +++ b/libirccd/irccd/daemon/service/rule_service.hpp Wed Mar 21 19:45:55 2018 +0100 @@ -46,37 +46,6 @@ public: /** - * Load a rule from a JSON object. - * - * For possible use in transport commands or Javascript API. - * - * \pre json.is_object() - * \param json the JSON object - * \return the new rule - * \throw rule_error on errors - */ - static rule from_json(const nlohmann::json& json); - - /** - * Helper to get rule index in a JSON object. - * - * \pre json.is_object() - * \param json the JSON object - * \param key the index property - * \return the index - * \throw rule_error on errors - */ - static unsigned get_index(const nlohmann::json& json, const std::string& key = "index"); - - /** - * Convert a rule into a JSON object. - * - * \param rule the rule - * \throw the JSON representation - */ - static nlohmann::json to_json(const rule& rule); - - /** * Create the rule service. */ rule_service(irccd& instance);