From aadf3feb7b8090796a4dd083c90a5bc4893c8faf Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Sun, 4 Mar 2018 16:42:05 +0100 Subject: [statistics] Refine permissions, add some new ones --- modules-available/statistics/inc/filter.inc.php | 9 ++- modules-available/statistics/inc/filterset.inc.php | 82 ++++++++++++++++++---- 2 files changed, 76 insertions(+), 15 deletions(-) (limited to 'modules-available/statistics/inc') diff --git a/modules-available/statistics/inc/filter.inc.php b/modules-available/statistics/inc/filter.inc.php index f6765059..565ea5f0 100644 --- a/modules-available/statistics/inc/filter.inc.php +++ b/modules-available/statistics/inc/filter.inc.php @@ -18,7 +18,7 @@ class Filter { $this->column = trim($column); $this->operator = trim($operator); - $this->argument = trim($argument); + $this->argument = is_array($argument) ? $argument : trim($argument); } /* returns a where clause and adds needed operators to the passed array */ @@ -245,7 +245,12 @@ class LocationFilter extends Filter $recursive = (substr($this->operator, -1) === '~'); $this->operator = str_replace('~', '=', $this->operator); - settype($this->argument, 'int'); + if (is_array($this->argument)) { + if ($recursive) + Util::traceError('Cannot use ~ operator for location with array'); + } else { + settype($this->argument, 'int'); + } $neg = $this->operator === '=' ? '' : 'NOT'; if ($this->argument === 0) { return "machine.locationid IS $neg NULL"; diff --git a/modules-available/statistics/inc/filterset.inc.php b/modules-available/statistics/inc/filterset.inc.php index 25c5c8fa..774bfd18 100644 --- a/modules-available/statistics/inc/filterset.inc.php +++ b/modules-available/statistics/inc/filterset.inc.php @@ -9,6 +9,8 @@ class FilterSet private $sortDirection; private $sortColumn; + private $cache = false; + public function __construct($filters) { $this->filters = $filters; @@ -16,19 +18,28 @@ class FilterSet public function setSort($col, $direction) { - $this->sortDirection = $direction === 'DESC' ? 'DESC' : 'ASC'; + $direction = ($direction === 'DESC' ? 'DESC' : 'ASC'); - if (is_string($col) && array_key_exists($col, Page_Statistics::$columns)) { - $this->sortColumn = $col; - } else { + if (!is_string($col) || !array_key_exists($col, Page_Statistics::$columns)) { /* default sorting column is clientip */ - $this->sortColumn = 'clientip'; + $col = 'clientip'; } - + if ($col === $this->sortColumn && $direction === $this->sortDirection) + return; + $this->cache = false; + $this->sortDirection = $direction; + $this->sortColumn = $col; } public function makeFragments(&$where, &$join, &$sort, &$args) { + if ($this->cache !== false) { + $where = $this->cache['where']; + $join = $this->cache['join']; + $sort = $this->cache['sort']; + $args = $this->cache['args']; + return; + } /* generate where clause & arguments */ $where = ''; $joins = []; @@ -54,16 +65,13 @@ class FilterSet $sort = " ORDER BY " . $concreteCol . " " . $this->sortDirection . ", machineuuid ASC"; + $this->cache = compact('where', 'join', 'sort', 'args'); } public function isNoId44Filter() { - foreach ($this->filters as $filter) { - if (get_class($filter) === 'Id44Filter' && $filter->argument == 0) { - return true; - } - } - return false; + $filter = $this->hasFilter('Id44Filter'); + return $filter !== false && $filter->argument == 0; } public function getSortDirection() @@ -78,10 +86,58 @@ class FilterSet public function filterNonClients() { - if (Module::get('runmode') === false) + if (Module::get('runmode') === false || $this->hasFilter('IsClientFilter') !== false) return; + $this->cache = false; // Runmode module exists, add filter $this->filters[] = new IsClientFilter(true); } + /** + * @param string $type filter type (class name) + * @return false|Filter The filter, false if not found + */ + public function hasFilter($type) + { + foreach ($this->filters as $filter) { + if (get_class($filter) === $type) { + return $filter; + } + } + return false; + } + + /** + * Add a location filter based on the allowed permissions for the given permission. + * Returns false if the user doesn't have the given permission for any location. + * + * @param string $permission permission to use + * @return bool false if no permission for any location, true otherwise + */ + public function setAllowedLocationsFromPermission($permission) + { + $locs = User::getAllowedLocations($permission); + if (empty($locs)) + return false; + if (in_array(0, $locs)) { + if (!isset($this->filters['permissions'])) + return true; + unset($this->filters['permissions']); + } else { + $this->filters['permissions'] = new LocationFilter('=', $locs); + } + $this->cache = false; + return true; + } + + /** + * @return false|array + */ + public function getAllowedLocations() + { + if (isset($this->filters['permissions']->argument) && is_array($this->filters['permissions']->argument)) + return $this->filters['permissions']->argument; + return false; + } + } -- cgit v1.2.3-55-g7522