diff options
-rw-r--r-- | CHANGELOG.rst | 3 | ||||
-rw-r--r-- | doc/biboumi.1.rst | 26 | ||||
-rw-r--r-- | src/bridge/bridge.cpp | 2 | ||||
-rw-r--r-- | src/config/config.cpp | 8 | ||||
-rw-r--r-- | src/config/config.hpp | 1 | ||||
-rw-r--r-- | src/database/database.cpp | 5 | ||||
-rw-r--r-- | src/database/database.hpp | 5 | ||||
-rw-r--r-- | src/xmpp/biboumi_adhoc_commands.cpp | 4 | ||||
-rw-r--r-- | tests/end_to_end/__main__.py | 25 |
9 files changed, 70 insertions, 9 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f327fb1..528e63f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -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 ======================== diff --git a/doc/biboumi.1.rst b/doc/biboumi.1.rst index 3c5ec8e..9227ff6 100644 --- a/doc/biboumi.1.rst +++ b/doc/biboumi.1.rst @@ -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) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 02ba565..8587264 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -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 { diff --git a/src/config/config.cpp b/src/config/config.cpp index 0f3d639..412b170 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -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, ""); diff --git a/src/config/config.hpp b/src/config/config.hpp index 2ba38cc..c5ef15d 100644 --- a/src/config/config.hpp +++ b/src/config/config.hpp @@ -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. diff --git a/src/database/database.cpp b/src/database/database.cpp index f706528..a2b88e2 100644 --- a/src/database/database.cpp +++ b/src/database/database.cpp @@ -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) { diff --git a/src/database/database.hpp b/src/database/database.hpp index f4b2ecd..f9695d3 100644 --- a/src/database/database.hpp +++ b/src/database/database.hpp @@ -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>; diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index d78dc98..bcdac39 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -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); diff --git a/tests/end_to_end/__main__.py b/tests/end_to_end/__main__.py index 93474ac..dfb6ef7 100644 --- a/tests/end_to_end/__main__.py +++ b/tests/end_to_end/__main__.py @@ -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(), |