summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2018-08-07 16:48:13 +0200
committerSimon Rettberg2018-08-07 16:48:13 +0200
commitf37c95a560f0d2bac96e4b0e650d12691181b876 (patch)
tree914e9db632b0ec3c44685cfa425be0bda549abcf
parent[roomplanner] Fix search feature: load user in ajax call (diff)
downloadslx-admin-f37c95a560f0d2bac96e4b0e650d12691181b876.tar.gz
slx-admin-f37c95a560f0d2bac96e4b0e650d12691181b876.tar.xz
slx-admin-f37c95a560f0d2bac96e4b0e650d12691181b876.zip
[syslog] Add user export feature
This will export all rows from tables that log user related content, data, events, helping administrators to conform to DSGVO information requests. Closes #3401
-rw-r--r--modules-available/syslog/api.inc.php39
-rw-r--r--modules-available/syslog/lang/de/template-tags.json4
-rw-r--r--modules-available/syslog/lang/en/template-tags.json4
-rw-r--r--modules-available/syslog/page.inc.php2
-rw-r--r--modules-available/syslog/permissions/permissions.json3
-rw-r--r--modules-available/syslog/templates/heading.html39
6 files changed, 87 insertions, 4 deletions
diff --git a/modules-available/syslog/api.inc.php b/modules-available/syslog/api.inc.php
index 18c42c31..945f9d09 100644
--- a/modules-available/syslog/api.inc.php
+++ b/modules-available/syslog/api.inc.php
@@ -1,5 +1,44 @@
<?php
+// Check for user data export
+if (($user = Request::post('export-user', false, 'string')) !== false) {
+ User::load();
+ User::assertPermission('export-user-data', null, '?do=syslog');
+ if (!Util::verifyToken()) {
+ die('Invalid Token');
+ }
+ $puser = preg_quote($user);
+ $exp = "$puser logged|^\[$puser\]";
+ Header('Content-Type: text/plain; charset=utf-8');
+ Header('Content-Disposition: attachment; filename=bwlehrpool-export-' .Util::sanitizeFilename($user) . '-' . date('Y-m-d') . '.txt');
+ $srcs = [];
+ $srcs[] = ['res' => Database::simpleQuery("SELECT dateline, logtypeid AS typeid, clientip, description FROM clientlog
+ WHERE description REGEXP :exp
+ ORDER BY dateline ASC", ['exp' => $exp])];
+ if (Module::get('statistics') !== false) {
+ $srcs[] = ['res' => Database::simpleQuery("SELECT dateline, typeid, clientip, data AS description FROM statistic
+ WHERE username = :user
+ ORDER BY dateline ASC", ['user' => $user])];
+ }
+ echo "# Begin log\n";
+ for (;;) {
+ unset($best);
+ foreach ($srcs as &$src) {
+ if (!isset($src['row'])) {
+ $src['row'] = $src['res']->fetch(PDO::FETCH_ASSOC);
+ }
+ if ($src['row'] !== false && (!isset($best) || $src['row']['dateline'] < $best['dateline'])) {
+ $best =& $src['row'];
+ }
+ }
+ if (!isset($best))
+ break;
+ echo date('Y-m-d H:i:s', $best['dateline']), "\t", $best['typeid'], "\t", $best['clientip'], "\t", $best['description'], "\n";
+ $best = null; // so we repopulate on next iteration
+ }
+ die("# End log\n");
+}
+
if (empty($_POST['type'])) die('Missing options.');
$type = mb_strtolower($_POST['type']);
diff --git a/modules-available/syslog/lang/de/template-tags.json b/modules-available/syslog/lang/de/template-tags.json
index b5c6f8c7..c00d619a 100644
--- a/modules-available/syslog/lang/de/template-tags.json
+++ b/modules-available/syslog/lang/de/template-tags.json
@@ -5,8 +5,12 @@
"lang_clientLog": "Client Log",
"lang_details": "Details",
"lang_event": "Ereignis",
+ "lang_export": "Exportieren",
+ "lang_exportUserDesc": "Mit dieser Funktion k\u00f6nnen Sie alle in der Datenbank vorhandenen Datens\u00e4tze zu einem bestimmten Benutzer exportieren. Bitte geben Sie den Benutzernamen genau so ein, wie ihn der Nutzer beim Login am Client angeben muss.",
"lang_filter": "Filter",
"lang_not": "not",
"lang_settings": "Einstellungen",
+ "lang_userExport": "Nutzer-Export",
+ "lang_userLogin": "Benutzer-Login",
"lang_when": "Wann"
} \ No newline at end of file
diff --git a/modules-available/syslog/lang/en/template-tags.json b/modules-available/syslog/lang/en/template-tags.json
index 1aae1fe9..24e9aaa1 100644
--- a/modules-available/syslog/lang/en/template-tags.json
+++ b/modules-available/syslog/lang/en/template-tags.json
@@ -5,8 +5,12 @@
"lang_clientLog": "Client Log",
"lang_details": "Details",
"lang_event": "Event",
+ "lang_export": "Export",
+ "lang_exportUserDesc": "This exports all data from the database relating to the given user login. Please specify the user name exactly the way they would provide it when logging in on a client.",
"lang_filter": "Filter",
"lang_not": "not",
"lang_settings": "Settings",
+ "lang_userExport": "User export",
+ "lang_userLogin": "User login",
"lang_when": "When"
} \ No newline at end of file
diff --git a/modules-available/syslog/page.inc.php b/modules-available/syslog/page.inc.php
index 00c55a3f..6c1a0a16 100644
--- a/modules-available/syslog/page.inc.php
+++ b/modules-available/syslog/page.inc.php
@@ -31,7 +31,7 @@ class Page_SysLog extends Page
protected function doRender()
{
$data = ['anondays' => Property::get(self::PROP_ANON_DAYS, 0)];
- Permission::addGlobalTags($data['perms'], NULL, ['configure-anonymization']);
+ Permission::addGlobalTags($data['perms'], NULL, ['configure-anonymization', 'export-user-data']);
Render::addTemplate("heading", $data);
if (!User::hasPermission("view")) {
diff --git a/modules-available/syslog/permissions/permissions.json b/modules-available/syslog/permissions/permissions.json
index cabf82f9..1f2373d4 100644
--- a/modules-available/syslog/permissions/permissions.json
+++ b/modules-available/syslog/permissions/permissions.json
@@ -4,5 +4,8 @@
},
"configure-anonymization": {
"location-aware": false
+ },
+ "export-user-data": {
+ "location-aware": false
}
} \ No newline at end of file
diff --git a/modules-available/syslog/templates/heading.html b/modules-available/syslog/templates/heading.html
index 2ab1a848..8dd3d440 100644
--- a/modules-available/syslog/templates/heading.html
+++ b/modules-available/syslog/templates/heading.html
@@ -1,7 +1,13 @@
<div class="page-header">
- <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>
+ <span class="buttonbar pull-right">
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#modal-export" {{perms.export-user-data.disabled}}>
+ <span class="glyphicon glyphicon-export"></span>
+ {{lang_userExport}}
+ </button>
+ <button type="button" class="btn btn-default" data-toggle="modal" data-target="#modal-settings">
+ <span class="glyphicon glyphicon-cog"></span> {{lang_settings}}
+ </button>
+ </span>
<div id="modal-settings" class="modal fade" role="dialog">
<div class="modal-dialog">
@@ -31,5 +37,32 @@
</div>
</div>
+ <div id="modal-export" class="modal fade" role="dialog">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <form method="post" action="api.php?do=syslog">
+ <input type="hidden" name="token" value="{{token}}">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal">&times;</button>
+ <h4 class="modal-title"><b>{{lang_userExport}}</b></h4>
+ </div>
+ <div class="modal-body">
+ <p>{{lang_exportUserDesc}}</p>
+ <label for="export-user-name">{{lang_userLogin}}</label>
+ <input id="export-user-name" type="text" name="export-user" class="form-control" style="width:100%">
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">{{lang_cancel}}</button>
+ <button type="submit" class="btn btn-primary">
+ <span class="glyphicon glyphicon-export"></span>
+ {{lang_export}}
+ </button>
+ </div>
+ </form>
+ </div>
+
+ </div>
+ </div>
+
<h1>{{lang_clientLog}}</h1>
</div> \ No newline at end of file