From cc9b18376da1dda3e0ed8b649b2968542da5cca2 Mon Sep 17 00:00:00 2001 From: Marius Hein Date: Fri, 2 Aug 2013 16:37:47 +0200 Subject: [PATCH] User preferences: Add doc, fix initial session write refs #4069 --- doc/preferences.md | 102 ++++++++++++++++++ library/Icinga/Application/Web.php | 11 +- .../Icinga/User/Preferences/SessionStore.php | 11 ++ 3 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 doc/preferences.md diff --git a/doc/preferences.md b/doc/preferences.md new file mode 100644 index 000000000..008282f02 --- /dev/null +++ b/doc/preferences.md @@ -0,0 +1,102 @@ +# Preferences + +Preferences are user based configuration for Icinga 2 Web. For example max page +items, languages or date time settings can controlled by users. + +# Architecture behind + +Preferences are initially loaded from a provider (ini files or database) and +stored into session at login time. After this step preferences are only +persisted to the configured backend, but never reloaded from them. + +# Configuration + +Preferences can be configured in config.ini in section, default settings are this: + + [preferences] + type=ini + +The ini provider uses the directory **config/preferences** to create one ini +file per user and persists the data into this file. If your want to drop your +preferences just drop the file from disk and you'll start with a new profile. + +## Database provider + +To be more flexible in distributed setups you can store preferences in a +database (pgsql or mysql), a typical configuration looks like the following +example: + + [preferences] + type=db + dbtype=pgsql + dbhost=127.0.0.1 + dbpassword=icingaweb + dbuser=icingaweb + dbname=icingaweb + +### Settings + +* **dbtype**: Database adapter, currently supporting ***mysql*** or ***pgsql*** + +* **dbhost**: Host of the database server, use localhost or 127.0.0.1 +for unix socket transport + +* **dbpassword**: Password for the configured database user + +* **dbuser**: User who can connect to database + +* **dbname**: Name of the database + +* **port**(optional): For network connections the specific port if not default +(3306 for mysql and 5432 for postgres) + +### Preparation + +To use this feature you need a running database environment. After creating a +database and a writable user you need to import the initial table file: + +* etc/schema/preferences.mysql.sql (for mysql database) +* etc/schema/preferemces.pgsql.sql (for postgres databases) + +#### Example for mysql + + # mysql -u root -p + mysql> create database icingaweb; + mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON icingaweb.* TO \ + 'icingaweb'@'localhost' IDENTIFIED BY 'icingaweb'; + mysql> exit + # mysql -u root -p icingaweb < /path/to/icingaweb/etc/schema/preferences.mysql.sql + +After following this steps above you can configure your preferences provider. + +## Coding API + +Preferenecs are controlled by the Preferences object which was injected into the +User object on application start (You do not have to think about). For example +if you have gathered the user object: + + $preferences = $user->getPreferences(); + // Get language with en_US as fallback + $preferences->get('app.language', 'en_US'); + $preferences->set('app.language', 'de_DE'); + $preferences->remove('app.language'); + + // Using transactional mode + $preferences->startTransaction(); + $preferences->set('test.pref1', 'pref1'); + $preferences->set('test.pref2', 'pref2'); + $preferences->remove('test.pref3'); + $preferemces->commit(); // Stores 3 changes in one operation + +## Namespaces and behaviour + +If you are using this API please obey following rules: + +* Use dotted notation for preferences +* Namespaces starting with one context identifier + * **app** as global identified (e.g. app.language) + * **mymodule** for your module + * **monitoring** for the monitoring module +* Use preferences wisely (set only when needed and write small settings) +* Use only simple data types, e.g. strings or numbers + * If you need complex types you have to do it your self (e.g. serialization) diff --git a/library/Icinga/Application/Web.php b/library/Icinga/Application/Web.php index 074e30c29..bdc6c4327 100644 --- a/library/Icinga/Application/Web.php +++ b/library/Icinga/Application/Web.php @@ -236,8 +236,13 @@ class Web extends ApplicationBootstrap // Performance: Do not ask provider if we've preferences // stored in session - $initialPreferences = (count($sessionStore->load())) - ? $sessionStore->load() : $preferenceStore->load(); + $initialPreferences = array(); + if (count($sessionStore->load())) { + $initialPreferences = $sessionStore->load(); + } else { + $initialPreferences = $preferenceStore->load(); + $sessionStore->writeAll($initialPreferences); + } $preferences = new Preferences($initialPreferences); @@ -251,6 +256,8 @@ class Web extends ApplicationBootstrap $requestCounter++; $user->getPreferences()->set('test.request.counter', $requestCounter); + var_dump($requestCounter); + return $user; } } diff --git a/library/Icinga/User/Preferences/SessionStore.php b/library/Icinga/User/Preferences/SessionStore.php index 0ac1424f5..70dbf1b2c 100644 --- a/library/Icinga/User/Preferences/SessionStore.php +++ b/library/Icinga/User/Preferences/SessionStore.php @@ -95,6 +95,17 @@ class SessionStore implements SplObserver, LoadInterface $this->session->write(); } + /** + * Public interface to copy all preferences into session + * + * @param array $preferences + */ + public function writeAll(array $preferences) + { + $this->session->set(self::DEFAULT_SESSION_NAMESPACE, $preferences); + $this->session->write(); + } + /** * Load preferences from source *