~singpolyma/biboumi

619c991a691a455efee2baa4e1fe96e64d27ff64 — louiz’ 5 years ago d7427fc
Add a nick field in the IRC server configuration form

fix #3317
M CHANGELOG.rst => CHANGELOG.rst +2 -0
@@ 11,6 11,8 @@ Version 8.0
- We now properly deal with a PostgreSQL server restart: whenever the
  connection is lost with the server, we try to reconnect and re-execute the
  query once.
- A Nick field has been added in the IRC server configuration form, to let
  the user force a nickname whenever a channel on the server is joined.

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

M doc/biboumi.1.rst => doc/biboumi.1.rst +6 -0
@@ 668,6 668,12 @@ On a server JID (e.g on the JID chat.freenode.org@biboumi.example.com)
    * SHA-1 fingerprint of the TLS certificate to trust: if you know the hash
      of the certificate that the server is supposed to use, and you only want
      to accept this one, set its SHA-1 hash in this field.
    * Nickname: A nickname that will be used instead of the nickname provided
      in the initial presence sent to join a channel. This can be used if the
      user always wants to have the same nickname on a given server, and not
      have to bother with setting that nick in all the bookmarks on that
      server. The nickname can still manually be changed with a standard nick
      change presence.
    * Server password: A password that will be sent just after the connection,
      in a PASS command. This is usually used in private servers, where you’re
      only allowed to connect if you have the password. Note that, although

M src/bridge/bridge.cpp => src/bridge/bridge.cpp +6 -1
@@ 166,10 166,15 @@ IrcClient* Bridge::find_irc_client(const std::string& hostname) const
    }
}

bool Bridge::join_irc_channel(const Iid& iid, const std::string& nickname, const std::string& password,
bool Bridge::join_irc_channel(const Iid& iid, std::string nickname, const std::string& password,
                              const std::string& resource, HistoryLimit history_limit)
{
  const auto& hostname = iid.get_server();
#ifdef USE_DATABASE
  auto soptions = Database::get_irc_server_options(this->get_bare_jid(), hostname);
  if (!soptions.col<Database::Nick>().empty())
    nickname = soptions.col<Database::Nick>();
#endif
  IrcClient* irc = this->make_irc_client(hostname, nickname);
  irc->history_limit = history_limit;
  this->add_resource_to_server(hostname, resource);

M src/bridge/bridge.hpp => src/bridge/bridge.hpp +1 -1
@@ 75,7 75,7 @@ public:
   * Try to join an irc_channel, does nothing and return true if the channel
   * was already joined.
   */
  bool join_irc_channel(const Iid& iid, const std::string& nickname, const std::string& password, const std::string& resource, HistoryLimit history_limit);
  bool join_irc_channel(const Iid& iid, std::string nickname, const std::string& password, const std::string& resource, HistoryLimit history_limit);

  void send_channel_message(const Iid& iid, const std::string& body, std::string id);
  void send_private_message(const Iid& iid, const std::string& body, const std::string& type="PRIVMSG");

M src/database/database.hpp => src/database/database.hpp +1 -1
@@ 92,7 92,7 @@ class Database
  using GlobalOptionsTable = Table<Id, Owner, MaxHistoryLength, RecordHistory, GlobalPersistent>;
  using GlobalOptions = GlobalOptionsTable::RowType;

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

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

M src/xmpp/biboumi_adhoc_commands.cpp => src/xmpp/biboumi_adhoc_commands.cpp +16 -0
@@ 293,6 293,20 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
      }
  }
#endif

  {
    XmlSubNode field(x, "field");
    field["var"] = "nick";
    field["type"] = "text-single";
    field["label"] = "Nickname";
    field["desc"] = "If set, will override the nickname provided in the initial presence sent to join the first server channel";
    if (!options.col<Database::Nick>().empty())
      {
        XmlSubNode value(field, "value");
        value.set_inner(options.col<Database::Nick>());
      }
  }

  {
    XmlSubNode pass(x, "field");
    pass["var"] = "pass";


@@ 427,6 441,8 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com

#endif // BOTAN_FOUND

          else if (field->get_tag("var") == "nick" && value)
            options.col<Database::Nick>() = value->get_inner();
          else if (field->get_tag("var") == "pass" && value)
            options.col<Database::Pass>() = value->get_inner();


M tests/end_to_end/__main__.py => tests/end_to_end/__main__.py +5 -1
@@ 2760,6 2760,7 @@ if __name__ == '__main__':
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='fingerprint']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-private'][@var='pass']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='after_connect_commands']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='nick']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='username']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='realname']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']",


@@ 2777,6 2778,7 @@ if __name__ == '__main__':
                                          "<field var='fingerprint'><value>12:12:12</value></field>"
                                          "<field var='pass'><value>coucou</value></field>"
                                          "<field var='after_connect_commands'><value>first command</value><value>second command</value></field>"
                                          "<field var='nick'><value>my_nickname</value></field>"
                                          "<field var='username'><value>username</value></field>"
                                          "<field var='realname'><value>realname</value></field>"
                                          "<field var='encoding_out'><value>UTF-8</value></field>"


@@ 2794,6 2796,7 @@ if __name__ == '__main__':
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='verify_cert']/dataform:value[text()='true']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='fingerprint']/dataform:value[text()='12:12:12']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-private'][@var='pass']/dataform:value[text()='coucou']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='nick']/dataform:value[text()='my_nickname']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='after_connect_commands']/dataform:value[text()='first command']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-multi'][@var='after_connect_commands']/dataform:value[text()='second command']",
                                             "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='username']/dataform:value[text()='username']",


@@ 2941,6 2944,7 @@ if __name__ == '__main__':
                                           "<field var='ports' />"
                                           "<field var='tls_ports'><value>7778</value></field>"
                                           "<field var='verify_cert'><value>0</value></field>"
                                           "<field var='nick'><value>my_special_nickname</value></field>"
                                           "</x></command></iq>"),
                      partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),



@@ 2950,7 2954,7 @@ if __name__ == '__main__':
                      partial(expect_stanza,
                              "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
                      partial(expect_stanza,
                              ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/{nick_one}']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
                              ("/presence[@to='{jid_one}/{resource_one}'][@from='#foo%{irc_server_one}/my_special_nickname']/muc_user:x/muc_user:item[@affiliation='admin'][@role='moderator']",
                               "/presence/muc_user:x/muc_user:status[@code='110']")
                              ),
                      partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),