~singpolyma/biboumi

bb476f4a0d60bbc41393a86a370aa94ab405b081 — louiz’ 4 years ago 9e4a3e2
Allow to override the addresses used to connect to an IRC network

fix #3273
M CHANGELOG.rst => CHANGELOG.rst +3 -0
@@ 4,6 4,9 @@ Version 8.0
- Add a complete='true' in MAM’s iq result when appropriate
- The “virtual” channel with an empty name (for example
  %irc.freenode.net@biboumi) has been entirely removed.
- Add an “Address” field in the servers’ configure form. This lets
  the user customize the address to use when connecting to a server.
  See https://lab.louiz.org/louiz/biboumi/issues/3273 for more details.

Version 7.2 - 2018-01-24
========================

M doc/biboumi.1.rst => doc/biboumi.1.rst +11 -0
@@ 621,6 621,17 @@ On a server JID (e.g on the JID chat.freenode.org@biboumi.example.com)
- configure: Lets each user configure some options that applies to the
  concerned IRC server.  The provided configuration form contains these
  fields:

    * Address: This address (IPv4, IPv6 or hostname) will be used, when
      biboumi connects to this server. This is a very handy way to have a
      custom name for a network, and be able to edit the address to use
      if one endpoint for that server is dead, but continue using the same
      JID. For example, a user could configure the server
      “freenode@biboumi.example.com”, set “chat.freenode.net” in its
      “Address” field, and then they would be able to user “freenode” as
      the network name forever: if “chat.freenode.net” breaks for some
      reason, it can be changed to “irc.freenode.org” instead, and the user
      would not need to change all their bookmarks and settings.
    * Realname: The customized “real name” as it will appear on the
      user’s whois. This option is not available if biboumi is configured
      with realname_customization to false.

M src/database/database.hpp => src/database/database.hpp +2 -1
@@ 84,6 84,7 @@ class Database

  struct RemoteJid: Column<std::string> { static constexpr auto name = "remote"; };

  struct Address: Column<std::string> { static constexpr auto name = "hostname_"; };

  using MucLogLineTable = Table<Id, Uuid, Owner, IrcChanName, IrcServerName, Date, Body, Nick>;
  using MucLogLine = MucLogLineTable::RowType;


@@ 91,7 92,7 @@ class Database
  using GlobalOptionsTable = Table<Id, Owner, MaxHistoryLength, RecordHistory, GlobalPersistent>;
  using GlobalOptions = GlobalOptionsTable::RowType;

  using IrcServerOptionsTable = Table<Id, Owner, Server, Pass, AfterConnectionCommand, TlsPorts, Ports, Username, Realname, VerifyCert, TrustedFingerprint, EncodingOut, EncodingIn, MaxHistoryLength>;
  using IrcServerOptionsTable = Table<Id, Owner, Server, Pass, AfterConnectionCommand, TlsPorts, Ports, Username, Realname, VerifyCert, TrustedFingerprint, EncodingOut, EncodingIn, MaxHistoryLength, Address>;
  using IrcServerOptions = IrcServerOptionsTable::RowType;

  using IrcChannelOptionsTable = Table<Id, Owner, Server, Channel, EncodingOut, EncodingIn, MaxHistoryLength, Persistent, RecordHistoryOptional>;

M src/irc/irc_client.cpp => src/irc/irc_client.cpp +9 -7
@@ 186,20 186,22 @@ void IrcClient::start()
  bool tls;
  std::tie(port, tls) = this->ports_to_try.top();
  this->ports_to_try.pop();
  this->bridge.send_xmpp_message(this->hostname, "", "Connecting to " +
                                  this->hostname + ":" + port + " (" +
                                  (tls ? "encrypted" : "not encrypted") + ")");

  this->bind_addr = Config::get("outgoing_bind", "");
  std::string address = this->hostname;

#ifdef BOTAN_FOUND
# ifdef USE_DATABASE
#ifdef USE_DATABASE
  auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(),
                                                  this->get_hostname());
# ifdef BOTAN_FOUND
  this->credential_manager.set_trusted_fingerprint(options.col<Database::TrustedFingerprint>());
# endif
  if (!options.col<Database::Address>().empty())
    address = options.col<Database::Address>();
#endif
  this->connect(this->hostname, port, tls);
  this->bridge.send_xmpp_message(this->hostname, "", "Connecting to " +
                                  address + ":" + port + " (" +
                                  (tls ? "encrypted" : "not encrypted") + ")");
  this->connect(address, port, tls);
}

void IrcClient::on_connection_failed(const std::string& reason)

M src/xmpp/biboumi_adhoc_commands.cpp => src/xmpp/biboumi_adhoc_commands.cpp +18 -0
@@ 228,6 228,19 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
  instructions.set_inner("Edit the form, to configure the settings of the IRC server " + server_domain);

  {
    XmlSubNode hostname(x, "field");
    hostname["var"] = "hostname";
    hostname["type"] = "text-single";
    hostname["label"] = "Address";
    hostname["desc"] = "The hostname (or IP) to connect to.";
    XmlSubNode value(hostname, "value");
    if (options.col<Database::Address>().empty())
      value.set_inner(server_domain);
    else
      value.set_inner(options.col<Database::Address>());
  }

  {
    XmlSubNode ports(x, "field");
    ports["var"] = "ports";
    ports["type"] = "text-multi";


@@ 375,6 388,11 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com
        {
          const XmlNode* value = field->get_child("value", "jabber:x:data");
          const std::vector<const XmlNode*> values = field->get_children("value", "jabber:x:data");

          if (field->get_tag("var") == "hostname")
            {
              options.col<Database::Address>() = value->get_inner();
            }
          if (field->get_tag("var") == "ports")
            {
              std::string ports;