summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--inc/paginate.inc.php2
-rw-r--r--modules-available/baseconfig_partitions_cdn/lang/de/permissions.json7
-rw-r--r--modules-available/baseconfig_partitions_cdn/lang/en/permissions.json7
-rw-r--r--modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json4
-rw-r--r--modules-available/baseconfig_partitions_cdn/page.inc.php41
-rw-r--r--modules-available/baseconfig_partitions_cdn/permissions/permissions.json7
-rw-r--r--modules-available/baseconfig_partitions_cdn/style.css4
-rw-r--r--modules-available/baseconfig_partitions_cdn/templates/_page.html60
-rw-r--r--modules-available/locations/page.inc.php1
-rw-r--r--modules-available/minilinux/lang/de/permissions.json4
-rw-r--r--modules-available/minilinux/lang/en/permissions.json4
-rw-r--r--modules-available/minilinux/page.inc.php80
-rw-r--r--modules-available/minilinux/permissions/permissions.json4
-rw-r--r--modules-available/minilinux/templates/filelist.html6
-rw-r--r--modules-available/rebootcontrol/lang/de/permissions.json5
-rw-r--r--modules-available/rebootcontrol/lang/en/permissions.json5
-rw-r--r--modules-available/rebootcontrol/page.inc.php66
-rw-r--r--modules-available/rebootcontrol/permissions/permissions.json5
-rw-r--r--modules-available/rebootcontrol/style.css5
-rw-r--r--modules-available/rebootcontrol/templates/_page.html94
-rw-r--r--modules-available/syslog/lang/de/permissions.json3
-rw-r--r--modules-available/syslog/lang/en/permissions.json3
-rw-r--r--modules-available/syslog/page.inc.php24
-rw-r--r--modules-available/syslog/permissions/permissions.json3
-rw-r--r--modules-available/syslog/templates/heading.html1
-rw-r--r--modules-available/syslog/templates/page-syslog.html1
-rw-r--r--modules-available/systemstatus/lang/de/permissions.json13
-rw-r--r--modules-available/systemstatus/lang/en/permissions.json13
-rw-r--r--modules-available/systemstatus/page.inc.php550
-rw-r--r--modules-available/systemstatus/permissions/permissions.json13
-rw-r--r--modules-available/systemstatus/templates/_page.html2
31 files changed, 650 insertions, 387 deletions
diff --git a/inc/paginate.inc.php b/inc/paginate.inc.php
index cdb4adf1..b212e252 100644
--- a/inc/paginate.inc.php
+++ b/inc/paginate.inc.php
@@ -65,8 +65,6 @@ class Paginate
$countQuery = preg_replace('/ORDER\s+BY\s.*?(\sASC|\sDESC|$)/is', '', $this->query);
$countQuery = preg_replace('/SELECT\s.*?\sFROM\s/is', 'SELECT Count(*) AS rowcount FROM ', $countQuery);
$countRes = Database::queryFirst($countQuery, $args);
- $args['limit_start'] = $this->currentPage;
- $args['limit_count'] = $this->perPage;
$query = $this->query . ' LIMIT ' . ($this->currentPage * $this->perPage) . ', ' . $this->perPage;
$retval = Database::simpleQuery($query, $args);
$this->totalRows = (int)$countRes['rowcount'];
diff --git a/modules-available/baseconfig_partitions_cdn/lang/de/permissions.json b/modules-available/baseconfig_partitions_cdn/lang/de/permissions.json
new file mode 100644
index 00000000..d5805e3d
--- /dev/null
+++ b/modules-available/baseconfig_partitions_cdn/lang/de/permissions.json
@@ -0,0 +1,7 @@
+{
+ "show": "Zeige Partitionen. Wird nicht benötigt, wenn Nutzer eine der anderen Rechte hat.",
+ "partitions.add": "Füge eine neue Partition hinzu.",
+ "partitions.delete": "Lösche eine Partition.",
+ "partitions.edit": "Speichere Änderungen an Partitionen.",
+ "partitions.reset": "Setze Partitionen auf Standardwerte zurück."
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/lang/en/permissions.json b/modules-available/baseconfig_partitions_cdn/lang/en/permissions.json
new file mode 100644
index 00000000..f751a839
--- /dev/null
+++ b/modules-available/baseconfig_partitions_cdn/lang/en/permissions.json
@@ -0,0 +1,7 @@
+{
+ "show": "Show Partitions. Not needed if User has any of the other permissions.",
+ "partitions.add": "Add a new partition.",
+ "partitions.delete": "Delete a partition.",
+ "partitions.edit": "Save changes of partitions.",
+ "partitions.reset": "Reset partitions to default."
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json b/modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json
index 04ce6c80..472e5870 100644
--- a/modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json
+++ b/modules-available/baseconfig_partitions_cdn/lang/en/template-tags.json
@@ -1,9 +1,9 @@
{
"lang_areYouSureNoUndo": "Are you sure? This cannot be undone!",
- "lang_confirm": "Would you like to save the settings on [ \/srv\/openslx\/www\/boot\/config ] ?",
+ "lang_confirm": "Would you like to save the settings on \/srv\/openslx\/www\/boot\/config?",
"lang_create": "Create",
"lang_discardChanges": "Discard Changes",
- "lang_explanationText": "Here you can configure what kind of partitions will be created on the client computers, and where they will be mounted",
+ "lang_explanationText": "Here you can configure what kind of partitions will be created on the client computers, and where they will be mounted.",
"lang_helpId": "Partition Id",
"lang_helpMountPoint": "Must be a directory: \/example\/directory\/",
"lang_helpOptions": "Currently, only option 'bootable' is available",
diff --git a/modules-available/baseconfig_partitions_cdn/page.inc.php b/modules-available/baseconfig_partitions_cdn/page.inc.php
index a1d1445f..b61ea448 100644
--- a/modules-available/baseconfig_partitions_cdn/page.inc.php
+++ b/modules-available/baseconfig_partitions_cdn/page.inc.php
@@ -10,23 +10,39 @@ class Page_BaseConfig_Partitions_CDN extends Page
$action = Request::post('action');
if($action == 'new_partition') {
- $this->addPartition();
+ if (User::hasPermission("partitions.add")) {
+ $this->addPartition();
+ }
}
if($action == 'reset') {
- $this->resetConfig();
+ if (User::hasPermission("partitions.reset")) {
+ $this->resetConfig();
+ }
}
$deletePartition = Request::get('deletePartition');
if($deletePartition !== false) { // TODO: CSRF: Actions that change/update/delete anything should be POST
- $this->deletePartition($deletePartition);
+ if (User::hasPermission("partitions.delete")) {
+ $this->deletePartition($deletePartition);
+ }
}
- $this->updatePartitions();
+ if(User::hasPermission("partitions.edit")) {
+ $this->updatePartitions();
+ }
}
protected function doRender()
{
- if (!User::hasPermission('baseconfig_local')) {
+ if (!User::isLoggedIn()) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=Main');
+ }
+
+ $hasAnyRight = User::hasPermission("partitions.add") || User::hasPermission("partitions.delete")
+ || User::hasPermission("partitions.edit") || User::hasPermission("partitions.reset");
+
+ if (!(User::hasPermission("show") || $hasAnyRight)) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
@@ -48,7 +64,11 @@ class Page_BaseConfig_Partitions_CDN extends Page
Render::addTemplate('_page', array(
'partitions' => $partitions,
- 'user' => User::getId()
+ 'user' => User::getId(),
+ 'allowedToAdd' => User::hasPermission("partitions.add"),
+ 'allowedToDelete' => User::hasPermission("partitions.delete"),
+ 'allowedToEdit' => User::hasPermission("partitions.edit"),
+ 'allowedToReset' => User::hasPermission("partitions.reset")
));
}
@@ -92,9 +112,9 @@ class Page_BaseConfig_Partitions_CDN extends Page
private function updatePartitions(){
$partitions = array();
foreach($_POST as $key => $value){
- if(substr($key,0,9) == 'partition'){
- $id = substr($key,10,1);
- $type = substr($key,12);
+
+ if (substr($key, 0, 9) == 'partition') {
+ list($key, $id, $type) = explode("-", $key);
$partitions[$id][$type] = $value;
}
}
@@ -111,6 +131,8 @@ class Page_BaseConfig_Partitions_CDN extends Page
Database::exec('UPDATE setting_partition SET partition_id=:partition_id, size=:size, mount_point=:mount_point,
options=:options WHERE id=:id AND user=:user;', $data);
}
+
+
if (!empty($partitions)) {
Message::addSuccess('partitions-updated');
Util::redirect('?do=BaseConfig_Partitions_CDN');
@@ -129,5 +151,6 @@ class Page_BaseConfig_Partitions_CDN extends Page
Database::exec ( "INSERT INTO setting_partition SET partition_id = '40', size = '20G', mount_point = '/cache/export/dnbd3', user = :user", $data );
Database::exec ( "INSERT INTO setting_partition SET partition_id = '41', size = '5G', mount_point = '/home', user = :user", $data );
Database::exec ( "INSERT INTO setting_partition SET partition_id = '82', size = '1G', user = :user", $data );
+ Util::redirect('?do=BaseConfig_Partitions_CDN');
}
} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/permissions/permissions.json b/modules-available/baseconfig_partitions_cdn/permissions/permissions.json
new file mode 100644
index 00000000..286a975b
--- /dev/null
+++ b/modules-available/baseconfig_partitions_cdn/permissions/permissions.json
@@ -0,0 +1,7 @@
+[
+ "show",
+ "partitions.add",
+ "partitions.delete",
+ "partitions.edit",
+ "partitions.reset"
+] \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/style.css b/modules-available/baseconfig_partitions_cdn/style.css
new file mode 100644
index 00000000..d55e5e5b
--- /dev/null
+++ b/modules-available/baseconfig_partitions_cdn/style.css
@@ -0,0 +1,4 @@
+.missingInput {
+ border-color: rgba(255, 0, 0, 0.8);
+ box-shadow: 0 1px 1px rgba(255, 0, 0, 0.075) inset, 0 0 8px rgba(255, 0, 0, 0.6);
+} \ No newline at end of file
diff --git a/modules-available/baseconfig_partitions_cdn/templates/_page.html b/modules-available/baseconfig_partitions_cdn/templates/_page.html
index 71cbb7db..2cb3f2a6 100644
--- a/modules-available/baseconfig_partitions_cdn/templates/_page.html
+++ b/modules-available/baseconfig_partitions_cdn/templates/_page.html
@@ -21,7 +21,7 @@
<input name='partition-{{id}}-options' type='text' class='form-control' size='30' value='{{options}}' placeholder='{{lang_partitionOptions}}'/>
</div>
<div class='col-sm-1 col-md-2'>
- <a class='btn btn-danger' href='?do=BaseConfig_Partitions_CDN&amp;deletePartition={{id}}&amp;token={{token}}'>
+ <a class='btn btn-danger btn-sm {{allowedToDelete}}disabled{{allowedToDelete}}' href='?do=BaseConfig_Partitions_CDN&amp;deletePartition={{id}}&amp;token={{token}}'>
<span class='glyphicon glyphicon-trash'></span>
</a>
</div>
@@ -30,16 +30,16 @@
{{/partitions}}
<div class='list-group-item clearfix'>
<div class="pull-right">
- <a class='btn btn-success ' data-toggle='modal' data-target='#add-partition'>
+ <button {{^allowedToAdd}}disabled{{/allowedToAdd}} type="button" class='btn btn-success' data-toggle='modal' data-target='#add-partition'>
<span class='glyphicon glyphicon-plus'></span> {{lang_newPartition}}
- </a>
+ </button>
</div>
</div>
</div>
<div class="pull-right">
- <a class="btn btn-default" data-toggle="modal" data-target="#downloadModal"><span class="glyphicon glyphicon-download-alt"></span> Download</a>
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#downloadModal"><span class="glyphicon glyphicon-download-alt"></span> Download</button>
<button class="btn btn-warning" type="reset"><span class="glyphicon glyphicon-refresh"></span> {{lang_discardChanges}}</button>
- <button class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
+ <button {{^allowedToEdit}}disabled{{/allowedToEdit}} class="btn btn-primary" type="submit"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button>
</div>
<div class ="modal fade" id="downloadModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
@@ -49,8 +49,10 @@
{{lang_confirm}}
</div>
<div class="modal-footer">
- <button type="button" onclick="saveConfig(false)" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
- <button type="button" onclick="saveConfig(true)" class="btn btn-sm btn-danger" name="download"> Download</button>
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="button" onclick="saveConfig()" class="btn btn-primary" name="download">
+ <span class="glyphicon glyphicon-download-alt"></span> Download
+ </button>
</div>
</div>
</div>
@@ -60,7 +62,7 @@
<form method="post" action="?do=BaseConfig_Partitions_CDN">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="reset">
- <button class="btn btn-danger" type="button" data-toggle="modal" data-target="#resetDefaultModal">{{lang_resetDefault}}</button>
+ <button {{^allowedToReset}}disabled{{/allowedToReset}} class="btn btn-danger" type="button" data-toggle="modal" data-target="#resetDefaultModal">{{lang_resetDefault}}</button>
<div class ="modal fade" id="resetDefaultModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" style="width: 400px" role="document">
@@ -70,7 +72,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
- <button type="submit" class="btn btn-sm btn-danger" name="resetDefault"> {{lang_resetDefault}}</button>
+ <button type="submit" class="btn btn-danger" name="resetDefault"> {{lang_resetDefault}}</button>
</div>
</div>
</div>
@@ -78,7 +80,7 @@
</form>
<!-- Create Partition Window -->
-<form action="?do=BaseConfig_Partitions_CDN" method="post">
+<form id="createPartitionForm" action="?do=BaseConfig_Partitions_CDN" method="post">
<div class="modal fade" id="add-partition" tabindex="-1" role="dialog">
<div class="modal-dialog">
@@ -89,12 +91,12 @@
<div class="modal-body">
<div class="input-group">
- <span class="input-group-addon" style="min-width:140px;">{{lang_partitionId}}</span>
+ <span class="input-group-addon" style="min-width:140px;">{{lang_partitionId}} *</span>
<input name="new-partition-id" class="form-control" type="text">
</div>
<p class="help-block">{{lang_helpId}}</p>
<div class="input-group">
- <span class="input-group-addon" style="min-width:140px;">{{lang_partitionSize}}</span>
+ <span class="input-group-addon" style="min-width:140px;">{{lang_partitionSize}} *</span>
<input name="new-partition-size" class="form-control" type="text">
</div>
<p class="help-block">{{lang_helpSize}}</p>
@@ -111,8 +113,10 @@
</div>
<div class="modal-footer">
- <a class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</a>
- <input type="submit" class="btn btn-primary" value="{{lang_create}}">
+ <button class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" class="btn btn-success">
+ <span class='glyphicon glyphicon-plus'></span> {{lang_create}}
+ </button>
</div>
</div>
</div>
@@ -120,12 +124,28 @@
<input type="hidden" name="action" value="new_partition">
<input type="hidden" name="token" value="{{token}}">
</form>
+
<script type="text/javascript">
- function saveConfig(download){
- if(download)
- window.location = 'api.php?do=baseconfig&user={{user}}&save=true';
- else
- window.location = 'api.php?do=baseconfig&user={{user}}';
- }
+ document.addEventListener("DOMContentLoaded", function () {
+ $("#createPartitionForm").submit(function () {
+ var input1 = $("input[name=new-partition-id]");
+ var input2 = $("input[name=new-partition-size]");
+ var id = $.trim(input1.val());
+ var size = $.trim(input2.val());
+ if (!id) {
+ input1.addClass("missingInput");
+ }
+ if (!size) {
+ input2.addClass("missingInput");
+ }
+ if (!id || !size) {
+ return false;
+ }
+ });
+ });
+
+ function saveConfig(){
+ window.location = 'api.php?do=baseconfig&user={{user}}&save=true';
+ }
</script> \ No newline at end of file
diff --git a/modules-available/locations/page.inc.php b/modules-available/locations/page.inc.php
index 0cfa5b90..9112e810 100644
--- a/modules-available/locations/page.inc.php
+++ b/modules-available/locations/page.inc.php
@@ -446,7 +446,6 @@ class Page_Locations extends Page
}
$addAllowedLocs = User::getAllowedLocations("location.add");
- $addAllowedLocs[] = 0;
$addAllowedList = Location::getLocations(0, 0, true);
foreach ($addAllowedList as &$loc) {
if (!in_array($loc["locationid"], $addAllowedLocs)) {
diff --git a/modules-available/minilinux/lang/de/permissions.json b/modules-available/minilinux/lang/de/permissions.json
new file mode 100644
index 00000000..372ffc88
--- /dev/null
+++ b/modules-available/minilinux/lang/de/permissions.json
@@ -0,0 +1,4 @@
+{
+ "show": "Zeige Komponenten des Minilinux. Wird nicht benötigt, wenn Nutzer eine der anderen Rechte hat.",
+ "update": "Aktualisieren von Komponenten des Minilinux."
+} \ No newline at end of file
diff --git a/modules-available/minilinux/lang/en/permissions.json b/modules-available/minilinux/lang/en/permissions.json
new file mode 100644
index 00000000..878388b0
--- /dev/null
+++ b/modules-available/minilinux/lang/en/permissions.json
@@ -0,0 +1,4 @@
+{
+ "show": "Show list of minilinux components. Not needed if User has any of the other permissions.",
+ "update": "Update minilinux components."
+} \ No newline at end of file
diff --git a/modules-available/minilinux/page.inc.php b/modules-available/minilinux/page.inc.php
index 98b0191d..710ffd15 100644
--- a/modules-available/minilinux/page.inc.php
+++ b/modules-available/minilinux/page.inc.php
@@ -7,7 +7,12 @@ class Page_MiniLinux extends Page
{
User::load();
- if (!User::hasPermission('superadmin')) {
+ if (!User::isLoggedIn()) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=Main');
+ }
+
+ if (!(User::hasPermission("show") || User::hasPermission("update"))) {
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
@@ -82,48 +87,51 @@ class Page_MiniLinux extends Page
$system['version'] = $selected['version'];
}
$data['versions'] = array_values($versionNumbers);
+ $data['allowedToUpdate'] = User::hasPermission("update");
echo Render::parse('filelist', $data);
return;
case 'download':
- $id = Request::post('id');
- $name = Request::post('name');
- if (!$id || !$name || strpos("$id$name", '/') !== false) {
- echo "Invalid download request";
- return;
- }
- $file = false;
- $gpg = 'missing';
- foreach ($data['systems'] as &$system) {
- if ($system['id'] !== $id) continue;
- foreach ($system['versions'] as &$version) {
- if ($version['version'] != $selectedVersion) continue;
- foreach ($version['files'] as &$f) {
- if ($f['name'] !== $name) continue;
- $file = $f;
- if (!empty($f['gpg'])) $gpg = $f['gpg'];
- break;
+ if (User::hasPermission("update")) {
+ $id = Request::post('id');
+ $name = Request::post('name');
+ if (!$id || !$name || strpos("$id$name", '/') !== false) {
+ echo "Invalid download request";
+ return;
+ }
+ $file = false;
+ $gpg = 'missing';
+ foreach ($data['systems'] as &$system) {
+ if ($system['id'] !== $id) continue;
+ foreach ($system['versions'] as &$version) {
+ if ($version['version'] != $selectedVersion) continue;
+ foreach ($version['files'] as &$f) {
+ if ($f['name'] !== $name) continue;
+ $file = $f;
+ if (!empty($f['gpg'])) $gpg = $f['gpg'];
+ break;
+ }
}
}
- }
- if ($file === false) {
- echo "Nonexistent system/file: $id / $name";
- return;
- }
- $task = Taskmanager::submit('DownloadFile', array(
- 'url' => CONFIG_REMOTE_ML . '/' . $id . '/' . $selectedVersion . '/' . $name,
- 'destination' => CONFIG_HTTP_DIR . '/' . $id . '/' . $name,
- 'gpg' => $gpg
- ));
- if (!isset($task['id'])) {
- echo 'Error launching download task: ' . $task['statusCode'];
+ if ($file === false) {
+ echo "Nonexistent system/file: $id / $name";
+ return;
+ }
+ $task = Taskmanager::submit('DownloadFile', array(
+ 'url' => CONFIG_REMOTE_ML . '/' . $id . '/' . $selectedVersion . '/' . $name,
+ 'destination' => CONFIG_HTTP_DIR . '/' . $id . '/' . $name,
+ 'gpg' => $gpg
+ ));
+ if (!isset($task['id'])) {
+ echo 'Error launching download task: ' . $task['statusCode'];
+ return;
+ }
+ Property::setDownloadTask($file['md5'], $task['id']);
+ echo Render::parse('download', array(
+ 'name' => $name,
+ 'task' => $task['id']
+ ));
return;
}
- Property::setDownloadTask($file['md5'], $task['id']);
- echo Render::parse('download', array(
- 'name' => $name,
- 'task' => $task['id']
- ));
- return;
}
}
diff --git a/modules-available/minilinux/permissions/permissions.json b/modules-available/minilinux/permissions/permissions.json
new file mode 100644
index 00000000..457d9810
--- /dev/null
+++ b/modules-available/minilinux/permissions/permissions.json
@@ -0,0 +1,4 @@
+[
+ "show",
+ "update"
+] \ No newline at end of file
diff --git a/modules-available/minilinux/templates/filelist.html b/modules-available/minilinux/templates/filelist.html
index a1d0aa48..34138c14 100644
--- a/modules-available/minilinux/templates/filelist.html
+++ b/modules-available/minilinux/templates/filelist.html
@@ -18,7 +18,7 @@
<p>
{{lang_canUpdate1}} <b>{{title}}</b> {{lang_canUpdate2}}
</p>
- <p><span class="btn btn-primary" onclick="slxUpdateAll(this, 'download-{{id}}')">{{lang_update}}</span></p>
+ <button {{^allowedToUpdate}}disabled{{/allowedToUpdate}} class="btn btn-primary" onclick="slxUpdateAll(this, 'download-{{id}}')"><span class="glyphicon glyphicon-refresh"></span> {{lang_update}}<span></span></button>
{{/systemChanged}}
{{^systemChanged}}
<p>{{lang_systemUpdated}}</p>
@@ -35,8 +35,8 @@
{{#fileChanged}}<span class="glyphicon glyphicon-exclamation-sign"></span> <b>{{lang_outdated}}</b>{{/fileChanged}}
</div>
<div class="col-xs-2">
- {{#fileChanged}}<span class="btn btn-primary btn-xs update-button" onclick="slxUpdate('{{uid}}', '{{id}}', '{{name}}')">{{lang_update}}</span>{{/fileChanged}}
- {{^fileChanged}}<span class="btn btn-default btn-xs" onclick="slxUpdate('{{uid}}', '{{id}}', '{{name}}')">{{lang_redownload}}</span>{{/fileChanged}}
+ {{#fileChanged}}<button {{^allowedToUpdate}}disabled{{/allowedToUpdate}} class="btn btn-primary btn-xs update-button" onclick="slxUpdate('{{uid}}', '{{id}}', '{{name}}')"><span class="glyphicon glyphicon-refresh"></span> {{lang_update}}</button> {{/fileChanged}}
+ {{^fileChanged}}<button {{^allowedToUpdate}}disabled{{/allowedToUpdate}} class="btn btn-default btn-xs" onclick="slxUpdate('{{uid}}', '{{id}}', '{{name}}')"><span class="glyphicon glyphicon-download-alt"></span> {{lang_redownload}}</button> {{/fileChanged}}
</div>
</div>
{{{download}}}
diff --git a/modules-available/rebootcontrol/lang/de/permissions.json b/modules-available/rebootcontrol/lang/de/permissions.json
new file mode 100644
index 00000000..92eeb37e
--- /dev/null
+++ b/modules-available/rebootcontrol/lang/de/permissions.json
@@ -0,0 +1,5 @@
+{
+ "shutdown": "Client herunterfahren.",
+ "reboot": "Client neustarten.",
+ "newkeypair": "Neues Schlüsselpaar generieren."
+} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/lang/en/permissions.json b/modules-available/rebootcontrol/lang/en/permissions.json
new file mode 100644
index 00000000..077890fb
--- /dev/null
+++ b/modules-available/rebootcontrol/lang/en/permissions.json
@@ -0,0 +1,5 @@
+{
+ "shutdown": "Shutdown Client.",
+ "reboot": "Reboot Client.",
+ "newkeypair": "Generate new Keypair."
+} \ No newline at end of file
diff --git a/modules-available/rebootcontrol/page.inc.php b/modules-available/rebootcontrol/page.inc.php
index fc3ded8f..fa34a05a 100644
--- a/modules-available/rebootcontrol/page.inc.php
+++ b/modules-available/rebootcontrol/page.inc.php
@@ -4,6 +4,9 @@ class Page_RebootControl extends Page
{
private $action = false;
+ private $allowedShutdownLocs = [];
+ private $allowedRebootLocs = [];
+ private $allowedLocs = [];
/**
* Called before any page rendering happens - early hook to check parameters etc.
@@ -17,21 +20,40 @@ class Page_RebootControl extends Page
Util::redirect('?do=Main'); // does not return
}
+ $this->allowedShutdownLocs = User::getAllowedLocations("shutdown");
+ $this->allowedRebootLocs = User::getAllowedLocations("reboot");
+ $this->allowedLocs = array_unique(array_merge($this->allowedShutdownLocs, $this->allowedRebootLocs));
+
$this->action = Request::any('action', 'show', 'string');
if ($this->action === 'startReboot' || $this->action === 'startShutdown') {
- $clients = Request::post('clients');
- if (!is_array($clients) || empty($clients)) {
- Message::addError('no-clients-selected');
- Util::redirect();
- }
+
$locationId = Request::post('locationId', false, 'int');
if ($locationId === false) {
Message::addError('locations.invalid-location-id', $locationId);
Util::redirect();
}
+
$shutdown = $this->action === "startShutdown";
+ // Check user permission (if user has no permission, the getAllowed-list will be empty and the check will fail)
+ if ($shutdown) {
+ if (!in_array($locationId, $this->allowedShutdownLocs)) {
+ Message::addError('main.no-permission');
+ Util::redirect();
+ }
+ } else {
+ if (!in_array($locationId, $this->allowedRebootLocs)) {
+ Message::addError('main.no-permission');
+ Util::redirect();
+ }
+ }
+
+ $clients = Request::post('clients');
+ if (!is_array($clients) || empty($clients)) {
+ Message::addError('no-clients-selected');
+ Util::redirect();
+ }
$minutes = Request::post('minutes', 0, 'int');
$list = RebootQueries::getMachinesByUuid($clients);
@@ -72,12 +94,34 @@ class Page_RebootControl extends Page
//location you want to see, default are "not assigned" clients
$requestedLocation = Request::get('location', 0, 'int');
- $data['data'] = RebootQueries::getMachineTable($requestedLocation);
- $data['locations'] = Location::getLocations($requestedLocation, 0, true);
+ // only fill table if user has at least one permission for the location
+ if (in_array($requestedLocation, $this->allowedLocs)) {
+ $data['data'] = RebootQueries::getMachineTable($requestedLocation);
+ $data['allowedToSelect'] = True;
+ }
+ $data['locations'] = Location::getLocations($requestedLocation, 0, true);
+ // Always show public key (it's public, isn't it?)
$data['pubKey'] = SSHKey::getPublicKey();
+ // disable each location user has no permission for
+ foreach ($data['locations'] as &$loc) {
+ if (!in_array($loc["locationid"], $this->allowedLocs)) {
+ $loc["disabled"] = "disabled";
+ }
+ }
+
+ // Only enable shutdown/reboot-button if user has permission for the location
+ if (in_array($requestedLocation, $this->allowedShutdownLocs)) {
+ $data['allowedToShutdown'] = True;
+ }
+ if (in_array($requestedLocation, $this->allowedRebootLocs)) {
+ $data['allowedToReboot'] = True;
+ }
+ $data['allowedToGenerateKey'] = User::hasPermission("newkeypair");
+
Render::addTemplate('_page', $data);
+
}
}
}
@@ -86,8 +130,12 @@ class Page_RebootControl extends Page
{
$this->action = Request::post('action', false, 'string');
if ($this->action === 'generateNewKeypair') {
- Property::set("rebootcontrol-private-key", false);
- echo SSHKey::getPublicKey();
+ if (User::hasPermission("newkeypair")) {
+ Property::set("rebootcontrol-private-key", false);
+ echo SSHKey::getPublicKey();
+ } else {
+ echo 'No permission.';
+ }
} else {
echo 'Invalid action.';
}
diff --git a/modules-available/rebootcontrol/permissions/permissions.json b/modules-available/rebootcontrol/permissions/permissions.json
new file mode 100644
index 00000000..5230c9bd
--- /dev/null
+++ b/modules-available/rebootcontrol/permissions/permissions.json
@@ -0,0 +1,5 @@
+[
+ "shutdown",
+ "reboot",
+ "newkeypair"
+] \ No newline at end of file
diff --git a/modules-available/rebootcontrol/style.css b/modules-available/rebootcontrol/style.css
index 442cd5de..f10a6157 100644
--- a/modules-available/rebootcontrol/style.css
+++ b/modules-available/rebootcontrol/style.css
@@ -16,11 +16,8 @@
margin-bottom: 0;
}
-#rebootButton, #settingsButton, #selectAllButton, #unselectAllButton {
+.controlButtons {
margin-left: 10px;
-}
-
-#rebootButton, #shutdownButton, #selectAllButton, #unselectAllButton {
width: 140px;
}
diff --git a/modules-available/rebootcontrol/templates/_page.html b/modules-available/rebootcontrol/templates/_page.html
index 1bef8dd4..e540cafb 100644
--- a/modules-available/rebootcontrol/templates/_page.html
+++ b/modules-available/rebootcontrol/templates/_page.html
@@ -8,58 +8,58 @@
<input type="hidden" name="token" value="{{token}}">
<div class="row">
<div class="col-md-12">
- <label>{{lang_location}}:
- <select id="locationDropdown" name="locationId" class="form-control" onchange="selectLocation()">
- {{#locations}}
- <option value="{{locationid}}" {{#selected}}selected{{/selected}}>{{locationpad}} {{locationname}}</option>
- {{/locations}}
- </select>
- </label>
- <button type="button" id="selectAllButton" class="btn btn-primary pull-right" onclick="selectAllRows()"><span class="glyphicon glyphicon-check"></span> {{lang_selectall}}</button>
- <button type="button" id="unselectAllButton" class="btn btn-default pull-right" onclick="unselectAllRows()" style="display: none;"><span class="glyphicon glyphicon-unchecked"></span> {{lang_unselectall}}</button>
- <button type="button" id="rebootButton" class="btn btn-warning pull-right" data-toggle="modal" data-target="#rebootModal" disabled><span class="glyphicon glyphicon-repeat"></span> {{lang_rebootButton}}</button>
- <button type="button" id="shutdownButton" class="btn btn-danger pull-right" data-toggle="modal" data-target="#shutdownModal" disabled><span class="glyphicon glyphicon-off"></span> {{lang_shutdownButton}}</button>
+ <label>{{lang_location}}:
+ <select id="locationDropdown" name="locationId" class="form-control" onchange="selectLocation()">
+ {{#locations}}
+ <option value="{{locationid}}" {{disabled}} {{#selected}}selected{{/selected}}>{{locationpad}} {{locationname}}</option>
+ {{/locations}}
+ </select>
+ </label>
+ <button type="button" id="selectAllButton" {{^allowedToSelect}}disabled{{/allowedToSelect}} class="btn btn-primary pull-right controlButtons" onclick="selectAllRows()"><span class="glyphicon glyphicon-check"></span> {{lang_selectall}}</button>
+ <button type="button" id="unselectAllButton" {{^allowedToSelect}}disabled{{/allowedToSelect}} class="btn btn-default pull-right controlButtons" onclick="unselectAllRows()" style="display: none;"><span class="glyphicon glyphicon-unchecked"></span> {{lang_unselectall}}</button>
+ <button type="button" {{#allowedToReboot}}id="rebootButton"{{/allowedToReboot}} class="btn btn-warning pull-right controlButtons" data-toggle="modal" data-target="#rebootModal" disabled><span class="glyphicon glyphicon-repeat"></span> {{lang_rebootButton}}</button>
+ <button type="button" {{#allowedToShutdown}}id="shutdownButton"{{/allowedToShutdown}} class="btn btn-danger pull-right controlButtons" data-toggle="modal" data-target="#shutdownModal" disabled><span class="glyphicon glyphicon-off"></span> {{lang_shutdownButton}}</button>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table class="table table-condensed table-hover stupidtable" id="dataTable">
<thead>
- <tr>
- <th data-sort="string">{{lang_client}}</th>
- <th data-sort="ipv4">{{lang_ip}}</th>
- <th data-sort="string">{{lang_status}}</th>
- <th data-sort="string">{{lang_session}}</th>
- <th data-sort="string">{{lang_user}}</th>
- <th data-sort="int" data-sort-default="desc">{{lang_selected}}</th>
- </tr>
+ <tr>
+ <th data-sort="string">{{lang_client}}</th>
+ <th data-sort="ipv4">{{lang_ip}}</th>
+ <th data-sort="string">{{lang_status}}</th>
+ <th data-sort="string">{{lang_session}}</th>
+ <th data-sort="string">{{lang_user}}</th>
+ <th data-sort="int" data-sort-default="desc">{{lang_selected}}</th>
+ </tr>
</thead>
<tbody>
{{#data}}
- <tr>
- <td>
- {{hostname}}
- {{^hostname}}{{clientip}}{{/hostname}}
- </td>
- <td>{{clientip}}</td>
- <td class="statusColumn">
- {{#status}}
- <span class="text-success">{{lang_on}}</span>
- {{/status}}
- {{^status}}
- <span class="text-danger">{{lang_off}}</span>
- {{/status}}
- </td>
- <td>{{#status}}{{currentsession}}{{/status}}</td>
- <td>{{#status}}{{currentuser}}{{/status}}</td>
- <td data-sort-value="0" class="checkboxColumn">
- <div class="checkbox">
- <input id="m-{{machineuuid}}" type="checkbox" name="clients[]" value='{{machineuuid}}'>
- <label for="m-{{machineuuid}}"></label>
- </div>
- </td>
- </tr>
+ <tr>
+ <td>
+ {{hostname}}
+ {{^hostname}}{{clientip}}{{/hostname}}
+ </td>
+ <td>{{clientip}}</td>
+ <td class="statusColumn">
+ {{#status}}
+ <span class="text-success">{{lang_on}}</span>
+ {{/status}}
+ {{^status}}
+ <span class="text-danger">{{lang_off}}</span>
+ {{/status}}
+ </td>
+ <td>{{#status}}{{currentsession}}{{/status}}</td>
+ <td>{{#status}}{{currentuser}}{{/status}}</td>
+ <td data-sort-value="0" class="checkboxColumn">
+ <div class="checkbox">
+ <input id="m-{{machineuuid}}" type="checkbox" name="clients[]" value='{{machineuuid}}'>
+ <label for="m-{{machineuuid}}"></label>
+ </div>
+ </td>
+ </tr>
{{/data}}
</tbody>
</table>
@@ -79,7 +79,7 @@
</div>
<div class="modal-body">
<span id="pubKeyTitle">{{lang_pubKey}}</span>
- <button class="btn btn-s btn-warning pull-right" onclick="generateNewKeypair()" type="button"><span class="glyphicon glyphicon-refresh"></span> {{lang_genNew}}</button>
+ <button {{^allowedToGenerateKey}}disabled{{/allowedToGenerateKey}} class="btn btn-s btn-warning pull-right" onclick="generateNewKeypair()" type="button"><span class="glyphicon glyphicon-refresh"></span> {{lang_genNew}}</button>
<pre id="pubKey">{{pubKey}}</pre>
</div>
<div class="modal-footer">
@@ -100,7 +100,7 @@
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
- <button type="submit" name="action" value="startReboot" class="btn btn-warning"><span class="glyphicon glyphicon-repeat"></span> {{lang_reboot}}</button>
+ <button type="submit" {{^allowedToReboot}}disabled{{/allowedToReboot}} name="action" value="startReboot" class="btn btn-warning"><span class="glyphicon glyphicon-repeat"></span> {{lang_reboot}}</button>
</div>
</div>
</div>
@@ -115,11 +115,11 @@
</div>
<div class="modal-body">
{{lang_shutdownCheck}}
- {{lang_shutdownIn}} <input id="shutdownTimer" name="minutes" title="{{lang_shutdownIn}}" type="number" value="0" min="0" onkeypress="return isNumberKey(event)"> {{lang_minutes}}
+ {{lang_shutdownIn}} <input id="shutdownTimer" name="minutes" title="{{lang_shutdownIn}}" type="number" value="0" min="0" onkeypress="return isNumberKey(event)"> {{lang_minutes}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
- <button type="submit" name="action" value="startShutdown" class="btn btn-danger"><span class="glyphicon glyphicon-off"></span> {{lang_shutdownButton}}</button>
+ <button type="submit" {{^allowedToShutdown}}disabled{{/allowedToShutdown}} name="action" value="startShutdown" class="btn btn-danger"><span class="glyphicon glyphicon-off"></span> {{lang_shutdownButton}}</button>
</div>
</div>
</div>
@@ -162,7 +162,7 @@
$('#rebootButton').prop('disabled', false);
$('#shutdownButton').prop('disabled', false);
}
- });
+ });
$('.checkboxColumn').click(function(e) {
if (e.target === this) {
$(this).find('input[type="checkbox"]').click();
diff --git a/modules-available/syslog/lang/de/permissions.json b/modules-available/syslog/lang/de/permissions.json
new file mode 100644
index 00000000..0cd05451
--- /dev/null
+++ b/modules-available/syslog/lang/de/permissions.json
@@ -0,0 +1,3 @@
+{
+ "view": "Client Log anschauen."
+} \ No newline at end of file
diff --git a/modules-available/syslog/lang/en/permissions.json b/modules-available/syslog/lang/en/permissions.json
new file mode 100644
index 00000000..497e199e
--- /dev/null
+++ b/modules-available/syslog/lang/en/permissions.json
@@ -0,0 +1,3 @@
+{
+ "view": "View client log."
+} \ No newline at end of file
diff --git a/modules-available/syslog/page.inc.php b/modules-available/syslog/page.inc.php
index e63ada85..a26ed9be 100644
--- a/modules-available/syslog/page.inc.php
+++ b/modules-available/syslog/page.inc.php
@@ -27,6 +27,13 @@ class Page_SysLog extends Page
protected function doRender()
{
+ Render::addTemplate("heading");
+
+ if (!User::hasPermission("view")) {
+ Message::addError('main.no-permission');
+ return;
+ }
+
$cutoff = strtotime('-1 month');
$res = Database::simpleQuery("SELECT logtypeid, Count(*) AS counter FROM clientlog WHERE dateline > $cutoff GROUP BY logtypeid ORDER BY counter ASC");
$types = array();
@@ -69,9 +76,22 @@ class Page_SysLog extends Page
$whereClause .= "machineuuid='" . preg_replace('/[^0-9a-zA-Z\-]/', '', Request::get('machineuuid', '', 'string')) . "'";
}
+
+ $allowedLocations = User::getAllowedLocations("view");
+ $joinClause = "";
+ if (!in_array(0, $allowedLocations)) {
+ $joinClause = "INNER JOIN machine USING (machineuuid)";
+ if (empty($whereClause))
+ $whereClause .= ' WHERE ';
+ else
+ $whereClause .= ' AND ';
+
+ $whereClause .= 'locationid IN (:allowedLocations)';
+ }
+
$lines = array();
- $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientip, machineuuid, description, extra FROM clientlog $whereClause ORDER BY logid DESC", 50);
- $res = $paginate->exec();
+ $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientlog.clientip, clientlog.machineuuid, description, extra FROM clientlog $joinClause $whereClause ORDER BY logid DESC", 50);
+ $res = $paginate->exec(array("allowedLocations" => $allowedLocations));
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$row['date'] = Util::prettyTime($row['dateline']);
$row['icon'] = $this->eventToIconName($row['logtypeid']);
diff --git a/modules-available/syslog/permissions/permissions.json b/modules-available/syslog/permissions/permissions.json
new file mode 100644
index 00000000..f04ea714
--- /dev/null
+++ b/modules-available/syslog/permissions/permissions.json
@@ -0,0 +1,3 @@
+[
+ "view"
+] \ No newline at end of file
diff --git a/modules-available/syslog/templates/heading.html b/modules-available/syslog/templates/heading.html
new file mode 100644
index 00000000..d6790a21
--- /dev/null
+++ b/modules-available/syslog/templates/heading.html
@@ -0,0 +1 @@
+<h1>{{lang_clientLog}}</h1> \ No newline at end of file
diff --git a/modules-available/syslog/templates/page-syslog.html b/modules-available/syslog/templates/page-syslog.html
index 585aa310..7ab81067 100644
--- a/modules-available/syslog/templates/page-syslog.html
+++ b/modules-available/syslog/templates/page-syslog.html
@@ -1,7 +1,6 @@
<button type="button" class="btn btn-default pull-right" data-toggle="modal" data-target="#modal-settings">
<span class="glyphicon glyphicon-cog"></span> {{lang_settings}}
</button>
-<h1>{{lang_clientLog}}</h1>
<style type="text/css">
.selectize-dropdown {
max-width: 500px;
diff --git a/modules-available/systemstatus/lang/de/permissions.json b/modules-available/systemstatus/lang/de/permissions.json
new file mode 100644
index 00000000..8fbae7a7
--- /dev/null
+++ b/modules-available/systemstatus/lang/de/permissions.json
@@ -0,0 +1,13 @@
+{
+ "show.overview.diskstat": "Zeige Speicherplatzwerte auf Übersichtsseite.",
+ "show.overview.services": "Zeige Dienste auf Übersichtsseite.",
+ "show.overview.addresses": "Zeige Adresskonfiguration auf Übersichtsseite.",
+ "show.overview.systeminfo": "Zeige Systemwerte auf Übersichtsseite.",
+ "show.overview.dmsdusers": "Zeige dmsd-Werte auf Übersichtsseite.",
+ "show.logs.bwlpserver": "Zeige bwlp-Server Logs.",
+ "show.logs.netstat": "Zeige netstat Logs.",
+ "show.logs.pslist": "Zeige ps-list Logs.",
+ "show.logs.ldapad": "Zeige ldap und ad Logs.",
+ "show.logs.lighttpd": "Zeige light-tpd Logs.",
+ "serverreboot": "Server neustarten."
+} \ No newline at end of file
diff --git a/modules-available/systemstatus/lang/en/permissions.json b/modules-available/systemstatus/lang/en/permissions.json
new file mode 100644
index 00000000..f297ff53
--- /dev/null
+++ b/modules-available/systemstatus/lang/en/permissions.json
@@ -0,0 +1,13 @@
+{
+ "show.overview.diskstat": "Show diskstats on overview page.",
+ "show.overview.services": "Show services on overview page.",
+ "show.overview.addresses": "Show addresses on overview page.",
+ "show.overview.systeminfo": "Show systeminfo on overview page.",
+ "show.overview.dmsdusers": "Show dmsd-stats on overview page.",
+ "show.logs.bwlpserver": "Show bwlp-server logs.",
+ "show.logs.netstat": "Show netstat logs.",
+ "show.logs.pslist": "Show ps-list logs.",
+ "show.logs.ldapad": "Show ldap+ad logs.",
+ "show.logs.lighttpd": "Show light-tpd logs.",
+ "serverreboot": "Reboot server."
+} \ No newline at end of file
diff --git a/modules-available/systemstatus/page.inc.php b/modules-available/systemstatus/page.inc.php
index 8a0e5f87..df0548fc 100644
--- a/modules-available/systemstatus/page.inc.php
+++ b/modules-available/systemstatus/page.inc.php
@@ -15,7 +15,12 @@ class Page_SystemStatus extends Page
}
if (Request::post('action') === 'reboot') {
- $this->rebootTask = Taskmanager::submit('Reboot');
+ if (User::hasPermission("serverreboot")) {
+ $this->rebootTask = Taskmanager::submit('Reboot');
+ } else {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=Main');
+ }
}
}
@@ -33,6 +38,7 @@ class Page_SystemStatus extends Page
'name' => Dictionary::translate('tab_' . $tab)
);
}
+ $data['allowedToReboot'] = User::hasPermission("serverreboot");
Render::addTemplate('_page', $data);
}
@@ -54,109 +60,122 @@ class Page_SystemStatus extends Page
protected function ajaxDmsdUsers()
{
- $ret = Download::asStringPost('http://127.0.0.1:9080/status/fileserver', false, 2, $code);
- $args = array();
- if ($code != 200) {
- $args['dmsd_error'] = true;
- } else {
- $data = @json_decode($ret, true);
- if (is_array($data)) {
- $args['uploads'] = $data['activeUploads'];
- $args['downloads'] = $data['activeDownloads'];
+ if (User::hasPermission("show.overview.dmsdusers")) {
+ $ret = Download::asStringPost('http://127.0.0.1:9080/status/fileserver', false, 2, $code);
+ $args = array();
+ if ($code != 200) {
+ $args['dmsd_error'] = true;
+ } else {
+ $data = @json_decode($ret, true);
+ if (is_array($data)) {
+ $args['uploads'] = $data['activeUploads'];
+ $args['downloads'] = $data['activeDownloads'];
+ }
}
+ if (file_exists('/run/reboot-required.pkgs')) {
+ $lines = file('/run/reboot-required.pkgs', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ $lines = array_unique($lines);
+ $args['packages'] = implode(', ', $lines);
+ }
+ echo Render::parse('ajax-reboot', $args);
+ } else {
+ echo "No permission to view this section.";
}
- if (file_exists('/run/reboot-required.pkgs')) {
- $lines = file('/run/reboot-required.pkgs', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
- $lines = array_unique($lines);
- $args['packages'] = implode(', ', $lines);
- }
- echo Render::parse('ajax-reboot', $args);
}
protected function ajaxDiskStat()
{
- $task = Taskmanager::submit('DiskStat');
- if ($task === false)
- return;
- $task = Taskmanager::waitComplete($task, 3000);
+ if (User::hasPermission("show.overview.diskstat")) {
+ $task = Taskmanager::submit('DiskStat');
+ if ($task === false)
+ return;
+ $task = Taskmanager::waitComplete($task, 3000);
- if (!isset($task['data']['list']) || empty($task['data']['list'])) {
- Taskmanager::addErrorMessage($task);
- return;
- }
- $store = Property::getVmStoreUrl();
- $storeUsage = false;
- $systemUsage = false;
- if ($store !== false) {
- if ($store === '<local>')
- $storePoint = '/';
- else
- $storePoint = CONFIG_VMSTORE_DIR;
- // Determine free space
- foreach ($task['data']['list'] as $entry) {
- if ($entry['mountPoint'] === $storePoint) {
- $storeUsage = array(
- 'percent' => $entry['usedPercent'],
- 'size' => Util::readableFileSize($entry['sizeKb'] * 1024),
- 'free' => Util::readableFileSize($entry['freeKb'] * 1024),
- 'color' => $this->usageColor($entry['usedPercent'])
- );
+ if (!isset($task['data']['list']) || empty($task['data']['list'])) {
+ Taskmanager::addErrorMessage($task);
+ return;
+ }
+ $store = Property::getVmStoreUrl();
+ $storeUsage = false;
+ $systemUsage = false;
+ if ($store !== false) {
+ if ($store === '<local>')
+ $storePoint = '/';
+ else
+ $storePoint = CONFIG_VMSTORE_DIR;
+ // Determine free space
+ foreach ($task['data']['list'] as $entry) {
+ if ($entry['mountPoint'] === $storePoint) {
+ $storeUsage = array(
+ 'percent' => $entry['usedPercent'],
+ 'size' => Util::readableFileSize($entry['sizeKb'] * 1024),
+ 'free' => Util::readableFileSize($entry['freeKb'] * 1024),
+ 'color' => $this->usageColor($entry['usedPercent'])
+ );
+ }
+ if ($entry['mountPoint'] === '/') {
+ $systemUsage = array(
+ 'percent' => $entry['usedPercent'],
+ 'size' => Util::readableFileSize($entry['sizeKb'] * 1024),
+ 'free' => Util::readableFileSize($entry['freeKb'] * 1024),
+ 'color' => $this->usageColor($entry['usedPercent'])
+ );
+ }
}
- if ($entry['mountPoint'] === '/') {
- $systemUsage = array(
- 'percent' => $entry['usedPercent'],
- 'size' => Util::readableFileSize($entry['sizeKb'] * 1024),
- 'free' => Util::readableFileSize($entry['freeKb'] * 1024),
- 'color' => $this->usageColor($entry['usedPercent'])
- );
+ $data = array(
+ 'store' => $storeUsage,
+ 'system' => $systemUsage
+ );
+ // Determine if proper vm store is being used
+ if ($store !== '<local>') {
+ $data['storeMissing'] = $store;
}
- }
- $data = array(
- 'store' => $storeUsage,
- 'system' => $systemUsage
- );
- // Determine if proper vm store is being used
- if ($store !== '<local>') {
- $data['storeMissing'] = $store;
- }
- foreach ($task['data']['list'] as $entry) {
- if ($entry['mountPoint'] !== CONFIG_VMSTORE_DIR)
- continue;
- if ($store !== $entry['fileSystem']) {
- $data['wrongStore'] = $entry['fileSystem'];
- break;
+ foreach ($task['data']['list'] as $entry) {
+ if ($entry['mountPoint'] !== CONFIG_VMSTORE_DIR)
+ continue;
+ if ($store !== $entry['fileSystem']) {
+ $data['wrongStore'] = $entry['fileSystem'];
+ break;
+ }
+ $data['storeMissing'] = false;
}
- $data['storeMissing'] = false;
+ } else {
+ $data['notConfigured'] = true;
}
+ echo Render::parse('diskstat', $data);
} else {
- $data['notConfigured'] = true;
+ echo "No permission to view this section.";
}
- echo Render::parse('diskstat', $data);
}
protected function ajaxAddressList()
{
- $task = Taskmanager::submit('LocalAddressesList');
- if ($task === false)
- return;
- $task = Taskmanager::waitComplete($task, 3000);
+ if (User::hasPermission("show.overview.addresses")) {
+ $task = Taskmanager::submit('LocalAddressesList');
+ if ($task === false)
+ return;
+ $task = Taskmanager::waitComplete($task, 3000);
- if (!isset($task['data']['addresses']) || empty($task['data']['addresses'])) {
- Taskmanager::addErrorMessage($task);
- return;
- }
+ if (!isset($task['data']['addresses']) || empty($task['data']['addresses'])) {
+ Taskmanager::addErrorMessage($task);
+ return;
+ }
- $sort = array();
- $primary = Property::getServerIp();
- foreach ($task['data']['addresses'] as &$addr) {
- $sort[] = $addr['type'] . $addr['ip'];
- if ($addr['ip'] === $primary)
- $addr['primary'] = true;
+ $sort = array();
+ $primary = Property::getServerIp();
+ foreach ($task['data']['addresses'] as &$addr) {
+ $sort[] = $addr['type'] . $addr['ip'];
+ if ($addr['ip'] === $primary)
+ $addr['primary'] = true;
+ }
+ array_multisort($sort, SORT_STRING, $task['data']['addresses']);
+ echo Render::parse('addresses', array(
+ 'addresses' => $task['data']['addresses']
+ ));
+ } else {
+ echo "No permission to view this section.";
}
- array_multisort($sort, SORT_STRING, $task['data']['addresses']);
- echo Render::parse('addresses', array(
- 'addresses' => $task['data']['addresses']
- ));
+
}
private function sysInfo()
@@ -178,39 +197,43 @@ class Page_SystemStatus extends Page
protected function ajaxSystemInfo()
{
- $cpuInfo = file_get_contents('/proc/cpuinfo');
- $uptime = file_get_contents('/proc/uptime');
- $cpuCount = preg_match_all('/\bprocessor\s/', $cpuInfo, $out);
- //$cpuCount = count($out);
- $data = array(
- 'cpuCount' => $cpuCount,
- 'memTotal' => '???',
- 'memFree' => '???',
- 'swapTotal' => '???',
- 'swapUsed' => '???',
- 'uptime' => '???'
- );
- if (preg_match('/^(\d+)\D/', $uptime, $out)) {
- $data['uptime'] = floor($out[1] / 86400) . ' ' . Dictionary::translate('lang_days') . ', ' . floor(($out[1] % 86400) / 3600) . ' ' . Dictionary::translate('lang_hours');
- }
- $info = $this->sysInfo();
- if (isset($info['MemTotal']) && isset($info['MemFree']) && isset($info['SwapTotal'])) {
- $data['memTotal'] = Util::readableFileSize($info['MemTotal'] * 1024);
- $data['memFree'] = Util::readableFileSize(($info['MemFree'] + $info['Buffers'] + $info['Cached']) * 1024);
- $data['memPercent'] = 100 - round((($info['MemFree'] + $info['Buffers'] + $info['Cached']) / $info['MemTotal']) * 100);
- $data['swapTotal'] = Util::readableFileSize($info['SwapTotal'] * 1024);
- $data['swapUsed'] = Util::readableFileSize(($info['SwapTotal'] - $info['SwapFree']) * 1024);
- $data['swapPercent'] = 100 - round(($info['SwapFree'] / $info['SwapTotal']) * 100);
- $data['swapWarning'] = ($data['swapPercent'] > 50 || ($info['SwapTotal'] - $info['SwapFree']) > 200000);
- }
- if (isset($info['CpuIdle']) && isset($info['CpuSystem']) && isset($info['CpuTotal'])) {
- $data['cpuLoad'] = 100 - round(($info['CpuIdle'] / $info['CpuTotal']) * 100);
- $data['cpuSystem'] = round(($info['CpuSystem'] / $info['CpuTotal']) * 100);
- $data['cpuLoadOk'] = true;
- $data['CpuTotal'] = $info['CpuTotal'];
- $data['CpuIdle'] = $info['CpuIdle'];
+ if (User::hasPermission("show.overview.systeminfo")) {
+ $cpuInfo = file_get_contents('/proc/cpuinfo');
+ $uptime = file_get_contents('/proc/uptime');
+ $cpuCount = preg_match_all('/\bprocessor\s/', $cpuInfo, $out);
+ //$cpuCount = count($out);
+ $data = array(
+ 'cpuCount' => $cpuCount,
+ 'memTotal' => '???',
+ 'memFree' => '???',
+ 'swapTotal' => '???',
+ 'swapUsed' => '???',
+ 'uptime' => '???'
+ );
+ if (preg_match('/^(\d+)\D/', $uptime, $out)) {
+ $data['uptime'] = floor($out[1] / 86400) . ' ' . Dictionary::translate('lang_days') . ', ' . floor(($out[1] % 86400) / 3600) . ' ' . Dictionary::translate('lang_hours');
+ }
+ $info = $this->sysInfo();
+ if (isset($info['MemTotal']) && isset($info['MemFree']) && isset($info['SwapTotal'])) {
+ $data['memTotal'] = Util::readableFileSize($info['MemTotal'] * 1024);
+ $data['memFree'] = Util::readableFileSize(($info['MemFree'] + $info['Buffers'] + $info['Cached']) * 1024);
+ $data['memPercent'] = 100 - round((($info['MemFree'] + $info['Buffers'] + $info['Cached']) / $info['MemTotal']) * 100);
+ $data['swapTotal'] = Util::readableFileSize($info['SwapTotal'] * 1024);
+ $data['swapUsed'] = Util::readableFileSize(($info['SwapTotal'] - $info['SwapFree']) * 1024);
+ $data['swapPercent'] = 100 - round(($info['SwapFree'] / $info['SwapTotal']) * 100);
+ $data['swapWarning'] = ($data['swapPercent'] > 50 || ($info['SwapTotal'] - $info['SwapFree']) > 200000);
+ }
+ if (isset($info['CpuIdle']) && isset($info['CpuSystem']) && isset($info['CpuTotal'])) {
+ $data['cpuLoad'] = 100 - round(($info['CpuIdle'] / $info['CpuTotal']) * 100);
+ $data['cpuSystem'] = round(($info['CpuSystem'] / $info['CpuTotal']) * 100);
+ $data['cpuLoadOk'] = true;
+ $data['CpuTotal'] = $info['CpuTotal'];
+ $data['CpuIdle'] = $info['CpuIdle'];
+ }
+ echo Render::parse('systeminfo', $data);
+ } else {
+ echo "No permission to view this section.";
}
- echo Render::parse('systeminfo', $data);
}
protected function ajaxSysPoll()
@@ -228,181 +251,208 @@ class Page_SystemStatus extends Page
protected function ajaxServices()
{
- $data = array('services' => array());
- $tasks = array();
+ if (User::hasPermission("show.overview.services")) {
+ $data = array('services' => array());
+ $tasks = array();
- $todo = ['dmsd', 'atftpd'];
- if (Module::isAvailable('dnbd3') && Dnbd3::isEnabled()) {
- $todo[] = 'dnbd3-server';
- }
+ $todo = ['dmsd', 'atftpd'];
+ if (Module::isAvailable('dnbd3') && Dnbd3::isEnabled()) {
+ $todo[] = 'dnbd3-server';
+ }
- foreach ($todo as $svc) {
+ foreach ($todo as $svc) {
+ $tasks[] = array(
+ 'name' => $svc,
+ 'task' => Taskmanager::submit('Systemctl', ['service' => $svc, 'operation' => 'is-active'])
+ );
+ }
$tasks[] = array(
- 'name' => $svc,
- 'task' => Taskmanager::submit('Systemctl', ['service' => $svc, 'operation' => 'is-active'])
+ 'name' => 'LDAP/AD-Proxy',
+ 'task' => Trigger::ldadp()
);
- }
- $tasks[] = array(
- 'name' => 'LDAP/AD-Proxy',
- 'task' => Trigger::ldadp()
- );
- $deadline = time() + 10;
- do {
- $done = true;
- foreach ($tasks as &$task) {
- if (!is_string($task['task']) && (Taskmanager::isFailed($task['task']) || Taskmanager::isFinished($task['task'])))
- continue;
- $task['task'] = Taskmanager::waitComplete($task['task'], 100);
- if (!Taskmanager::isFailed($task['task']) && !Taskmanager::isFinished($task['task'])) {
- $done = false;
+ $deadline = time() + 10;
+ do {
+ $done = true;
+ foreach ($tasks as &$task) {
+ if (!is_string($task['task']) && (Taskmanager::isFailed($task['task']) || Taskmanager::isFinished($task['task'])))
+ continue;
+ $task['task'] = Taskmanager::waitComplete($task['task'], 100);
+ if (!Taskmanager::isFailed($task['task']) && !Taskmanager::isFinished($task['task'])) {
+ $done = false;
+ }
}
- }
- unset($task);
- } while (!$done && time() < $deadline);
-
- foreach ($tasks as $task) {
- $fail = Taskmanager::isFailed($task['task']);
- $data['services'][] = array(
- 'name' => $task['name'],
- 'fail' => $fail,
- 'data' => isset($task['data']) ? $task['data'] : null,
- 'unknown' => $task['task'] === false
- );
- }
-
- echo Render::parse('services', $data);
- }
+ unset($task);
+ } while (!$done && time() < $deadline);
- protected function ajaxDmsdLog()
- {
- $fh = @fopen('/var/log/dmsd.log', 'r');
- if ($fh === false) {
- echo 'Error opening log file';
- return;
- }
- fseek($fh, -6000, SEEK_END);
- $data = fread($fh, 6000);
- @fclose($fh);
- if ($data === false) {
- echo 'Error reading from log file';
- return;
- }
- // If we could read less, try the .1 file too
- $amount = 6000 - strlen($data);
- if ($amount > 100) {
- $fh = @fopen('/var/log/dmsd.log.1', 'r');
- if ($fh !== false) {
- fseek($fh, -$amount, SEEK_END);
- $data = fread($fh, $amount) . $data;
- @fclose($fh);
+ foreach ($tasks as $task) {
+ $fail = Taskmanager::isFailed($task['task']);
+ $data['services'][] = array(
+ 'name' => $task['name'],
+ 'fail' => $fail,
+ 'data' => isset($task['data']) ? $task['data'] : null,
+ 'unknown' => $task['task'] === false
+ );
}
- }
- if (strlen($data) < 5990) {
- $start = 0;
+
+ echo Render::parse('services', $data);
} else {
- $start = strpos($data, "\n") + 1;
+ echo "No permission to view this section.";
}
- echo '<pre>', htmlspecialchars(substr($data, $start), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>';
}
- protected function ajaxLighttpdLog()
+ protected function ajaxDmsdLog()
{
- $fh = @fopen('/var/log/lighttpd/error.log', 'r');
- if ($fh === false) {
- echo 'Error opening log file';
- return;
- }
- fseek($fh, -6000, SEEK_END);
- $data = fread($fh, 6000);
- @fclose($fh);
- if ($data === false) {
- echo 'Error reading from log file';
- return;
- }
- // If we could read less, try the .1 file too
- $amount = 6000 - strlen($data);
- if ($amount > 100) {
- $fh = @fopen('/var/log/lighttpd/error.log.1', 'r');
- if ($fh !== false) {
- fseek($fh, -$amount, SEEK_END);
- $data = fread($fh, $amount) . $data;
- @fclose($fh);
+ if (User::hasPermission("show.logs.bwlpserver")) {
+ $fh = @fopen('/var/log/dmsd.log', 'r');
+ if ($fh === false) {
+ echo 'Error opening log file';
+ return;
}
- }
- if (strlen($data) < 5990) {
- $start = 0;
+ fseek($fh, -6000, SEEK_END);
+ $data = fread($fh, 6000);
+ @fclose($fh);
+ if ($data === false) {
+ echo 'Error reading from log file';
+ return;
+ }
+ // If we could read less, try the .1 file too
+ $amount = 6000 - strlen($data);
+ if ($amount > 100) {
+ $fh = @fopen('/var/log/dmsd.log.1', 'r');
+ if ($fh !== false) {
+ fseek($fh, -$amount, SEEK_END);
+ $data = fread($fh, $amount) . $data;
+ @fclose($fh);
+ }
+ }
+ if (strlen($data) < 5990) {
+ $start = 0;
+ } else {
+ $start = strpos($data, "\n") + 1;
+ }
+ echo '<pre>', htmlspecialchars(substr($data, $start), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>';
} else {
- $start = strpos($data, "\n") + 1;
+ echo "No permission to view this section.";
}
- echo '<pre>', htmlspecialchars(substr($data, $start), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>';
}
- protected function ajaxLdadpLog()
+ protected function ajaxLighttpdLog()
{
- $haveSysconfig = Module::isAvailable('sysconfig');
- $files = glob('/var/log/ldadp/*.log', GLOB_NOSORT);
- if ($files === false || empty($files)) echo('No logs found');
- $now = time();
- foreach ($files as $file) {
- $mod = filemtime($file);
- if ($now - $mod > 86400) continue;
- // New enough - handle
- preg_match(',/(\d+)\.log,', $file, $out);
- $module = $haveSysconfig ? ConfigModule::get($out[1]) : false;
- if ($module === false) {
- echo '<h4>Module ', $out[1], '</h4>';
- } else {
- echo '<h4>Module ', htmlspecialchars($module->title()), '</h4>';
- }
- $fh = @fopen($file, 'r');
+ if (User::hasPermission("show.logs.lighttpd")) {
+ $fh = @fopen('/var/log/lighttpd/error.log', 'r');
if ($fh === false) {
- echo '<pre>Error opening log file</pre>';
- continue;
+ echo 'Error opening log file';
+ return;
}
- fseek($fh, -5000, SEEK_END);
- $data = fread($fh, 5000);
+ fseek($fh, -6000, SEEK_END);
+ $data = fread($fh, 6000);
@fclose($fh);
if ($data === false) {
- echo '<pre>Error reading from log file</pre>';
- continue;
+ echo 'Error reading from log file';
+ return;
+ }
+ // If we could read less, try the .1 file too
+ $amount = 6000 - strlen($data);
+ if ($amount > 100) {
+ $fh = @fopen('/var/log/lighttpd/error.log.1', 'r');
+ if ($fh !== false) {
+ fseek($fh, -$amount, SEEK_END);
+ $data = fread($fh, $amount) . $data;
+ @fclose($fh);
+ }
}
- if (strlen($data) < 4990) {
+ if (strlen($data) < 5990) {
$start = 0;
} else {
$start = strpos($data, "\n") + 1;
}
echo '<pre>', htmlspecialchars(substr($data, $start), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>';
+ } else {
+ echo "No permission to view this section.";
+ }
+
+ }
+
+ protected function ajaxLdadpLog()
+ {
+ if (User::hasPermission("show.logs.ldapad")) {
+ $haveSysconfig = Module::isAvailable('sysconfig');
+ $files = glob('/var/log/ldadp/*.log', GLOB_NOSORT);
+ if ($files === false || empty($files)) echo('No logs found');
+ $now = time();
+ foreach ($files as $file) {
+ $mod = filemtime($file);
+ if ($now - $mod > 86400) continue;
+ // New enough - handle
+ preg_match(',/(\d+)\.log,', $file, $out);
+ $module = $haveSysconfig ? ConfigModule::get($out[1]) : false;
+ if ($module === false) {
+ echo '<h4>Module ', $out[1], '</h4>';
+ } else {
+ echo '<h4>Module ', htmlspecialchars($module->title()), '</h4>';
+ }
+ $fh = @fopen($file, 'r');
+ if ($fh === false) {
+ echo '<pre>Error opening log file</pre>';
+ continue;
+ }
+ fseek($fh, -5000, SEEK_END);
+ $data = fread($fh, 5000);
+ @fclose($fh);
+ if ($data === false) {
+ echo '<pre>Error reading from log file</pre>';
+ continue;
+ }
+ if (strlen($data) < 4990) {
+ $start = 0;
+ } else {
+ $start = strpos($data, "\n") + 1;
+ }
+ echo '<pre>', htmlspecialchars(substr($data, $start), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>';
+ }
+ } else {
+ echo "No permission to view this section.";
}
}
protected function ajaxNetstat()
{
- $taskId = Taskmanager::submit('Netstat');
- if ($taskId === false)
- return;
- $status = Taskmanager::waitComplete($taskId, 3500);
+ if(User::hasPermission("show.logs.netstat")) {
+ $taskId = Taskmanager::submit('Netstat');
+ if ($taskId === false)
+ return;
+ $status = Taskmanager::waitComplete($taskId, 3500);
- if (isset($status['data']['messages']))
- $data = $status['data']['messages'];
- else
- $data = 'Taskmanager error';
+ if (isset($status['data']['messages']))
+ $data = $status['data']['messages'];
+ else
+ $data = 'Taskmanager error';
+
+ echo '<pre>', htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>';
+ } else {
+ echo "No permission to view this section.";
+ }
- echo '<pre>', htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>';
}
protected function ajaxPsList()
{
- $taskId = Taskmanager::submit('PsList');
- if ($taskId === false)
- return;
- $status = Taskmanager::waitComplete($taskId, 3500);
+ if (User::hasPermission("show.logs.pslist")) {
+ $taskId = Taskmanager::submit('PsList');
+ if ($taskId === false)
+ return;
+ $status = Taskmanager::waitComplete($taskId, 3500);
+
+ if (isset($status['data']['messages']))
+ $data = $status['data']['messages'];
+ else
+ $data = 'Taskmanager error';
- if (isset($status['data']['messages']))
- $data = $status['data']['messages'];
- else
- $data = 'Taskmanager error';
+ echo '<pre>', htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>';
+ } else {
+ echo "No permission to view this section.";
+ }
- echo '<pre>', htmlspecialchars($data, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), '</pre>';
}
private function usageColor($percent)
diff --git a/modules-available/systemstatus/permissions/permissions.json b/modules-available/systemstatus/permissions/permissions.json
new file mode 100644
index 00000000..0333564b
--- /dev/null
+++ b/modules-available/systemstatus/permissions/permissions.json
@@ -0,0 +1,13 @@
+[
+ "show.overview.diskstat",
+ "show.overview.services",
+ "show.overview.adresses",
+ "show.overview.systeminfo",
+ "show.overview.dmsdusers",
+ "show.logs.bwlpserver",
+ "show.logs.netstat",
+ "show.logs.pslist",
+ "show.logs.ldapad",
+ "show.logs.lighttpd",
+ "serverreboot"
+] \ No newline at end of file
diff --git a/modules-available/systemstatus/templates/_page.html b/modules-available/systemstatus/templates/_page.html
index 0de94cad..715fd233 100644
--- a/modules-available/systemstatus/templates/_page.html
+++ b/modules-available/systemstatus/templates/_page.html
@@ -86,7 +86,7 @@
<form class="form-adduser" action="?do=SystemStatus" method="post">
<input type="hidden" name="token" value="{{token}}">
<input type="hidden" name="action" value="reboot">
- <button class="btn btn-warning" type="button" data-toggle="modal" data-target="#rebootServerModal"><span class="glyphicon glyphicon-repeat"></span> {{lang_serverReboot}}</button>
+ <button {{^allowedToReboot}}disabled{{/allowedToReboot}} class="btn btn-warning" type="button" data-toggle="modal" data-target="#rebootServerModal"><span class="glyphicon glyphicon-repeat"></span> {{lang_serverReboot}}</button>
<div class ="modal fade" id="rebootServerModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">