summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--louloulibs/xmpp/xmpp_component.cpp8
-rw-r--r--louloulibs/xmpp/xmpp_component.hpp4
-rw-r--r--src/xmpp/biboumi_component.cpp39
-rw-r--r--src/xmpp/biboumi_component.hpp2
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<std::string> kickable_errors{
BiboumiComponent::BiboumiComponent(std::shared_ptr<Poller> 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<std::string, std::unique_ptr<Bridge>> bridges;
+ AdhocCommandsHandler irc_server_adhoc_commands_handler;
+
BiboumiComponent(const BiboumiComponent&) = delete;
BiboumiComponent(BiboumiComponent&&) = delete;
BiboumiComponent& operator=(const BiboumiComponent&) = delete;