From 924cd61091de766f78390dab588b6413696db70a Mon Sep 17 00:00:00 2001
From: Pierre Lespagnol <pierre.lespagnol@savoirfairelinux.com>
Date: Thu, 25 Feb 2021 16:50:30 -0500
Subject: [PATCH] conference: add account preference to enable moderation for
 all

Gitlab: #453

Change-Id: I9a870b2f930c69fe26432f1f15169d13365e702d
---
 .../cx.ring.Ring.ConfigurationManager.xml     | 11 +++++++++
 bin/dbus/dbusconfigurationmanager.cpp         | 13 +++++++++++
 bin/dbus/dbusconfigurationmanager.h           |  2 ++
 bin/jni/configurationmanager.i                |  2 ++
 configure.ac                                  |  2 +-
 src/account.cpp                               |  8 ++++++-
 src/account.h                                 |  4 ++++
 src/account_schema.h                          |  1 +
 src/client/configurationmanager.cpp           | 12 ++++++++++
 src/conference.cpp                            |  5 ++++
 src/dring/account_const.h                     |  1 +
 src/dring/configurationmanager_interface.h    | 11 +++++++++
 src/manager.cpp                               | 23 +++++++++++++++++++
 src/manager.h                                 |  2 ++
 14 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
index cea57710e8..059e4b60bb 100644
--- a/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
+++ b/bin/dbus/cx.ring.Ring.ConfigurationManager.xml
@@ -1785,5 +1785,16 @@
            <arg type="s" name="accountID" direction="in"/>
            <arg type="b" name="isModEnabled" direction="out"/>
        </method>
+
+       <method name="setAllModerators" tp:name-for-bindings="setAllModerators">
+           <tp:added version="9.10.0"/>
+           <arg type="s" name="accountID" direction="in"/>
+           <arg type="b" name="allModerators" direction="in"/>
+       </method>
+       <method name="isAllModerators" tp:name-for-bindings="isAllModerators">
+           <tp:added version="9.10.0"/>
+           <arg type="s" name="accountID" direction="in"/>
+           <arg type="b" name="allModerators" direction="out"/>
+       </method>
    </interface>
 </node>
diff --git a/bin/dbus/dbusconfigurationmanager.cpp b/bin/dbus/dbusconfigurationmanager.cpp
index 927a7c22ac..7e2ea1afb2 100644
--- a/bin/dbus/dbusconfigurationmanager.cpp
+++ b/bin/dbus/dbusconfigurationmanager.cpp
@@ -777,3 +777,16 @@ DBusConfigurationManager::isLocalModeratorsEnabled(const std::string& accountID)
     return DRing::isLocalModeratorsEnabled(accountID);
 }
 
+void
+DBusConfigurationManager::setAllModerators(const std::string& accountID,
+                                                const bool& allModerators)
+{
+    return DRing::setAllModerators(accountID, allModerators);
+}
+
+bool
+DBusConfigurationManager::isAllModerators(const std::string& accountID)
+{
+    return DRing::isAllModerators(accountID);
+}
+
diff --git a/bin/dbus/dbusconfigurationmanager.h b/bin/dbus/dbusconfigurationmanager.h
index 114e4e4af3..956b28b2f4 100644
--- a/bin/dbus/dbusconfigurationmanager.h
+++ b/bin/dbus/dbusconfigurationmanager.h
@@ -181,6 +181,8 @@ class DRING_PUBLIC DBusConfigurationManager :
         std::vector<std::string> getDefaultModerators(const std::string& accountID);
         void enableLocalModerators(const std::string& accountID, const bool& isModEnabled);
         bool isLocalModeratorsEnabled(const std::string& accountID);
+        void setAllModerators(const std::string& accountID, const bool& allModerators);
+        bool isAllModerators(const std::string& accountID);
 };
 
 #endif // __RING_DBUSCONFIGURATIONMANAGER_H__
diff --git a/bin/jni/configurationmanager.i b/bin/jni/configurationmanager.i
index bee1cd6a77..3a2f9445c9 100644
--- a/bin/jni/configurationmanager.i
+++ b/bin/jni/configurationmanager.i
@@ -234,6 +234,8 @@ void setDefaultModerator(const std::string& accountID, const std::string& peerUR
 std::vector<std::string> getDefaultModerators(const std::string& accountID);
 void enableLocalModerators(const std::string& accountID, bool isModEnabled);
 bool isLocalModeratorsEnabled(const std::string& accountID);
+void setAllModerators(const std::string& accountID, bool allModerators);
+bool isAllModerators(const std::string& accountID);
 
 }
 
diff --git a/configure.ac b/configure.ac
index feb83231ea..c9926a7a9a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@ dnl Jami - configure.ac for automake 1.9 and autoconf 2.59
 
 dnl Process this file with autoconf to produce a configure script.
 AC_PREREQ([2.65])
-AC_INIT([Jami Daemon],[9.9.0],[ring@gnu.org],[jami])
+AC_INIT([Jami Daemon],[9.10.0],[ring@gnu.org],[jami])
 
 AC_COPYRIGHT([[Copyright (c) Savoir-faire Linux 2004-2020]])
 AC_REVISION([$Revision$])
diff --git a/src/account.cpp b/src/account.cpp
index a391b395f5..c1f7f43e05 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -89,6 +89,7 @@ const char* const Account::ACTIVE_CODEC_KEY = "activeCodecs";
 const std::string Account::DEFAULT_USER_AGENT = Account::setDefaultUserAgent();
 const char* const Account::DEFAULT_MODERATORS_KEY = "defaultModerators";
 const char* const Account::LOCAL_MODERATORS_ENABLED_KEY = "localModeratorsEnabled";
+const char* const Account::ALL_MODERATORS_ENABLED_KEY = "allModeratorsEnabled";
 
 #ifdef __ANDROID__
 constexpr const char* const DEFAULT_RINGTONE_PATH
@@ -117,6 +118,7 @@ Account::Account(const std::string& accountID)
     , mailBox_()
     , upnpEnabled_(true)
     , localModeratorsEnabled_(true)
+    , allModeratorsEnabled_(true)
 {
     // Initialize the codec order, used when creating a new account
     loadDefaultCodecs();
@@ -242,6 +244,7 @@ Account::serialize(YAML::Emitter& out) const
     out << YAML::Key << UPNP_ENABLED_KEY << YAML::Value << upnpEnabled_;
     out << YAML::Key << DEFAULT_MODERATORS_KEY << YAML::Value << string_join(defaultModerators_);
     out << YAML::Key << LOCAL_MODERATORS_ENABLED_KEY << YAML::Value << localModeratorsEnabled_;
+    out << YAML::Key << ALL_MODERATORS_ENABLED_KEY << YAML::Value << allModeratorsEnabled_;
 }
 
 void
@@ -297,6 +300,7 @@ Account::unserialize(const YAML::Node& node)
     parseValueOptional(node, DEFAULT_MODERATORS_KEY, defMod);
     defaultModerators_ = string_split_set(defMod);
     parseValueOptional(node, LOCAL_MODERATORS_ENABLED_KEY, localModeratorsEnabled_);
+    parseValueOptional(node, ALL_MODERATORS_ENABLED_KEY, allModeratorsEnabled_);
 }
 
 void
@@ -325,6 +329,7 @@ Account::setAccountDetails(const std::map<std::string, std::string>& details)
     auto defMod = string_join(defaultModerators_);
     parseString(details, Conf::CONFIG_DEFAULT_MODERATORS, defMod);
     parseBool(details, Conf::CONFIG_LOCAL_MODERATORS_ENABLED, localModeratorsEnabled_);
+    parseBool(details, Conf::CONFIG_ALL_MODERATORS_ENABLED, allModeratorsEnabled_);
 }
 
 std::map<std::string, std::string>
@@ -346,7 +351,8 @@ Account::getAccountDetails() const
             {Conf::CONFIG_RINGTONE_PATH, ringtonePath_},
             {Conf::CONFIG_UPNP_ENABLED, upnpEnabled_ ? TRUE_STR : FALSE_STR},
             {Conf::CONFIG_DEFAULT_MODERATORS, string_join(defaultModerators_)},
-            {Conf::CONFIG_LOCAL_MODERATORS_ENABLED, localModeratorsEnabled_ ? TRUE_STR : FALSE_STR}};
+            {Conf::CONFIG_LOCAL_MODERATORS_ENABLED, localModeratorsEnabled_ ? TRUE_STR : FALSE_STR},
+            {Conf::CONFIG_ALL_MODERATORS_ENABLED, allModeratorsEnabled_ ? TRUE_STR : FALSE_STR}};
 }
 
 std::map<std::string, std::string>
diff --git a/src/account.h b/src/account.h
index 4285dd9713..0b00e46b48 100644
--- a/src/account.h
+++ b/src/account.h
@@ -325,6 +325,8 @@ public:
 
     bool isLocalModeratorsEnabled() const { return localModeratorsEnabled_; }
     void enableLocalModerators(bool isModEnabled) { localModeratorsEnabled_ = isModEnabled; }
+    bool isAllModerators() const { return allModeratorsEnabled_; }
+    void setAllModerators(bool isAllModeratorEnabled) { allModeratorsEnabled_ = isAllModeratorEnabled; }
 
 public: // virtual methods that has to be implemented by concrete classes
     /**
@@ -399,6 +401,7 @@ protected:
     static const char* const ACTIVE_CODEC_KEY;
     static const char* const DEFAULT_MODERATORS_KEY;
     static const char* const LOCAL_MODERATORS_ENABLED_KEY;
+    static const char* const ALL_MODERATORS_ENABLED_KEY;
 
     static const std::string DEFAULT_USER_AGENT;
 
@@ -518,6 +521,7 @@ protected:
 
     std::set<std::string> defaultModerators_ {};
     bool localModeratorsEnabled_;
+    bool allModeratorsEnabled_;
 
     /**
      * private account codec searching functions
diff --git a/src/account_schema.h b/src/account_schema.h
index f5a187fcf9..f66d87e92e 100644
--- a/src/account_schema.h
+++ b/src/account_schema.h
@@ -72,6 +72,7 @@ static const char* const CONFIG_PUBLISHED_ADDRESS = "Account.publishedAddress";
 static const char* const CONFIG_UPNP_ENABLED = "Account.upnpEnabled";
 static const char* const CONFIG_DEFAULT_MODERATORS = "Account.defaultModerator";
 static const char* const CONFIG_LOCAL_MODERATORS_ENABLED = "Account.localModeratorEnabled";
+static const char* const CONFIG_ALL_MODERATORS_ENABLED = "Account.allModeratorEnabled";
 
 // SIP specific parameters
 static const char* const CONFIG_STUN_SERVER = "STUN.server";
diff --git a/src/client/configurationmanager.cpp b/src/client/configurationmanager.cpp
index 9a9219ccf8..ba947450f7 100644
--- a/src/client/configurationmanager.cpp
+++ b/src/client/configurationmanager.cpp
@@ -1104,4 +1104,16 @@ isLocalModeratorsEnabled(const std::string& accountID)
     return jami::Manager::instance().isLocalModeratorsEnabled(accountID);
 }
 
+void
+setAllModerators(const std::string& accountID, bool allModerators)
+{
+    jami::Manager::instance().setAllModerators(accountID, allModerators);
+}
+
+bool
+isAllModerators(const std::string& accountID)
+{
+    return jami::Manager::instance().isAllModerators(accountID);
+}
+
 } // namespace DRing
diff --git a/src/conference.cpp b/src/conference.cpp
index 5651bc8440..0106ac03cd 100644
--- a/src/conference.cpp
+++ b/src/conference.cpp
@@ -201,6 +201,11 @@ Conference::add(const std::string& participant_id)
                     }
                     localModAdded_ = true;
                 }
+
+                // Check for allModeratorEnabled preference
+                if (account->isAllModerators()) {
+                    moderators_.emplace(string_remove_suffix(call->getPeerNumber(), '@'));
+                }
             }
         }
 #ifdef ENABLE_VIDEO
diff --git a/src/dring/account_const.h b/src/dring/account_const.h
index 9828c7223e..f5f6893734 100644
--- a/src/dring/account_const.h
+++ b/src/dring/account_const.h
@@ -153,6 +153,7 @@ constexpr static const char BOOTSTRAP_LIST_URL[] = "Account.bootstrapListUrl";
 constexpr static const char DHT_PROXY_LIST_URL[] = "Account.dhtProxyListUrl";
 constexpr static const char DEFAULT_MODERATORS[] = "Account.defaultModerators";
 constexpr static const char LOCAL_MODERATORS_ENABLED[] = "Account.localModeratorsEnabled";
+constexpr static const char ALL_MODERATORS_ENABLED[] = "Account.allModeratorsEnabled";
 
 namespace Audio {
 
diff --git a/src/dring/configurationmanager_interface.h b/src/dring/configurationmanager_interface.h
index b44a4c013d..1c388d34eb 100644
--- a/src/dring/configurationmanager_interface.h
+++ b/src/dring/configurationmanager_interface.h
@@ -309,6 +309,17 @@ DRING_PUBLIC void enableLocalModerators(const std::string& accountID,
  */
 DRING_PUBLIC bool isLocalModeratorsEnabled(const std::string& accountID);
 
+/**
+ * Enable/disable all moderators for conferences
+ */
+DRING_PUBLIC void setAllModerators(const std::string& accountID,
+                                        bool allModerators);
+
+/**
+ * Get all moderators state
+ */
+DRING_PUBLIC bool isAllModerators(const std::string& accountID);
+
 struct DRING_PUBLIC AudioSignal
 {
     struct DRING_PUBLIC DeviceEvent
diff --git a/src/manager.cpp b/src/manager.cpp
index b3c6e0ac38..f4715ea5ef 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -3321,4 +3321,27 @@ Manager::isLocalModeratorsEnabled(const std::string& accountID)
     return acc->isLocalModeratorsEnabled();
 }
 
+void
+Manager::setAllModerators(const std::string& accountID, bool allModerators)
+{
+    auto acc = getAccount(accountID);
+    if (!acc) {
+        JAMI_ERR("Fail to set all moderators, account %s not found", accountID.c_str());
+        return;
+    }
+    acc->setAllModerators(allModerators);
+    saveConfig(acc);
+}
+
+bool
+Manager::isAllModerators(const std::string& accountID)
+{
+    auto acc = getAccount(accountID);
+    if (!acc) {
+        JAMI_ERR("Fail to get all moderators, account %s not found", accountID.c_str());
+        return true; // Default value
+    }
+    return acc->isAllModerators();
+}
+
 } // namespace jami
diff --git a/src/manager.h b/src/manager.h
index c5a2bb1ef0..bf57726f25 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -940,6 +940,8 @@ public:
     std::vector<std::string> getDefaultModerators(const std::string& accountID);
     void enableLocalModerators(const std::string& accountID, bool state);
     bool isLocalModeratorsEnabled(const std::string& accountID);
+    void setAllModerators(const std::string& accountID, bool allModerators);
+    bool isAllModerators(const std::string& accountID);
 
 
 private:
-- 
GitLab