Mercurial > irccd
changeset 586:f462cc16b517
Irccd: server_error now takes server name
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 05 Dec 2017 21:09:45 +0100 |
parents | 1ad88e2e3086 |
children | 312af09354e0 |
files | libirccd-js/irccd/js/server_jsapi.cpp libirccd/irccd/command.cpp libirccd/irccd/server.cpp libirccd/irccd/server.hpp libirccd/irccd/server_service.cpp libirccd/irccd/server_service.hpp tests/src/plugin-load-command/main.cpp tests/src/server-connect-command/main.cpp |
diffstat | 8 files changed, 211 insertions(+), 155 deletions(-) [+] |
line wrap: on
line diff
--- a/libirccd-js/irccd/js/server_jsapi.cpp Tue Dec 05 20:45:21 2017 +0100 +++ b/libirccd-js/irccd/js/server_jsapi.cpp Tue Dec 05 21:09:45 2017 +0100 @@ -370,7 +370,7 @@ try { auto json = duk_json_encode(ctx, 0); - auto s = server::from_json(dukx_get_irccd(ctx).service(), nlohmann::json::parse(json)); + auto s = server_service::from_json(dukx_get_irccd(ctx).service(), nlohmann::json::parse(json)); duk_push_this(ctx); duk_push_pointer(ctx, new std::shared_ptr<server>(std::move(s)));
--- a/libirccd/irccd/command.cpp Tue Dec 05 20:45:21 2017 +0100 +++ b/libirccd/irccd/command.cpp Tue Dec 05 21:09:45 2017 +0100 @@ -153,12 +153,12 @@ auto id = json_util::get_string(args, "server"); if (!string_util::is_identifier(id)) - throw server_error(server_error::invalid_identifier); + throw server_error(server_error::invalid_identifier, ""); auto server = daemon.servers().get(id); if (!server) - throw server_error(server_error::not_found); + throw server_error(server_error::not_found, id); return server; } @@ -256,10 +256,10 @@ void server_connect_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { - auto server = server::from_json(irccd.service(), args); + auto server = server_service::from_json(irccd.service(), args); if (irccd.servers().has(server->name())) - throw server_error(server_error::error::already_exists); + throw server_error(server_error::error::already_exists, server->name()); irccd.servers().add(std::move(server)); client.success("server-connect"); @@ -278,14 +278,15 @@ irccd.servers().clear(); else { if (!it->is_string()) - throw server_error(server_error::invalid_identifier); + throw server_error(server_error::invalid_identifier, ""); - auto s = irccd.servers().get(it->get<std::string>()); + auto name = it->get<std::string>(); + auto s = irccd.servers().get(name); if (!s) - throw server_error(server_error::not_found); + throw server_error(server_error::not_found, name); - irccd.servers().remove(it->get<std::string>()); + irccd.servers().remove(name); } client.success("server-disconnect"); @@ -329,15 +330,16 @@ void server_invite_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto target = json_util::get_string(args, "target"); auto channel = json_util::get_string(args, "channel"); if (target.empty()) - throw server_error(server_error::invalid_nickname); + throw server_error(server_error::invalid_nickname, server->name()); if (channel.empty()) - throw server_error(server_error::invalid_channel); + throw server_error(server_error::invalid_channel, server->name()); - get_server(irccd, args)->invite(target, channel); + server->invite(target, channel); client.success("server-invite"); } @@ -348,13 +350,14 @@ void server_join_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto channel = json_util::get_string(args, "channel"); auto password = json_util::get_string(args, "password"); if (channel.empty()) - throw server_error(server_error::invalid_channel); + throw server_error(server_error::invalid_channel, server->name()); - get_server(irccd, args)->join(channel, password); + server->join(channel, password); client.success("server-join"); } @@ -365,16 +368,17 @@ void server_kick_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto target = json_util::get_string(args, "target"); auto channel = json_util::get_string(args, "channel"); auto reason = json_util::get_string(args, "reason"); if (target.empty()) - throw server_error(server_error::invalid_nickname); + throw server_error(server_error::invalid_nickname, server->name()); if (channel.empty()) - throw server_error(server_error::invalid_channel); + throw server_error(server_error::invalid_channel, server->name()); - get_server(irccd, args)->kick(target, channel, reason); + server->kick(target, channel, reason); client.success("server-kick"); } @@ -404,13 +408,14 @@ void server_me_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto channel = json_util::get_string(args, "target"); auto message = json_util::get_string(args, "message"); if (channel.empty()) - throw server_error(server_error::invalid_channel); + throw server_error(server_error::invalid_channel, server->name()); - get_server(irccd, args)->me(channel, message); + server->me(channel, message); client.success("server-me"); } @@ -421,13 +426,14 @@ void server_message_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto channel = json_util::get_string(args, "target"); auto message = json_util::get_string(args, "message"); if (channel.empty()) - throw server_error(server_error::invalid_channel); + throw server_error(server_error::invalid_channel, server->name()); - get_server(irccd, args)->message(channel, message); + server->message(channel, message); client.success("server-message"); } @@ -438,19 +444,20 @@ void server_mode_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto channel = json_util::get_string(args, "channel"); auto mode = json_util::get_string(args, "mode"); if (channel.empty()) - throw server_error(server_error::invalid_channel); + throw server_error(server_error::invalid_channel, server->name()); if (mode.empty()) - throw server_error(server_error::invalid_mode); + throw server_error(server_error::invalid_mode, server->name()); auto limit = json_util::get_string(args, "limit"); auto user = json_util::get_string(args, "user"); auto mask = json_util::get_string(args, "mask"); - get_server(irccd, args)->mode(channel, mode, limit, user, mask); + server->mode(channel, mode, limit, user, mask); client.success("server-mode"); } @@ -461,12 +468,13 @@ void server_nick_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto nick = json_util::get_string(args, "nickname"); if (nick.empty()) - throw server_error(server_error::invalid_nickname); + throw server_error(server_error::invalid_nickname, server->name()); - get_server(irccd, args)->set_nickname(nick); + server->set_nickname(nick); client.success("server-nick"); } @@ -477,13 +485,14 @@ void server_notice_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto channel = json_util::get_string(args, "target"); auto message = json_util::get_string(args, "message"); if (channel.empty()) - throw server_error(server_error::invalid_channel); + throw server_error(server_error::invalid_channel, server->name()); - get_server(irccd, args)->notice(channel, message); + server->notice(channel, message); client.success("server-notice"); } @@ -494,13 +503,14 @@ void server_part_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto channel = json_util::get_string(args, "channel"); auto reason = json_util::get_string(args, "reason"); if (channel.empty()) - throw server_error(server_error::invalid_channel); + throw server_error(server_error::invalid_channel, server->name()); - get_server(irccd, args)->part(channel, reason); + server->part(channel, reason); client.success("server-part"); } @@ -518,12 +528,13 @@ server->reconnect(); } else { if (!server->is_string() || !string_util::is_identifier(server->get<std::string>())) - throw server_error(server_error::invalid_identifier); + throw server_error(server_error::invalid_identifier, ""); - auto s = irccd.servers().get(server->get<std::string>()); + auto name = server->get<std::string>(); + auto s = irccd.servers().get(name); if (!s) - throw server_error(server_error::not_found); + throw server_error(server_error::not_found, name); s->reconnect(); } @@ -538,13 +549,14 @@ void server_topic_command::exec(irccd& irccd, transport_client& client, const nlohmann::json& args) { + auto server = get_server(irccd, args); auto channel = json_util::get_string(args, "channel"); auto topic = json_util::get_string(args, "topic"); if (channel.empty()) - throw server_error(server_error::invalid_channel); + throw server_error(server_error::invalid_channel, server->name()); - get_server(irccd, args)->topic(channel, topic); + server->topic(channel, topic); client.success("server-topic"); }
--- a/libirccd/irccd/server.cpp Tue Dec 05 20:45:21 2017 +0100 +++ b/libirccd/irccd/server.cpp Tue Dec 05 21:09:45 2017 +0100 @@ -104,48 +104,6 @@ return modes; } -std::string from_json_get_id(const nlohmann::json& json) -{ - auto id = json_util::get_string(json, "name"); - - if (!string_util::is_identifier(id)) - throw server_error(server_error::invalid_identifier); - - return id; -} - -std::string from_json_get_host(const nlohmann::json& json) -{ - auto host = json_util::get_string(json, "host"); - - if (host.empty()) - throw server_error(server_error::invalid_hostname); - - return host; -} - -template <typename T> -T from_json_get_uint(const nlohmann::json& json, - const std::string& key, - server_error::error error, - T fallback) - -{ - auto v = json.find(key); - - if (v == json.end()) - return fallback; - if (!v->is_number()) - throw server_error(error); - - auto n = v->get<unsigned>(); - - if (n > std::numeric_limits<T>::max()) - throw server_error(error); - - return static_cast<T>(n); -} - } // !namespace void server::remove_joined_channel(const std::string& channel) @@ -153,40 +111,6 @@ jchannels_.erase(std::remove(jchannels_.begin(), jchannels_.end(), channel), jchannels_.end()); } -std::shared_ptr<server> server::from_json(boost::asio::io_service& service, const nlohmann::json& object) -{ - // TODO: move this function in server_service. - auto sv = std::make_shared<server>(service, from_json_get_id(object)); - - sv->set_host(from_json_get_host(object)); - sv->set_port(from_json_get_uint(object, "port", - server_error::invalid_port, sv->port())); - sv->set_password(json_util::get_string(object, "password")); - sv->set_nickname(json_util::get_string(object, "nickname", sv->nickname())); - sv->set_realname(json_util::get_string(object, "realname", sv->realname())); - sv->set_username(json_util::get_string(object, "username", sv->username())); - sv->set_ctcp_version(json_util::get_string(object, "ctcpVersion", sv->ctcp_version())); - sv->set_command_char(json_util::get_string(object, "commandChar", sv->command_char())); - - if (json_util::get_bool(object, "ipv6")) - sv->set_flags(sv->flags() | server::ipv6); - if (json_util::get_bool(object, "sslVerify")) - sv->set_flags(sv->flags() | server::ssl_verify); - if (json_util::get_bool(object, "autoRejoin")) - sv->set_flags(sv->flags() | server::auto_rejoin); - if (json_util::get_bool(object, "joinInvite")) - sv->set_flags(sv->flags() | server::join_invite); - - if (json_util::get_bool(object, "ssl")) -#if defined(HAVE_SSL) - sv->set_flags(sv->flags() | server::ssl); -#else - throw server_error(server_error::ssl_disabled); -#endif - - return sv; -} - channel server::split_channel(const std::string& value) { auto pos = value.find(':'); @@ -749,6 +673,12 @@ send(string_util::sprintf("WHOIS %s %s", target, target)); } +server_error::server_error(error code, std::string name) noexcept + : system_error(make_error_code(code)) + , name_(std::move(name)) +{ +} + const boost::system::error_category& server_category() { static const class category : public boost::system::error_category {
--- a/libirccd/irccd/server.hpp Tue Dec 05 20:45:21 2017 +0100 +++ b/libirccd/irccd/server.hpp Tue Dec 05 21:09:45 2017 +0100 @@ -453,18 +453,6 @@ public: /** - * Convert a JSON object as a server. - * - * Used in JavaScript API and transport commands. - * - * \param service the io service - * \param object the object - * \return the server - * \throw std::exception on failures - */ - static std::shared_ptr<server> from_json(boost::asio::io_service& service, const nlohmann::json& object); - - /** * Split a channel from the form channel:password into a server_channel * object. * @@ -953,10 +941,27 @@ ssl_disabled, }; +private: + std::string name_; + +public: /** - * Inherited constructors. + * Constructor. + * + * \param code the error code + * \param name the server name */ - using system_error::system_error; + server_error(error code, std::string name) noexcept; + + /** + * Get the server that triggered the error. + * + * \return the name + */ + inline const std::string& name() const noexcept + { + return name_; + } }; /**
--- a/libirccd/irccd/server_service.cpp Tue Dec 05 20:45:21 2017 +0100 +++ b/libirccd/irccd/server_service.cpp Tue Dec 05 21:09:45 2017 +0100 @@ -16,6 +16,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include <irccd/json_util.hpp> + #include "irccd.hpp" #include "logger.hpp" #include "plugin_service.hpp" @@ -56,23 +58,77 @@ } template <typename T> -T to_uint(const std::string& value, server_error::error errc) +T to_int(const std::string& value, const std::string& name, server_error::error errc) +{ + try { + return string_util::to_int<T>(value); + } catch (...) { + throw server_error(errc, name); + } +} + +template <typename T> +T to_uint(const std::string& value, const std::string& name, server_error::error errc) { try { return string_util::to_uint<T>(value); } catch (...) { - throw server_error(errc); + throw server_error(errc, name); } } template <typename T> -T to_int(const std::string& value, server_error::error errc) +T to_uint(const nlohmann::json& value, const std::string& name, server_error::error errc) +{ + if (!value.is_number()) + throw server_error(errc, name); + + auto n = value.get<unsigned>(); + + if (n > std::numeric_limits<T>::max()) + throw server_error(errc, name); + + return static_cast<T>(n); +} + +std::string to_id(const ini::section& sc) +{ + auto id = sc.get("name"); + + if (!string_util::is_identifier(id.value())) + throw server_error(server_error::invalid_identifier, ""); + + return id.value(); +} + +std::string to_id(const nlohmann::json& object) { - try { - return string_util::to_int<T>(value); - } catch (...) { - throw server_error(errc); - } + auto id = json_util::get_string(object, "name"); + + if (!string_util::is_identifier(id)) + throw server_error(server_error::invalid_identifier, ""); + + return id; +} + +std::string to_host(const ini::section& sc, const std::string& name) +{ + auto value = sc.get("host"); + + if (value.empty()) + throw server_error(server_error::invalid_hostname, name); + + return name; +} + +std::string to_host(const nlohmann::json& object, const std::string& name) +{ + auto value = json_util::get_string(object, "host"); + + if (value.empty()) + throw server_error(server_error::invalid_hostname, name); + + return value; } void load_server_identity(std::shared_ptr<server>& server, @@ -109,23 +165,14 @@ { assert(sc.key() == "server"); + auto sv = std::make_shared<server>(service, to_id(sc)); + + // Mandatory fields. + sv->set_host(to_host(sc, sv->name())); + + // Optional fields. ini::section::const_iterator it; - // Name. - auto name = sc.get("name").value(); - - if (!string_util::is_identifier(name)) - throw server_error(server_error::invalid_identifier); - - auto sv = std::make_shared<server>(service, name); - - // Host - if ((it = sc.find("host")) == sc.end()) - throw server_error(server_error::invalid_hostname); - - sv->set_host(it->value()); - - // Optional password if ((it = sc.find("password")) != sc.end()) sv->set_password(it->value()); @@ -173,13 +220,20 @@ // Reconnect and ping timeout if ((it = sc.find("port")) != sc.end()) - sv->set_port(to_uint<std::uint16_t>(it->value(), server_error::invalid_port)); + sv->set_port(to_uint<std::uint16_t>(it->value(), + sv->name(), server_error::invalid_port)); + if ((it = sc.find("reconnect-tries")) != sc.end()) - sv->set_reconnect_tries(to_int<std::int8_t>(it->value(), server_error::invalid_reconnect_tries)); + sv->set_reconnect_tries(to_int<std::int8_t>(it->value(), + sv->name(), server_error::invalid_reconnect_tries)); + if ((it = sc.find("reconnect-timeout")) != sc.end()) - sv->set_reconnect_delay(to_uint<std::uint16_t>(it->value(), server_error::invalid_reconnect_timeout)); + sv->set_reconnect_delay(to_uint<std::uint16_t>(it->value(), + sv->name(), server_error::invalid_reconnect_timeout)); + if ((it = sc.find("ping-timeout")) != sc.end()) - sv->set_ping_timeout(to_uint<std::uint16_t>(it->value(), server_error::invalid_ping_timeout)); + sv->set_ping_timeout(to_uint<std::uint16_t>(it->value(), + sv->name(), server_error::invalid_ping_timeout)); return sv; } @@ -526,6 +580,43 @@ ); } +std::shared_ptr<server> server_service::from_json(boost::asio::io_service& service, const nlohmann::json& object) +{ + // TODO: move this function in server_service. + auto sv = std::make_shared<server>(service, to_id(object)); + + // Mandatory fields. + sv->set_host(to_host(object, sv->name())); + + // Optional fields. + if (object.count("port")) + sv->set_port(to_uint<std::uint16_t>(object["port"], sv->name(), server_error::invalid_port)); + sv->set_password(json_util::get_string(object, "password")); + sv->set_nickname(json_util::get_string(object, "nickname", sv->nickname())); + sv->set_realname(json_util::get_string(object, "realname", sv->realname())); + sv->set_username(json_util::get_string(object, "username", sv->username())); + sv->set_ctcp_version(json_util::get_string(object, "ctcpVersion", sv->ctcp_version())); + sv->set_command_char(json_util::get_string(object, "commandChar", sv->command_char())); + + if (json_util::get_bool(object, "ipv6")) + sv->set_flags(sv->flags() | server::ipv6); + if (json_util::get_bool(object, "sslVerify")) + sv->set_flags(sv->flags() | server::ssl_verify); + if (json_util::get_bool(object, "autoRejoin")) + sv->set_flags(sv->flags() | server::auto_rejoin); + if (json_util::get_bool(object, "joinInvite")) + sv->set_flags(sv->flags() | server::join_invite); + + if (json_util::get_bool(object, "ssl")) +#if defined(HAVE_SSL) + sv->set_flags(sv->flags() | server::ssl); +#else + throw server_error(server_error::ssl_disabled); +#endif + + return sv; +} + server_service::server_service(irccd &irccd) : irccd_(irccd) {
--- a/libirccd/irccd/server_service.hpp Tue Dec 05 20:45:21 2017 +0100 +++ b/libirccd/irccd/server_service.hpp Tue Dec 05 21:09:45 2017 +0100 @@ -31,6 +31,7 @@ namespace irccd { +class config; class irccd; /** @@ -59,6 +60,18 @@ public: /** + * Convert a JSON object as a server. + * + * Used in JavaScript API and transport commands. + * + * \param service the io service + * \param object the object + * \return the server + * \throw std::exception on failures + */ + static std::shared_ptr<server> from_json(boost::asio::io_service& service, const nlohmann::json& object); + + /** * Create the server service. */ server_service(irccd& instance);
--- a/tests/src/plugin-load-command/main.cpp Tue Dec 05 20:45:21 2017 +0100 +++ b/tests/src/plugin-load-command/main.cpp Tue Dec 05 21:09:45 2017 +0100 @@ -30,6 +30,11 @@ class custom_loader : public plugin_loader { public: + custom_loader() + : plugin_loader({}, {".none"}) + { + } + std::shared_ptr<plugin> open(const std::string&, const std::string&) noexcept override {
--- a/tests/src/server-connect-command/main.cpp Tue Dec 05 20:45:21 2017 +0100 +++ b/tests/src/server-connect-command/main.cpp Tue Dec 05 21:09:45 2017 +0100 @@ -223,7 +223,7 @@ return result; }); - BOOST_ASSERT(result == server_error::invalid_port_number); + BOOST_ASSERT(result == server_error::invalid_port); } BOOST_AUTO_TEST_CASE(invalid_port_2) @@ -244,7 +244,7 @@ return result; }); - BOOST_ASSERT(result == server_error::invalid_port_number); + BOOST_ASSERT(result == server_error::invalid_port); } BOOST_AUTO_TEST_CASE(invalid_port_3) @@ -265,7 +265,7 @@ return result; }); - BOOST_ASSERT(result == server_error::invalid_port_number); + BOOST_ASSERT(result == server_error::invalid_port); } #if !defined(HAVE_SSL)