From 8e24cd7208ca8addaee1fc31ca75ff5512c1fe80 Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Sat, 27 May 2017 19:32:12 -0600 Subject: [PATCH] Add user adding/removing/editing and security log viewing/clearing. --- action.php | 23 ++++++++++-- lang/en_us.php | 16 ++++++++- lang/messages.php | 12 +++++++ lib/authlog.php | 29 +++++++++++++++ lib/getlogtable.php | 86 ++++++++++++++++++++++++++++++++++++++++++++ pages.php | 21 +++++++++++ pages/authlog.php | 58 ++++++++++++++++++++++++++++++ pages/clearlog.php | 26 ++++++++++++++ pages/deluser.php | 60 +++++++++++++++++++++++++++++++ pages/edituser.php | 2 +- required.php | 6 +++- static/js/authlog.js | 45 +++++++++++++++++++++++ 12 files changed, 378 insertions(+), 6 deletions(-) create mode 100644 lib/authlog.php create mode 100644 lib/getlogtable.php create mode 100644 pages/authlog.php create mode 100644 pages/clearlog.php create mode 100644 pages/deluser.php create mode 100644 static/js/authlog.js diff --git a/action.php b/action.php index af6ea0f..c2e5c84 100644 --- a/action.php +++ b/action.php @@ -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'); diff --git a/lang/en_us.php b/lang/en_us.php index bd43efd..b270412 100644 --- a/lang/en_us.php +++ b/lang/en_us.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", ]); \ No newline at end of file diff --git a/lang/messages.php b/lang/messages.php index 5602842..a064b8c 100644 --- a/lang/messages.php +++ b/lang/messages.php @@ -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" ] ]); diff --git a/lib/authlog.php b/lib/authlog.php new file mode 100644 index 0000000..597100e --- /dev/null +++ b/lib/authlog.php @@ -0,0 +1,29 @@ +insert("authlog", ['logtime' => date("Y-m-d H:i:s"), 'logtype' => $type, 'uid' => $uid, 'ip' => $ip, 'otherdata' => $data]); +} \ No newline at end of file diff --git a/lib/getlogtable.php b/lib/getlogtable.php new file mode 100644 index 0000000..3aef495 --- /dev/null +++ b/lib/getlogtable.php @@ -0,0 +1,86 @@ +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); diff --git a/pages.php b/pages.php index cc0aaba..6547af2 100644 --- a/pages.php +++ b/pages.php @@ -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" ] diff --git a/pages/authlog.php b/pages/authlog.php new file mode 100644 index 0000000..699ab53 --- /dev/null +++ b/pages/authlog.php @@ -0,0 +1,58 @@ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+

+ +

+
+
+
+ select('logtypes', 'typename'); + foreach ($types as $type) { + ?> +
+ +
+ +
+
+
+
+
\ No newline at end of file diff --git a/pages/clearlog.php b/pages/clearlog.php new file mode 100644 index 0000000..85ac254 --- /dev/null +++ b/pages/clearlog.php @@ -0,0 +1,26 @@ + +
+
+
+
+

+ +

+
+
+
+

+

+
+
+ +
+
+
\ No newline at end of file diff --git a/pages/deluser.php b/pages/deluser.php new file mode 100644 index 0000000..acb7ed7 --- /dev/null +++ b/pages/deluser.php @@ -0,0 +1,60 @@ +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(); +} +?> +
+
+
+
+

+ +

+
+
+
+

+

+
+
+
+ +
+
+ +
+ +
+ +
+ +
+
+ +
+
+
\ No newline at end of file diff --git a/pages/edituser.php b/pages/edituser.php index 4c9d143..ac37f47 100644 --- a/pages/edituser.php +++ b/pages/edituser.php @@ -127,7 +127,7 @@ if ($userdata['typecode'] != "LOCAL") { - + diff --git a/required.php b/required.php index bfaf63b..50675bb 100644 --- a/required.php +++ b/required.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."); } } diff --git a/static/js/authlog.js b/static/js/authlog.js new file mode 100644 index 0000000..a9f7c99 --- /dev/null +++ b/static/js/authlog.js @@ -0,0 +1,45 @@ +$('#logtable').DataTable({ + responsive: { + details: { + display: $.fn.dataTable.Responsive.display.modal({ + header: function (row) { + var data = row.data(); + return " " + 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); + } + } +}); \ No newline at end of file