From 45e8fe56a688ec03201cdfc3dfea6ae186af682d Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 18 Sep 2015 21:55:21 +0200 Subject: Add an AdhocCommandsHandler to store commands specific to IRC servers --- louloulibs/xmpp/xmpp_component.cpp | 8 ++++---- louloulibs/xmpp/xmpp_component.hpp | 4 ++-- src/xmpp/biboumi_component.cpp | 39 +++++++++++++++++++++++++++++++------- src/xmpp/biboumi_component.hpp | 2 ++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index 2214ecf..3017c0b 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -587,22 +587,22 @@ void XmppComponent::send_version(const std::string& id, const std::string& jid_t this->send_stanza(iq); } -void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, const bool with_admin_only) +void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, const std::string& from_jid, const bool with_admin_only, const AdhocCommandsHandler& adhoc_handler) { Stanza iq("iq"); iq["type"] = "result"; iq["id"] = id; iq["to"] = requester_jid; - iq["from"] = this->served_hostname; + iq["from"] = from_jid; XmlNode query("query"); query["xmlns"] = DISCO_ITEMS_NS; query["node"] = ADHOC_NS; - for (const auto& kv: this->adhoc_commands_handler.get_commands()) + for (const auto& kv: adhoc_handler.get_commands()) { if (kv.second.is_admin_only() && !with_admin_only) continue; XmlNode item("item"); - item["jid"] = this->served_hostname; + item["jid"] = from_jid; item["node"] = kv.first; item["name"] = kv.second.name; query.add_child(std::move(item)); diff --git a/louloulibs/xmpp/xmpp_component.hpp b/louloulibs/xmpp/xmpp_component.hpp index e45bb36..06236fe 100644 --- a/louloulibs/xmpp/xmpp_component.hpp +++ b/louloulibs/xmpp/xmpp_component.hpp @@ -184,8 +184,8 @@ public: * Send the list of all available ad-hoc commands to that JID. The list is * different depending on what JID made the request. */ - void send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, - const bool with_admin_only); + void send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, const std::string& from_jid, + const bool with_admin_only, const AdhocCommandsHandler& adhoc_handler); /** * Send an iq version request */ diff --git a/src/xmpp/biboumi_component.cpp b/src/xmpp/biboumi_component.cpp index 51775ab..974676b 100644 --- a/src/xmpp/biboumi_component.cpp +++ b/src/xmpp/biboumi_component.cpp @@ -41,7 +41,8 @@ static std::set kickable_errors{ BiboumiComponent::BiboumiComponent(std::shared_ptr poller, const std::string& hostname, const std::string& secret): - XmppComponent(poller, hostname, secret) + XmppComponent(poller, hostname, secret), + irc_server_adhoc_commands_handler(this) { this->stanza_handlers.emplace("presence", std::bind(&BiboumiComponent::handle_presence, this,std::placeholders::_1)); @@ -313,9 +314,21 @@ void BiboumiComponent::handle_iq(const Stanza& stanza) { Stanza response("iq"); response["to"] = from; - response["from"] = this->served_hostname; + response["from"] = to_str; response["id"] = id; - XmlNode inner_node = this->adhoc_commands_handler.handle_request(from, *query); + + // Depending on the 'to' jid in the request, we use one adhoc + // command handler or an other + Iid iid(to.local); + AdhocCommandsHandler* adhoc_handler; + if (!to.local.empty() && !iid.is_user && !iid.is_channel) + adhoc_handler = &this->irc_server_adhoc_commands_handler; + else + adhoc_handler = &this->adhoc_commands_handler; + + // Execute the command, if any, and get a result XmlNode that we + // insert in our response + XmlNode inner_node = adhoc_handler->handle_request(from, to_str, *query); if (inner_node.get_child("error", ADHOC_NS)) response["type"] = "error"; else @@ -370,10 +383,22 @@ void BiboumiComponent::handle_iq(const Stanza& stanza) if (node == ADHOC_NS) { Jid from_jid(from); - this->send_adhoc_commands_list(id, from, - (Config::get("admin", "") == - from_jid.local + "@" + from_jid.domain)); - stanza_error.disable(); + if (to.local.empty()) + { // Get biboumi's adhoc commands + this->send_adhoc_commands_list(id, from, this->served_hostname, + (Config::get("admin", "") == + from_jid.local + "@" + from_jid.domain), + this->adhoc_commands_handler); + stanza_error.disable(); + } + else if (!iid.is_user && !iid.is_channel) + { // Get the server's adhoc commands + this->send_adhoc_commands_list(id, from, to_str, + (Config::get("admin", "") == + from_jid.local + "@" + from_jid.domain), + this->irc_server_adhoc_commands_handler); + stanza_error.disable(); + } } else if (node.empty() && !iid.is_user && !iid.is_channel) { // Disco on an IRC server: get the list of channels diff --git a/src/xmpp/biboumi_component.hpp b/src/xmpp/biboumi_component.hpp index 8b0b3da..fe99f2d 100644 --- a/src/xmpp/biboumi_component.hpp +++ b/src/xmpp/biboumi_component.hpp @@ -97,6 +97,8 @@ private: */ std::unordered_map> bridges; + AdhocCommandsHandler irc_server_adhoc_commands_handler; + BiboumiComponent(const BiboumiComponent&) = delete; BiboumiComponent(BiboumiComponent&&) = delete; BiboumiComponent& operator=(const BiboumiComponent&) = delete; -- cgit v1.2.3