Commit 45e8fe56 authored by louiz’'s avatar louiz’

Add an AdhocCommandsHandler to store commands specific to IRC servers

parent 19666d2f
...@@ -587,22 +587,22 @@ void XmppComponent::send_version(const std::string& id, const std::string& jid_t ...@@ -587,22 +587,22 @@ void XmppComponent::send_version(const std::string& id, const std::string& jid_t
this->send_stanza(iq); 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"); Stanza iq("iq");
iq["type"] = "result"; iq["type"] = "result";
iq["id"] = id; iq["id"] = id;
iq["to"] = requester_jid; iq["to"] = requester_jid;
iq["from"] = this->served_hostname; iq["from"] = from_jid;
XmlNode query("query"); XmlNode query("query");
query["xmlns"] = DISCO_ITEMS_NS; query["xmlns"] = DISCO_ITEMS_NS;
query["node"] = ADHOC_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) if (kv.second.is_admin_only() && !with_admin_only)
continue; continue;
XmlNode item("item"); XmlNode item("item");
item["jid"] = this->served_hostname; item["jid"] = from_jid;
item["node"] = kv.first; item["node"] = kv.first;
item["name"] = kv.second.name; item["name"] = kv.second.name;
query.add_child(std::move(item)); query.add_child(std::move(item));
......
...@@ -184,8 +184,8 @@ public: ...@@ -184,8 +184,8 @@ public:
* Send the list of all available ad-hoc commands to that JID. The list is * Send the list of all available ad-hoc commands to that JID. The list is
* different depending on what JID made the request. * different depending on what JID made the request.
*/ */
void send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, 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 bool with_admin_only, const AdhocCommandsHandler& adhoc_handler);
/** /**
* Send an iq version request * Send an iq version request
*/ */
......
...@@ -41,7 +41,8 @@ static std::set<std::string> kickable_errors{ ...@@ -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): 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", this->stanza_handlers.emplace("presence",
std::bind(&BiboumiComponent::handle_presence, this,std::placeholders::_1)); std::bind(&BiboumiComponent::handle_presence, this,std::placeholders::_1));
...@@ -313,9 +314,21 @@ void BiboumiComponent::handle_iq(const Stanza& stanza) ...@@ -313,9 +314,21 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
{ {
Stanza response("iq"); Stanza response("iq");
response["to"] = from; response["to"] = from;
response["from"] = this->served_hostname; response["from"] = to_str;
response["id"] = id; 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)) if (inner_node.get_child("error", ADHOC_NS))
response["type"] = "error"; response["type"] = "error";
else else
...@@ -370,10 +383,22 @@ void BiboumiComponent::handle_iq(const Stanza& stanza) ...@@ -370,10 +383,22 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
if (node == ADHOC_NS) if (node == ADHOC_NS)
{ {
Jid from_jid(from); Jid from_jid(from);
this->send_adhoc_commands_list(id, from, if (to.local.empty())
(Config::get("admin", "") == { // Get biboumi's adhoc commands
from_jid.local + "@" + from_jid.domain)); this->send_adhoc_commands_list(id, from, this->served_hostname,
stanza_error.disable(); (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) else if (node.empty() && !iid.is_user && !iid.is_channel)
{ // Disco on an IRC server: get the list of channels { // Disco on an IRC server: get the list of channels
......
...@@ -97,6 +97,8 @@ private: ...@@ -97,6 +97,8 @@ private:
*/ */
std::unordered_map<std::string, std::unique_ptr<Bridge>> bridges; std::unordered_map<std::string, std::unique_ptr<Bridge>> bridges;
AdhocCommandsHandler irc_server_adhoc_commands_handler;
BiboumiComponent(const BiboumiComponent&) = delete; BiboumiComponent(const BiboumiComponent&) = delete;
BiboumiComponent(BiboumiComponent&&) = delete; BiboumiComponent(BiboumiComponent&&) = delete;
BiboumiComponent& operator=(const BiboumiComponent&) = delete; BiboumiComponent& operator=(const BiboumiComponent&) = delete;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment