Controller: Validate restriction columns

This commit is contained in:
Johannes Meyer 2015-06-18 16:42:27 +02:00
parent 1cabe95506
commit fb9641fb3c
2 changed files with 72 additions and 2 deletions
library/Icinga/Data/Filter
modules/monitoring/library/Monitoring

View File

@ -4,6 +4,7 @@
namespace Icinga\Data\Filter;
use Icinga\Exception\ProgrammingError;
use Icinga\Exception\QueryException;
/**
* FilterChain
@ -18,6 +19,8 @@ abstract class FilterChain extends Filter
protected $operatorSymbol;
protected $allowedColumns;
public function hasId($id)
{
foreach ($this->filters() as $filter) {
@ -116,6 +119,12 @@ abstract class FilterChain extends Filter
return $this->operatorSymbol;
}
public function setAllowedFilterColumns(array $columns)
{
$this->allowedColumns = $columns;
return $this;
}
public function listFilteredColumns()
{
$columns = array();
@ -196,11 +205,41 @@ abstract class FilterChain extends Filter
public function addFilter(Filter $filter)
{
if (! empty($this->allowedColumns)) {
$this->validateFilterColumns($filter);
}
$this->filters[] = $filter;
$filter->setId($this->getId() . '-' . $this->count());
return $this;
}
protected function validateFilterColumns(Filter $filter)
{
if ($filter->isExpression()) {
$valid = false;
foreach ($this->allowedColumns as $column) {
if (is_callable($column)) {
if (call_user_func($column, $filter->getColumn())) {
$valid = true;
break;
}
} elseif ($filter->getColumn() === $column) {
$valid = true;
break;
}
}
if (! $valid) {
throw new QueryException('Invalid filter column provided: %s', $filter->getColumn());
}
} else {
foreach ($filter->filters() as $subFilter) {
$this->validateFilterColumns($subFilter);
}
}
}
public function &filters()
{
return $this->filters;

View File

@ -3,6 +3,8 @@
namespace Icinga\Module\Monitoring;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\QueryException;
use Icinga\Data\Filter\Filter;
use Icinga\Data\Filterable;
use Icinga\File\Csv;
@ -52,16 +54,45 @@ class Controller extends IcingaWebController
* Apply a restriction on the given data view
*
* @param string $restriction The name of restriction
* @param Filterable $filterable The filterable to restrict
* @param Filterable $view The filterable to restrict
*
* @return Filterable The filterable
*/
protected function applyRestriction($restriction, Filterable $view)
{
$restrictions = Filter::matchAny();
$restrictions->setAllowedFilterColumns(array(
'host_name',
'hostgroup_name',
'service_description',
'servicegroup_name',
function ($c) {
return preg_match('/^_(?:host|service)_/', $c);
}
));
foreach ($this->getRestrictions($restriction) as $filter) {
$restrictions->addFilter(Filter::fromQueryString($filter));
try {
$restrictions->addFilter(Filter::fromQueryString($filter));
} catch (QueryException $e) {
throw new ConfigurationError(
$this->translate(
'Cannot apply restriction %s using the filter %s. You can only use the following columns: %s'
),
$restriction,
$filter,
implode(', ', array(
'host_name',
'hostgroup_name',
'service_description',
'servicegroup_name',
'_(host|service)_<customvar-name>'
)),
$e
);
}
}
$view->applyFilter($restrictions);
return $view;
}