From 001c63e376a52d89a2e3fb6ae4fee73b6f71df8f Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Wed, 10 Feb 2016 16:21:19 +0100 Subject: [PATCH 1/9] Don't rely on case sensitive usernames in preferences stored in INI files refs #11051 --- library/Icinga/Application/Config.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/library/Icinga/Application/Config.php b/library/Icinga/Application/Config.php index 22757d5f9..251ed4fb6 100644 --- a/library/Icinga/Application/Config.php +++ b/library/Icinga/Application/Config.php @@ -472,11 +472,17 @@ class Config implements Countable, Iterator, Selectable $filename = $type . 's.ini'; } - return static::resolvePath( - ($username ? 'preferences' . DIRECTORY_SEPARATOR . $username : 'navigation') - . DIRECTORY_SEPARATOR - . $filename - ); + if ($username) { + $path = static::resolvePath(implode(DIRECTORY_SEPARATOR, array('preferences', $username, $filename))); + if (realpath($path) === false) { + $path = static::resolvePath(implode(DIRECTORY_SEPARATOR, array( + 'preferences', strtolower($username), $filename + ))); + } + } else { + $path = static::resolvePath('navigation' . DIRECTORY_SEPARATOR . $filename); + } + return $path; } /** From a5924f2ca860194153214d4dad0b03c2ed3a1e2a Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Wed, 10 Feb 2016 16:22:51 +0100 Subject: [PATCH 2/9] Don't rely on case sensitive usernames in navigation items stored in INI files refs #11051 --- library/Icinga/Application/Web.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/Icinga/Application/Web.php b/library/Icinga/Application/Web.php index d179398fd..d0535423f 100644 --- a/library/Icinga/Application/Web.php +++ b/library/Icinga/Application/Web.php @@ -172,7 +172,7 @@ class Web extends EmbeddedWeb { // TODO: Provide a more sophisticated solution - if (isset($config['owner']) && $config['owner'] === $this->user->getUsername()) { + if (isset($config['owner']) && strtolower($config['owner']) === strtolower($this->user->getUsername())) { unset($config['owner']); unset($config['users']); unset($config['groups']); @@ -195,7 +195,7 @@ class Web extends EmbeddedWeb if (isset($config['users'])) { $users = array_map('trim', explode(',', strtolower($config['users']))); - if (in_array('*', $users, true) || in_array($this->user->getUsername(), $users, true)) { + if (in_array('*', $users, true) || in_array(strtolower($this->user->getUsername()), $users, true)) { unset($config['owner']); unset($config['users']); unset($config['groups']); From 809861cb5305832605f50096575319e4dba9931f Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 11 Feb 2016 11:48:50 +0100 Subject: [PATCH 3/9] FilterExpression: make case insensitive matching possible refs #11051 --- .../Icinga/Data/Filter/FilterExpression.php | 60 ++++++++++++++++++- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/library/Icinga/Data/Filter/FilterExpression.php b/library/Icinga/Data/Filter/FilterExpression.php index bb4cdd8b4..fe10bdc76 100644 --- a/library/Icinga/Data/Filter/FilterExpression.php +++ b/library/Icinga/Data/Filter/FilterExpression.php @@ -11,12 +11,20 @@ class FilterExpression extends Filter protected $sign; protected $expression; + /** + * Does this filter compare case sensitive? + * + * @var bool + */ + protected $caseSensitive; + public function __construct($column, $sign, $expression) { $column = trim($column); $this->column = $column; $this->sign = $sign; $this->expression = $expression; + $this->caseSensitive = true; } public function isExpression() @@ -55,6 +63,14 @@ class FilterExpression extends Filter return $this->expression; } + /** + * @return bool + */ + public function getCaseSensitive() + { + return $this->caseSensitive; + } + public function setExpression($expression) { $this->expression = $expression; @@ -69,6 +85,17 @@ class FilterExpression extends Filter return $this; } + /** + * @param bool $caseSensitive + * + * @return $this + */ + public function setCaseSensitive($caseSensitive) + { + $this->caseSensitive = $caseSensitive; + return $this; + } + public function listFilteredColumns() { return array($this->getColumn()); @@ -97,6 +124,26 @@ class FilterExpression extends Filter return $this->column . $this->sign . $expression; } + /** + * If $var is a scalar, do the same as strtolower() would do. + * If $var is an array, map $this->strtolowerRecursive() to its elements. + * Otherwise, return $var unchanged. + * + * @param mixed $var + * + * @return mixed + */ + protected function strtolowerRecursive($var) + { + if ($var === null || is_scalar($var)) { + return strtolower($var); + } + if (is_array($var)) { + return array_map(array($this, 'strtolowerRecursive'), $var); + } + return $var; + } + public function matches($row) { try { @@ -106,11 +153,18 @@ class FilterExpression extends Filter return false; } - if (is_array($this->expression)) { - return in_array($rowValue, $this->expression); + if ($this->caseSensitive) { + $expression = $this->expression; + } else { + $rowValue = $this->strtolowerRecursive($rowValue); + $expression = $this->strtolowerRecursive($this->expression); } - $expression = (string) $this->expression; + if (is_array($expression)) { + return in_array($rowValue, $expression); + } + + $expression = (string) $expression; if (strpos($expression, '*') === false) { if (is_array($rowValue)) { return in_array($expression, $rowValue); From 8ebc92ee44b2f5f57e86324b8f02d5ca03026728 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 11 Feb 2016 11:59:57 +0100 Subject: [PATCH 4/9] Implement FilterMatchCaseInsensitive refs #11051 --- .../Data/Filter/FilterMatchCaseInsensitive.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 library/Icinga/Data/Filter/FilterMatchCaseInsensitive.php diff --git a/library/Icinga/Data/Filter/FilterMatchCaseInsensitive.php b/library/Icinga/Data/Filter/FilterMatchCaseInsensitive.php new file mode 100644 index 000000000..7d8f37115 --- /dev/null +++ b/library/Icinga/Data/Filter/FilterMatchCaseInsensitive.php @@ -0,0 +1,12 @@ +caseSensitive = false; + } +} From aae7c1150ea1fa989ff41f4261f9a63de26770f7 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 11 Feb 2016 12:00:33 +0100 Subject: [PATCH 5/9] Implement FilterMatchNotCaseInsensitive refs #11051 --- .../Data/Filter/FilterMatchNotCaseInsensitive.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 library/Icinga/Data/Filter/FilterMatchNotCaseInsensitive.php diff --git a/library/Icinga/Data/Filter/FilterMatchNotCaseInsensitive.php b/library/Icinga/Data/Filter/FilterMatchNotCaseInsensitive.php new file mode 100644 index 000000000..3ac27d12e --- /dev/null +++ b/library/Icinga/Data/Filter/FilterMatchNotCaseInsensitive.php @@ -0,0 +1,12 @@ +caseSensitive = false; + } +} From 07913238b3633b3498a42287789ec5dc72dbdc93 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Wed, 10 Feb 2016 16:22:51 +0100 Subject: [PATCH 6/9] Navigation items listing: don't rely on case sensitive usernames stored in INI files refs #11051 --- application/controllers/NavigationController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/application/controllers/NavigationController.php b/application/controllers/NavigationController.php index 4c600a96b..51b5dae1c 100644 --- a/application/controllers/NavigationController.php +++ b/application/controllers/NavigationController.php @@ -7,6 +7,7 @@ use Exception; use Icinga\Application\Config; use Icinga\Exception\NotFoundError; use Icinga\Data\DataArray\ArrayDatasource; +use Icinga\Data\Filter\FilterMatchCaseInsensitive; use Icinga\Forms\ConfirmRemovalForm; use Icinga\Forms\Navigation\NavigationConfigForm; use Icinga\Web\Controller; @@ -78,7 +79,7 @@ class NavigationController extends Controller $config->getConfigObject()->setKeyColumn('name'); $query = $config->select(); if ($owner !== null) { - $query->where('owner', $owner); + $query->applyFilter(new FilterMatchCaseInsensitive('owner', '=', $owner)); } foreach ($query as $itemConfig) { From ea9bc6cebdbdd9aed00a7c47388ecaa86d9abd3a Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 11 Feb 2016 13:29:00 +0100 Subject: [PATCH 7/9] Conform to coding guidelines refs #11051 --- library/Icinga/Application/Config.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/Icinga/Application/Config.php b/library/Icinga/Application/Config.php index 251ed4fb6..de8fec6f4 100644 --- a/library/Icinga/Application/Config.php +++ b/library/Icinga/Application/Config.php @@ -475,9 +475,10 @@ class Config implements Countable, Iterator, Selectable if ($username) { $path = static::resolvePath(implode(DIRECTORY_SEPARATOR, array('preferences', $username, $filename))); if (realpath($path) === false) { - $path = static::resolvePath(implode(DIRECTORY_SEPARATOR, array( - 'preferences', strtolower($username), $filename - ))); + $path = static::resolvePath(implode( + DIRECTORY_SEPARATOR, + array('preferences', strtolower($username), $filename) + )); } } else { $path = static::resolvePath('navigation' . DIRECTORY_SEPARATOR . $filename); From e97426e1dff4c3fe5c973aa0d2084786cf86a8c5 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 11 Feb 2016 13:30:34 +0100 Subject: [PATCH 8/9] FilterExpression: document getCaseSensitive() and setCaseSensitive() refs #11051 --- library/Icinga/Data/Filter/FilterExpression.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/Icinga/Data/Filter/FilterExpression.php b/library/Icinga/Data/Filter/FilterExpression.php index fe10bdc76..c4449e58e 100644 --- a/library/Icinga/Data/Filter/FilterExpression.php +++ b/library/Icinga/Data/Filter/FilterExpression.php @@ -64,6 +64,8 @@ class FilterExpression extends Filter } /** + * Return whether this filter compares case sensitive + * * @return bool */ public function getCaseSensitive() @@ -86,6 +88,8 @@ class FilterExpression extends Filter } /** + * Set this filter's case sensitivity + * * @param bool $caseSensitive * * @return $this From 8493540f4302e94785db65edb65f4905ec10c25b Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Thu, 11 Feb 2016 13:32:42 +0100 Subject: [PATCH 9/9] FilterExpression: provide default value for setCaseSensitive() refs #11051 --- library/Icinga/Data/Filter/FilterExpression.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/Icinga/Data/Filter/FilterExpression.php b/library/Icinga/Data/Filter/FilterExpression.php index c4449e58e..ad6105cdf 100644 --- a/library/Icinga/Data/Filter/FilterExpression.php +++ b/library/Icinga/Data/Filter/FilterExpression.php @@ -94,7 +94,7 @@ class FilterExpression extends Filter * * @return $this */ - public function setCaseSensitive($caseSensitive) + public function setCaseSensitive($caseSensitive = true) { $this->caseSensitive = $caseSensitive; return $this;