Implement logging. Closes #67

This commit is contained in:
Mark Schouten 2016-08-05 11:57:04 +02:00
parent e429005134
commit cbea4778ef
5 changed files with 168 additions and 9 deletions

BIN
img/delete.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
img/delete_inverted.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

View file

@ -128,6 +128,7 @@ function do_db_auth($u, $p) {
$db->close(); $db->close();
if ($userinfo and $userinfo['password'] and (crypt($p, $userinfo['password']) === $userinfo['password'])) { if ($userinfo and $userinfo['password'] and (crypt($p, $userinfo['password']) === $userinfo['password'])) {
writelog('Succesful login.');
return TRUE; return TRUE;
} }
@ -151,6 +152,11 @@ function add_user($username, $isadmin = FALSE, $password = '') {
$ret = $q->execute(); $ret = $q->execute();
$db->close(); $db->close();
if ($isadmin) {
writelog("Added user $username as admin.");
} else {
writelog("Added user $username.");
}
return $ret; return $ret;
} }
@ -167,10 +173,12 @@ function update_user($username, $isadmin, $password) {
$q->bindValue(1, (int)(bool)$isadmin, SQLITE3_INTEGER); $q->bindValue(1, (int)(bool)$isadmin, SQLITE3_INTEGER);
$q->bindValue(2, $password, SQLITE3_TEXT); $q->bindValue(2, $password, SQLITE3_TEXT);
$q->bindValue(3, $username, SQLITE3_TEXT); $q->bindValue(3, $username, SQLITE3_TEXT);
writelog("Updating password and/or settings for $username. Admin: ".(int)(bool)$isadmin);
} else { } else {
$q = $db->prepare('UPDATE users SET isadmin = ? WHERE emailaddress = ?'); $q = $db->prepare('UPDATE users SET isadmin = ? WHERE emailaddress = ?');
$q->bindValue(1, (int)(bool)$isadmin, SQLITE3_INTEGER); $q->bindValue(1, (int)(bool)$isadmin, SQLITE3_INTEGER);
$q->bindValue(2, $username, SQLITE3_TEXT); $q->bindValue(2, $username, SQLITE3_TEXT);
writelog("Updating settings for $username. Admin: ".(int)(bool)$isadmin);
} }
$ret = $q->execute(); $ret = $q->execute();
$db->close(); $db->close();
@ -178,13 +186,14 @@ function update_user($username, $isadmin, $password) {
return $ret; return $ret;
} }
function delete_user($id) { function delete_user($username) {
$db = get_db(); $db = get_db();
$q = $db->prepare('DELETE FROM users WHERE id = ?'); $q = $db->prepare('DELETE FROM users WHERE id = ?');
$q->bindValue(1, $id, SQLITE3_INTEGER); $q->bindValue(1, $id, SQLITE3_INTEGER);
$ret = $q->execute(); $ret = $q->execute();
$db->close(); $db->close();
writelog("Deleted user $username.");
return $ret; return $ret;
} }
@ -242,7 +251,43 @@ function user_template_names() {
return $templatenames; return $templatenames;
} }
function getlogs() {
$db = get_db();
$r = $db->query('SELECT * FROM logs ORDER BY timestamp DESC');
$ret = array();
while ($row = $r->fetchArray(SQLITE3_ASSOC)) {
array_push($ret, $row);
}
return $ret;
}
function clearlogs() {
$db = get_db();
$q = $db->query('DELETE FROM logs;');
$db->close();
writelog("Logtable truncated.");
}
function writelog($line) {
try {
$db = get_db();
$q = $db->prepare('CREATE TABLE IF NOT EXISTS logs (
id INTEGER PRIMARY KEY,
user TEXT NOT NULL,
log TEXT NOT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP);');
$ret = $q->execute();
$q = $db->prepare('INSERT INTO logs (user, log) VALUES (:user, :log)');
$q->bindValue(':user', get_sess_user(), SQLITE3_TEXT);
$q->bindValue(':log', $line, SQLITE3_TEXT);
$q->execute();
$db->close();
} catch (Exception $e) {
return jtable_respond(null, 'error', $e->getMessage());
}
}
/* This function was taken from https://gist.github.com/rsky/5104756 to make /* This function was taken from https://gist.github.com/rsky/5104756 to make
it available on older php versions. Thanks! */ it available on older php versions. Thanks! */

109
index.php
View file

@ -113,6 +113,9 @@ if ($blocklogin === TRUE) {
<div id="wrap"> <div id="wrap">
<div id="dnssecinfo"> <div id="dnssecinfo">
</div> </div>
<div id="clearlogs" style="display: none;">
Are you sure you want to clear all the logs? Maybe save them first?
</div>
<div id="menu" class="jtable-main-container <?php if ($menutype === 'horizontal') { ?>horizontal<?php } ?>"> <div id="menu" class="jtable-main-container <?php if ($menutype === 'horizontal') { ?>horizontal<?php } ?>">
<div class="jtable-title menu-title"> <div class="jtable-title menu-title">
<div class="jtable-title-text"> <div class="jtable-title-text">
@ -123,6 +126,7 @@ if ($blocklogin === TRUE) {
<li><a href="#" id="zoneadmin">Zones</a></li> <li><a href="#" id="zoneadmin">Zones</a></li>
<?php if (is_adminuser()) { ?> <?php if (is_adminuser()) { ?>
<li><a href="#" id="useradmin">Users</a></li> <li><a href="#" id="useradmin">Users</a></li>
<li><a href="#" id="logadmin">Logs</a></li>
<?php } ?> <?php } ?>
<li><a href="#" id="aboutme">About me</a></li> <li><a href="#" id="aboutme">About me</a></li>
<li><a href="index.php?logout=1">Logout</a></li> <li><a href="index.php?logout=1">Logout</a></li>
@ -148,6 +152,9 @@ if ($blocklogin === TRUE) {
<div id="users"> <div id="users">
<div class="tables" id="Users"></div> <div class="tables" id="Users"></div>
</div> </div>
<div id="logs">
<div class="tables" id="Logs"></div>
</div>
<?php } ?> <?php } ?>
<div id="AboutMe"> <div id="AboutMe">
@ -847,26 +854,39 @@ $(document).ready(function () {
}); });
<?php if (is_adminuser()) { ?> <?php if (is_adminuser()) { ?>
$('#Logs').hide();
$('#Users').hide(); $('#Users').hide();
$('#AboutMe').hide(); $('#AboutMe').hide();
$('#aboutme').click(function () { $('#aboutme').click(function () {
$('#Logs').hide();
$('#Users').hide(); $('#Users').hide();
$('#MasterZones').hide(); $('#MasterZones').hide();
$('#SlaveZones').hide(); $('#SlaveZones').hide();
$('#AboutMe').show(); $('#AboutMe').show();
}); });
$('#useradmin').click(function () { $('#useradmin').click(function () {
$('#Users').show(); $('#Logs').hide();
$('#MasterZones').hide(); $('#MasterZones').hide();
$('#SlaveZones').hide(); $('#SlaveZones').hide();
$('#AboutMe').hide(); $('#AboutMe').hide();
$('#Users').jtable('load');
$('#Users').show();
}); });
$('#zoneadmin').click(function () { $('#zoneadmin').click(function () {
$('#Logs').hide();
$('#Users').hide(); $('#Users').hide();
$('#AboutMe').hide(); $('#AboutMe').hide();
$('#MasterZones').show(); $('#MasterZones').show();
$('#SlaveZones').show(); $('#SlaveZones').show();
}); });
$('#logadmin').click(function () {
$('#Users').hide();
$('#AboutMe').hide();
$('#MasterZones').hide();
$('#SlaveZones').hide();
$('#Logs').jtable('load');
$('#Logs').show();
});
$('#Users').jtable({ $('#Users').jtable({
title: 'Users', title: 'Users',
paging: true, paging: true,
@ -910,7 +930,92 @@ $(document).ready(function () {
$("#SlaveZones").jtable('reload'); $("#SlaveZones").jtable('reload');
} }
}); });
$('#Users').jtable('load');
$('#Logs').jtable({
title: 'Logs',
paging: true,
pageSize: 20,
sorting: false,
actions: {
listAction: 'logs.php?action=list',
deleteAction: 'logs.php?action=delete',
},
messages: {
deleteConfirmation: 'This entry will be deleted. Are you sure?'
},
toolbar: {
hoverAnimation: true,
hoverAnimationDuration: 60,
hoverAnimationEasing: undefined,
items: [
{
icon: 'img/delete_inverted.png',
text: 'Clear logs',
click: function() {
$("#clearlogs").dialog({
modal: true,
title: "Clear all logs",
width: 'auto',
buttons: {
Ok: function() {
$.get("logs.php?action=clear");
$( this ).dialog( "close" );
$('#Logs').jtable('load');
},
Cancel: function() {
$( this ).dialog( "close" );
return false;
}
}
});
}
},
{
icon: 'img/export.png',
text: 'Save logs',
click: function () {
var $zexport = $.get("logs.php?action=export", function(data) {
console.log(data);
blob = new Blob([data], { type: 'text/plain' });
var dl = document.createElement('a');
dl.addEventListener('click', function(ev) {
dl.href = URL.createObjectURL(blob);
dl.download = 'nseditlogs.txt';
}, false);
if (document.createEvent) {
var event = document.createEvent("MouseEvents");
event.initEvent("click", true, true);
dl.dispatchEvent(event);
}
});
}
}
],
},
fields: {
id: {
title: 'key',
key: true,
type: 'hidden'
},
user: {
title: 'User',
width: '10%',
display: displayContent('user'),
},
log: {
title: 'Log',
width: '80%',
display: displayContent('log'),
},
timestamp: {
title: 'Timestamp',
width: '10%',
display: displayContent('timestamp')
}
}
});
<?php } ?> <?php } ?>
$('#MasterZones').jtable('load'); $('#MasterZones').jtable('load');
$('#SlaveZones').jtable('load'); $('#SlaveZones').jtable('load');

View file

@ -188,9 +188,6 @@ case "listrecords":
$zone = new Zone(); $zone = new Zone();
$zone->parse($zonedata); $zone->parse($zonedata);
$records = $zone->rrsets2records(); $records = $zone->rrsets2records();
foreach ($records as &$record) {
$record['id'] = json_encode($record);
}
if (isset($_GET['jtSorting'])) { if (isset($_GET['jtSorting'])) {
list($scolumn, $sorder) = preg_split("/ /", $_GET['jtSorting']); list($scolumn, $sorder) = preg_split("/ /", $_GET['jtSorting']);
switch ($scolumn) { switch ($scolumn) {
@ -218,6 +215,7 @@ case "delete":
$api->deletezone($_POST['id']); $api->deletezone($_POST['id']);
delete_db_zone($zone['name']); delete_db_zone($zone['name']);
writelog("Deleted zone ".$zone['name']);
jtable_respond(null, 'delete'); jtable_respond(null, 'delete');
break; break;
@ -302,6 +300,7 @@ case "create":
} }
$zone = $api->savezone($zone->export()); $zone = $api->savezone($zone->export());
writelog("Created zone ".$zone['name']);
jtable_respond($zone, 'single'); jtable_respond($zone, 'single');
break; break;
@ -327,6 +326,7 @@ case "update":
} }
} }
writelog("Updated zone ".$zone->name);
jtable_respond($api->savezone($zone->export()), 'single'); jtable_respond($api->savezone($zone->export()), 'single');
break; break;
@ -363,6 +363,7 @@ case "createrecord":
$record = $zone->addRecord($name, $type, $content, $_POST['disabled'], $_POST['ttl'], $_POST['setptr']); $record = $zone->addRecord($name, $type, $content, $_POST['disabled'], $_POST['ttl'], $_POST['setptr']);
$api->savezone($zone->export()); $api->savezone($zone->export());
writelog("Created record: ".$record['id']);
jtable_respond($record, 'single'); jtable_respond($record, 'single');
break; break;
@ -378,8 +379,9 @@ case "editrecord":
$api->savezone($zone->export()); $api->savezone($zone->export());
$record['id'] = json_encode($record); $record = $zone->getRecord($_POST['name'], $_POST['type'], $_POST['content']);
jtable_respond($zone->getRecord($_POST['name'], $_POST['type'], $_POST['content']), 'single'); writelog("Updated record ".$_POST['id']." to ".$record['id']);
jtable_respond($record, 'single');
break; break;
case "deleterecord": case "deleterecord":
@ -392,10 +394,12 @@ case "deleterecord":
$api->savezone($zone->export()); $api->savezone($zone->export());
writelog("Deleted record ".$_POST['id']);
jtable_respond(null, 'delete'); jtable_respond(null, 'delete');
break; break;
case "export": case "export":
writelog("Exported zone ".$_GET['zoneid']);
jtable_respond($api->exportzone($_GET['zoneid']), 'single'); jtable_respond($api->exportzone($_GET['zoneid']), 'single');
break; break;
@ -403,6 +407,10 @@ case "clone":
$name = $_POST['destname']; $name = $_POST['destname'];
$src = $_POST['sourcename']; $src = $_POST['sourcename'];
if (!string_ends_with($name, '.')) {
$name = $name.".";
}
if (!_valid_label($name)) { if (!_valid_label($name)) {
jtable_respond(null, 'error', "Invalid destination zonename"); jtable_respond(null, 'error', "Invalid destination zonename");
} }
@ -424,6 +432,7 @@ case "clone":
} }
$zone = $api->savezone($srczone->export()); $zone = $api->savezone($srczone->export());
writelog("Cloned zone $src into $name");
jtable_respond($zone, 'single'); jtable_respond($zone, 'single');
break; break;