summaryrefslogtreecommitdiffstats
path: root/modules-available/statistics
diff options
context:
space:
mode:
authorUdo Walter2017-12-28 21:12:08 +0100
committerUdo Walter2017-12-28 21:12:08 +0100
commitbf3ea5f9ffe8c0f34744b858dd0a294bbf091ddc (patch)
treef189e5299e5be14717c08b9f244100e0a7bc6a4f /modules-available/statistics
parent[eventlog] added permission to view the log (diff)
downloadslx-admin-bf3ea5f9ffe8c0f34744b858dd0a294bbf091ddc.tar.gz
slx-admin-bf3ea5f9ffe8c0f34744b858dd0a294bbf091ddc.tar.xz
slx-admin-bf3ea5f9ffe8c0f34744b858dd0a294bbf091ddc.zip
[statistics] added permissions to view client statistics, delete clients and edit notes of clients
Diffstat (limited to 'modules-available/statistics')
-rw-r--r--modules-available/statistics/lang/de/permissions.json5
-rw-r--r--modules-available/statistics/lang/en/permissions.json5
-rw-r--r--modules-available/statistics/page.inc.php72
-rw-r--r--modules-available/statistics/permissions/permissions.json5
-rw-r--r--modules-available/statistics/templates/clientlist.html44
-rw-r--r--modules-available/statistics/templates/filterbox.html4
-rw-r--r--modules-available/statistics/templates/machine-notes.html4
7 files changed, 105 insertions, 34 deletions
diff --git a/modules-available/statistics/lang/de/permissions.json b/modules-available/statistics/lang/de/permissions.json
new file mode 100644
index 00000000..15303993
--- /dev/null
+++ b/modules-available/statistics/lang/de/permissions.json
@@ -0,0 +1,5 @@
+{
+ "view": "Client Statistiken anschauen.",
+ "note": "Client Notizen speichern.",
+ "delete": "Client löschen."
+} \ No newline at end of file
diff --git a/modules-available/statistics/lang/en/permissions.json b/modules-available/statistics/lang/en/permissions.json
new file mode 100644
index 00000000..7be32f22
--- /dev/null
+++ b/modules-available/statistics/lang/en/permissions.json
@@ -0,0 +1,5 @@
+{
+ "view": "View client statistics.",
+ "note": "Save client notes.",
+ "delete": "Delete client."
+} \ No newline at end of file
diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php
index ea5b6f03..77b52e0d 100644
--- a/modules-available/statistics/page.inc.php
+++ b/modules-available/statistics/page.inc.php
@@ -21,6 +21,8 @@ class Page_Statistics extends Page
private $query;
+ private $locationsAllowedToView;
+
/**
* @var bool whether we have a SubPage from the pages/ subdir
*/
@@ -134,11 +136,14 @@ class Page_Statistics extends Page
{
$this->initConstants();
User::load();
- if (!User::hasPermission('superadmin')) {
+ if (!User::isLoggedIn()) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
+ $this->locationsAllowedToView = User::getAllowedLocations("view");
+
+
$show = Request::any('show', 'stat', 'string');
$show = preg_replace('/[^a-z0-9_\-]/', '', $show);
@@ -153,16 +158,20 @@ class Page_Statistics extends Page
$action = Request::post('action');
if ($action === 'setnotes') {
$uuid = Request::post('uuid', '', 'string');
- $text = Request::post('content', '', 'string');
- if (empty($text)) {
- $text = null;
+ $locationid = Database::queryFirst('SELECT locationid FROM machine WHERE machineuuid = :uuid',
+ array('uuid' => $uuid))['locationid'];
+ if (User::hasPermission("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);
}
- 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);
@@ -188,10 +197,12 @@ class Page_Statistics extends Page
$res = Database::simpleQuery('SELECT machineuuid, locationid FROM machine WHERE machineuuid IN (:ids)', compact('ids'));
$ids = array_flip($ids);
$delete = [];
+ $allowedLocations = User::getAllowedLocations("delete");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- // TODO: Check locationid permissions
- unset($ids[$row['machineuuid']]);
- $delete[] = $row['machineuuid'];
+ if (in_array($row['locationid'], $allowedLocations)) {
+ unset($ids[$row['machineuuid']]);
+ $delete[] = $row['machineuuid'];
+ }
}
if (!empty($delete)) {
Database::exec('DELETE FROM machine WHERE machineuuid IN (:delete)', compact('delete'));
@@ -277,7 +288,8 @@ class Page_Statistics extends Page
foreach (Location::getLocations() as $loc) {
$locsFlat['L' . $loc['locationid']] = array(
'pad' => $loc['locationpad'],
- 'name' => $loc['locationname']
+ 'name' => $loc['locationname'],
+ 'disabled' => !in_array($loc['locationid'], $this->locationsAllowedToView)
);
}
}
@@ -333,8 +345,9 @@ class Page_Statistics extends Page
private function showSummary($filterSet)
{
$filterSet->makeFragments($where, $join, $sort, $args);
-
- $known = Database::queryFirst("SELECT Count(*) AS val FROM machine $join WHERE ($where)", $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) {
$this->redirectFirst($where, $join, $args);
@@ -394,7 +407,8 @@ 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();
@@ -427,7 +441,8 @@ 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)) {
@@ -473,7 +488,8 @@ 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();
@@ -497,7 +513,8 @@ 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;
@@ -549,7 +566,8 @@ 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"
@@ -583,7 +601,8 @@ 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';
@@ -594,18 +613,20 @@ class Page_Statistics extends Page
$join .= ' LEFT JOIN runmode USING (machineuuid) ';
}
}
- $res = Database::simpleQuery('SELECT machineuuid, macaddr, clientip, lastseen,'
+ $res = Database::simpleQuery('SELECT machineuuid, locationid, macaddr, clientip, lastseen,'
. ' logintime, state, realcores, mbram, kvmstate, cpumodel, id44mb, hostname, notes IS NOT NULL AS hasnotes,'
. ' badsectors ' . $xtra . ' FROM machine'
. " $join WHERE $where $sort", $args);
$rows = array();
$singleMachine = 'none';
+ $deleteAllowedLocations = User::getAllowedLocations("delete");
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
if ($singleMachine === 'none') {
$singleMachine = $row['machineuuid'];
} else {
$singleMachine = false;
}
+ $row['deleteAllowed'] = in_array($row['locationid'], $deleteAllowedLocations);
$row['state_' . $row['state']] = true;
//$row['firstseen'] = Util::prettyTime($row['firstseen']);
$row['lastseen_int'] = $row['lastseen'];
@@ -749,6 +770,10 @@ class Page_Statistics extends Page
Message::addError('unknown-machine', $uuid);
return;
}
+ if (!in_array($client['locationid'], $this->locationsAllowedToView)) {
+ Message::addError('main.no-permission');
+ return;
+ }
// Hack: Get raw collected data
if (Request::get('raw', false)) {
Header('Content-Type: text/plain; charset=utf-8');
@@ -960,6 +985,7 @@ class Page_Statistics extends Page
));
}
// Notes
+ $client["notesAllowed"] = User::hasPermission("note", $client["locationid"]);
Render::addTemplate('machine-notes', $client);
}
diff --git a/modules-available/statistics/permissions/permissions.json b/modules-available/statistics/permissions/permissions.json
new file mode 100644
index 00000000..97a49036
--- /dev/null
+++ b/modules-available/statistics/permissions/permissions.json
@@ -0,0 +1,5 @@
+[
+ "view",
+ "note",
+ "delete"
+] \ No newline at end of file
diff --git a/modules-available/statistics/templates/clientlist.html b/modules-available/statistics/templates/clientlist.html
index 13e148fa..3d3e66a4 100644
--- a/modules-available/statistics/templates/clientlist.html
+++ b/modules-available/statistics/templates/clientlist.html
@@ -10,22 +10,22 @@
<td></td>
<td></td>
<td class="text-right">
- <button class="btn btn-default btn-xs" onclick="popupFilter('lastseen')">
+ <button type="button" class="btn btn-default btn-xs" onclick="popupFilter('lastseen')">
<span id="btn_filter_lastseen" class="glyphicon glyphicon-filter"></span>
</button>
</td>
<td>
- <button class="btn btn-default btn-xs" onclick="popupFilter('kvmstate')">
+ <button type="button" class="btn btn-default btn-xs" onclick="popupFilter('kvmstate')">
<span id="btn_filter_kvmstate" class="glyphicon glyphicon-filter"></span>
</button>
</td>
<td class="text-right">
- <button class="btn btn-default btn-xs" onclick="popupFilter('gbram')">
+ <button type="button" class="btn btn-default btn-xs" onclick="popupFilter('gbram')">
<span id="btn_filter_gbram" class="glyphicon glyphicon-filter"></span>
</button>
</td>
<td class="text-right">
- <button class="btn btn-default btn-xs" onclick="popupFilter('hddgb')">
+ <button type="button" class="btn btn-default btn-xs" onclick="popupFilter('hddgb')">
<span id="btn_filter_hddgb" class="glyphicon glyphicon-filter"></span>
</button>
</td>
@@ -49,11 +49,15 @@
{{#rows}}
<tr>
<td data-sort-value="{{hostname}}" class="text-nowrap">
+ {{#deleteAllowed}}
<div class="checkbox checkbox-inline">
- <input type="checkbox" name="uuid[]" value="{{machineuuid}}">
+ <input type="checkbox" name="uuid[]" value="{{machineuuid}}" class="deleteCheckboxes">
<label></label>
</div>
- {{#hasnotes}}<span class="glyphicon glyphicon-exclamation-sign pull-right"></span>{{/hasnotes}}
+ {{/deleteAllowed}}
+ {{#hasnotes}}
+ <span class="glyphicon glyphicon-exclamation-sign pull-right"></span>
+ {{/hasnotes}}
{{#state_OFFLINE}}
<span class="glyphicon glyphicon-off" title="{{lang_machineOff}}"></span>
{{/state_OFFLINE}}
@@ -91,10 +95,10 @@
</table>
<div class="text-right buttonbar">
<button type="reset" class="btn btn-default">
- <span class="glyphicon glyphicon-remove"></span>
+ <span class="glyphicon glyphicon-refresh"></span>
{{lang_reset}}
</button>
- <button type="button" class="btn btn-danger" onclick="$('#del-confirm').modal()">
+ <button id="deleteButton" type="button" class="btn btn-danger" onclick="$('#del-confirm').modal()">
<span class="glyphicon glyphicon-trash"></span>
{{lang_delete}}
</button>
@@ -122,6 +126,9 @@
</form>
<script type="application/javascript"><!--
+
+selectedMachineCounter = 0;
+
document.addEventListener("DOMContentLoaded", function () {
['gbram', 'hddgb', 'realcores', 'kvmstate', 'lastseen', 'clientip'].forEach(function (v) {
var $sortBtn = $('#sortButton-' + v);
@@ -138,6 +145,27 @@ document.addEventListener("DOMContentLoaded", function () {
container: 'body',
trigger : 'hover'
});
+
+ $("#deleteButton").prop("disabled", true);
+ $(".deleteCheckboxes").change(function() {
+ if ($(this).is(':checked')) {
+ selectedMachineCounter++;
+ if (selectedMachineCounter === 1) {
+ $("#deleteButton").prop("disabled", false);
+ }
+ } else {
+ selectedMachineCounter--;
+ if (selectedMachineCounter === 0) {
+ $("#deleteButton").prop("disabled", true);
+ }
+ }
+ });
+
+ $("button[type=reset]").click(function() {
+ selectedMachineCounter = 0;
+ $("#deleteButton").prop("disabled", true);
+ });
+
});
function toggleButton(v) {
diff --git a/modules-available/statistics/templates/filterbox.html b/modules-available/statistics/templates/filterbox.html
index 32464031..758bc287 100644
--- a/modules-available/statistics/templates/filterbox.html
+++ b/modules-available/statistics/templates/filterbox.html
@@ -176,10 +176,12 @@ document.addEventListener("DOMContentLoaded", function () {
$('#argumentSelect').show();
columns[col]['values'].forEach(function (v) {
var t = v;
+ var disabled = true;
if (col === 'location' && slxLocations['L' + v]) {
t = slxLocations['L' + v].pad + ' ' + slxLocations['L' + v].name;
+ disabled = slxLocations['L' + v].disabled;
}
- $('#argumentSelect').append($('<option>', { value: v, text: t }));
+ $('#argumentSelect').append($('<option>', { value: v, text: t, disabled: disabled }));
});
} else {
$('#argumentInput').datepicker('remove');
diff --git a/modules-available/statistics/templates/machine-notes.html b/modules-available/statistics/templates/machine-notes.html
index 22ed96e9..66e44da4 100644
--- a/modules-available/statistics/templates/machine-notes.html
+++ b/modules-available/statistics/templates/machine-notes.html
@@ -8,9 +8,9 @@
<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">{{notes}}</textarea>
+ <textarea name="content" class="form-control" cols="101" rows="10" {{^notesAllowed}}disabled{{/notesAllowed}}>{{notes}}</textarea>
<br/>
- <button type="submit" class="btn btn-primary pull-right"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button type="submit" class="btn btn-primary pull-right" {{^notesAllowed}}disabled{{/notesAllowed}}><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</form>
</div>
</div>