Mercurial > irccd
changeset 543:7051034bf2ee
Irccdctl: abort in case of error
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 21 Nov 2017 13:40:39 +0100 |
parents | 80c3caafe9d3 |
children | 8d9662b2beee |
files | irccdctl/cli.cpp libcommon/irccd/network_errc.cpp libcommon/irccd/network_errc.hpp libirccd/irccd/transport_client.hpp libirccd/irccd/transport_server.cpp libirccd/irccd/transport_server.hpp libirccdctl/irccd/ctl/network_connection.hpp |
diffstat | 7 files changed, 68 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/irccdctl/cli.cpp Tue Nov 21 12:29:50 2017 +0100 +++ b/irccdctl/cli.cpp Tue Nov 21 13:40:39 2017 +0100 @@ -37,6 +37,11 @@ if (code) throw boost::system::system_error(code); + if (message["error"].is_number_integer()) + throw boost::system::system_error(static_cast<network_errc>(message["error"].template get<int>())); + if (message["error"].is_string()) + throw std::runtime_error(message["error"].template get<std::string>()); + auto c = json_util::to_string(message["command"]); if (c != req["command"].get<std::string>()) { @@ -44,11 +49,6 @@ return; } - if (message["error"].is_number_integer()) - throw boost::system::system_error(static_cast<network_errc>(message["error"].template get<int>())); - if (message["error"].is_string()) - throw std::runtime_error(message["error"].template get<std::string>()); - if (handler) handler(std::move(message)); });
--- a/libcommon/irccd/network_errc.cpp Tue Nov 21 12:29:50 2017 +0100 +++ b/libcommon/irccd/network_errc.cpp Tue Nov 21 13:40:39 2017 +0100 @@ -44,6 +44,8 @@ return "invalid message"; case network_errc::corrupt_message: return "corrupt message"; + case network_errc::auth_required: + return "auth required"; default: return "unknown error"; }
--- a/libcommon/irccd/network_errc.hpp Tue Nov 21 12:29:50 2017 +0100 +++ b/libcommon/irccd/network_errc.hpp Tue Nov 21 13:40:39 2017 +0100 @@ -40,6 +40,7 @@ invalid_auth, //!< invalid credentials in auth command invalid_message, //!< the message was not JSON corrupt_message, //!< error occured while sending a message + auth_required //!< authentication is required and was not issued }; /**
--- a/libirccd/irccd/transport_client.hpp Tue Nov 21 12:29:50 2017 +0100 +++ b/libirccd/irccd/transport_client.hpp Tue Nov 21 13:40:39 2017 +0100 @@ -230,12 +230,14 @@ * Convenient error overload. * * \param cname the command name + * \pre !reason.empty() * \param reason the reason string * \param handler the optional handler */ inline void error(const std::string& cname, const std::string& reason, send_t handler = nullptr) { assert(!cname.empty()); + assert(!reason.empty()); error({ { "command", cname }, @@ -246,11 +248,25 @@ /** * Convenient error overload. * + * \pre !reason.empty() + * \param reason the reason string + * \param handler the handler + */ + inline void error(const std::string& reason, send_t handler = nullptr) + { + assert(!reason.empty()); + + error({{ "error", reason }}, std::move(handler)); + } + + /** + * Convenient error overload. + * * \param cname the command name * \param reason the error code * \param handler the optional handler */ - inline void error(const std::string& cname, network_errc reason, send_t handler) + inline void error(const std::string& cname, network_errc reason, send_t handler = nullptr) { assert(!cname.empty()); @@ -259,6 +275,20 @@ { "error", static_cast<int>(reason) } }, std::move(handler)); } + + /** + * Convenient error overload. + * + * \pre reason != network_errc::no_error + * \param reason the reason string + * \param handler the handler + */ + inline void error(network_errc reason, send_t handler = nullptr) + { + assert(reason != network_errc::no_error); + + error({{ "error", static_cast<int>(reason) }}, std::move(handler)); + } }; /**
--- a/libirccd/irccd/transport_server.cpp Tue Nov 21 12:29:50 2017 +0100 +++ b/libirccd/irccd/transport_server.cpp Tue Nov 21 13:40:39 2017 +0100 @@ -20,30 +20,11 @@ #include <cassert> +#include "json_util.hpp" #include "transport_server.hpp" namespace irccd { -bool transport_server::do_auth_check(nlohmann::json message, accept_t handler) -{ - assert(handler); - - auto command = message["command"]; - auto password = message["password"]; - - if (!command.is_string() || !password.is_string()) { - handler(nullptr, network_errc::invalid_message); - return false; - } - - if (command != "auth" || password.get<std::string>() != password_) { - handler(nullptr, network_errc::invalid_auth); - return false; - } - - return true; -} - void transport_server::do_auth(std::shared_ptr<transport_client> client, accept_t handler) { assert(client); @@ -52,11 +33,24 @@ client->recv([this, client, handler] (auto message, auto code) { if (code) handler(client, code); - if (do_auth_check(message, handler)) { - clients_.insert(client); + + clients_.insert(client); + + auto command = json_util::to_string(message["command"]); + auto password = json_util::to_string(message["password"]); + + if (command != "auth") { + client->error(network_errc::auth_required); + code = network_errc::auth_required; + } else if (password != password_) { + client->error(network_errc::invalid_auth); + code = network_errc::invalid_auth; + } else { client->set_state(transport_client::state_t::ready); - handler(client, code); + code = network_errc::no_error; } + + handler(client, code); }); }
--- a/libirccd/irccd/transport_server.hpp Tue Nov 21 12:29:50 2017 +0100 +++ b/libirccd/irccd/transport_server.hpp Tue Nov 21 13:40:39 2017 +0100 @@ -58,7 +58,6 @@ client_set_t clients_; std::string password_; - bool do_auth_check(nlohmann::json, accept_t); void do_auth(std::shared_ptr<transport_client>, accept_t); void do_greetings(std::shared_ptr<transport_client>, accept_t);
--- a/libirccdctl/irccd/ctl/network_connection.hpp Tue Nov 21 12:29:50 2017 +0100 +++ b/libirccdctl/irccd/ctl/network_connection.hpp Tue Nov 21 13:40:39 2017 +0100 @@ -94,11 +94,22 @@ input_.consume(xfer); + /* + * Only catch parse error from JSON to avoid calling the handler twice + * if the handler throws from itself. + * + * TODO: in json 3.0.0, you may catch nlohmann::json::parse_error + * instead. + */ + nlohmann::json json; + try { - handler(code, nlohmann::json::parse(command)); + json = nlohmann::json::parse(command); } catch (...) { handler(network_errc::invalid_message, nullptr); } + + handler(network_errc::no_error, std::move(json)); }); }