Merge branch 'fixed_server'
This commit is contained in:
@@ -59,6 +59,24 @@ The configuration file uses a simple format of the form
|
||||
privileges), for example some administration ad-hoc commands will only be
|
||||
available to that JID.
|
||||
|
||||
`fixed_irc_server`
|
||||
|
||||
If this option contains the hostname of an IRC server (for example
|
||||
irc.example.org), then biboumi will enforce the connexion to that IRC
|
||||
server only. This means that a JID like "#chan@biboumi.example.com" must
|
||||
be used instead of "#chan%irc.example.org@biboumi.example.com". In that
|
||||
mode, the virtual channel (see *Connect to an IRC server*) is not
|
||||
available and you still need to use the ! separator to send message to an
|
||||
IRC user (for example "foo!@biboumi.example.com" to send a message to
|
||||
foo), although the in-room JID still work as expected
|
||||
("#channel@biboumi.example.com/Nick"). On the other hand, the '%' lose
|
||||
any meaning. It can appear in the JID but will not be interpreted as a
|
||||
separator (thus the JID "#channel%hello@biboumi.example.com" points to the
|
||||
channel named "#channel%hello" on the configured IRC server) This option
|
||||
can for example be used by an administrator that just wants to let their
|
||||
users join their own IRC server using an XMPP client, while forbidding
|
||||
access to any other IRC server.
|
||||
|
||||
`log_file`
|
||||
|
||||
A filename into which logs are written. If none is provided, the logs are
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <xmpp/xmpp_stanza.hpp>
|
||||
#include <irc/irc_message.hpp>
|
||||
#include <network/poller.hpp>
|
||||
#include <utils/empty_if_fixed_server.hpp>
|
||||
#include <utils/encoding.hpp>
|
||||
#include <utils/tolower.hpp>
|
||||
#include <logger/logger.hpp>
|
||||
@@ -580,13 +581,13 @@ void Bridge::send_user_join(const std::string& hostname,
|
||||
std::string role;
|
||||
std::tie(role, affiliation) = get_role_affiliation_from_irc_mode(user_mode);
|
||||
|
||||
this->xmpp->send_user_join(chan_name + "%" + hostname, user->nick, user->host,
|
||||
this->xmpp->send_user_join(chan_name + utils::empty_if_fixed_server("%" + hostname), user->nick, user->host,
|
||||
affiliation, role, this->user_jid, self);
|
||||
}
|
||||
|
||||
void Bridge::send_topic(const std::string& hostname, const std::string& chan_name, const std::string& topic)
|
||||
{
|
||||
this->xmpp->send_topic(chan_name + "%" + hostname, this->make_xmpp_body(topic), this->user_jid);
|
||||
this->xmpp->send_topic(chan_name + utils::empty_if_fixed_server("%" + hostname), this->make_xmpp_body(topic), this->user_jid);
|
||||
}
|
||||
|
||||
std::string Bridge::get_own_nick(const Iid& iid)
|
||||
@@ -623,7 +624,7 @@ void Bridge::send_affiliation_role_change(const Iid& iid, const std::string& tar
|
||||
|
||||
void Bridge::send_iq_version_request(const std::string& nick, const std::string& hostname)
|
||||
{
|
||||
this->xmpp->send_iq_version_request(nick + "!" + hostname, this->user_jid);
|
||||
this->xmpp->send_iq_version_request(nick + "!" + utils::empty_if_fixed_server(hostname), this->user_jid);
|
||||
}
|
||||
|
||||
void Bridge::send_xmpp_ping_request(const std::string& nick, const std::string& hostname,
|
||||
@@ -632,7 +633,7 @@ void Bridge::send_xmpp_ping_request(const std::string& nick, const std::string&
|
||||
// Use revstr because the forwarded ping to target XMPP user must not be
|
||||
// the same that the request iq, but we also need to get it back easily
|
||||
// (revstr again)
|
||||
this->xmpp->send_ping_request(nick + "!" + hostname, this->user_jid, utils::revstr(id));
|
||||
this->xmpp->send_ping_request(nick + "!" + utils::empty_if_fixed_server(hostname), this->user_jid, utils::revstr(id));
|
||||
}
|
||||
|
||||
void Bridge::set_preferred_from_jid(const std::string& nick, const std::string& full_jid)
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
#include <utils/tolower.hpp>
|
||||
#include <config/config.hpp>
|
||||
|
||||
#include <irc/iid.hpp>
|
||||
|
||||
Iid::Iid(const std::string& iid):
|
||||
is_channel(false),
|
||||
is_user(false)
|
||||
{
|
||||
const std::string fixed_irc_server = Config::get("fixed_irc_server", "");
|
||||
if (fixed_irc_server.empty())
|
||||
this->init(iid);
|
||||
else
|
||||
this->init_with_fixed_server(iid, fixed_irc_server);
|
||||
}
|
||||
|
||||
|
||||
void Iid::init(const std::string& iid)
|
||||
{
|
||||
const std::string::size_type sep = iid.find_first_of("%!");
|
||||
if (sep != std::string::npos)
|
||||
@@ -20,6 +31,26 @@ Iid::Iid(const std::string& iid):
|
||||
this->set_server(iid);
|
||||
}
|
||||
|
||||
void Iid::init_with_fixed_server(const std::string& iid, const std::string& hostname)
|
||||
{
|
||||
this->set_server(hostname);
|
||||
|
||||
const std::string::size_type sep = iid.find("!");
|
||||
|
||||
// Without any separator, we consider that it's a channel
|
||||
if (sep == std::string::npos)
|
||||
{
|
||||
this->is_channel = true;
|
||||
this->set_local(iid);
|
||||
}
|
||||
else // A separator can be present to differenciate a channel from a user,
|
||||
// but the part behind it (the hostname) is ignored
|
||||
{
|
||||
this->set_local(iid.substr(0, sep));
|
||||
this->is_user = true;
|
||||
}
|
||||
}
|
||||
|
||||
Iid::Iid(const Iid& other):
|
||||
is_channel(other.is_channel),
|
||||
is_user(other.is_user),
|
||||
@@ -66,6 +97,14 @@ std::string Iid::get_sep() const
|
||||
namespace std {
|
||||
const std::string to_string(const Iid& iid)
|
||||
{
|
||||
if (Config::get("fixed_irc_server", "").empty())
|
||||
return iid.get_local() + iid.get_sep() + iid.get_server();
|
||||
else
|
||||
{
|
||||
if (iid.get_sep() == "!")
|
||||
return iid.get_local() + iid.get_sep();
|
||||
else
|
||||
return iid.get_local();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,10 @@ public:
|
||||
std::string get_sep() const;
|
||||
|
||||
private:
|
||||
|
||||
void init(const std::string& iid);
|
||||
void init_with_fixed_server(const std::string& iid, const std::string& hostname);
|
||||
|
||||
std::string local;
|
||||
std::string server;
|
||||
|
||||
|
||||
@@ -303,6 +303,7 @@ int main()
|
||||
/**
|
||||
* IID parsing
|
||||
*/
|
||||
{
|
||||
std::cout << color << "Testing IID parsing…" << reset << std::endl;
|
||||
Iid iid1("foo!irc.example.org");
|
||||
std::cout << std::to_string(iid1) << std::endl;
|
||||
@@ -336,5 +337,66 @@ int main()
|
||||
assert(!iid4.is_channel);
|
||||
assert(!iid4.is_user);
|
||||
|
||||
Iid iid5("nick!");
|
||||
std::cout << std::to_string(iid5) << std::endl;
|
||||
assert(std::to_string(iid5) == "nick!");
|
||||
assert(iid5.get_local() == "nick");
|
||||
assert(iid5.get_server() == "");
|
||||
assert(!iid5.is_channel);
|
||||
assert(iid5.is_user);
|
||||
|
||||
Iid iid6("##channel%");
|
||||
std::cout << std::to_string(iid6) << std::endl;
|
||||
assert(std::to_string(iid6) == "##channel%");
|
||||
assert(iid6.get_local() == "##channel");
|
||||
assert(iid6.get_server() == "");
|
||||
assert(iid6.is_channel);
|
||||
assert(!iid6.is_user);
|
||||
}
|
||||
|
||||
{
|
||||
std::cout << color << "Testing IID parsing with a fixed server configured…" << reset << std::endl;
|
||||
// Now do the same tests, but with a configured fixed_irc_server
|
||||
Config::set("fixed_irc_server", "fixed.example.com", false);
|
||||
|
||||
Iid iid1("foo!irc.example.org");
|
||||
std::cout << std::to_string(iid1) << std::endl;
|
||||
assert(std::to_string(iid1) == "foo!");
|
||||
assert(iid1.get_local() == "foo");
|
||||
assert(iid1.get_server() == "fixed.example.com");
|
||||
assert(!iid1.is_channel);
|
||||
assert(iid1.is_user);
|
||||
|
||||
Iid iid2("#test%irc.example.org");
|
||||
std::cout << std::to_string(iid2) << std::endl;
|
||||
assert(std::to_string(iid2) == "#test%irc.example.org");
|
||||
assert(iid2.get_local() == "#test%irc.example.org");
|
||||
assert(iid2.get_server() == "fixed.example.com");
|
||||
assert(iid2.is_channel);
|
||||
assert(!iid2.is_user);
|
||||
|
||||
// Note that it is impossible to adress the IRC server directly, or to
|
||||
// use the virtual channel, in that mode
|
||||
|
||||
// Iid iid3("%irc.example.org");
|
||||
// Iid iid4("irc.example.org");
|
||||
|
||||
Iid iid5("nick!");
|
||||
std::cout << std::to_string(iid5) << std::endl;
|
||||
assert(std::to_string(iid5) == "nick!");
|
||||
assert(iid5.get_local() == "nick");
|
||||
assert(iid5.get_server() == "fixed.example.com");
|
||||
assert(!iid5.is_channel);
|
||||
assert(iid5.is_user);
|
||||
|
||||
Iid iid6("##channel%");
|
||||
std::cout << std::to_string(iid6) << std::endl;
|
||||
assert(std::to_string(iid6) == "##channel%");
|
||||
assert(iid6.get_local() == "##channel%");
|
||||
assert(iid6.get_server() == "fixed.example.com");
|
||||
assert(iid6.is_channel);
|
||||
assert(!iid6.is_user);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef EMPTY_IF_FIXED_SERVER_HPP_INCLUDED
|
||||
#define EMPTY_IF_FIXED_SERVER_HPP_INCLUDED
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <config/config.hpp>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
inline std::string empty_if_fixed_server(std::string&& str)
|
||||
{
|
||||
if (!Config::get("fixed_irc_server", "").empty())
|
||||
return {};
|
||||
return str;
|
||||
}
|
||||
|
||||
inline std::string empty_if_fixed_server(const std::string& str)
|
||||
{
|
||||
if (!Config::get("fixed_irc_server", "").empty())
|
||||
return {};
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* EMPTY_IF_FIXED_SERVER_HPP_INCLUDED */
|
||||
Reference in New Issue
Block a user