@@ -11,6 +11,8 @@ Version 8.0
|
|||||||
- We now properly deal with a PostgreSQL server restart: whenever the
|
- 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
|
connection is lost with the server, we try to reconnect and re-execute the
|
||||||
query once.
|
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
|
Version 7.2 - 2018-01-24
|
||||||
========================
|
========================
|
||||||
|
|||||||
@@ -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
|
* 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
|
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.
|
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,
|
* 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
|
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
|
only allowed to connect if you have the password. Note that, although
|
||||||
|
|||||||
@@ -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 std::string& resource, HistoryLimit history_limit)
|
||||||
{
|
{
|
||||||
const auto& hostname = iid.get_server();
|
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);
|
IrcClient* irc = this->make_irc_client(hostname, nickname);
|
||||||
irc->history_limit = history_limit;
|
irc->history_limit = history_limit;
|
||||||
this->add_resource_to_server(hostname, resource);
|
this->add_resource_to_server(hostname, resource);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public:
|
|||||||
* Try to join an irc_channel, does nothing and return true if the channel
|
* Try to join an irc_channel, does nothing and return true if the channel
|
||||||
* was already joined.
|
* 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_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");
|
void send_private_message(const Iid& iid, const std::string& body, const std::string& type="PRIVMSG");
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class Database
|
|||||||
using GlobalOptionsTable = Table<Id, Owner, MaxHistoryLength, RecordHistory, GlobalPersistent>;
|
using GlobalOptionsTable = Table<Id, Owner, MaxHistoryLength, RecordHistory, GlobalPersistent>;
|
||||||
using GlobalOptions = GlobalOptionsTable::RowType;
|
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 IrcServerOptions = IrcServerOptionsTable::RowType;
|
||||||
|
|
||||||
using IrcChannelOptionsTable = Table<Id, Owner, Server, Channel, EncodingOut, EncodingIn, MaxHistoryLength, Persistent, RecordHistoryOptional>;
|
using IrcChannelOptionsTable = Table<Id, Owner, Server, Channel, EncodingOut, EncodingIn, MaxHistoryLength, Persistent, RecordHistoryOptional>;
|
||||||
|
|||||||
@@ -293,6 +293,20 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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");
|
XmlSubNode pass(x, "field");
|
||||||
pass["var"] = "pass";
|
pass["var"] = "pass";
|
||||||
@@ -427,6 +441,8 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com
|
|||||||
|
|
||||||
#endif // BOTAN_FOUND
|
#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)
|
else if (field->get_tag("var") == "pass" && value)
|
||||||
options.col<Database::Pass>() = value->get_inner();
|
options.col<Database::Pass>() = value->get_inner();
|
||||||
|
|
||||||
|
|||||||
@@ -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-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-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-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='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='realname']",
|
||||||
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='encoding_in']",
|
"/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='fingerprint'><value>12:12:12</value></field>"
|
||||||
"<field var='pass'><value>coucou</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='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='username'><value>username</value></field>"
|
||||||
"<field var='realname'><value>realname</value></field>"
|
"<field var='realname'><value>realname</value></field>"
|
||||||
"<field var='encoding_out'><value>UTF-8</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='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-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-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()='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-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']",
|
"/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='ports' />"
|
||||||
"<field var='tls_ports'><value>7778</value></field>"
|
"<field var='tls_ports'><value>7778</value></field>"
|
||||||
"<field var='verify_cert'><value>0</value></field>"
|
"<field var='verify_cert'><value>0</value></field>"
|
||||||
|
"<field var='nick'><value>my_special_nickname</value></field>"
|
||||||
"</x></command></iq>"),
|
"</x></command></iq>"),
|
||||||
partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='completed']/commands:note[@type='info'][text()='Configuration successfully applied.']"),
|
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,
|
partial(expect_stanza,
|
||||||
"/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
|
"/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
|
||||||
partial(expect_stanza,
|
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']")
|
"/presence/muc_user:x/muc_user:status[@code='110']")
|
||||||
),
|
),
|
||||||
partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
|
partial(expect_stanza, "/message[@from='#foo%{irc_server_one}'][@type='groupchat']/subject[not(text())]"),
|
||||||
|
|||||||
Reference in New Issue
Block a user