summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2018-03-04 16:42:05 +0100
committerSimon Rettberg2018-03-04 16:42:05 +0100
commitaadf3feb7b8090796a4dd083c90a5bc4893c8faf (patch)
tree515e141009a855d76011e315b2f832c51adc0409
parent[sysconfig] Add permissions (diff)
downloadslx-admin-aadf3feb7b8090796a4dd083c90a5bc4893c8faf.tar.gz
slx-admin-aadf3feb7b8090796a4dd083c90a5bc4893c8faf.tar.xz
slx-admin-aadf3feb7b8090796a4dd083c90a5bc4893c8faf.zip
[statistics] Refine permissions, add some new ones
-rw-r--r--modules-available/statistics/inc/filter.inc.php9
-rw-r--r--modules-available/statistics/inc/filterset.inc.php82
-rw-r--r--modules-available/statistics/page.inc.php139
-rw-r--r--modules-available/statistics/pages/projectors.inc.php2
-rw-r--r--modules-available/statistics/permissions/permissions.json19
-rw-r--r--modules-available/statistics/templates/clientlist.html18
-rw-r--r--modules-available/statistics/templates/cpumodels.html4
-rw-r--r--modules-available/statistics/templates/filterbox.html6
-rw-r--r--modules-available/statistics/templates/id44.html2
-rw-r--r--modules-available/statistics/templates/kvmstate.html2
-rw-r--r--modules-available/statistics/templates/machine-main.html12
-rw-r--r--modules-available/statistics/templates/machine-notes.html7
-rw-r--r--modules-available/statistics/templates/memory.html2
-rw-r--r--modules-available/statistics/templates/summary.html4
14 files changed, 207 insertions, 101 deletions
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;
+ }
+
}
diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php
index e89180ed..3baac190 100644
--- a/modules-available/statistics/page.inc.php
+++ b/modules-available/statistics/page.inc.php
@@ -20,8 +20,7 @@ class Page_Statistics extends Page
public static $columns;
private $query;
-
- private $locationsAllowedToView;
+ private $show;
/**
* @var bool whether we have a SubPage from the pages/ subdir
@@ -151,15 +150,23 @@ class Page_Statistics extends Page
Util::redirect('?do=Main');
}
- $this->locationsAllowedToView = User::getAllowedLocations("view");
-
-
- $show = Request::any('show', 'stat', 'string');
- $show = preg_replace('/[^a-z0-9_\-]/', '', $show);
+ $this->show = Request::any('show', false, 'string');
+ if ($this->show === false) {
+ if (User::hasPermission('view.summary')) {
+ $this->show = 'summary';
+ } elseif (User::hasPermission('view.list')) {
+ $this->show = 'list';
+ } else {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=main');
+ }
+ } else {
+ $this->show = preg_replace('/[^a-z0-9_\-]/', '', $this->show);
+ }
- if (file_exists('modules/statistics/pages/' . $show . '.inc.php')) {
+ if (file_exists('modules/statistics/pages/' . $this->show . '.inc.php')) {
- require_once 'modules/statistics/pages/' . $show . '.inc.php';
+ require_once 'modules/statistics/pages/' . $this->show . '.inc.php';
$this->haveSubpage = true;
SubPage::doPreprocess();
@@ -168,20 +175,23 @@ class Page_Statistics extends Page
$action = Request::post('action');
if ($action === 'setnotes') {
$uuid = Request::post('uuid', '', 'string');
- $locationid = Database::queryFirst('SELECT locationid FROM machine WHERE machineuuid = :uuid',
- array('uuid' => $uuid))['locationid'];
- if (User::hasPermission("machine.note", $locationid)) {
- $text = Request::post('content', '', 'string');
- if (empty($text)) {
- $text = null;
- }
- Database::exec('UPDATE machine SET notes = :text WHERE machineuuid = :uuid', array(
- 'uuid' => $uuid,
- 'text' => $text,
- ));
- Message::addSuccess('notes-saved');
- Util::redirect('?do=Statistics&uuid=' . $uuid);
+ $res = Database::queryFirst('SELECT locationid FROM machine WHERE machineuuid = :uuid',
+ array('uuid' => $uuid));
+ if ($res === false) {
+ Message::addError('unknown-machine', $uuid);
+ Util::redirect('?do=statistics');
+ }
+ User::assertPermission("machine.note.edit", (int)$res['locationid']);
+ $text = Request::post('content', null, 'string');
+ if (empty($text)) {
+ $text = null;
}
+ Database::exec('UPDATE machine SET notes = :text WHERE machineuuid = :uuid', array(
+ 'uuid' => $uuid,
+ 'text' => $text,
+ ));
+ Message::addSuccess('notes-saved');
+ Util::redirect('?do=statistics&uuid=' . $uuid);
} elseif ($action === 'delmachines') {
$this->deleteMachines();
Util::redirect('?do=statistics', true);
@@ -204,14 +214,20 @@ class Page_Statistics extends Page
Message::addError('main.parameter-empty', 'uuid');
return;
}
+ $allowedLocations = User::getAllowedLocations("machine.delete");
+ if (empty($allowedLocations)) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=statistics');
+ }
$res = Database::simpleQuery('SELECT machineuuid, locationid FROM machine WHERE machineuuid IN (:ids)', compact('ids'));
$ids = array_flip($ids);
$delete = [];
- $allowedLocations = User::getAllowedLocations("machine.delete");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ unset($ids[$row['machineuuid']]);
if (in_array($row['locationid'], $allowedLocations)) {
- unset($ids[$row['machineuuid']]);
$delete[] = $row['machineuuid'];
+ } else {
+ Message::addError('no-permission-location', $row['locationid']);
}
}
if (!empty($delete)) {
@@ -219,7 +235,6 @@ class Page_Statistics extends Page
Message::addSuccess('deleted-n-machines', count($delete));
}
if (!empty($ids)) {
- // TODO: Warn permissions
Message::addWarning('unknown-machine', implode(', ', array_keys($ids)));
}
}
@@ -237,8 +252,6 @@ class Page_Statistics extends Page
return;
}
- $show = Request::get('show', 'stat', 'string');
-
/* read filter */
$this->query = Request::any('filters', false);
if ($this->query === false) {
@@ -251,23 +264,31 @@ class Page_Statistics extends Page
$filterSet = new FilterSet($filters);
$filterSet->setSort($sortColumn, $sortDirection);
- if ($show == 'list') {
+ if (!$filterSet->setAllowedLocationsFromPermission('view.' . $this->show)) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=statistics');
+ }
+
+ if ($this->show === 'list') {
Render::openTag('div', array('class' => 'row'));
$this->showFilter('list', $filterSet);
Render::closeTag('div');
$this->showMachineList($filterSet);
return;
+ } elseif ($this->show === 'summary') {
+ $filterSet->filterNonClients();
+ Render::openTag('div', array('class' => 'row'));
+ $this->showFilter('summary', $filterSet);
+ $this->showSummary($filterSet);
+ $this->showMemory($filterSet);
+ $this->showId44($filterSet);
+ $this->showKvmState($filterSet);
+ $this->showLatestMachines($filterSet);
+ $this->showSystemModels($filterSet);
+ Render::closeTag('div');
+ } else {
+ Message::addError('main.value-invalid', 'show', $this->show);
}
- $filterSet->filterNonClients();
- Render::openTag('div', array('class' => 'row'));
- $this->showFilter('stat', $filterSet);
- $this->showSummary($filterSet);
- $this->showMemory($filterSet);
- $this->showId44($filterSet);
- $this->showKvmState($filterSet);
- $this->showLatestMachines($filterSet);
- $this->showSystemModels($filterSet);
- Render::closeTag('div');
}
/**
@@ -295,15 +316,17 @@ class Page_Statistics extends Page
$locsFlat = array();
if (Module::isAvailable('locations')) {
+ $allowed = $filterSet->getAllowedLocations();
foreach (Location::getLocations() as $loc) {
$locsFlat['L' . $loc['locationid']] = array(
'pad' => $loc['locationpad'],
'name' => $loc['locationname'],
- 'disabled' => !in_array($loc['locationid'], $this->locationsAllowedToView)
+ 'disabled' => $allowed !== false && !in_array($loc['locationid'], $allowed),
);
}
}
+ Permission::addGlobalTags($data['perms'], null, ['view.summary', 'view.list']);
$data['locations'] = json_encode($locsFlat);
Render::addTemplate('filterbox', $data);
@@ -355,8 +378,6 @@ class Page_Statistics extends Page
private function showSummary($filterSet)
{
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$known = Database::queryFirst("SELECT Count(*) AS val FROM machine $join WHERE $where", $args);
// If we only have one machine, redirect to machine details
if ($known['val'] == 1) {
@@ -417,8 +438,6 @@ class Page_Statistics extends Page
global $STATS_COLORS;
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$res = Database::simpleQuery('SELECT systemmodel, Round(AVG(realcores)) AS cores, Count(*) AS `count` FROM machine'
. " $join WHERE $where GROUP BY systemmodel ORDER BY `count` DESC, systemmodel ASC", $args);
$lines = array();
@@ -451,8 +470,6 @@ class Page_Statistics extends Page
global $STATS_COLORS, $SIZE_RAM;
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$res = Database::simpleQuery("SELECT mbram, Count(*) AS `count` FROM machine $join WHERE $where GROUP BY mbram", $args);
$lines = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
@@ -498,8 +515,6 @@ class Page_Statistics extends Page
private function showKvmState($filterSet)
{
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$colors = array('UNKNOWN' => '#666', 'UNSUPPORTED' => '#ea5', 'DISABLED' => '#e55', 'ENABLED' => '#6d6');
$res = Database::simpleQuery("SELECT kvmstate, Count(*) AS `count` FROM machine $join WHERE $where GROUP BY kvmstate ORDER BY `count` DESC", $args);
$lines = array();
@@ -523,8 +538,6 @@ class Page_Statistics extends Page
global $STATS_COLORS, $SIZE_ID44;
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$res = Database::simpleQuery("SELECT id44mb, Count(*) AS `count` FROM machine $join WHERE $where GROUP BY id44mb", $args);
$lines = array();
$total = 0;
@@ -576,8 +589,6 @@ class Page_Statistics extends Page
private function showLatestMachines($filterSet)
{
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$args['cutoff'] = ceil(time() / 3600) * 3600 - 86400 * 10;
$res = Database::simpleQuery("SELECT machineuuid, clientip, hostname, firstseen, mbram, kvmstate, id44mb FROM machine $join"
@@ -611,8 +622,6 @@ class Page_Statistics extends Page
{
Module::isAvailable('js_stupidtable');
$filterSet->makeFragments($where, $join, $sort, $args);
- $args['allowedLocations'] = $this->locationsAllowedToView;
- $where = "locationid IN (:allowedLocations) AND ($where)";
$xtra = '';
if ($filterSet->isNoId44Filter()) {
$xtra .= ', data';
@@ -630,13 +639,16 @@ class Page_Statistics extends Page
$rows = array();
$singleMachine = 'none';
$deleteAllowedLocations = User::getAllowedLocations("machine.delete");
+ $detailsAllowedLocations = User::getAllowedLocations("machine.view-details");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
if ($singleMachine === 'none') {
$singleMachine = $row['machineuuid'];
} else {
$singleMachine = false;
}
- $row['deleteAllowed'] = in_array($row['locationid'], $deleteAllowedLocations);
+ // TODO: This only makes sense as long as there is only one action to perform on selected clients; reboot/shutdown is planned
+ $row['delete_disabled'] = in_array($row['locationid'], $deleteAllowedLocations) ? '' : 'disabled';
+ $row['link_details'] = in_array($row['locationid'], $detailsAllowedLocations);
$row['state_' . $row['state']] = true;
//$row['firstseen'] = Util::prettyTime($row['firstseen']);
$row['lastseen_int'] = $row['lastseen'];
@@ -673,7 +685,7 @@ class Page_Statistics extends Page
if ($singleMachine !== false && $singleMachine !== 'none') {
Util::redirect('?do=statistics&uuid=' . $singleMachine);
}
- Render::addTemplate('clientlist', array(
+ $data = array(
'rowCount' => count($rows),
'rows' => $rows,
'query' => $this->query,
@@ -684,7 +696,8 @@ class Page_Statistics extends Page
'showList' => 1,
'show' => 'list',
'redirect' => $_SERVER['QUERY_STRING']
- ));
+ );
+ Render::addTemplate('clientlist', $data);
}
private function ramColorClass($mb)
@@ -787,10 +800,7 @@ class Page_Statistics extends Page
Message::addError('unknown-machine', $uuid);
return;
}
- if (!in_array($client['locationid'], $this->locationsAllowedToView)) {
- Message::addError('main.no-permission');
- return;
- }
+ User::assertPermission('machine.view-details', (int)$client['locationid']);
// Hack: Get raw collected data
if (Request::get('raw', false)) {
Header('Content-Type: text/plain; charset=utf-8');
@@ -891,6 +901,7 @@ class Page_Statistics extends Page
$client['screens'][] = $row;
}
array_multisort($ports, SORT_ASC, $client['screens']);
+ Permission::addGlobalTags($client['perms'], null, ['hardware.projectors.edit', 'hardware.projectors.view']);
// Throw output at user
Render::addTemplate('machine-main', $client);
// Sessions
@@ -1002,8 +1013,10 @@ class Page_Statistics extends Page
));
}
// Notes
- $client["notesAllowed"] = User::hasPermission("machine.note", $client["locationid"]);
- Render::addTemplate('machine-notes', $client);
+ if (User::hasPermission('machine.note.*', (int)$client['locationid'])) {
+ Permission::addGlobalTags($client['perms'], (int)$client['locationid'], ['machine.note.edit']);
+ Render::addTemplate('machine-notes', $client);
+ }
}
private function eventToIconName($event)
@@ -1026,6 +1039,8 @@ class Page_Statistics extends Page
protected function doAjax()
{
+ if (!User::load())
+ return;
$param = Request::any('lookup', false, 'string');
if ($param === false) {
die('No lookup given');
diff --git a/modules-available/statistics/pages/projectors.inc.php b/modules-available/statistics/pages/projectors.inc.php
index cde542c6..cdd0195e 100644
--- a/modules-available/statistics/pages/projectors.inc.php
+++ b/modules-available/statistics/pages/projectors.inc.php
@@ -13,6 +13,7 @@ class SubPage
private static function handleProjector($action)
{
+ User::assertPermission('hardware.projectors.edit');
$hwid = Request::post('hwid', false, 'int');
if ($hwid === false) {
Util::traceError('Param hwid missing');
@@ -43,6 +44,7 @@ class SubPage
private static function showProjectors()
{
+ User::assertPermission('hardware.projectors.*');
$res = Database::simpleQuery('SELECT h.hwname, h.hwid FROM statistic_hw h'
. " INNER JOIN statistic_hw_prop p ON (h.hwid = p.hwid AND p.prop = :projector)"
. " WHERE h.hwtype = :screen ORDER BY h.hwname ASC", array(
diff --git a/modules-available/statistics/permissions/permissions.json b/modules-available/statistics/permissions/permissions.json
index da489998..663a8dc4 100644
--- a/modules-available/statistics/permissions/permissions.json
+++ b/modules-available/statistics/permissions/permissions.json
@@ -2,10 +2,25 @@
"machine.delete": {
"location-aware": true
},
- "machine.note": {
+ "machine.note.view": {
"location-aware": true
},
- "view": {
+ "machine.note.edit": {
+ "location-aware": true
+ },
+ "hardware.projectors.view": {
+ "location-aware": false
+ },
+ "hardware.projectors.edit": {
+ "location-aware": false
+ },
+ "machine.view-details": {
+ "location-aware": true
+ },
+ "view.summary": {
+ "location-aware": true
+ },
+ "view.list": {
"location-aware": true
}
} \ No newline at end of file
diff --git a/modules-available/statistics/templates/clientlist.html b/modules-available/statistics/templates/clientlist.html
index d06eb4f7..b81515ab 100644
--- a/modules-available/statistics/templates/clientlist.html
+++ b/modules-available/statistics/templates/clientlist.html
@@ -49,12 +49,10 @@
{{#rows}}
<tr>
<td data-sort-value="{{hostname}}" class="text-nowrap">
- {{#deleteAllowed}}
- <div class="checkbox checkbox-inline">
- <input type="checkbox" name="uuid[]" value="{{machineuuid}}" class="deleteCheckboxes">
- <label></label>
- </div>
- {{/deleteAllowed}}
+ <div class="checkbox checkbox-inline">
+ <input type="checkbox" name="uuid[]" value="{{machineuuid}}" class="deleteCheckboxes" {{delete_disabled}}>
+ <label></label>
+ </div>
{{#hasnotes}}
<span class="glyphicon glyphicon-exclamation-sign pull-right"></span>
{{/hasnotes}}
@@ -70,7 +68,13 @@
{{#state_STANDBY}}
<span class="glyphicon glyphicon-off green" title="{{lang_machineStandby}}"></span>
{{/state_STANDBY}}
- <a href="?do=Statistics&amp;uuid={{machineuuid}}"><b>{{hostname}}</b></a>
+ {{#link_details}}
+ <a href="?do=Statistics&amp;uuid={{machineuuid}}">
+ {{/link_details}}
+ <b>{{hostname}}</b>
+ {{#link_details}}
+ </a>
+ {{/link_details}}
<div class="small">{{machineuuid}}</div>
{{#rmmodule}}
<div class="small">{{lang_runMode}}:
diff --git a/modules-available/statistics/templates/cpumodels.html b/modules-available/statistics/templates/cpumodels.html
index d684c914..d89a5b2f 100644
--- a/modules-available/statistics/templates/cpumodels.html
+++ b/modules-available/statistics/templates/cpumodels.html
@@ -19,11 +19,11 @@
<tr id="{{id}}" class="{{collapse}}">
<td data-sort-value="{{systemmodel}}" class="text-left text-nowrap filter-col" data-filter-col="systemmodel">
<table style="width:100%; table-layout: fixed;"><tr><td style="overflow:hidden;text-overflow: ellipsis;">
- <a class="filter-val" data-filter-val="{{systemmodel}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~systemmodel={{urlsystemmodel}}">{{systemmodel}}</a>
+ <a class="filter-val" data-filter-val="{{systemmodel}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~systemmodel={{urlsystemmodel}}">{{systemmodel}}</a>
</td></tr></table>
</td>
<td data-sort-value="{{cores}}" class="text-right filter-col" data-filter-col="realcores">
- <a class="filter-val" data-filter-val="{{cores}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~realcores={{cores}}">{{cores}}</a>
+ <a class="filter-val" data-filter-val="{{cores}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~realcores={{cores}}">{{cores}}</a>
</td>
<td class="text-right">{{count}}</td>
</tr>
diff --git a/modules-available/statistics/templates/filterbox.html b/modules-available/statistics/templates/filterbox.html
index 58b66a75..0178d7ea 100644
--- a/modules-available/statistics/templates/filterbox.html
+++ b/modules-available/statistics/templates/filterbox.html
@@ -13,7 +13,7 @@
<select id="operatorSelect" name="operator" class="form-control col-4-xs"> </select>
</div>
<div class="form-group">
- <input name="argument" id="argumentInput" class="form-control col-4-xs"> </input>
+ <input name="argument" id="argumentInput" class="form-control col-4-xs">
<select name="argument" id="argumentSelect" class="form-control col-4-xs"> </select>
</div>
@@ -41,11 +41,11 @@
<div class="btn-group pull-right">
- <button class="btn btn-default {{statButtonClass}}" type="submit" name="show" value="stat">
+ <button class="btn btn-default {{statButtonClass}}" type="submit" name="show" value="summary" {{perms.view.summary.disabled}}>
<span class="glyphicon glyphicon-stats"></span>
{{lang_showVisualization}}
</button>
- <button class="btn btn-default {{listButtonClass}}" type="submit" name="show" value="list">
+ <button class="btn btn-default {{listButtonClass}}" type="submit" name="show" value="list" {{perms.view.list.disabled}}>
<span class="glyphicon glyphicon-list"></span>
{{lang_showList}}
</button>
diff --git a/modules-available/statistics/templates/id44.html b/modules-available/statistics/templates/id44.html
index d3b1ab1c..de1c71ad 100644
--- a/modules-available/statistics/templates/id44.html
+++ b/modules-available/statistics/templates/id44.html
@@ -17,7 +17,7 @@
{{#rows}}
<tr id="tmpid{{gb}}" class="{{class}} {{collapse}}">
<td data-sort-value="{{gb}}" class="text-left text-nowrap">
- <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~hddgb={{gb}}">{{gb}}&thinsp;GiB</a>
+ <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~hddgb={{gb}}">{{gb}}&thinsp;GiB</a>
</td>
<td class="text-right">{{count}}</td>
</tr>
diff --git a/modules-available/statistics/templates/kvmstate.html b/modules-available/statistics/templates/kvmstate.html
index 3704eda0..efa3bad3 100644
--- a/modules-available/statistics/templates/kvmstate.html
+++ b/modules-available/statistics/templates/kvmstate.html
@@ -17,7 +17,7 @@
{{#rows}}
<tr id="kvm{{kvmstate}}">
<td data-sort-value="{{kvmstate}}" class="text-left text-nowrap">
- <a class="filter-val" data-filter-val="{{kvmstate}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~kvmstate={{kvmstate}}">{{kvmstate}}</a>
+ <a class="filter-val" data-filter-val="{{kvmstate}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~kvmstate={{kvmstate}}">{{kvmstate}}</a>
</td>
<td class="text-right">{{count}}</td>
</tr>
diff --git a/modules-available/statistics/templates/machine-main.html b/modules-available/statistics/templates/machine-main.html
index d8f2c521..f1021482 100644
--- a/modules-available/statistics/templates/machine-main.html
+++ b/modules-available/statistics/templates/machine-main.html
@@ -157,13 +157,19 @@
{{#hwname}}
<div class="pull-right btn-group btn-group-xs">
{{#projector}}
- <a href="?do=statistics&amp;show=projectors" class="btn btn-default">{{lang_projector}}</a>
+ <a href="?do=statistics&amp;show=projectors" class="btn btn-default {{perms.hardware.projectors.view.disabled}}">
+ {{lang_projector}}
+ </a>
<button form="delprojector" type="submit" name="hwid" value="{{hwid}}"
- class="btn btn-danger"><span class="glyphicon glyphicon-remove"></span></button>
+ class="btn btn-danger" {{perms.hardware.projectors.edit.disabled}}>
+ <span class="glyphicon glyphicon-remove"></span>
+ </button>
{{/projector}}
{{^projector}}
<button form="addprojector" type="submit" name="hwid" value="{{hwid}}"
- class="btn btn-success"><span class="glyphicon glyphicon-plus"></span> {{lang_projector}}</button>
+ class="btn btn-success" {{perms.hardware.projectors.edit.disabled}}>
+ <span class="glyphicon glyphicon-plus"></span> {{lang_projector}}
+ </button>
{{/projector}}
</div>
{{/hwname}}
diff --git a/modules-available/statistics/templates/machine-notes.html b/modules-available/statistics/templates/machine-notes.html
index 66e44da4..c352580f 100644
--- a/modules-available/statistics/templates/machine-notes.html
+++ b/modules-available/statistics/templates/machine-notes.html
@@ -8,9 +8,12 @@
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="setnotes">
<input type="hidden" name="uuid" value="{{machineuuid}}">
- <textarea name="content" class="form-control" cols="101" rows="10" {{^notesAllowed}}disabled{{/notesAllowed}}>{{notes}}</textarea>
+ <textarea name="content" class="form-control" cols="101" rows="10" {{perms.machine.note.edit.disabled}}>{{notes}}</textarea>
<br/>
- <button type="submit" class="btn btn-primary pull-right" {{^notesAllowed}}disabled{{/notesAllowed}}><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button type="submit" class="btn btn-primary pull-right" {{perms.machine.note.edit.disabled}}>
+ <span class="glyphicon glyphicon-floppy-disk"></span>
+ {{lang_save}}
+ </button>
</form>
</div>
</div>
diff --git a/modules-available/statistics/templates/memory.html b/modules-available/statistics/templates/memory.html
index 6bc13980..cfb86062 100644
--- a/modules-available/statistics/templates/memory.html
+++ b/modules-available/statistics/templates/memory.html
@@ -17,7 +17,7 @@
{{#rows}}
<tr id="ramid{{gb}}" class="{{class}} {{collapse}}">
<td class="text-left text-nowrap" data-sort-value="{{gb}}">
- <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~gbram={{gb}}">{{gb}}&thinsp;GiB</a>
+ <a class="filter-val" data-filter-val="{{gb}}" href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~gbram={{gb}}">{{gb}}&thinsp;GiB</a>
</td>
<td class="text-right">{{count}}</td>
</tr>
diff --git a/modules-available/statistics/templates/summary.html b/modules-available/statistics/templates/summary.html
index fe9559ed..3ede7bc5 100644
--- a/modules-available/statistics/templates/summary.html
+++ b/modules-available/statistics/templates/summary.html
@@ -8,8 +8,8 @@
{{/runmode}}
<div>
{{lang_knownMachines}}: <b>{{known}}</b>&emsp;
- <a href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~state=on">{{lang_onlineMachines}}</a>: <b>{{online}}</b>&emsp;
- <a href="?do=Statistics&amp;show=stat&amp;filters={{query}}~,~state=occupied">{{lang_inUseMachines}}</a>: <b>{{used}}</b> (<b>{{usedpercent}}%</b>)
+ <a href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~state=on">{{lang_onlineMachines}}</a>: <b>{{online}}</b>&emsp;
+ <a href="?do=Statistics&amp;show=summary&amp;filters={{query}}~,~state=occupied">{{lang_inUseMachines}}</a>: <b>{{used}}</b> (<b>{{usedpercent}}%</b>)
</div>
{{#badhdd}}
<div>