~singpolyma/biboumi

45e8fe56a688ec03201cdfc3dfea6ae186af682d — Florent Le Coz 7 years ago 19666d2
Add an AdhocCommandsHandler to store commands specific to IRC servers
M louloulibs/xmpp/xmpp_component.cpp => louloulibs/xmpp/xmpp_component.cpp +4 -4
@@ 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));

M louloulibs/xmpp/xmpp_component.hpp => louloulibs/xmpp/xmpp_component.hpp +2 -2
@@ 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
   */

M src/xmpp/biboumi_component.cpp => src/xmpp/biboumi_component.cpp +32 -7
@@ 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

M src/xmpp/biboumi_component.hpp => src/xmpp/biboumi_component.hpp +2 -0
@@ 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;