From a42c8d1f247e7baa5209a510985b3a075ed82091 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:11:16 +0200 Subject: [PATCH 01/39] lib/db: Allow to create oci8 connections refs #9683 --- library/Icinga/Data/Db/DbConnection.php | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/library/Icinga/Data/Db/DbConnection.php b/library/Icinga/Data/Db/DbConnection.php index 270767f8d..0ff04a81c 100644 --- a/library/Icinga/Data/Db/DbConnection.php +++ b/library/Icinga/Data/Db/DbConnection.php @@ -150,19 +150,18 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp . 'NO_AUTO_CREATE_USER,ANSI_QUOTES,PIPES_AS_CONCAT,NO_ENGINE_SUBSTITUTION\';'; $adapterParamaters['port'] = $this->config->get('port', 3306); break; + case 'oci': + $adapter = 'Oracle'; + unset($adapterParamaters['options']); + unset($adapterParamaters['driver_options']); + $adapterParamaters['driver_options'] = array( + 'lob_as_string' => true + ); + break; case 'pgsql': $adapter = 'Pdo_Pgsql'; $adapterParamaters['port'] = $this->config->get('port', 5432); break; - /*case 'oracle': - if ($this->dbtype === 'oracle') { - $attributes['persistent'] = true; - } - $this->db = ZfDb::factory($adapter, $attributes); - if ($adapter === 'Oracle') { - $this->db->setLobAsString(false); - } - break;*/ default: throw new ConfigurationError( 'Backend "%s" is not supported', From 44c19fc5e6dc3e2d5d826d14c6729aa36d4658cf Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:14:11 +0200 Subject: [PATCH 02/39] lib/db: Allow to create oracle (pdo_oci) connections refs #9683 --- library/Icinga/Data/Db/DbConnection.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/Icinga/Data/Db/DbConnection.php b/library/Icinga/Data/Db/DbConnection.php index 0ff04a81c..c7ecc9f5f 100644 --- a/library/Icinga/Data/Db/DbConnection.php +++ b/library/Icinga/Data/Db/DbConnection.php @@ -158,6 +158,9 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp 'lob_as_string' => true ); break; + case 'oracle': + $adapter = 'Pdo_Oci'; + break; case 'pgsql': $adapter = 'Pdo_Pgsql'; $adapterParamaters['port'] = $this->config->get('port', 5432); From 4763b6b20a41b674f9ca416421437a1afaca0d03 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:15:04 +0200 Subject: [PATCH 03/39] lib/db: Allow to configure persistent connections refs #9683 --- library/Icinga/Data/Db/DbConnection.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/Icinga/Data/Db/DbConnection.php b/library/Icinga/Data/Db/DbConnection.php index c7ecc9f5f..a5548209c 100644 --- a/library/Icinga/Data/Db/DbConnection.php +++ b/library/Icinga/Data/Db/DbConnection.php @@ -62,8 +62,7 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp private static $driverOptions = array( PDO::ATTR_TIMEOUT => 10, PDO::ATTR_CASE => PDO::CASE_LOWER, - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - // TODO: allow configurable PDO::ATTR_PERSISTENT => true + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ); /** @@ -131,6 +130,7 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp 'username' => $this->config->username, 'password' => $this->config->password, 'dbname' => $this->config->dbname, + 'persistent' => (bool) $this->config->get('persistent', false), 'options' => & $genericAdapterOptions, 'driver_options' => & $driverOptions ); From 771efae1a256d0ed451e772ba5748fe11ec772af Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:20:37 +0200 Subject: [PATCH 04/39] lib/db: Allow to configure mssql resources refs #9683 --- library/Icinga/Data/Db/DbConnection.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/Icinga/Data/Db/DbConnection.php b/library/Icinga/Data/Db/DbConnection.php index a5548209c..e62e24464 100644 --- a/library/Icinga/Data/Db/DbConnection.php +++ b/library/Icinga/Data/Db/DbConnection.php @@ -136,6 +136,10 @@ class DbConnection implements Selectable, Extensible, Updatable, Reducible, Insp ); $this->dbType = strtolower($this->config->get('db', 'mysql')); switch ($this->dbType) { + case 'mssql': + $adapter = 'Pdo_Mssql'; + $adapterParamaters['pdoType'] = $this->config->get('pdoType', 'dblib'); + break; case 'mysql': $adapter = 'Pdo_Mysql'; /* From 9f3ef5cc8dbe60113fe9c5ccc2b0c3a4cf148348 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:29:08 +0200 Subject: [PATCH 05/39] lib: Add Platform::hasMssqlSupport() refs #9683 --- library/Icinga/Application/Platform.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/Icinga/Application/Platform.php b/library/Icinga/Application/Platform.php index cc72857f9..bb4aa9ca8 100644 --- a/library/Icinga/Application/Platform.php +++ b/library/Icinga/Application/Platform.php @@ -318,6 +318,18 @@ class Platform return false; } + /** + * Return whether it's possible to connect to a MSSQL database + * + * Checks whether the Zend framework adapter for MSSQL is available + * + * @return bool + */ + public static function hasMssqlSupport() + { + return static::classExists('Zend_Db_Adapter_Pdo_Mssql'); + } + /** * Return whether it's possible to connect to a MySQL database * From bba1838c7d09dd30d04470cb7db07f7c994619bf Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:32:24 +0200 Subject: [PATCH 06/39] lib: Add Platform::hasOracleSupport() refs #9683 --- library/Icinga/Application/Platform.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/Icinga/Application/Platform.php b/library/Icinga/Application/Platform.php index bb4aa9ca8..7c3f06671 100644 --- a/library/Icinga/Application/Platform.php +++ b/library/Icinga/Application/Platform.php @@ -342,6 +342,18 @@ class Platform return static::extensionLoaded('mysql') && static::classExists('Zend_Db_Adapter_Pdo_Mysql'); } + /** + * Return whether it's possible to connect to a Oracle database using PDO_OCI + * + * Checks whether the OCI PDO extension has been loaded and the Zend framework adapter for Oci is available + * + * @return bool + */ + public static function hasOracleSupport() + { + return static::extensionLoaded('pdo_oci') && static::classExists('Zend_Db_Adapter_Pdo_Mysql'); + } + /** * Return whether it's possible to connect to a PostgreSQL database * From 358f1750fb3d2d91915492230b89a4b0b49f3b9f Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:33:38 +0200 Subject: [PATCH 07/39] lib: Add Platform::hasOciSupport() refs #9683 --- library/Icinga/Application/Platform.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/library/Icinga/Application/Platform.php b/library/Icinga/Application/Platform.php index 7c3f06671..3095566e5 100644 --- a/library/Icinga/Application/Platform.php +++ b/library/Icinga/Application/Platform.php @@ -342,6 +342,18 @@ class Platform return static::extensionLoaded('mysql') && static::classExists('Zend_Db_Adapter_Pdo_Mysql'); } + /** + * Return whether it's possible to connect to a Oracle database using OCI8 + * + * Checks whether the OCI8 extension has been loaded and the Zend framework adapter for Oracle is available + * + * @return bool + */ + public static function hasOciSupport() + { + return static::extensionLoaded('oci8') && static::classExists('Zend_Db_Adapter_Oracle'); + } + /** * Return whether it's possible to connect to a Oracle database using PDO_OCI * From d52bb7d92a515883b33478a8a8c8ad1f9cd602ad Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:43:41 +0200 Subject: [PATCH 08/39] lib: Add Platform::hasLdapSupport() and Platform::hasDatabaseSupport() refs #9683 --- library/Icinga/Application/Platform.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/library/Icinga/Application/Platform.php b/library/Icinga/Application/Platform.php index 3095566e5..55b4d9d4d 100644 --- a/library/Icinga/Application/Platform.php +++ b/library/Icinga/Application/Platform.php @@ -318,6 +318,29 @@ class Platform return false; } + /** + * Return whether it's possible to connect to a LDAP server + * + * Checks whether the ldap extension is loaded + * + * @return bool + */ + public static function hasLdapSupport() + { + return static::extensionLoaded('ldap'); + } + + /** + * Return whether it's possible to connect to any of the supported database servers + * + * @return bool + */ + public static function hasDatabaseSupport() + { + return static::hasMssqlSupport() || static::hasMysqlSupport() || static::hasOciSupport() + || static::hasOracleSupport() || static::hasPostgresqlSupport(); + } + /** * Return whether it's possible to connect to a MSSQL database * From e64ad87745c80b0a1f15f9687ac69b35c5945949 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:44:06 +0200 Subject: [PATCH 09/39] Use Platform::hasDatabaseSupport() and Platform::hasLdapSupport() in the resource config refs #9683 --- application/forms/Config/ResourceConfigForm.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/forms/Config/ResourceConfigForm.php b/application/forms/Config/ResourceConfigForm.php index 4dccabceb..bd6523a05 100644 --- a/application/forms/Config/ResourceConfigForm.php +++ b/application/forms/Config/ResourceConfigForm.php @@ -236,10 +236,10 @@ class ResourceConfigForm extends ConfigForm 'livestatus' => 'Livestatus', 'ssh' => $this->translate('SSH Identity'), ); - if ($resourceType === 'ldap' || Platform::extensionLoaded('ldap')) { + if ($resourceType === 'ldap' || Platform::hasLdapSupport()) { $resourceTypes['ldap'] = 'LDAP'; } - if ($resourceType === 'db' || Platform::hasMysqlSupport() || Platform::hasPostgresqlSupport()) { + if ($resourceType === 'db' || Platform::hasDatabaseSupport()) { $resourceTypes['db'] = $this->translate('SQL Database'); } From 56bef276e0e30e383f4ce648586d740ca32cd37e Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:44:35 +0200 Subject: [PATCH 10/39] Allow to create MSSQL and Oracle resources refs #9683 --- application/forms/Config/Resource/DbResourceForm.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/application/forms/Config/Resource/DbResourceForm.php b/application/forms/Config/Resource/DbResourceForm.php index 3339b59bf..793808d73 100644 --- a/application/forms/Config/Resource/DbResourceForm.php +++ b/application/forms/Config/Resource/DbResourceForm.php @@ -27,13 +27,23 @@ class DbResourceForm extends Form public function createElements(array $formData) { $dbChoices = array(); + if (Platform::hasMssqlSupport()) { + $dbChoices['mssql'] = 'MSSQL'; + } if (Platform::hasMysqlSupport()) { $dbChoices['mysql'] = 'MySQL'; } + if (Platform::hasOciSupport()) { + $dbChoices['oci'] = 'Oracle (OCI8)'; + } + if (Platform::hasOracleSupport()) { + $dbChoices['oracle'] = 'Oracle'; + } if (Platform::hasPostgresqlSupport()) { $dbChoices['pgsql'] = 'PostgreSQL'; } + $this->addElement( 'text', 'name', From 947d5c6190ef4ca543f44c2e7d010d1b97507780 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:52:54 +0200 Subject: [PATCH 11/39] Don't require to configure a port for database connections --- application/forms/Config/Resource/DbResourceForm.php | 1 - 1 file changed, 1 deletion(-) diff --git a/application/forms/Config/Resource/DbResourceForm.php b/application/forms/Config/Resource/DbResourceForm.php index 793808d73..2cac94292 100644 --- a/application/forms/Config/Resource/DbResourceForm.php +++ b/application/forms/Config/Resource/DbResourceForm.php @@ -78,7 +78,6 @@ class DbResourceForm extends Form 'number', 'port', array( - 'required' => true, 'preserveDefault' => true, 'label' => $this->translate('Port'), 'description' => $this->translate('The port to use'), From e8c21868ff2a8996da14d3b2348e254d1db56a33 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:57:09 +0200 Subject: [PATCH 12/39] lib: Fix Number::isValid() - Calls $this->translate() - Always performs is_numeric check, even if the element is not required --- library/Icinga/Web/Form/Element/Number.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/Icinga/Web/Form/Element/Number.php b/library/Icinga/Web/Form/Element/Number.php index 8a1217363..31bec6433 100644 --- a/library/Icinga/Web/Form/Element/Number.php +++ b/library/Icinga/Web/Form/Element/Number.php @@ -134,8 +134,8 @@ class Number extends FormElement { $this->setValue($value); $value = $this->getValue(); - if (! is_numeric($value)) { - $this->addError(sprintf($this->translate('\'%s\' is not a valid number'), $value)); + if ($this->isRequired() && ! is_numeric($value)) { + $this->addError(sprintf(t('\'%s\' is not a valid number'), $value)); return false; } return parent::isValid($value, $context); From e45140dd86cf5b2830c4c359f8ea105b2cf7a4b8 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 16:57:43 +0200 Subject: [PATCH 13/39] Don't mess w/ default ports when configuration a database connection --- application/forms/Config/Resource/DbResourceForm.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/application/forms/Config/Resource/DbResourceForm.php b/application/forms/Config/Resource/DbResourceForm.php index 2cac94292..e08094069 100644 --- a/application/forms/Config/Resource/DbResourceForm.php +++ b/application/forms/Config/Resource/DbResourceForm.php @@ -80,8 +80,7 @@ class DbResourceForm extends Form array( 'preserveDefault' => true, 'label' => $this->translate('Port'), - 'description' => $this->translate('The port to use'), - 'value' => ! array_key_exists('db', $formData) || $formData['db'] === 'mysql' ? 3306 : 5432 + 'description' => $this->translate('The port to use') ) ); $this->addElement( From 65e4d23d8946ffd83a05280d868a1fcdca57c8dd Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 17:01:09 +0200 Subject: [PATCH 14/39] Require a port only for postgres connections Screw it! refs #9683 --- application/forms/Config/Resource/DbResourceForm.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/application/forms/Config/Resource/DbResourceForm.php b/application/forms/Config/Resource/DbResourceForm.php index e08094069..fd55e7c66 100644 --- a/application/forms/Config/Resource/DbResourceForm.php +++ b/application/forms/Config/Resource/DbResourceForm.php @@ -78,9 +78,11 @@ class DbResourceForm extends Form 'number', 'port', array( - 'preserveDefault' => true, + 'description' => $this->translate('The port to use'), 'label' => $this->translate('Port'), - 'description' => $this->translate('The port to use') + 'preserveDefault' => true, + 'required' => isset($formData['db']) && $formData['db'] === 'pgsql', + 'value' => isset($formData['db']) && $formData['db'] === 'pgsql' ? 5432 : null ) ); $this->addElement( From 61f251d6adbceab57752395d50e893d6cda76f98 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 17:08:25 +0200 Subject: [PATCH 15/39] Allow to configure persistent database connections --- application/forms/Config/Resource/DbResourceForm.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/application/forms/Config/Resource/DbResourceForm.php b/application/forms/Config/Resource/DbResourceForm.php index fd55e7c66..93290d3c6 100644 --- a/application/forms/Config/Resource/DbResourceForm.php +++ b/application/forms/Config/Resource/DbResourceForm.php @@ -113,6 +113,17 @@ class DbResourceForm extends Form 'description' => $this->translate('The password to use for authentication') ) ); + $this->addElement( + 'checkbox', + 'persistent', + array( + 'description' => $this->translate( + 'Check this box for persistent database connections. Persistent connections are not closed at the' + . ' end of a request, but are cached and re-used. This is experimental' + ), + 'label' => $this->translate('Persistent') + ) + ); return $this; } From 4e1543fd349359d734e673680f8a57bd6ca77d1a Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 7 Sep 2015 17:23:12 +0200 Subject: [PATCH 16/39] Make MySQL the default choice when configuring database connections again --- application/forms/Config/Resource/DbResourceForm.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application/forms/Config/Resource/DbResourceForm.php b/application/forms/Config/Resource/DbResourceForm.php index 93290d3c6..bf1617c97 100644 --- a/application/forms/Config/Resource/DbResourceForm.php +++ b/application/forms/Config/Resource/DbResourceForm.php @@ -27,12 +27,12 @@ class DbResourceForm extends Form public function createElements(array $formData) { $dbChoices = array(); - if (Platform::hasMssqlSupport()) { - $dbChoices['mssql'] = 'MSSQL'; - } if (Platform::hasMysqlSupport()) { $dbChoices['mysql'] = 'MySQL'; } + if (Platform::hasMssqlSupport()) { + $dbChoices['mssql'] = 'MSSQL'; + } if (Platform::hasOciSupport()) { $dbChoices['oci'] = 'Oracle (OCI8)'; } From 1b6f5861b7c1ef2719a2e6b3a765bd1d0c7913d4 Mon Sep 17 00:00:00 2001 From: Matthias Jentsch Date: Wed, 16 Sep 2015 15:31:53 +0200 Subject: [PATCH 17/39] Highlight selected table rows in related actions Allow declaring related controllers for action tables and highlight table rows based on the queries in links pointing to those actions. fixes #10155 --- .../views/scripts/list/comments.phtml | 1 + .../views/scripts/list/downtimes.phtml | 1 + .../views/scripts/list/hosts.phtml | 1 + .../views/scripts/list/services.phtml | 1 + public/js/icinga/behavior/actiontable.js | 44 +++++++++++++++++-- 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/modules/monitoring/application/views/scripts/list/comments.phtml b/modules/monitoring/application/views/scripts/list/comments.phtml index 44b452f42..d5a1e8fb5 100644 --- a/modules/monitoring/application/views/scripts/list/comments.phtml +++ b/modules/monitoring/application/views/scripts/list/comments.phtml @@ -15,6 +15,7 @@ " data-icinga-multiselect-data="comment_id"> peekAhead($this->compact) as $comment): ?> diff --git a/modules/monitoring/application/views/scripts/list/downtimes.phtml b/modules/monitoring/application/views/scripts/list/downtimes.phtml index a45bd0499..7aae0454d 100644 --- a/modules/monitoring/application/views/scripts/list/downtimes.phtml +++ b/modules/monitoring/application/views/scripts/list/downtimes.phtml @@ -21,6 +21,7 @@ if (! $this->compact): ?>
" data-icinga-multiselect-data="downtime_id"> diff --git a/modules/monitoring/application/views/scripts/list/hosts.phtml b/modules/monitoring/application/views/scripts/list/hosts.phtml index 859f01aec..c6c0342fd 100644 --- a/modules/monitoring/application/views/scripts/list/hosts.phtml +++ b/modules/monitoring/application/views/scripts/list/hosts.phtml @@ -23,6 +23,7 @@ if (! $this->compact): ?> data-base-target="_next" class="action multiselect" data-icinga-multiselect-url="href('monitoring/hosts/show') ?>" + data-icinga-multiselect-controllers="href("monitoring/hosts") ?>" data-icinga-multiselect-data="host" > diff --git a/modules/monitoring/application/views/scripts/list/services.phtml b/modules/monitoring/application/views/scripts/list/services.phtml index 3b0ae8859..5100b8193 100644 --- a/modules/monitoring/application/views/scripts/list/services.phtml +++ b/modules/monitoring/application/views/scripts/list/services.phtml @@ -24,6 +24,7 @@ if (! $this->compact): ?>
" + data-icinga-multiselect-controllers="href("monitoring/services") ?>" data-icinga-multiselect-data="service,host"> 1 && this.getMultiselectionUrl() === this.icinga.utils.parseUrl(hash).path) { + if (query.length > 1 && this.hasMultiselectionUrl(this.icinga.utils.parseUrl(hash).path)) { // select all rows with matching filters var self = this; $.each(query, function(i, selection) { From a34c108da50353f05186566aaf152221145fe50f Mon Sep 17 00:00:00 2001 From: Matthias Jentsch Date: Wed, 16 Sep 2015 15:45:57 +0200 Subject: [PATCH 18/39] Allow mixed selection of host and service comments --- .../monitoring/application/views/scripts/list/comments.phtml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/monitoring/application/views/scripts/list/comments.phtml b/modules/monitoring/application/views/scripts/list/comments.phtml index d5a1e8fb5..6e3f4dcc5 100644 --- a/modules/monitoring/application/views/scripts/list/comments.phtml +++ b/modules/monitoring/application/views/scripts/list/comments.phtml @@ -47,7 +47,8 @@ 'title' => sprintf( $this->translate('Show detailed information for this comment about host %s'), $comment->host_display_name - ) + ), + 'class' => 'rowaction' ) ); ?> From f46504554ed65d2b226fdb2d9d0cd9e1ce9ff386 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Thu, 17 Sep 2015 11:48:25 +0200 Subject: [PATCH 19/39] lib: Check for mssql extension too in Platform::hasMssqlSupport() refs #9683 --- library/Icinga/Application/Platform.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/Icinga/Application/Platform.php b/library/Icinga/Application/Platform.php index 55b4d9d4d..0dfc0c6c2 100644 --- a/library/Icinga/Application/Platform.php +++ b/library/Icinga/Application/Platform.php @@ -344,13 +344,13 @@ class Platform /** * Return whether it's possible to connect to a MSSQL database * - * Checks whether the Zend framework adapter for MSSQL is available + * Checks whether the mssql pdo extension has been loaded and Zend framework adapter for MSSQL is available * * @return bool */ public static function hasMssqlSupport() { - return static::classExists('Zend_Db_Adapter_Pdo_Mssql'); + return static::extensionLoaded('mssql') && static::classExists('Zend_Db_Adapter_Pdo_Mssql'); } /** From 06c6b09863ec249c781c40608bb57554e5193c38 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Thu, 17 Sep 2015 12:46:49 +0200 Subject: [PATCH 20/39] Set default port for Postgres connections if it's the first available driver refs #9683 --- .../forms/Config/Resource/DbResourceForm.php | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/application/forms/Config/Resource/DbResourceForm.php b/application/forms/Config/Resource/DbResourceForm.php index bf1617c97..d79ad248b 100644 --- a/application/forms/Config/Resource/DbResourceForm.php +++ b/application/forms/Config/Resource/DbResourceForm.php @@ -30,20 +30,26 @@ class DbResourceForm extends Form if (Platform::hasMysqlSupport()) { $dbChoices['mysql'] = 'MySQL'; } + if (Platform::hasPostgresqlSupport()) { + $dbChoices['pgsql'] = 'PostgreSQL'; + } if (Platform::hasMssqlSupport()) { $dbChoices['mssql'] = 'MSSQL'; } - if (Platform::hasOciSupport()) { - $dbChoices['oci'] = 'Oracle (OCI8)'; - } if (Platform::hasOracleSupport()) { $dbChoices['oracle'] = 'Oracle'; } - if (Platform::hasPostgresqlSupport()) { - $dbChoices['pgsql'] = 'PostgreSQL'; + if (Platform::hasOciSupport()) { + $dbChoices['oci'] = 'Oracle (OCI8)'; + } + $offerPostgres = false; + if (isset($formData['db'])) { + if ($formData['db'] === 'pgsql') { + $offerPostgres = true; + } + } elseif (key($dbChoices) === 'pgsql') { + $offerPostgres = true; } - - $this->addElement( 'text', 'name', @@ -81,8 +87,8 @@ class DbResourceForm extends Form 'description' => $this->translate('The port to use'), 'label' => $this->translate('Port'), 'preserveDefault' => true, - 'required' => isset($formData['db']) && $formData['db'] === 'pgsql', - 'value' => isset($formData['db']) && $formData['db'] === 'pgsql' ? 5432 : null + 'required' => $offerPostgres, + 'value' => $offerPostgres ? 5432 : null ) ); $this->addElement( From 79c9a8af9bee2f86002b0d8598b8695065f3256f Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Thu, 17 Sep 2015 12:52:09 +0200 Subject: [PATCH 21/39] lib: Fix Number::isValid(), again :) --- library/Icinga/Web/Form/Element/Number.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/Icinga/Web/Form/Element/Number.php b/library/Icinga/Web/Form/Element/Number.php index 31bec6433..f7fa5292a 100644 --- a/library/Icinga/Web/Form/Element/Number.php +++ b/library/Icinga/Web/Form/Element/Number.php @@ -134,7 +134,7 @@ class Number extends FormElement { $this->setValue($value); $value = $this->getValue(); - if ($this->isRequired() && ! is_numeric($value)) { + if ($value !== '' && ! is_numeric($value)) { $this->addError(sprintf(t('\'%s\' is not a valid number'), $value)); return false; } From eff92498631f1f341513bb0d6e85702fc6d547e6 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Thu, 17 Sep 2015 13:01:58 +0200 Subject: [PATCH 22/39] lib: Don't provide LDAP server-side sort request if the query has no order refs #10147 --- .../Icinga/Protocol/Ldap/LdapConnection.php | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/library/Icinga/Protocol/Ldap/LdapConnection.php b/library/Icinga/Protocol/Ldap/LdapConnection.php index ed93ecf7e..ca83c4ff7 100644 --- a/library/Icinga/Protocol/Ldap/LdapConnection.php +++ b/library/Icinga/Protocol/Ldap/LdapConnection.php @@ -667,17 +667,20 @@ class LdapConnection implements Selectable, Inspectable $ds = $this->getConnection(); $serverSorting = $this->getCapabilities()->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID); - if ($serverSorting && $query->hasOrder()) { - ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array( - array( - 'oid' => LdapCapabilities::LDAP_SERVER_SORT_OID, - 'value' => $this->encodeSortRules($query->getOrder()) - ) - )); - } elseif ($query->hasOrder()) { - foreach ($query->getOrder() as $rule) { - if (! in_array($rule[0], $fields)) { - $fields[] = $rule[0]; + + if ($query->hasOrder()) { + if ($serverSorting) { + ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array( + array( + 'oid' => LdapCapabilities::LDAP_SERVER_SORT_OID, + 'value' => $this->encodeSortRules($query->getOrder()) + ) + )); + } else { + foreach ($query->getOrder() as $rule) { + if (! in_array($rule[0], $fields)) { + $fields[] = $rule[0]; + } } } } @@ -778,7 +781,7 @@ class LdapConnection implements Selectable, Inspectable // server to return results even if the paged search request cannot be satisfied ldap_control_paged_result($ds, $pageSize, false, $cookie); - if ($serverSorting) { + if ($serverSorting && $query->hasOrder()) { ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array( array( 'oid' => LdapCapabilities::LDAP_SERVER_SORT_OID, From 8cea292745f21302cdc721371fdf6fece4424aa1 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Thu, 17 Sep 2015 16:22:24 +0200 Subject: [PATCH 23/39] monitoring: Fix grouping of host and service status when filtering for group columns refs #9956 --- .../Backend/Ido/Query/HoststatusQuery.php | 16 ++++++++-------- .../Backend/Ido/Query/ServicestatusQuery.php | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php index 9898ccac9..7f1066bfc 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php @@ -289,26 +289,26 @@ class HoststatusQuery extends IdoQuery } $groupedTables = array(); if ($this->hasJoinedVirtualTable('servicegroups')) { + $group[] = 'ho.object_id'; + $group[] = 'h.host_id'; + $groupedTables['hosts'] = true; $serviceGroupColumns = array_keys($this->columnMap['servicegroups']); $selectedServiceGroupColumns = array_intersect($serviceGroupColumns, array_keys($this->columns)); if (! empty($selectedServiceGroupColumns)) { - $group[] = 'ho.object_id'; - $group[] = 'h.host_id'; $group[] = 'sgo.object_id'; $group[] = 'sg.servicegroup_id'; - $groupedTables['hosts'] = true; $groupedTables['servicegroups'] = true; } } if ($this->hasJoinedVirtualTable('hostgroups')) { + if (! isset($groupedTables['hosts'])) { + $group[] = 'ho.object_id'; + $group[] = 'h.host_id'; + $groupedTables['hosts'] = true; + } $hostGroupColumns = array_keys($this->columnMap['hostgroups']); $selectedHostGroupColumns = array_intersect($hostGroupColumns, array_keys($this->columns)); if (! empty($selectedHostGroupColumns)) { - if (! isset($groupedTables['hosts'])) { - $group[] = 'ho.object_id'; - $group[] = 'h.host_id'; - $groupedTables['hosts'] = true; - } $group[] = 'hgo.object_id'; $group[] = 'hg.hostgroup_id'; $groupedTables['hostgroups'] = true; diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatusQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatusQuery.php index 734e138d4..1c9785548 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatusQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatusQuery.php @@ -409,26 +409,26 @@ class ServicestatusQuery extends IdoQuery } $groupedTables = array(); if ($this->hasJoinedVirtualTable('servicegroups')) { + $group[] = 'so.object_id'; + $group[] = 's.service_id'; + $groupedTables['services'] = true; $serviceGroupColumns = array_keys($this->columnMap['servicegroups']); $selectedServiceGroupColumns = array_intersect($serviceGroupColumns, array_keys($this->columns)); if (! empty($selectedServiceGroupColumns)) { - $group[] = 'so.object_id'; - $group[] = 's.service_id'; $group[] = 'sgo.object_id'; $group[] = 'sg.servicegroup_id'; - $groupedTables['services'] = true; $groupedTables['servicegroups'] = true; } } if ($this->hasJoinedVirtualTable('hostgroups')) { + if (! isset($groupedTables['services'])) { + $group[] = 'so.object_id'; + $group[] = 's.service_id'; + $groupedTables['services'] = true; + } $hostGroupColumns = array_keys($this->columnMap['hostgroups']); $selectedHostGroupColumns = array_intersect($hostGroupColumns, array_keys($this->columns)); if (! empty($selectedHostGroupColumns)) { - if (! isset($groupedTables['services'])) { - $group[] = 'so.object_id'; - $group[] = 's.service_id'; - $groupedTables['services'] = true; - } $group[] = 'hgo.object_id'; $group[] = 'hg.hostgroup_id'; $groupedTables['hostgroups'] = true; From 3b135c6b6f32590f784e8d878c89a9d9de3d2bee Mon Sep 17 00:00:00 2001 From: Matthias Jentsch Date: Thu, 17 Sep 2015 16:03:42 +0200 Subject: [PATCH 24/39] Fix PostgreSQL queries that use GROUP BY Add missing instance_id to getGroup query functions to avoid query errors in PostgreSQL. fixes #10160 --- .../library/Monitoring/Backend/Ido/Query/HostcommentQuery.php | 4 ++++ .../Monitoring/Backend/Ido/Query/HostdowntimeQuery.php | 4 ++++ .../Monitoring/Backend/Ido/Query/HostnotificationQuery.php | 4 ++++ .../library/Monitoring/Backend/Ido/Query/HoststatusQuery.php | 3 +++ .../Monitoring/Backend/Ido/Query/ServicecommentQuery.php | 4 ++++ .../Monitoring/Backend/Ido/Query/ServicedowntimeQuery.php | 4 ++++ .../Monitoring/Backend/Ido/Query/ServicenotificationQuery.php | 4 ++++ .../Monitoring/Backend/Ido/Query/ServicestatusQuery.php | 3 +++ 8 files changed, 30 insertions(+) diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostcommentQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostcommentQuery.php index 54c675087..2b06a00ef 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostcommentQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostcommentQuery.php @@ -181,6 +181,10 @@ class HostcommentQuery extends IdoQuery if ($this->hasJoinedVirtualTable('hoststatus')) { $group[] = 'hs.hoststatus_id'; } + + if ($this->hasJoinedVirtualTable('instances')) { + $group[] = 'i.instance_id'; + } } return $group; diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostdowntimeQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostdowntimeQuery.php index a8ff8355b..c6ffc4aee 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostdowntimeQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostdowntimeQuery.php @@ -187,6 +187,10 @@ class HostdowntimeQuery extends IdoQuery if ($this->hasJoinedVirtualTable('hoststatus')) { $group[] = 'hs.hoststatus_id'; } + + if ($this->hasJoinedVirtualTable('instances')) { + $group[] = 'i.instance_id'; + } } return $group; diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php index b06e5440b..d18c05408 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HostnotificationQuery.php @@ -265,6 +265,10 @@ class HostnotificationQuery extends IdoQuery if ($this->hasJoinedVirtualTable('acknowledgements')) { $group[] = 'a.acknowledgement_id'; } + + if ($this->hasJoinedVirtualTable('instances')) { + $group[] = 'i.instance_id'; + } } return $group; diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php index 7f1066bfc..02a2fb8fb 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php @@ -336,6 +336,9 @@ class HoststatusQuery extends IdoQuery $group[] = 'so.object_id'; $group[] = 's.service_id'; break; + case 'instances': + $group[] = 'i.instance_id'; + break; default: continue 2; } diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicecommentQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicecommentQuery.php index 8b2b9e04f..dea7554ba 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicecommentQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicecommentQuery.php @@ -203,6 +203,10 @@ class ServicecommentQuery extends IdoQuery if ($this->hasJoinedVirtualTable('servicestatus')) { $group[] = 'ss.servicestatus_id'; } + + if ($this->hasJoinedVirtualTable('instances')) { + $group[] = 'i.instance_id'; + } } return $group; diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicedowntimeQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicedowntimeQuery.php index 18a22ea93..98f12f84d 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicedowntimeQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicedowntimeQuery.php @@ -210,6 +210,10 @@ class ServicedowntimeQuery extends IdoQuery if ($this->hasJoinedVirtualTable('servicestatus')) { $group[] = 'ss.servicestatus_id'; } + + if ($this->hasJoinedVirtualTable('instances')) { + $group[] = 'i.instance_id'; + } } return $group; diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php index 30e4dc7e2..9b8963055 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicenotificationQuery.php @@ -268,6 +268,10 @@ class ServicenotificationQuery extends IdoQuery if ($this->hasJoinedVirtualTable('acknowledgements')) { $group[] = 'a.acknowledgement_id'; } + + if ($this->hasJoinedVirtualTable('instances')) { + $group[] = 'i.instance_id'; + } } return $group; diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatusQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatusQuery.php index 1c9785548..a4b1d7272 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatusQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/ServicestatusQuery.php @@ -452,6 +452,9 @@ class ServicestatusQuery extends IdoQuery case 'hoststatus': $group[] = 'hs.hoststatus_id'; break; + case 'instances': + $group[] = 'i.instance_id'; + break; case 'servicestatus': $group[] = 'ss.servicestatus_id'; break; From 17e8f01d248ddae45910de8c3015b03588e7675a Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Fri, 18 Sep 2015 15:34:12 +0200 Subject: [PATCH 25/39] Use the DN to fetch group memberships from LDAP fixes #9901 --- .../Authentication/User/LdapUserBackend.php | 7 +++++- .../UserGroup/LdapUserGroupBackend.php | 24 ++++++++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/library/Icinga/Authentication/User/LdapUserBackend.php b/library/Icinga/Authentication/User/LdapUserBackend.php index a33c23691..d8ea19ca2 100644 --- a/library/Icinga/Authentication/User/LdapUserBackend.php +++ b/library/Icinga/Authentication/User/LdapUserBackend.php @@ -364,7 +364,12 @@ class LdapUserBackend extends LdapRepository implements UserBackendInterface, In return false; } - return $this->ds->testCredentials($userDn, $password); + $testCredentialsResult = $this->ds->testCredentials($userDn, $password); + if ($testCredentialsResult) { + $user->setAdditional('ldap_dn', $userDn); + } + + return $testCredentialsResult; } catch (LdapException $e) { throw new AuthenticationException( 'Failed to authenticate user "%s" against backend "%s". An exception was thrown:', diff --git a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php index 25fc27fb9..035005937 100644 --- a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php +++ b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php @@ -532,18 +532,20 @@ class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBacken */ public function getMemberships(User $user) { - $userQuery = $this->ds - ->select() - ->from($this->userClass) - ->where($this->userNameAttribute, $user->getUsername()) - ->setBase($this->userBaseDn) - ->setUsePagedResults(false); - if ($this->userFilter) { - $userQuery->where(new Expression($this->userFilter)); - } + if (($userDn = $user->getAdditional('ldap_dn')) === null) { + $userQuery = $this->ds + ->select() + ->from($this->userClass) + ->where($this->userNameAttribute, $user->getUsername()) + ->setBase($this->userBaseDn) + ->setUsePagedResults(false); + if ($this->userFilter) { + $userQuery->where(new Expression($this->userFilter)); + } - if (($userDn = $userQuery->fetchDn()) === null) { - return array(); + if (($userDn = $userQuery->fetchDn()) === null) { + return array(); + } } $groupQuery = $this->ds From dd0e924e8d0882210ada1f3e2eaf527fdee16ed0 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Fri, 18 Sep 2015 16:11:51 +0200 Subject: [PATCH 26/39] Do not validate section names in forms fixes #10151 --- .../forms/Config/UserBackend/DbBackendForm.php | 14 -------------- .../Config/UserBackend/ExternalBackendForm.php | 14 -------------- .../forms/Config/UserBackend/LdapBackendForm.php | 14 -------------- .../Config/UserGroup/DbUserGroupBackendForm.php | 14 -------------- .../UserGroup/LdapUserGroupBackendForm.php | 14 -------------- application/forms/Dashboard/DashletForm.php | 16 +--------------- .../forms/Config/BackendConfigForm.php | 14 -------------- .../forms/Config/TransportConfigForm.php | 14 -------------- 8 files changed, 1 insertion(+), 113 deletions(-) diff --git a/application/forms/Config/UserBackend/DbBackendForm.php b/application/forms/Config/UserBackend/DbBackendForm.php index 49426c073..a683c838b 100644 --- a/application/forms/Config/UserBackend/DbBackendForm.php +++ b/application/forms/Config/UserBackend/DbBackendForm.php @@ -53,20 +53,6 @@ class DbBackendForm extends Form 'label' => $this->translate('Backend Name'), 'description' => $this->translate( 'The name of this authentication provider that is used to differentiate it from others' - ), - 'validators' => array( - array( - 'Regex', - false, - array( - 'pattern' => '/^[^\\[\\]:]+$/', - 'messages' => array( - 'regexNotMatch' => $this->translate( - 'The name cannot contain \'[\', \']\' or \':\'.' - ) - ) - ) - ) ) ) ); diff --git a/application/forms/Config/UserBackend/ExternalBackendForm.php b/application/forms/Config/UserBackend/ExternalBackendForm.php index 4f3a4585f..317e35f81 100644 --- a/application/forms/Config/UserBackend/ExternalBackendForm.php +++ b/application/forms/Config/UserBackend/ExternalBackendForm.php @@ -32,20 +32,6 @@ class ExternalBackendForm extends Form 'label' => $this->translate('Backend Name'), 'description' => $this->translate( 'The name of this authentication provider that is used to differentiate it from others' - ), - 'validators' => array( - array( - 'Regex', - false, - array( - 'pattern' => '/^[^\\[\\]:]+$/', - 'messages' => array( - 'regexNotMatch' => $this->translate( - 'The backend name cannot contain \'[\', \']\' or \':\'.' - ) - ) - ) - ) ) ) ); diff --git a/application/forms/Config/UserBackend/LdapBackendForm.php b/application/forms/Config/UserBackend/LdapBackendForm.php index ac6765598..75634b6cb 100644 --- a/application/forms/Config/UserBackend/LdapBackendForm.php +++ b/application/forms/Config/UserBackend/LdapBackendForm.php @@ -57,20 +57,6 @@ class LdapBackendForm extends Form 'label' => $this->translate('Backend Name'), 'description' => $this->translate( 'The name of this authentication provider that is used to differentiate it from others.' - ), - 'validators' => array( - array( - 'Regex', - false, - array( - 'pattern' => '/^[^\\[\\]:]+$/', - 'messages' => array( - 'regexNotMatch' => $this->translate( - 'The name cannot contain \'[\', \']\' or \':\'.' - ) - ) - ) - ) ) ) ); diff --git a/application/forms/Config/UserGroup/DbUserGroupBackendForm.php b/application/forms/Config/UserGroup/DbUserGroupBackendForm.php index 9d7545fe7..5d1cf1839 100644 --- a/application/forms/Config/UserGroup/DbUserGroupBackendForm.php +++ b/application/forms/Config/UserGroup/DbUserGroupBackendForm.php @@ -34,20 +34,6 @@ class DbUserGroupBackendForm extends Form 'label' => $this->translate('Backend Name'), 'description' => $this->translate( 'The name of this user group backend that is used to differentiate it from others' - ), - 'validators' => array( - array( - 'Regex', - false, - array( - 'pattern' => '/^[^\\[\\]:]+$/', - 'messages' => array( - 'regexNotMatch' => $this->translate( - 'The name cannot contain \'[\', \']\' or \':\'.' - ) - ) - ) - ) ) ) ); diff --git a/application/forms/Config/UserGroup/LdapUserGroupBackendForm.php b/application/forms/Config/UserGroup/LdapUserGroupBackendForm.php index 4f67b788b..4aeab8e1d 100644 --- a/application/forms/Config/UserGroup/LdapUserGroupBackendForm.php +++ b/application/forms/Config/UserGroup/LdapUserGroupBackendForm.php @@ -39,20 +39,6 @@ class LdapUserGroupBackendForm extends Form 'label' => $this->translate('Backend Name'), 'description' => $this->translate( 'The name of this user group backend that is used to differentiate it from others' - ), - 'validators' => array( - array( - 'Regex', - false, - array( - 'pattern' => '/^[^\\[\\]:]+$/', - 'messages' => array( - 'regexNotMatch' => $this->translate( - 'The name cannot contain \'[\', \']\' or \':\'.' - ) - ) - ) - ) ) ) ); diff --git a/application/forms/Dashboard/DashletForm.php b/application/forms/Dashboard/DashletForm.php index 1e31a938d..d25001a23 100644 --- a/application/forms/Dashboard/DashletForm.php +++ b/application/forms/Dashboard/DashletForm.php @@ -77,21 +77,7 @@ class DashletForm extends Form array( 'required' => true, 'label' => $this->translate('Dashlet Title'), - 'description' => $this->translate('Enter a title for the dashlet.'), - 'validators' => array( - array( - 'Regex', - false, - array( - 'pattern' => '/^[^\\[\\]]+$/', - 'messages' => array( - 'regexNotMatch' => $this->translate( - 'The name cannot contain \'[\' or \']\'.' - ) - ) - ) - ) - ) + 'description' => $this->translate('Enter a title for the dashlet.') ) ); $this->addElement( diff --git a/modules/monitoring/application/forms/Config/BackendConfigForm.php b/modules/monitoring/application/forms/Config/BackendConfigForm.php index d5a960d20..03c293d7c 100644 --- a/modules/monitoring/application/forms/Config/BackendConfigForm.php +++ b/modules/monitoring/application/forms/Config/BackendConfigForm.php @@ -193,20 +193,6 @@ class BackendConfigForm extends ConfigForm 'label' => $this->translate('Backend Name'), 'description' => $this->translate( 'The name of this monitoring backend that is used to differentiate it from others' - ), - 'validators' => array( - array( - 'Regex', - false, - array( - 'pattern' => '/^[^\\[\\]:]+$/', - 'messages' => array( - 'regexNotMatch' => $this->translate( - 'The name cannot contain \'[\', \']\' or \':\'.' - ) - ) - ) - ) ) ) ); diff --git a/modules/monitoring/application/forms/Config/TransportConfigForm.php b/modules/monitoring/application/forms/Config/TransportConfigForm.php index dc679c5da..f21fdd73d 100644 --- a/modules/monitoring/application/forms/Config/TransportConfigForm.php +++ b/modules/monitoring/application/forms/Config/TransportConfigForm.php @@ -217,20 +217,6 @@ class TransportConfigForm extends ConfigForm 'label' => $this->translate('Transport Name'), 'description' => $this->translate( 'The name of this command transport that is used to differentiate it from others' - ), - 'validators' => array( - array( - 'Regex', - false, - array( - 'pattern' => '/^[^\\[\\]:]+$/', - 'messages' => array( - 'regexNotMatch' => $this->translate( - 'The name cannot contain \'[\', \']\' or \':\'.' - ) - ) - ) - ) ) ) ); From f3df1f228de818cc4825434dc8f3b3d1dfc5a30c Mon Sep 17 00:00:00 2001 From: Jo Rhett Date: Fri, 18 Sep 2015 13:37:04 -0700 Subject: [PATCH 27/39] Fix for support issue 9950, do lookups properly on posixGroup group classes --- .../UserGroup/LdapUserGroupBackend.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php index 035005937..ea94ad8d8 100644 --- a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php +++ b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php @@ -543,15 +543,22 @@ class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBacken $userQuery->where(new Expression($this->userFilter)); } - if (($userDn = $userQuery->fetchDn()) === null) { - return array(); + # Posix group only uses simple user name + if ($this->groupClass == 'posixGroup') { + $queryUsername = $user->getUsername(); + } + # LDAP groups use the complete DN + else { + if (($queryUsername = $userQuery->fetchDn()) === null) { + return array(); + } } } $groupQuery = $this->ds ->select() ->from($this->groupClass, array($this->groupNameAttribute)) - ->where($this->groupMemberAttribute, $userDn) + ->where($this->groupMemberAttribute, $queryUsername) ->setBase($this->groupBaseDn); if ($this->groupFilter) { $groupQuery->where(new Expression($this->groupFilter)); From 8bfc7b8805150f4068a8957216f85b30691f9c15 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Mon, 21 Sep 2015 13:26:42 +0200 Subject: [PATCH 28/39] Repair "Show More" links in the Alert Summary fixes #9995 --- .../controllers/AlertsummaryController.php | 12 +++++++++--- .../views/scripts/alertsummary/index.phtml | 10 ++++++---- .../views/scripts/list/notifications.phtml | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/modules/monitoring/application/controllers/AlertsummaryController.php b/modules/monitoring/application/controllers/AlertsummaryController.php index 88100d01b..dc28d9035 100644 --- a/modules/monitoring/application/controllers/AlertsummaryController.php +++ b/modules/monitoring/application/controllers/AlertsummaryController.php @@ -57,7 +57,9 @@ class AlertsummaryController extends Controller $this->view->title = $this->translate('Alert Summary'); $this->view->intervalBox = $this->createIntervalBox(); - $this->view->recentAlerts = $this->createRecentAlerts(); + list($recentAlerts, $recentAlertsUrl) = $this->createRecentAlerts(); + $this->view->recentAlerts = $recentAlerts; + $this->view->recentAlertsUrl = $recentAlertsUrl; $this->view->interval = $this->getInterval(); $this->view->defectChart = $this->createDefectImage(); $this->view->healingChart = $this->createHealingChart(); @@ -80,6 +82,7 @@ class AlertsummaryController extends Controller ); $this->applyRestriction('monitoring/filter/objects', $query); $this->view->notifications = $query; + $this->view->notificationsUrl = 'monitoring/list/notifications'; $this->setupLimitControl(); $this->setupPaginationControl($this->view->notifications); @@ -487,7 +490,7 @@ class AlertsummaryController extends Controller /** * Top recent alerts * - * @return mixed + * @return array */ private function createRecentAlerts() { @@ -508,7 +511,10 @@ class AlertsummaryController extends Controller $query->order('notification_start_time', 'desc'); - return $query->limit(5); + return array( + $query->limit(5), + 'monitoring/list/notifications?sort=notification_start_time&dir=desc' + ); } /** diff --git a/modules/monitoring/application/views/scripts/alertsummary/index.phtml b/modules/monitoring/application/views/scripts/alertsummary/index.phtml index d96ca5bdc..f84395000 100644 --- a/modules/monitoring/application/views/scripts/alertsummary/index.phtml +++ b/modules/monitoring/application/views/scripts/alertsummary/index.phtml @@ -59,8 +59,9 @@
partial('list/notifications.phtml', array( - 'notifications' => $this->recentAlerts, - 'compact' => true + 'notifications' => $this->recentAlerts, + 'compact' => true, + 'notificationsUrl' => $recentAlertsUrl )); ?>
@@ -70,8 +71,9 @@
partial('list/notifications.phtml', array( - 'notifications' => $this->notifications, - 'compact' => true + 'notifications' => $this->notifications, + 'compact' => true, + 'notificationsUrl' => $notificationsUrl )); ?>
diff --git a/modules/monitoring/application/views/scripts/list/notifications.phtml b/modules/monitoring/application/views/scripts/list/notifications.phtml index 06028c993..6e08abaa7 100644 --- a/modules/monitoring/application/views/scripts/list/notifications.phtml +++ b/modules/monitoring/application/views/scripts/list/notifications.phtml @@ -72,7 +72,7 @@ if (! $this->compact): ?> hasMore()): ?> qlink( $this->translate('Show More'), - $this->url()->without(array('view', 'limit')), + $this->url(isset($notificationsUrl) ? $notificationsUrl : null)->without(array('view', 'limit')), null, array( 'data-base-target' => '_next', From 84554d245dfc20e9623bd4be34b1b8b6244c4a2e Mon Sep 17 00:00:00 2001 From: Matthias Jentsch Date: Tue, 22 Sep 2015 12:51:00 +0200 Subject: [PATCH 29/39] Conform to coding guidelines refs #9950 --- .../Authentication/UserGroup/LdapUserGroupBackend.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php index ea94ad8d8..de25a7c3c 100644 --- a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php +++ b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php @@ -543,12 +543,11 @@ class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBacken $userQuery->where(new Expression($this->userFilter)); } - # Posix group only uses simple user name - if ($this->groupClass == 'posixGroup') { + if ($this->groupClass === 'posixGroup') { + # Posix group only uses simple user name $queryUsername = $user->getUsername(); - } - # LDAP groups use the complete DN - else { + } else { + # LDAP groups use the complete DN if (($queryUsername = $userQuery->fetchDn()) === null) { return array(); } From 46f2f71c57ea8686a72f42b028b40b704ffdd30b Mon Sep 17 00:00:00 2001 From: Matthias Jentsch Date: Tue, 22 Sep 2015 13:02:08 +0200 Subject: [PATCH 30/39] Improve logging of membership queries refs #9950 --- .../Icinga/Authentication/UserGroup/LdapUserGroupBackend.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php index de25a7c3c..21dea70ae 100644 --- a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php +++ b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php @@ -12,6 +12,7 @@ use Icinga\Protocol\Ldap\Expression; use Icinga\Repository\LdapRepository; use Icinga\Repository\RepositoryQuery; use Icinga\User; +use Icinga\Application\Logger; class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBackendInterface { @@ -563,10 +564,12 @@ class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBacken $groupQuery->where(new Expression($this->groupFilter)); } + Logger::debug('Fetching groups for user %s using filter %s.', $user->getUsername(), $groupQuery->__toString()); $groups = array(); foreach ($groupQuery as $row) { $groups[] = $row->{$this->groupNameAttribute}; } + Logger::debug('Fetched %d groups: %s.', count($groups), join(', ', $groups)); return $groups; } From 42fb1a174b431ba6a1fe52770ad625c09875ab6e Mon Sep 17 00:00:00 2001 From: Matthias Jentsch Date: Tue, 22 Sep 2015 14:08:15 +0200 Subject: [PATCH 31/39] Do not crash when ldap_dn is defined in additional variables refs #9950 --- .../UserGroup/LdapUserGroupBackend.php | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php index 21dea70ae..490fa44db 100644 --- a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php +++ b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php @@ -533,23 +533,23 @@ class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBacken */ public function getMemberships(User $user) { - if (($userDn = $user->getAdditional('ldap_dn')) === null) { - $userQuery = $this->ds - ->select() - ->from($this->userClass) - ->where($this->userNameAttribute, $user->getUsername()) - ->setBase($this->userBaseDn) - ->setUsePagedResults(false); - if ($this->userFilter) { - $userQuery->where(new Expression($this->userFilter)); - } + if ($this->groupClass === 'posixGroup') { + # Posix group only uses simple user name + $userDn = $user->getUsername(); + } else { + # LDAP groups use the complete DN + if (($userDn = $user->getAdditional('ldap_dn')) === null) { + $userQuery = $this->ds + ->select() + ->from($this->userClass) + ->where($this->userNameAttribute, $user->getUsername()) + ->setBase($this->userBaseDn) + ->setUsePagedResults(false); + if ($this->userFilter) { + $userQuery->where(new Expression($this->userFilter)); + } - if ($this->groupClass === 'posixGroup') { - # Posix group only uses simple user name - $queryUsername = $user->getUsername(); - } else { - # LDAP groups use the complete DN - if (($queryUsername = $userQuery->fetchDn()) === null) { + if (($userDn = $userQuery->fetchDn()) === null) { return array(); } } @@ -558,7 +558,7 @@ class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBacken $groupQuery = $this->ds ->select() ->from($this->groupClass, array($this->groupNameAttribute)) - ->where($this->groupMemberAttribute, $queryUsername) + ->where($this->groupMemberAttribute, $userDn) ->setBase($this->groupBaseDn); if ($this->groupFilter) { $groupQuery->where(new Expression($this->groupFilter)); From b4411569347e4a945a768ae3f0c1f7c6cefe9eed Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 22 Sep 2015 11:54:13 +0200 Subject: [PATCH 32/39] Implement IniParser::parseIniFile() refs #10150 --- library/Icinga/File/Ini/IniParser.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/library/Icinga/File/Ini/IniParser.php b/library/Icinga/File/Ini/IniParser.php index 43c96836d..b22841f78 100644 --- a/library/Icinga/File/Ini/IniParser.php +++ b/library/Icinga/File/Ini/IniParser.php @@ -9,6 +9,7 @@ use Icinga\File\Ini\Dom\Document; use Icinga\File\Ini\Dom\Directive; use Icinga\Application\Logger; use Icinga\Exception\ConfigurationError; +use Icinga\Exception\NotReadableError; class IniParser { @@ -239,4 +240,25 @@ class IniParser } return $doc; } + + /** + * Read the ini file and parse it with ::parseIni() + * + * @param string $file The ini file to read + * + * @return Document A mutable DOM object + * @throws NotReadableError When the file cannot be read + */ + public static function parseIniFile($file) + { + if (false === ($path = realpath($file))) { + throw new NotReadableError('couldn\'t compute the absolute path of `%s\'', $file); + } + + if (false === ($content = file_get_contents($path))) { + throw new NotReadableError('couldn\'t read the file `%s\'', $path); + } + + return self::parseIni($content); + } } From 777c4d0bafa7565b62b5f73d2a54973585d7646b Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 22 Sep 2015 14:03:19 +0200 Subject: [PATCH 33/39] Implement Section::toArray() refs #10150 --- library/Icinga/File/Ini/Dom/Section.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/Icinga/File/Ini/Dom/Section.php b/library/Icinga/File/Ini/Dom/Section.php index dbc9188cb..42dbac709 100644 --- a/library/Icinga/File/Ini/Dom/Section.php +++ b/library/Icinga/File/Ini/Dom/Section.php @@ -169,4 +169,18 @@ class Section $str = str_replace(';', '\\;', $str); return str_replace(PHP_EOL, ' ', $str); } + + /** + * Convert $this to an array + * + * @return array + */ + public function toArray() + { + $a = array(); + foreach ($this->directives as $directive) { + $a[$directive->getKey()] = $directive->getValue(); + } + return $a; + } } From acb93ce1ae4d761a2fead31aac0e1648efffb6db Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 22 Sep 2015 14:13:10 +0200 Subject: [PATCH 34/39] Implement Document::toArray() refs #10150 --- library/Icinga/File/Ini/Dom/Document.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/library/Icinga/File/Ini/Dom/Document.php b/library/Icinga/File/Ini/Dom/Document.php index 69b628916..32f5b92c9 100644 --- a/library/Icinga/File/Ini/Dom/Document.php +++ b/library/Icinga/File/Ini/Dom/Document.php @@ -115,4 +115,18 @@ class Document } return $str; } + + /** + * Convert $this to an array + * + * @return array + */ + public function toArray() + { + $a = array(); + foreach ($this->sections as $section) { + $a[$section->getName()] = $section->toArray(); + } + return $a; + } } From 626c3494e48d600adc21fbfd33d4ffa2f17e7541 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 22 Sep 2015 14:46:15 +0200 Subject: [PATCH 35/39] Config::fromIni(): use IniParser::parseIniFile() instead of parse_ini_file() refs #10150 --- library/Icinga/Application/Config.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/Icinga/Application/Config.php b/library/Icinga/Application/Config.php index 0538f01d4..d7bfe64a6 100644 --- a/library/Icinga/Application/Config.php +++ b/library/Icinga/Application/Config.php @@ -12,6 +12,7 @@ use Icinga\Data\ConfigObject; use Icinga\Data\Selectable; use Icinga\Data\SimpleQuery; use Icinga\File\Ini\IniWriter; +use Icinga\File\Ini\IniParser; use Icinga\Exception\NotReadableError; /** @@ -313,7 +314,7 @@ class Config implements Countable, Iterator, Selectable if ($filepath === false) { $emptyConfig->setConfigFile($file); } elseif (is_readable($filepath)) { - $config = new static(new ConfigObject(parse_ini_file($filepath, true))); + $config = static::fromArray(IniParser::parseIniFile($filepath)->toArray()); $config->setConfigFile($filepath); return $config; } elseif (@file_exists($filepath)) { From b69311165c0c207451e12593610ab7e1ed8677dc Mon Sep 17 00:00:00 2001 From: Matthias Jentsch Date: Tue, 22 Sep 2015 14:53:29 +0200 Subject: [PATCH 36/39] Conform to coding guidelines --- .../Icinga/Authentication/UserGroup/LdapUserGroupBackend.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php index 490fa44db..1d29e018d 100644 --- a/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php +++ b/library/Icinga/Authentication/UserGroup/LdapUserGroupBackend.php @@ -534,10 +534,10 @@ class LdapUserGroupBackend /*extends LdapRepository*/ implements UserGroupBacken public function getMemberships(User $user) { if ($this->groupClass === 'posixGroup') { - # Posix group only uses simple user name + // Posix group only uses simple user name $userDn = $user->getUsername(); } else { - # LDAP groups use the complete DN + // LDAP groups use the complete DN if (($userDn = $user->getAdditional('ldap_dn')) === null) { $userQuery = $this->ds ->select() From a090907373f24efbf71c9d19f3978270e522f48a Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 22 Sep 2015 14:46:15 +0200 Subject: [PATCH 37/39] Conform to coding guidelines --- library/Icinga/File/Ini/IniParser.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/Icinga/File/Ini/IniParser.php b/library/Icinga/File/Ini/IniParser.php index b22841f78..35e708594 100644 --- a/library/Icinga/File/Ini/IniParser.php +++ b/library/Icinga/File/Ini/IniParser.php @@ -251,12 +251,12 @@ class IniParser */ public static function parseIniFile($file) { - if (false === ($path = realpath($file))) { - throw new NotReadableError('couldn\'t compute the absolute path of `%s\'', $file); + if (($path = realpath($file)) === false) { + throw new NotReadableError('Couldn\'t compute the absolute path of `%s\'', $file); } - if (false === ($content = file_get_contents($path))) { - throw new NotReadableError('couldn\'t read the file `%s\'', $path); + if (($content = file_get_contents($path)) === false) { + throw new NotReadableError('Couldn\'t read the file `%s\'', $path); } return self::parseIni($content); From 8dc9928cb374dd70016409f6fc527c3003d127e9 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 22 Sep 2015 14:46:15 +0200 Subject: [PATCH 38/39] IniParser::parseIniFile(): return a Config instance refs #10150 --- library/Icinga/Application/Config.php | 4 +--- library/Icinga/File/Ini/IniParser.php | 5 +++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/library/Icinga/Application/Config.php b/library/Icinga/Application/Config.php index d7bfe64a6..bfe2ddd60 100644 --- a/library/Icinga/Application/Config.php +++ b/library/Icinga/Application/Config.php @@ -314,9 +314,7 @@ class Config implements Countable, Iterator, Selectable if ($filepath === false) { $emptyConfig->setConfigFile($file); } elseif (is_readable($filepath)) { - $config = static::fromArray(IniParser::parseIniFile($filepath)->toArray()); - $config->setConfigFile($filepath); - return $config; + return IniParser::parseIniFile($filepath); } elseif (@file_exists($filepath)) { throw new NotReadableError(t('Cannot read config file "%s". Permission denied'), $filepath); } diff --git a/library/Icinga/File/Ini/IniParser.php b/library/Icinga/File/Ini/IniParser.php index 35e708594..72925cac1 100644 --- a/library/Icinga/File/Ini/IniParser.php +++ b/library/Icinga/File/Ini/IniParser.php @@ -10,6 +10,7 @@ use Icinga\File\Ini\Dom\Directive; use Icinga\Application\Logger; use Icinga\Exception\ConfigurationError; use Icinga\Exception\NotReadableError; +use Icinga\Application\Config; class IniParser { @@ -246,7 +247,7 @@ class IniParser * * @param string $file The ini file to read * - * @return Document A mutable DOM object + * @return Config * @throws NotReadableError When the file cannot be read */ public static function parseIniFile($file) @@ -259,6 +260,6 @@ class IniParser throw new NotReadableError('Couldn\'t read the file `%s\'', $path); } - return self::parseIni($content); + return Config::fromArray(self::parseIni($content)->toArray())->setConfigFile($file); } } From 812545c04bbc57ea42d75add1d9f85c1a27cab5a Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Tue, 22 Sep 2015 14:46:15 +0200 Subject: [PATCH 39/39] IniStore::load(): use IniParser::parseIniFile() instead of parse_ini_file() refs #10150 --- library/Icinga/User/Preferences/Store/IniStore.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/Icinga/User/Preferences/Store/IniStore.php b/library/Icinga/User/Preferences/Store/IniStore.php index 88fa7edec..e5dbe4286 100644 --- a/library/Icinga/User/Preferences/Store/IniStore.php +++ b/library/Icinga/User/Preferences/Store/IniStore.php @@ -8,6 +8,7 @@ use Icinga\Exception\NotReadableError; use Icinga\Exception\NotWritableError; use Icinga\User\Preferences; use Icinga\User\Preferences\PreferencesStore; +use Icinga\File\Ini\IniParser; /** * Load and save user preferences from and to INI files @@ -57,7 +58,7 @@ class IniStore extends PreferencesStore $this->getUser()->getUsername() ); } else { - $this->preferences = parse_ini_file($this->preferencesFile, true); + $this->preferences = IniParser::parseIniFile($this->preferencesFile)->toArray(); } }