~singpolyma/biboumi

1691cf8f64d6175c61ddf9a4f4a95b44c32d698e — Florent Le Coz 8 years ago f1de6d0
Introduce the configure ad-hoc command on irc servers

Provides two options for now, and they have no effect yet
A louloulibs/utils/string.cpp => louloulibs/utils/string.cpp +6 -0
@@ 0,0 1,6 @@
#include <utils/string.hpp>

bool to_bool(const std::string& val)
{
  return (val == "1" || val == "true");
}

A louloulibs/utils/string.hpp => louloulibs/utils/string.hpp +8 -0
@@ 0,0 1,8 @@
#ifndef STRING_UTILS_HPP_INCLUDED
#define STRING_UTILS_HPP_INCLUDED

#include <string>

bool to_bool(const std::string& val);

#endif /* STRING_UTILS_HPP_INCLUDED */

M src/test.cpp => src/test.cpp +8 -0
@@ 13,6 13,7 @@
#include <utils/tolower.hpp>
#include <utils/revstr.hpp>
#include <irc/irc_user.hpp>
#include <utils/string.hpp>
#include <utils/split.hpp>
#include <utils/xdg.hpp>
#include <xmpp/jid.hpp>


@@ 170,6 171,13 @@ int main()
  const std::string ltr = "coucou";
  assert(utils::revstr(ltr) == "uocuoc");

  assert(to_bool("true"));
  assert(!to_bool("trou"));
  assert(to_bool("1"));
  assert(!to_bool("0"));
  assert(!to_bool("-1"));
  assert(!to_bool("false"));

  /**
   * XML parsing
   */

M src/xmpp/biboumi_adhoc_commands.cpp => src/xmpp/biboumi_adhoc_commands.cpp +97 -0
@@ 1,6 1,16 @@
#include <xmpp/biboumi_adhoc_commands.hpp>
#include <xmpp/biboumi_component.hpp>
#include <bridge/bridge.hpp>
#include <utils/string.hpp>
#include <xmpp/jid.hpp>

#include <biboumi.h>

#ifdef USE_DATABASE
#include <database/database.hpp>
#endif

using namespace std::string_literals;

void DisconnectUserStep1(XmppComponent* xmpp_component, AdhocSession&, XmlNode& command_node)
{


@@ 97,3 107,90 @@ void DisconnectUserStep2(XmppComponent* xmpp_component, AdhocSession& session, X
  command_node.add_child(std::move(error));
  session.terminate();
}

#ifdef USE_DATABASE
void ConfigureIrcServerStep1(XmppComponent* xmpp_component, AdhocSession& session, XmlNode& command_node)
{
  auto biboumi_component = static_cast<BiboumiComponent*>(xmpp_component);

  const Jid owner(session.get_owner_jid());
  const Jid target(session.get_target_jid());
  auto options = Database::get_irc_server_options(owner.local + "@" + owner.domain,
                                                  target.local);

  XmlNode x("jabber:x:data:x");
  x["type"] = "form";
  XmlNode title("title");
  title.set_inner("Configure the IRC server "s + target.local);
  x.add_child(std::move(title));
  XmlNode instructions("instructions");
  instructions.set_inner("Edit the form, to configure the settings of the IRC server "s + target.local);
  x.add_child(std::move(instructions));

  XmlNode require_tls("field");
  require_tls["var"] = "require_tls";
  require_tls["type"] = "boolean";
  require_tls["label"] = "Require TLS (refuse to connect insecurely)";
  XmlNode require_tls_value("value");
  require_tls_value.set_inner(options.requireTls ? "true": "false");
  require_tls.add_child(std::move(require_tls_value));
  XmlNode required("required");
  require_tls.add_child(required);
  x.add_child(std::move(require_tls));

  XmlNode pass("field");
  pass["var"] = "pass";
  pass["type"] = "text-private";
  pass["label"] = "Server password (to be used in a PASS command when connecting)";
  if (!options.pass.value().empty())
    {
      XmlNode pass_value("value");
      pass_value.set_inner(options.pass.value());
      pass.add_child(std::move(pass_value));
    }
  pass.add_child(required);
  x.add_child(std::move(pass));

  command_node.add_child(std::move(x));
}

void ConfigureIrcServerStep2(XmppComponent* xmpp_component, AdhocSession& session, XmlNode& command_node)
{
  auto biboumi_component = static_cast<BiboumiComponent*>(xmpp_component);

  const XmlNode* x = command_node.get_child("x", "jabber:x:data");
  if (x)
    {
      const Jid owner(session.get_owner_jid());
      const Jid target(session.get_target_jid());
      auto options = Database::get_irc_server_options(owner.local + "@" + owner.domain,
                                                      target.local);
      for (const XmlNode* field: x->get_children("field", "jabber:x:data"))
        {
          const XmlNode* value = field->get_child("value", "jabber:x:data");
          if (field->get_tag("var") == "require_tls" &&
              value && !value->get_inner().empty())
            options.requireTls = to_bool(value->get_inner());

          else if (field->get_tag("var") == "pass" &&
              value && !value->get_inner().empty())
            options.pass = value->get_inner();
        }

      options.update();

      command_node.delete_all_children();
      XmlNode note("note");
      note["type"] = "info";
      note.set_inner("Configuration successfully applied.");
      command_node.add_child(std::move(note));
      return;
    }
  XmlNode error(ADHOC_NS":error");
  error["type"] = "modify";
  XmlNode condition(STANZA_NS":bad-request");
  error.add_child(std::move(condition));
  command_node.add_child(std::move(error));
  session.terminate();
}
#endif  // USE_DATABASE

M src/xmpp/biboumi_adhoc_commands.hpp => src/xmpp/biboumi_adhoc_commands.hpp +3 -0
@@ 10,4 10,7 @@ class XmppComponent;
void DisconnectUserStep1(XmppComponent*, AdhocSession& session, XmlNode& command_node);
void DisconnectUserStep2(XmppComponent*, AdhocSession& session, XmlNode& command_node);

void ConfigureIrcServerStep1(XmppComponent*, AdhocSession& session, XmlNode& command_node);
void ConfigureIrcServerStep2(XmppComponent*, AdhocSession& session, XmlNode& command_node);

#endif /* BIBOUMI_ADHOC_COMMANDS_HPP_INCLUDED */

M src/xmpp/biboumi_component.cpp => src/xmpp/biboumi_component.cpp +7 -0
@@ 17,6 17,7 @@
#include <stdio.h>

#include <louloulibs.h>
#include <biboumi.h>

#include <uuid.h>



@@ 57,6 58,12 @@ BiboumiComponent::BiboumiComponent(std::shared_ptr<Poller> poller, const std::st
    {"disconnect-user", AdhocCommand({&DisconnectUserStep1, &DisconnectUserStep2}, "Disconnect a user from the gateway", true)},
    {"reload", AdhocCommand({&Reload}, "Reload biboumi’s configuration", true)}
  };

  this->irc_server_adhoc_commands_handler.get_commands() = {
#ifdef USE_DATABASE
    {"configure", AdhocCommand({&ConfigureIrcServerStep1, &ConfigureIrcServerStep2}, "Configure a few settings for that IRC server", false)},
#endif
  };
}

void BiboumiComponent::shutdown()