M CHANGELOG.rst => CHANGELOG.rst +3 -0
@@ 15,6 15,9 @@ Version 6.0
supported.
- Invitations can now be sent to any JID, not only JIDs served by the biboumi
instance itself.
+ - The persistent_by_default configuration option has been added, this
+ lets the administrator decide whether or not the rooms should be
+ persistent or not by default, for all users.
Version 5.0 - 2017-05-24
========================
M doc/biboumi.1.rst => doc/biboumi.1.rst +22 -4
@@ 100,6 100,21 @@ 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.
+persistent_by_default
+---------------------
+
+If this option is set to `true`, all rooms will be persistent by default:
+the value of the “persistent” option in the global configuration of each
+user will be “true”, but the value of each individual room will still
+default to false. This means that a user just needs to change the global
+“persistent” configuration option to false in order to override this.
+
+If it is set to false (the default value), all rooms are not persistent by
+default.
+
+Each room can be configured individually by each user, to override this
+default value. See `Ad-hoc commands`_.
+
realname_customization
----------------------
@@ 595,10 610,13 @@ On the gateway itself (e.g on the JID biboumi.example.com):
the database.
* Max history length: The maximum number of lines in the history
that the server is allowed to send when joining a channel.
- * Persistent: Overrides the value specified in each individual channel,
- all channels are persistent, whether or not their specific value is
- true or false. See below for more details on what a persistent
- channel is.
+
+ * Persistent: Overrides the value specified in each individual channel.
+ If this option is set to true, all channels are persistent, whether
+ or not their specific value is true or false. This option is true by
+ default for everyone if the `persistent_by_default` configuration
+ option is true, otherwise it’s false. See below for more details on
+ what a persistent channel is. This value is
On a server JID (e.g on the JID chat.freenode.org@biboumi.example.com)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
M src/bridge/bridge.cpp => src/bridge/bridge.cpp +1 -1
@@ 435,7 435,7 @@ void Bridge::leave_irc_channel(Iid&& iid, const std::string& status_message, con
bool persistent = false;
#ifdef USE_DATABASE
const auto goptions = Database::get_global_options(this->user_jid);
- if (goptions.col<Database::Persistent>())
+ if (goptions.col<Database::GlobalPersistent>())
persistent = true;
else
{
M src/config/config.cpp => src/config/config.cpp +8 -0
@@ 23,6 23,14 @@ std::string Config::get(const std::string& option, const std::string& def)
return it->second;
}
+bool Config::get_bool(const std::string& option, const bool def)
+{
+ auto res = Config::get(option, "");
+ if (res.empty())
+ return def;
+ return res == "true";
+}
+
int Config::get_int(const std::string& option, const int& def)
{
std::string res = Config::get(option, "");
M src/config/config.hpp => src/config/config.hpp +1 -0
@@ 44,6 44,7 @@ public:
* the second argument as the default.
*/
static int get_int(const std::string&, const int&);
+ static bool get_bool(const std::string&, const bool);
/**
* Set a value for the given option. And write all the config
* in the file from which it was read if save is true.
M src/database/database.cpp => src/database/database.cpp +5 -0
@@ 6,6 6,8 @@
#include <utils/get_first_non_empty.hpp>
#include <utils/time.hpp>
+#include <config/config.hpp>
+
#include <database/index.hpp>
#include <sqlite3.h>
@@ 18,6 20,9 @@ Database::IrcChannelOptionsTable Database::irc_channel_options("IrcChannelOption
Database::RosterTable Database::roster("roster");
std::map<Database::CacheKey, Database::EncodingIn::real_type> Database::encoding_in_cache{};
+Database::GlobalPersistent::GlobalPersistent():
+ Column<bool>{Config::get_bool("persistent_by_default", false)}
+{}
void Database::open(const std::string& filename)
{
M src/database/database.hpp => src/database/database.hpp +4 -1
@@ 73,6 73,9 @@ class Database
struct Persistent: Column<bool> { static constexpr auto name = "persistent_";
Persistent(): Column<bool>(false) {} };
+ struct GlobalPersistent: Column<bool> { static constexpr auto name = "persistent_";
+ GlobalPersistent(); };
+
struct LocalJid: Column<std::string> { static constexpr auto name = "local"; };
struct RemoteJid: Column<std::string> { static constexpr auto name = "remote"; };
@@ 81,7 84,7 @@ class Database
using MucLogLineTable = Table<Id, Uuid, Owner, IrcChanName, IrcServerName, Date, Body, Nick>;
using MucLogLine = MucLogLineTable::RowType;
- using GlobalOptionsTable = Table<Id, Owner, MaxHistoryLength, RecordHistory, Persistent>;
+ 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>;
M src/xmpp/biboumi_adhoc_commands.cpp => src/xmpp/biboumi_adhoc_commands.cpp +2 -2
@@ 159,7 159,7 @@ void ConfigureGlobalStep1(XmppComponent&, AdhocSession& session, XmlNode& comman
{
XmlSubNode value(persistent, "value");
value.set_name("value");
- if (options.col<Database::Persistent>())
+ if (options.col<Database::GlobalPersistent>())
value.set_inner("true");
else
value.set_inner("false");
@@ 193,7 193,7 @@ void ConfigureGlobalStep2(XmppComponent& xmpp_component, AdhocSession& session,
}
else if (field->get_tag("var") == "persistent" &&
value)
- options.col<Database::Persistent>() = to_bool(value->get_inner());
+ options.col<Database::GlobalPersistent>() = to_bool(value->get_inner());
}
options.save(Database::db);
M tests/end_to_end/__main__.py => tests/end_to_end/__main__.py +24 -1
@@ 377,7 377,15 @@ port=8811
fixed_irc_server=irc.localhost
admin=admin@example.com
identd_port=1113
-"""}
+""",
+
+'persistent_by_default':
+"""hostname=biboumi.localhost
+password=coucou
+db_name=e2e_test.sqlite
+port=8811
+persistent_by_default=true
+""",}
common_replacements = {
'irc_server_one': 'irc.localhost@biboumi.localhost',
@@ 2650,6 2658,7 @@ if __name__ == '__main__':
"/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure your global settings for the component.']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='max_history_length']/dataform:value[text()='20']",
"/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='record_history']/dataform:value[text()='true']",
+ "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='persistent']/dataform:value[text()='false']",
"/iq/commands:command/commands:actions/commands:next",
),
after = partial(save_value, "sessionid", partial(extract_attribute, "/iq[@type='result']/commands:command[@node='configure']", "sessionid"))
@@ 2671,6 2680,20 @@ if __name__ == '__main__':
partial(send_stanza, "<iq type='set' id='id4' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' action='cancel' node='configure' sessionid='{sessionid}' /></iq>"),
partial(expect_stanza, "/iq[@type='result']/commands:command[@node='configure'][@status='canceled']"),
]),
+ Scenario("global_configure_persistent_by_default",
+ [
+ handshake_sequence(),
+ partial(send_stanza, "<iq type='set' id='id1' from='{jid_one}/{resource_one}' to='{biboumi_host}'><command xmlns='http://jabber.org/protocol/commands' node='configure' action='execute' /></iq>"),
+ partial(expect_stanza, ("/iq[@type='result']/commands:command[@node='configure'][@sessionid][@status='executing']",
+ "/iq/commands:command/dataform:x[@type='form']/dataform:title[text()='Configure some global default settings.']",
+ "/iq/commands:command/dataform:x[@type='form']/dataform:instructions[text()='Edit the form, to configure your global settings for the component.']",
+ "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='text-single'][@var='max_history_length']/dataform:value[text()='20']",
+ "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='record_history']/dataform:value[text()='true']",
+ "/iq/commands:command/dataform:x[@type='form']/dataform:field[@type='boolean'][@var='persistent']/dataform:value[text()='true']",
+ "/iq/commands:command/commands:actions/commands:next",
+ ),
+ ),
+ ],conf='persistent_by_default'),
Scenario("irc_server_configure",
[
handshake_sequence(),