Add user adding/removing/editing and security log viewing/clearing.

master
Skylar Ittner 7 years ago
parent 4b6fcd8f7c
commit 8e24cd7208

@ -5,6 +5,7 @@
*/
require_once __DIR__ . "/required.php";
require_once __DIR__ . "/lib/login.php";
require_once __DIR__ . "/lib/authlog.php";
dieifnotloggedin();
@ -42,18 +43,18 @@ switch ($VARS['action']) {
if (is_empty($VARS['name']) || is_empty($VARS['username']) || is_empty($VARS['status'])) {
returnToSender('invalid_parameters');
}
if (!$database->has('acctstatus', ['statusid' => $VARS['status']])) {
returnToSender("invalid_parameters");
}
$data = [
'realname' => $VARS['name'],
'username' => $VARS['username'],
'email' => $VARS['email'],
'acctstatus' => $VARS['status']
];
if (!is_empty($VARS['pass'])) {
$data['password'] = password_hash($VARS['pass'], PASSWORD_BCRYPT);
}
@ -63,11 +64,27 @@ switch ($VARS['action']) {
$data['phone2'] = "";
$data['accttype'] = 1;
$database->insert('accounts', $data);
insertAuthLog(17, $_SESSION['uid'], $data['username'] . ", " . $data['realname'] . ", " . $data['email'] . ", " . $data['acctstatus']);
} else {
$olddata = $database->select('accounts', '*', ['uid' => $VARS['id']])[0];
$database->update('accounts', $data, ['uid' => $VARS['id']]);
insertAuthLog(17, $_SESSION['uid'], "OLD: " . $olddata['username'] . ", " . $olddata['realname'] . ", " . $olddata['email'] . ", " . $olddata['acctstatus'] . "; NEW: " . $data['username'] . ", " . $data['realname'] . ", " . $data['email'] . ", " . $data['acctstatus']);
}
returnToSender("user_saved");
case "deleteuser":
if ($database->has('accounts', ['uid' => $VARS['id']]) !== TRUE) {
returnToSender("invalid_userid");
}
$olddata = $database->select('accounts', '*', ['uid' => $VARS['id']])[0];
$database->delete('accounts', ['uid' => $VARS['id']]);
insertAuthLog(16, $_SESSION['uid'], $olddata['username'] . ", " . $olddata['realname'] . ", " . $olddata['email'] . ", " . $olddata['acctstatus']);
returnToSender("user_deleted");
case "clearlog":
$rows = $database->count('authlog');
$database->delete('authlog');
insertAuthLog(15, $_SESSION['uid'], lang2("removed n entries", ['n' => $rows], false));
returnToSender("log_cleared");
case "signout":
session_destroy();
header('Location: index.php');

@ -46,5 +46,19 @@ define("STRINGS", [
"placeholder email address" => "jdoe@example.com",
"placeholder password" => "swordfish",
"new password" => "New Password",
"non-local account warning" => "This account is not locally managed. Changes made here will not synchronize to the directory server and some attributes cannot be edited."
"non-local account warning" => "This account is not locally managed. Changes made here will not synchronize to the directory server and some attributes cannot be edited.",
"delete user" => "Delete User",
"really delete user" => "Are you sure you want to delete this user? This action cannot be reversed.",
"user deleted" => "User account deleted.",
"user does not exist" => "User does not exist.",
"logtime" => "Date/Time",
"logtype" => "Event Type",
"ip address" => "IP Address",
"other data" => "Other",
"security log" => "Security Log",
"event type reference" => "Event Type Reference",
"clear log" => "Clear Log",
"really clear log" => "Are you sure you want to purge the security log? This action cannot be reversed.",
"log cleared" => "Security log cleared.",
"removed n entries" => "Removed {n} entries",
]);

@ -20,5 +20,17 @@ define("MESSAGES", [
"user_saved" => [
"string" => "user saved",
"type" => "success"
],
"user_deleted" => [
"string" => "user deleted",
"type" => "success"
],
"user_not_exists" => [
"string" => "user does not exist",
"type" => "danger"
],
"log_cleared" => [
"string" => "log cleared",
"type" => "success"
]
]);

@ -0,0 +1,29 @@
<?php
require_once __DIR__ . "/../required.php";
dieifnotloggedin();
function insertAuthLog($type, $uid = null, $data = "") {
global $database;
// find IP address
$ip = "";
if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) {
$ip = $_SERVER["HTTP_CF_CONNECTING_IP"];
} else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
$ip = $_SERVER["HTTP_CLIENT_IP"];
} else if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} else if (isset($_SERVER["HTTP_X_FORWARDED"])) {
$ip = $_SERVER["HTTP_X_FORWARDED"];
} else if (isset($_SERVER["HTTP_FORWARDED_FOR"])) {
$ip = $_SERVER["HTTP_FORWARDED_FOR"];
} else if (isset($_SERVER["HTTP_FORWARDED"])) {
$ip = $_SERVER["HTTP_FORWARDED"];
} else if (isset($_SERVER["REMOTE_ADDR"])) {
$ip = $_SERVER["REMOTE_ADDR"];
} else {
$ip = "NOT FOUND";
}
$database->insert("authlog", ['logtime' => date("Y-m-d H:i:s"), 'logtype' => $type, 'uid' => $uid, 'ip' => $ip, 'otherdata' => $data]);
}

@ -0,0 +1,86 @@
<?php
require __DIR__ . '/../required.php';
dieifnotloggedin();
header("Content-Type: application/json");
$out = [];
$out['draw'] = intval($VARS['draw']);
$out['recordsTotal'] = $database->count('authlog');
$filter = false;
// sort
$order = null;
$sortby = "DESC";
if ($VARS['order'][0]['dir'] == 'asc') {
$sortby = "ASC";
}
switch ($VARS['order'][0]['column']) {
case 1:
$order = ["logtime" => $sortby];
break;
case 2:
$order = ["typename" => $sortby];
break;
case 3:
$order = ["username" => $sortby];
break;
case 5:
$order = ["ip" => $sortby];
break;
case 6:
$order = ["otherdata" => $sortby];
break;
}
// search
if (!is_empty($VARS['search']['value'])) {
$filter = true;
$wherenolimit = [
"OR" => [
"logtime[~]" => $VARS['search']['value'],
"typename[~]" => $VARS['search']['value'],
"username[~]" => $VARS['search']['value'],
"ip[~]" => $VARS['search']['value'],
"otherdata[~]" => $VARS['search']['value']
]
];
$where = $wherenolimit;
$where["LIMIT"] = [$VARS['start'], $VARS['length']];
} else {
$where = ["LIMIT" => [$VARS['start'], $VARS['length']]];
}
if (!is_null($order)) {
$where["ORDER"] = $order;
}
$log = $database->select('authlog', [
"[>]accounts" => ['uid' => 'uid'],
"[>]logtypes" => ['logtype' => 'logtype']
], [
'logtime',
'typename',
'username',
'ip',
'otherdata'
], $where);
$out['status'] = "OK";
if ($filter) {
$recordsFiltered = $database->count('authlog', [
"[>]accounts" => ['uid' => 'uid'],
"[>]logtypes" => ['logtype' => 'logtype']
], 'logid', $wherenolimit);
} else {
$recordsFiltered = $out['recordsTotal'];
}
$out['recordsFiltered'] = $recordsFiltered;
$out['log'] = $log;
echo json_encode($out);

@ -27,6 +27,27 @@ define("PAGES", [
"static/js/edituser.js"
]
],
"deluser" => [
"title" => "delete user",
"navbar" => false
],
"authlog" => [
"title" => "security log",
"navbar" => true,
"icon" => "list",
"styles" => [
"static/css/datatables.min.css",
"static/css/tables.css"
],
"scripts" => [
"static/js/datatables.min.js",
"static/js/authlog.js"
],
],
"clearlog" => [
"title" => "clear log",
"navbar" => false
],
"404" => [
"title" => "404 error"
]

@ -0,0 +1,58 @@
<?php
require_once __DIR__ . '/../required.php';
redirectifnotloggedin();
?>
<div class="btn-group" style="margin-bottom: 10px;">
<a href="app.php?page=clearlog" class="btn btn-warning"><i class="fa fa-times"></i> <?php lang("clear log"); ?></a>
</div>
<table id="logtable" class="table table-bordered table-striped">
<thead>
<tr>
<th data-priority="0"></th>
<th data-priority="1"><i class="fa fa-fw fa-calendar"></i> <?php lang('logtime'); ?></th>
<th data-priority="1"><i class="fa fa-fw fa-server"></i> <?php lang('logtype'); ?></th>
<th data-priority="2"><i class="fa fa-fw fa-id-badge"></i> <?php lang('username'); ?></th>
<th data-priority="3"><i class="fa fa-fw fa-globe"></i> <?php lang('ip address'); ?></th>
<th data-priority="3"><i class="fa fa-fw fa-info-circle"></i> <?php lang('other data'); ?></th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th data-priority="0"></th>
<th data-priority="1"><i class="fa fa-fw fa-calendar"></i> <?php lang('logtime'); ?></th>
<th data-priority="1"><i class="fa fa-fw fa-server"></i> <?php lang('logtype'); ?></th>
<th data-priority="2"><i class="fa fa-fw fa-id-badge"></i> <?php lang('username'); ?></th>
<th data-priority="3"><i class="fa fa-fw fa-globe"></i> <?php lang('ip address'); ?></th>
<th data-priority="3"><i class="fa fa-fw fa-info-circle"></i> <?php lang('other data'); ?></th>
</tfoot>
</table>
<br />
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 col-sm-offset-3 col-md-offset-4">
<div class="panel panel-blue">
<div class="panel-heading">
<h3 class="panel-title">
<?php lang('event type reference'); ?>
</h3>
</div>
<div class="panel-body">
<div class="list-group">
<?php
$types = $database->select('logtypes', 'typename');
foreach ($types as $type) {
?>
<div class="list-group-item">
<?php echo $type; ?>
</div>
<?php
}
?>
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,26 @@
<?php
require_once __DIR__ . "/../required.php";
redirectifnotloggedin();
?>
<div class="row">
<div class="col-xs-12 col-sm-6 col-sm-offset-3">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">
<?php lang("clear log") ?>
</h3>
</div>
<div class="panel-body">
<div style="text-align: center;">
<p><i class="fa fa-exclamation-triangle fa-5x"></i></p>
<h4><?php lang("really clear log") ?></h4>
</div>
</div>
<div class="panel-footer">
<a href="action.php?action=clearlog&source=authlog" class="btn btn-danger"><i class="fa fa-times"></i> <?php lang('delete'); ?></a>
<a href="app.php?page=authlog" class="btn btn-primary pull-right"><i class="fa fa-arrow-left"></i> <?php lang('cancel'); ?></a>
</div>
</div>
</div>
</div>

@ -0,0 +1,60 @@
<?php
if (!is_empty($VARS['id'])) {
if ($database->has('accounts', ['uid' => $VARS['id']])) {
$userdata = $database->select('accounts', ['[>]accttypes' => ['accttype' => 'typeid']], [
'uid',
'username',
'realname',
'email'
], [
'uid' => $VARS['id']
])[0];
} else {
// user id is invalid
header('Location: app.php?page=users&msg=user_not_exists');
die();
}
} else {
// user id is invalid
header('Location: app.php?page=users&msg=user_not_exists');
die();
}
?>
<div class="row">
<div class="col-xs-12 col-sm-6 col-sm-offset-3">
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">
<?php lang("delete user") ?>
</h3>
</div>
<div class="panel-body">
<div style="text-align: center;">
<p><i class="fa fa-exclamation-triangle fa-5x"></i></p>
<h4><?php lang("really delete user") ?></h4>
</div>
<div class="list-group">
<div class="list-group-item">
<i class="fa fa-fw fa-user"></i> <?php echo $userdata['realname']; ?>
</div>
<div class="list-group-item">
<i class="fa fa-fw fa-id-badge"></i> <?php echo $userdata['username']; ?>
</div>
<?php
if (!is_empty($userdata['email'])) {
?>
<div class="list-group-item">
<i class="fa fa-fw fa-envelope"></i> <?php echo $userdata['email']; ?>
</div>
<?php
}
?>
</div>
</div>
<div class="panel-footer">
<a href="action.php?action=deleteuser&source=users&id=<?php echo htmlspecialchars($VARS['id']); ?>" class="btn btn-danger"><i class="fa fa-times"></i> <?php lang('delete'); ?></a>
<a href="app.php?page=users" class="btn btn-primary pull-right"><i class="fa fa-arrow-left"></i> <?php lang('cancel'); ?></a>
</div>
</div>
</div>
</div>

@ -127,7 +127,7 @@ if ($userdata['typecode'] != "LOCAL") {
<?php
if ($editing) {
?>
<a href="action.php?action=deleteuser&source=users&userid=<?php echo htmlspecialchars($VARS['id']); ?>" style="margin-top: 8px;" class="btn btn-danger btn-xs pull-right"><i class="fa fa-times"></i> <?php lang('delete'); ?></a>
<a href="app.php?page=deluser&id=<?php echo htmlspecialchars($VARS['id']); ?>" style="margin-top: 8px;" class="btn btn-danger btn-xs pull-right"><i class="fa fa-times"></i> <?php lang('delete'); ?></a>
<?php
}
?>

@ -130,7 +130,11 @@ function lang2($key, $replace, $echo = true) {
function dieifnotloggedin() {
if ($_SESSION['loggedin'] != true) {
sendError("Session expired. Please log out and log in again.");
die("You don't have permission to be here.");
}
require_once __DIR__ . "/lib/login.php";
if (account_has_permission($_SESSION['username'], "ADMIN") == FALSE) {
die("You don't have permission to be here.");
}
}

@ -0,0 +1,45 @@
$('#logtable').DataTable({
responsive: {
details: {
display: $.fn.dataTable.Responsive.display.modal({
header: function (row) {
var data = row.data();
return "<i class=\"fa fa-list fa-fw\"></i> " + data[1];
}
}),
renderer: $.fn.dataTable.Responsive.renderer.tableAll({
tableClass: 'table'
}),
type: "column"
}
},
columnDefs: [
{
targets: 0,
className: 'control',
orderable: false
}
],
order: [
[1, 'desc']
],
serverSide: true,
ajax: {
url: "lib/getlogtable.php",
dataFilter: function (data) {
var json = jQuery.parseJSON(data);
json.data = [];
json.log.forEach(function (row) {
json.data.push([
"",
row.logtime,
row.typename,
(row.username == null ? "---" : row.username),
row.ip,
row.otherdata
]);
});
return JSON.stringify(json);
}
}
});
Loading…
Cancel
Save