diff options
-rw-r--r-- | CHANGELOG.rst | 2 | ||||
-rw-r--r-- | doc/biboumi.1.rst | 6 | ||||
-rw-r--r-- | src/bridge/bridge.cpp | 7 | ||||
-rw-r--r-- | src/bridge/bridge.hpp | 2 | ||||
-rw-r--r-- | src/database/database.hpp | 2 | ||||
-rw-r--r-- | src/xmpp/biboumi_adhoc_commands.cpp | 16 | ||||
-rw-r--r-- | tests/end_to_end/__main__.py | 6 |
7 files changed, 37 insertions, 4 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ee31f7d..bf25e52 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -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 ======================== diff --git a/doc/biboumi.1.rst b/doc/biboumi.1.rst index 2f17823..ccf3985 100644 --- a/doc/biboumi.1.rst +++ b/doc/biboumi.1.rst @@ -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 diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index aba2f05..bff86b9 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -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); diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index 3798465..a4ee693 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -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"); diff --git a/src/database/database.hpp b/src/database/database.hpp index 5dde447..d986ecc 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -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>; diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index d773ec3..66298d4 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -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(); diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 914f545..6b97e4a 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -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())]"), |