summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2021-03-15 10:24:37 +0100
committerSimon Rettberg2021-03-15 10:24:37 +0100
commitf9ec4c5a85b71621cde0ff9fd1eead65f9b41931 (patch)
tree3f2622c34e8ae93dd4f17599342e0452b0abdbd3
parent[statistics] Remove logintime filter (diff)
downloadslx-admin-f9ec4c5a85b71621cde0ff9fd1eead65f9b41931.tar.gz
slx-admin-f9ec4c5a85b71621cde0ff9fd1eead65f9b41931.tar.xz
slx-admin-f9ec4c5a85b71621cde0ff9fd1eead65f9b41931.zip
[syslog] Make client log searchable
Closes #3474
-rw-r--r--modules-available/syslog/lang/de/template-tags.json1
-rw-r--r--modules-available/syslog/lang/en/template-tags.json1
-rw-r--r--modules-available/syslog/page.inc.php75
-rw-r--r--modules-available/syslog/templates/page-syslog.html18
4 files changed, 56 insertions, 39 deletions
diff --git a/modules-available/syslog/lang/de/template-tags.json b/modules-available/syslog/lang/de/template-tags.json
index c00d619a..90d0a294 100644
--- a/modules-available/syslog/lang/de/template-tags.json
+++ b/modules-available/syslog/lang/de/template-tags.json
@@ -9,6 +9,7 @@
"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_searchString": "Suchbegriff",
"lang_settings": "Einstellungen",
"lang_userExport": "Nutzer-Export",
"lang_userLogin": "Benutzer-Login",
diff --git a/modules-available/syslog/lang/en/template-tags.json b/modules-available/syslog/lang/en/template-tags.json
index 24e9aaa1..725f7e94 100644
--- a/modules-available/syslog/lang/en/template-tags.json
+++ b/modules-available/syslog/lang/en/template-tags.json
@@ -9,6 +9,7 @@
"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_searchString": "Search term",
"lang_settings": "Settings",
"lang_userExport": "User export",
"lang_userLogin": "User login",
diff --git a/modules-available/syslog/page.inc.php b/modules-available/syslog/page.inc.php
index 6c1a0a16..6868994e 100644
--- a/modules-available/syslog/page.inc.php
+++ b/modules-available/syslog/page.inc.php
@@ -25,6 +25,17 @@ class Page_SysLog extends Page
}
Util::redirect('?do=syslog');
}
+ if (Request::isPost()) {
+ $search = Request::any('search');
+ $filter = Request::any('filter');
+ $not = Request::any('not', false, 'bool');
+ $machineuuid = Request::any('machineuuid');
+ Session::set('log_search', $search);
+ Session::set('log_filter', $filter);
+ Session::set('log_not', $not);
+ Session::save();
+ Util::redirect('?do=syslog&' . http_build_query(compact('search', 'filter', 'not', 'machineuuid')));
+ }
User::assertPermission('*');
}
@@ -40,63 +51,62 @@ class Page_SysLog extends Page
}
$cutoff = strtotime('-1 month');
- $res = Database::simpleQuery("SELECT logtypeid, Count(*) AS counter FROM clientlog WHERE dateline > $cutoff GROUP BY logtypeid ORDER BY counter ASC");
+ $res = Database::simpleQuery("SELECT logtypeid, Count(*) AS counter
+ FROM clientlog
+ WHERE dateline > $cutoff
+ GROUP BY logtypeid ORDER BY counter ASC");
$types = array();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$types[$row['logtypeid']] = $row;
}
- if (Request::get('filter') !== false) {
+ if (Request::get('filter') !== false || Request::get('search') !== false) {
+ $search = Request::get('search');
$filter = Request::get('filter');
- $not = Request::get('not') ? 'NOT' : '';
- } elseif (Request::post('filter') !== false) {
- $filter = Request::post('filter');
- $not = Request::post('not') ? 'NOT' : '';
-
- Session::set('log_filter', $filter);
- Session::set('log_not', $not);
- Session::save();
+ $not = Request::get('not', false, 'bool');
} else {
+ $search = Session::get('log_search');
$filter = Session::get('log_filter');
- $not = Session::get('log_not') ? 'NOT' : '';
+ $not = (bool)Session::get('log_not');
}
+ $qArgs = [];
+ $whereClause = '1';
if (!empty($filter)) {
- $filterList = explode(',', $filter);
- $whereClause = array();
+ $whereClause .= ' AND ( ';
+ if ($not) {
+ $whereClause .= 'NOT ';
+ }
+ $filterList = array_unique(explode(',', $filter));
foreach ($filterList as $filterItem) {
- $filterItem = preg_replace('/[^a-z0-9_\-]/', '', trim($filterItem));
- if (empty($filterItem) || in_array($filterItem, $whereClause)) continue;
- $whereClause[] = "'$filterItem'";
if (!isset($types[$filterItem])) {
$types[$filterItem] = ['logtypeid' => $filterItem, 'counter' => ''];
}
}
- if (!empty($whereClause)) $whereClause = ' WHERE logtypeid ' . $not . ' IN (' . implode(', ', $whereClause) . ')';
+ $whereClause .= "logtypeid IN (:typeids) )";
+ $qArgs['typeids'] = $filterList;
+ }
+ if (!empty($search)) {
+ $qArgs['search'] = '%' . str_replace(array('=', '_', '%', '*', '?'), array('==', '=_', '=%', '%', '_'), $search) . '%';
+ $whereClause .= " AND description LIKE :search ESCAPE '='";
}
- if (!isset($whereClause) || empty($whereClause)) $whereClause = '';
if (Request::get('machineuuid')) {
- if (empty($whereClause))
- $whereClause .= ' WHERE ';
- else
- $whereClause .= ' AND ';
-
- $whereClause .= "machineuuid='" . preg_replace('/[^0-9a-zA-Z\-]/', '', Request::get('machineuuid', '', 'string')) . "'";
+ $whereClause .= " AND machineuuid = :uuid";
+ $qArgs['uuid'] = 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)';
+ $whereClause .= ' locationid IN (:allowedLocations)';
+ $qArgs['allowedLocations'] = $allowedLocations;
}
$lines = array();
- $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));
+ $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientlog.clientip, clientlog.machineuuid, description, extra
+ FROM clientlog $joinClause
+ WHERE $whereClause
+ ORDER BY logid DESC", 50);
+ $res = $paginate->exec($qArgs);
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$row['date'] = Util::prettyTime($row['dateline']);
$row['icon'] = $this->eventToIconName($row['logtypeid']);
@@ -105,6 +115,7 @@ class Page_SysLog extends Page
$paginate->render('page-syslog', array(
'filter' => $filter,
+ 'search' => $search,
'not' => $not,
'list' => $lines,
'types' => json_encode(array_values($types)),
diff --git a/modules-available/syslog/templates/page-syslog.html b/modules-available/syslog/templates/page-syslog.html
index 9d05d434..2b7c1439 100644
--- a/modules-available/syslog/templates/page-syslog.html
+++ b/modules-available/syslog/templates/page-syslog.html
@@ -3,8 +3,9 @@
max-width: 500px;
}
</style>
-<form method="post" action="?do=SysLog{{#machineuuid}}&machineuuid={{machineuuid}}{{/machineuuid}}">
+<form method="post" action="?do=syslog">
<input type="hidden" name="token" value="{{token}}">
+ <input type="hidden" name="machineuuid" value="{{machineuuid}}">
<div class="pull-left">
<label for="filterstring">{{lang_filter}}</label>
</div>
@@ -12,6 +13,11 @@
<div class="row">
+ <div class="col-sm-11">
+ <div>
+ <input class="form-control" id="filterstring" placeholder="id" value="{{filter}}" name="filter">
+ </div>
+ </div>
<div class="col-sm-1">
<div class="checkbox">
<input id="notbox" type="checkbox" name="not" {{#not}}checked="checked"{{/not}}>
@@ -19,12 +25,10 @@
</div>
</div>
<div class="col-sm-11">
- <div class="input-group">
- <input id="filterstring" placeholder="id" value="{{filter}}" name="filter">
- <span style="padding-bottom: 5px;" class="input-group-btn">
- <button class="btn btn-primary" type="submit">{{lang_applyFilter}}</button>
- </span>
- </div>
+ <input class="form-control" placeholder="{{lang_searchString}}" value="{{search}}" name="search">
+ </div>
+ <div class="col-sm-1">
+ <button class="btn btn-primary" type="submit">{{lang_applyFilter}}</button>
</div>
</div>
</form>