summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2012-02-17 16:57:01 (GMT)
committerKevin Smith <git@kismith.co.uk>2012-02-21 14:34:55 (GMT)
commit3605b6622bc8b4abb810fac6b53f7f71be0fa7de (patch)
tree638a8fd6449dd235931fe307e50119adf9c9fe22 /Swift/Controllers/Settings
parentb05f8fcb285d2d13d2be50a3eb1062048fbe30f5 (diff)
downloadswift-contrib-3605b6622bc8b4abb810fac6b53f7f71be0fa7de.zip
swift-contrib-3605b6622bc8b4abb810fac6b53f7f71be0fa7de.tar.bz2
Introduce system settings policies.
Release-Notes: It is now possible for sysadmins to deploy files with policies for configuration options, such as making it impossible for users to save passwords or to force sound notifications off, or to set defaults. Also allow changing an option so that Swift disconnects on idle timeout, instead of going away.
Diffstat (limited to 'Swift/Controllers/Settings')
-rw-r--r--Swift/Controllers/Settings/DummySettingsProvider.h36
-rw-r--r--Swift/Controllers/Settings/SettingsProvider.h62
-rw-r--r--Swift/Controllers/Settings/SettingsProviderHierachy.cpp95
-rw-r--r--Swift/Controllers/Settings/SettingsProviderHierachy.h46
-rw-r--r--Swift/Controllers/Settings/XMLSettingsProvider.cpp124
-rw-r--r--Swift/Controllers/Settings/XMLSettingsProvider.h56
6 files changed, 401 insertions, 18 deletions
diff --git a/Swift/Controllers/Settings/DummySettingsProvider.h b/Swift/Controllers/Settings/DummySettingsProvider.h
index 90e1921..bb7d2e6 100644
--- a/Swift/Controllers/Settings/DummySettingsProvider.h
+++ b/Swift/Controllers/Settings/DummySettingsProvider.h
@@ -6,22 +6,44 @@
#pragma once
-#include "Swift/Controllers/Settings/SettingsProvider.h"
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+
+#include <map>
namespace Swift {
class DummySettingsProvider : public SettingsProvider {
public:
virtual ~DummySettingsProvider() {}
- virtual std::string getStringSetting(const std::string&) {return "";}
- virtual void storeString(const std::string &, const std::string &) {}
- virtual bool getBoolSetting(const std::string &, bool ) {return true;}
- virtual void storeBool(const std::string &, bool ) {}
- virtual int getIntSetting(const std::string &, int ) {return 0;}
- virtual void storeInt(const std::string &, int ) {}
+ virtual std::string getSetting(const Setting<std::string>& setting) {
+ return stringValues.find(setting.getKey()) != stringValues.end() ? stringValues[setting.getKey()] : setting.getDefaultValue();
+ };
+ virtual void storeSetting(const Setting<std::string>& setting, const std::string& value) {
+ stringValues[setting.getKey()] = value;
+ onSettingChanged(setting.getKey());
+ };
+ virtual bool getSetting(const Setting<bool>& setting) {
+ return boolValues.find(setting.getKey()) != boolValues.end() ? boolValues[setting.getKey()] : setting.getDefaultValue();
+ };
+ virtual void storeSetting(const Setting<bool>& setting, const bool& value) {
+ boolValues[setting.getKey()] = value;
+ onSettingChanged(setting.getKey());
+ };
+ virtual int getSetting(const Setting<int>& setting) {
+ return intValues.find(setting.getKey()) != intValues.end() ? intValues[setting.getKey()] : setting.getDefaultValue();
+ };
+ virtual void storeSetting(const Setting<int>& setting, const int& value) {
+ intValues[setting.getKey()] = value;
+ onSettingChanged(setting.getKey());
+ };
virtual std::vector<std::string> getAvailableProfiles() {return std::vector<std::string>();}
virtual void createProfile(const std::string& ) {}
virtual void removeProfile(const std::string& ) {}
+ virtual bool getIsSettingFinal(const std::string& ) {return false;}
+ private:
+ std::map<std::string, std::string> stringValues;
+ std::map<std::string, int> intValues;
+ std::map<std::string, bool> boolValues;
};
}
diff --git a/Swift/Controllers/Settings/SettingsProvider.h b/Swift/Controllers/Settings/SettingsProvider.h
index a5ff4eb..e884add 100644
--- a/Swift/Controllers/Settings/SettingsProvider.h
+++ b/Swift/Controllers/Settings/SettingsProvider.h
@@ -1,33 +1,73 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2012 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-#ifndef SWIFTEN_SettingsProvider_H
-#define SWIFTEN_SettingsProvider_H
+#pragma once
-#include <string>
+#include <Swiften/Base/boost_bsignals.h>
+#include <string>
#include <vector>
namespace Swift {
class SettingsProvider {
+
+ public:
+ template <typename T>
+ class Setting {
+ public:
+ Setting(const std::string& key, const T& defaultValue) : key(key), defaultValue(defaultValue) {
+
+ }
+
+ const std::string& getKey() const {
+ return key;
+ }
+
+ const T& getDefaultValue() const {
+ return defaultValue;
+ }
+
+ private:
+ std::string key;
+ T defaultValue;
+ };
+
public:
virtual ~SettingsProvider() {}
- virtual std::string getStringSetting(const std::string &settingPath) = 0;
- virtual void storeString(const std::string &settingPath, const std::string &settingValue) = 0;
- virtual bool getBoolSetting(const std::string &settingPath, bool defaultValue) = 0;
- virtual void storeBool(const std::string &settingPath, bool settingValue) = 0;
- virtual int getIntSetting(const std::string &settingPath, int defaultValue) = 0;
- virtual void storeInt(const std::string &settingPath, int settingValue) = 0;
+ virtual std::string getSetting(const Setting<std::string>& setting) = 0;
+ virtual void storeSetting(const Setting<std::string>& setting, const std::string& value) = 0;
+ virtual bool getSetting(const Setting<bool>& setting) = 0;
+ virtual void storeSetting(const Setting<bool>& setting, const bool& value) = 0;
+ virtual int getSetting(const Setting<int>& setting) = 0;
+ virtual void storeSetting(const Setting<int>& setting, const int& value) = 0;
+
virtual std::vector<std::string> getAvailableProfiles() = 0;
virtual void createProfile(const std::string& profile) = 0;
virtual void removeProfile(const std::string& profile) = 0;
+ /** A final setting is one that this settings provider says may not be overriden by lower priority profiles.
+ * e.g. An Administrator-set configuration to disallow saving user passwords could not be overridden by the user.
+ */
+ template<typename T>
+ bool getIsSettingFinal(const Setting<T>& setting) {
+ return getIsSettingFinal(setting.getKey());
+ }
+
+ friend class SettingsProviderHierachy;
+ protected:
+ virtual bool getIsSettingFinal(const std::string& settingPath) = 0;
+
+ public:
+ /**
+ * Emitted when a setting is changed.
+ */
+ boost::signal<void (const std::string& /*Setting's Path*/)> onSettingChanged;
};
}
-#endif
+
diff --git a/Swift/Controllers/Settings/SettingsProviderHierachy.cpp b/Swift/Controllers/Settings/SettingsProviderHierachy.cpp
new file mode 100644
index 0000000..3b7d13c
--- /dev/null
+++ b/Swift/Controllers/Settings/SettingsProviderHierachy.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
+
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Base/Log.h>
+namespace Swift {
+
+SettingsProviderHierachy::~SettingsProviderHierachy() {
+}
+
+std::string SettingsProviderHierachy::getSetting(const Setting<std::string>& setting) {
+ foreach (SettingsProvider* provider, providers_) {
+ std::string providerSetting = provider->getSetting(setting);
+ if (providerSetting != setting.getDefaultValue()) {
+ return providerSetting;
+ }
+ }
+ return setting.getDefaultValue();
+}
+
+void SettingsProviderHierachy::storeSetting(const Setting<std::string>& setting, const std::string& settingValue) {
+ if (!getIsSettingFinal(setting.getKey())) {
+ getWritableProvider()->storeSetting(setting, settingValue);
+ }
+}
+
+bool SettingsProviderHierachy::getSetting(const Setting<bool>& setting) {
+ foreach (SettingsProvider* provider, providers_) {
+ bool providerSetting = provider->getSetting(setting);
+ if (providerSetting != setting.getDefaultValue()) {
+ return providerSetting;
+ }
+ }
+ return setting.getDefaultValue();
+}
+
+void SettingsProviderHierachy::storeSetting(const Setting<bool>& setting, const bool& settingValue) {
+ if (!getIsSettingFinal(setting.getKey())) {
+ getWritableProvider()->storeSetting(setting, settingValue);
+ }
+}
+
+int SettingsProviderHierachy::getSetting(const Setting<int>& setting) {
+ foreach (SettingsProvider* provider, providers_) {
+ int providerSetting = provider->getSetting(setting);
+ if (providerSetting != setting.getDefaultValue()) {
+ return providerSetting;
+ }
+ }
+ return setting.getDefaultValue();
+}
+
+void SettingsProviderHierachy::storeSetting(const Setting<int>& setting, const int& settingValue) {
+ if (!getIsSettingFinal(setting.getKey())) {
+ getWritableProvider()->storeSetting(setting, settingValue);
+ }
+}
+
+std::vector<std::string> SettingsProviderHierachy::getAvailableProfiles() {
+ /* Always pull profiles from the topmost */
+ return getWritableProvider()->getAvailableProfiles();
+}
+
+void SettingsProviderHierachy::createProfile(const std::string& profile) {
+ return getWritableProvider()->createProfile(profile);
+}
+
+void SettingsProviderHierachy::removeProfile(const std::string& profile) {
+ return getWritableProvider()->removeProfile(profile);
+}
+
+bool SettingsProviderHierachy::getIsSettingFinal(const std::string& settingPath) {
+ bool isFinal = false;
+ foreach (SettingsProvider* provider, providers_) {
+ isFinal |= provider->getIsSettingFinal(settingPath);
+ }
+ return isFinal;
+}
+
+SettingsProvider* SettingsProviderHierachy::getWritableProvider() {
+ return providers_.back();
+}
+
+void SettingsProviderHierachy::addProviderToTopOfStack(SettingsProvider* provider) {
+ providers_.push_back(provider);
+ provider->onSettingChanged.connect(onSettingChanged);
+}
+
+}
+
diff --git a/Swift/Controllers/Settings/SettingsProviderHierachy.h b/Swift/Controllers/Settings/SettingsProviderHierachy.h
new file mode 100644
index 0000000..b7f6961
--- /dev/null
+++ b/Swift/Controllers/Settings/SettingsProviderHierachy.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+
+namespace Swift {
+
+class SettingsProviderHierachy : public SettingsProvider {
+ public:
+ virtual ~SettingsProviderHierachy();
+ virtual std::string getSetting(const Setting<std::string>& setting);
+ virtual void storeSetting(const Setting<std::string>& setting, const std::string& value);
+ virtual bool getSetting(const Setting<bool>& setting);
+ virtual void storeSetting(const Setting<bool>& setting, const bool& value);
+ virtual int getSetting(const Setting<int>& setting);
+ virtual void storeSetting(const Setting<int>& setting, const int& value);
+ virtual std::vector<std::string> getAvailableProfiles();
+ virtual void createProfile(const std::string& profile);
+ virtual void removeProfile(const std::string& profile);
+ protected:
+ virtual bool getIsSettingFinal(const std::string& settingPath);
+
+ public:
+ /**
+ * Adds a provider less significant than any already added.
+ * This means that if an existing provider has a setting, this provider won't be asked.
+ * Any settings will be pushed into the topmost (least significant) provider.
+ * Does not take ownership of provider.
+ */
+ void addProviderToTopOfStack(SettingsProvider* provider);
+ private:
+ SettingsProvider* getWritableProvider();
+ private:
+ /* Start/Left is most significant (lowest), left overrides right.*/
+ std::vector<SettingsProvider*> providers_;
+};
+
+}
+
+
+
diff --git a/Swift/Controllers/Settings/XMLSettingsProvider.cpp b/Swift/Controllers/Settings/XMLSettingsProvider.cpp
new file mode 100644
index 0000000..6ad3170
--- /dev/null
+++ b/Swift/Controllers/Settings/XMLSettingsProvider.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/Controllers/Settings/XMLSettingsProvider.h>
+
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+
+#include <Swiften/Parser/PlatformXMLParserFactory.h>
+#include <Swiften/Parser/XMLParser.h>
+#include <Swiften/Base/Log.h>
+
+namespace Swift {
+
+XMLSettingsProvider::XMLSettingsProvider(const std::string& xmlConfig) : level_(0) {
+ if (!xmlConfig.empty()) {
+ PlatformXMLParserFactory factory;
+ XMLParser* parser = factory.createXMLParser(this);
+ if (parser->parse(xmlConfig)) {
+ SWIFT_LOG(debug) << "Found and parsed system config" << std::endl;
+ }
+ else {
+ SWIFT_LOG(debug) << "Found invalid system config" << std::endl;
+ }
+ delete parser;
+ }
+ else {
+ SWIFT_LOG(debug) << "No system config found" << std::endl;
+ }
+}
+
+XMLSettingsProvider::~XMLSettingsProvider() {
+
+}
+
+std::string XMLSettingsProvider::getSetting(const Setting<std::string>& setting) {
+ if (values_.find(setting.getKey()) != values_.end()) {
+ std::string value = values_[setting.getKey()];
+ return value;
+ }
+ return setting.getDefaultValue();
+}
+
+void XMLSettingsProvider::storeSetting(const Setting<std::string>& /*settingPath*/, const std::string& /*settingValue*/) {
+ assert(false);
+}
+
+bool XMLSettingsProvider::getSetting(const Setting<bool>& setting) {
+ if (values_.find(setting.getKey()) != values_.end()) {
+ std::string value = values_[setting.getKey()];
+ return boost::iequals(value, "true") || value == "1";
+ }
+ return setting.getDefaultValue();
+}
+
+void XMLSettingsProvider::storeSetting(const Setting<bool>& /*settingPath*/, const bool& /*settingValue*/) {
+ assert(false);
+}
+
+int XMLSettingsProvider::getSetting(const Setting<int>& setting) {
+ if (values_.find(setting.getKey()) != values_.end()) {
+ std::string value = values_[setting.getKey()];
+ try {
+ return value.empty() ? setting.getDefaultValue() : boost::lexical_cast<int>(value);;
+ }
+ catch(boost::bad_lexical_cast &) {}
+ }
+ return setting.getDefaultValue();
+}
+
+void XMLSettingsProvider::storeSetting(const Setting<int>& /*settingPath*/, const int& /*settingValue*/) {
+ assert(false);
+}
+
+std::vector<std::string> XMLSettingsProvider::getAvailableProfiles() {
+ assert(false);
+}
+
+void XMLSettingsProvider::createProfile(const std::string& /*profile*/) {
+ assert(false);
+}
+
+void XMLSettingsProvider::removeProfile(const std::string& /*profile*/) {
+ assert(false);
+}
+
+bool XMLSettingsProvider::getIsSettingFinal(const std::string& settingPath) {
+ return finals_.count(settingPath);
+}
+
+void XMLSettingsProvider::handleStartElement(const std::string& element, const std::string& /*ns*/, const AttributeMap& attributes) {
+ level_++;
+ if (level_ == SettingLevel) {
+ if (attributes.getBoolAttribute("final", false)) {
+ finals_.insert(element);
+ }
+ currentElement_ = element;
+ currentText_ = "";
+ }
+}
+
+void XMLSettingsProvider::handleEndElement(const std::string& /*element*/, const std::string& /*ns*/) {
+ if (level_ == SettingLevel) {
+ values_[currentElement_] = currentText_;
+ SWIFT_LOG(debug) << "Setting value of " << currentElement_ << " to " << currentText_ << std::endl;
+ }
+ level_--;
+}
+
+void XMLSettingsProvider::handleCharacterData(const std::string& data) {
+ if (level_ >= SettingLevel) {
+ currentText_ += data;
+ }
+}
+
+
+}
+
+
+
+
diff --git a/Swift/Controllers/Settings/XMLSettingsProvider.h b/Swift/Controllers/Settings/XMLSettingsProvider.h
new file mode 100644
index 0000000..61abd11
--- /dev/null
+++ b/Swift/Controllers/Settings/XMLSettingsProvider.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+#include <Swiften/Parser/XMLParserClient.h>
+
+#include <map>
+#include <set>
+
+namespace Swift {
+
+class XMLSettingsProvider : public SettingsProvider, public XMLParserClient {
+ public:
+ XMLSettingsProvider(const std::string& xmlConfig);
+ virtual ~XMLSettingsProvider();
+ virtual std::string getSetting(const Setting<std::string>& setting);
+ virtual void storeSetting(const Setting<std::string>& setting, const std::string& value);
+ virtual bool getSetting(const Setting<bool>& setting);
+ virtual void storeSetting(const Setting<bool>& setting, const bool& value);
+ virtual int getSetting(const Setting<int>& setting);
+ virtual void storeSetting(const Setting<int>& setting, const int& value);
+ virtual std::vector<std::string> getAvailableProfiles();
+ virtual void createProfile(const std::string& profile);
+ virtual void removeProfile(const std::string& profile);
+
+ virtual void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string& ns);
+ virtual void handleCharacterData(const std::string& data);
+
+ protected:
+ virtual bool getIsSettingFinal(const std::string& settingPath);
+ private:
+ std::map<std::string /*settingPath*/, std::string /*settingValue*/> values_;
+ /* Settings that are final*/
+ std::set<std::string /*settingPath*/> finals_;
+
+ enum Level {
+ TopLevel = 0,
+ SettingLevel = 2
+ };
+
+ int level_;
+ std::string currentElement_;
+ std::string currentText_;
+};
+
+}
+
+
+
+