diff --git a/action.php b/action.php index f4f4851..af6ea0f 100644 --- a/action.php +++ b/action.php @@ -3,11 +3,15 @@ /** * Make things happen when buttons are pressed and forms submitted. */ - require_once __DIR__ . "/required.php"; +require_once __DIR__ . "/lib/login.php"; dieifnotloggedin(); +if (account_has_permission($_SESSION['username'], "ADMIN") == FALSE) { + die("You don't have permission to be here."); +} + /** * Redirects back to the page ID in $_POST/$_GET['source'] with the given message ID. * The message will be displayed by the app. @@ -25,8 +29,49 @@ function returnToSender($msg, $arg = "") { } switch ($VARS['action']) { + case "edituser": + if (is_empty($VARS['id'])) { + $insert = true; + } else { + if ($database->has('accounts', ['uid' => $VARS['id']])) { + $insert = false; + } else { + returnToSender("invalid_userid"); + } + } + 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); + } + + if ($insert) { + $data['phone1'] = ""; + $data['phone2'] = ""; + $data['accttype'] = 1; + $database->insert('accounts', $data); + } else { + $database->update('accounts', $data, ['uid' => $VARS['id']]); + } + + returnToSender("user_saved"); case "signout": session_destroy(); header('Location: index.php'); die("Logged out."); + default: + die("Invalid action"); } \ No newline at end of file diff --git a/api.php b/api.php index 963268c..cec8d4e 100644 --- a/api.php +++ b/api.php @@ -14,7 +14,7 @@ header("Content-Type: application/json"); $username = $VARS['username']; $password = $VARS['password']; -if (user_exists($username) !== true || authenticate_user($username, $password, $errmsg) !== true) { +if (user_exists($username) !== true || authenticate_user($username, $password, $errmsg) !== true || account_has_permission($username, "ADMIN") !== true) { header("HTTP/1.1 403 Unauthorized"); die("\"403 Unauthorized\""); } diff --git a/app.php b/app.php index c4c009b..afc7164 100644 --- a/app.php +++ b/app.php @@ -1,10 +1,7 @@ "Enter the six-digit code from your mobile authenticator app.", "2fa incorrect" => "Authentication code incorrect.", "login incorrect" => "Login incorrect.", + "no admin permission" => "You do not have permission to access this system.", "login server unavailable" => "Login server unavailable. Try again later or contact technical support.", "account locked" => "This account has been disabled. Contact technical support.", "password expired" => "You must change your password before continuing.", @@ -35,5 +36,15 @@ define("STRINGS", [ "total users" => "Total Users", "view users" => "View Users", "normal accounts" => "Normal Accounts", - "locked accounts" => "Locked Accounts" + "locked accounts" => "Locked Accounts", + "editing user" => "Editing {user}", + "invalid userid" => "Invalid user ID.", + "user saved" => "User saved.", + "adding user" => "Adding new user", + "placeholder name" => "John Doe", + "placeholder username" => "jdoe", + "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." ]); \ No newline at end of file diff --git a/lang/messages.php b/lang/messages.php index 8ac0b7a..5602842 100644 --- a/lang/messages.php +++ b/lang/messages.php @@ -12,5 +12,13 @@ define("MESSAGES", [ "404_error" => [ "string" => "page not found", "type" => "info" + ], + "invalid_userid" => [ + "string" => "invalid userid", + "type" => "danger" + ], + "user_saved" => [ + "string" => "user saved", + "type" => "success" ] ]); diff --git a/lib/login.php b/lib/login.php index 88c5313..aeeead2 100644 --- a/lib/login.php +++ b/lib/login.php @@ -157,6 +157,37 @@ function get_account_status($username) { } } +/** + * Check if the given username has the given permission (or admin access) + * @param string $username + * @param string $permcode + * @return boolean TRUE if the user has the permission (or admin access), else FALSE + */ +function account_has_permission($username, $permcode) { + $client = new GuzzleHttp\Client(); + + $response = $client + ->request('POST', PORTAL_API, [ + 'form_params' => [ + 'key' => PORTAL_KEY, + 'action' => "permission", + 'username' => $username, + 'code' => $permcode + ] + ]); + + if ($response->getStatusCode() > 299) { + sendError("Login server error: " . $response->getBody()); + } + + $resp = json_decode($response->getBody(), TRUE); + if ($resp['status'] == "OK") { + return $resp['has_permission']; + } else { + return false; + } +} + //////////////////////////////////////////////////////////////////////////////// // Login handling // //////////////////////////////////////////////////////////////////////////////// diff --git a/pages.php b/pages.php index 350c4df..cc0aaba 100644 --- a/pages.php +++ b/pages.php @@ -20,6 +20,13 @@ define("PAGES", [ "static/js/users.js" ], ], + "edituser" => [ + "title" => "edit user", + "navbar" => false, + "scripts" => [ + "static/js/edituser.js" + ] + ], "404" => [ "title" => "404 error" ] diff --git a/pages/edituser.php b/pages/edituser.php new file mode 100644 index 0000000..4c9d143 --- /dev/null +++ b/pages/edituser.php @@ -0,0 +1,136 @@ + '', + 'username' => '', + 'realname' => '', + 'email' => '', + 'acctstatus' => '', + 'typecode' => 'LOCAL' +]; + +$editing = false; + +if (!is_empty($VARS['id'])) { + if ($database->has('accounts', ['uid' => $VARS['id']])) { + $editing = true; + $userdata = $database->select('accounts', ['[>]accttypes' => ['accttype' => 'typeid']], [ + 'uid', + 'username', + 'realname', + 'email', + 'acctstatus', + 'typecode' + ], [ + 'uid' => $VARS['id'] + ])[0]; + } else { + // user id is invalid, redirect to a page that won't cause an error when pressing Save + header('Location: app.php?page=edituser'); + } +} + +if ($userdata['typecode'] != "LOCAL") { + $localacct = false; +} else { + $localacct = true; +} +?> + +
+
+
+

+ + "" . htmlspecialchars($userdata['realname']) . ""]); ?> + + + +

+
+
+ +
+ +
+ +
+ + " required="required" value="" /> +
+ +
+
+
+ + class="form-control" name="username" id="username" placeholder="" required="required" value="" /> +
+
+
+
+ + " value="" /> +
+
+
+ +
+
+
+ + autocomplete="new-password" class="form-control" name="pass" id="pass" placeholder="" /> +
+
+ +
+
+ + +
+
+
+ +
+ + + + + + +
+
\ No newline at end of file diff --git a/pages/home.php b/pages/home.php index 864df43..8428667 100644 --- a/pages/home.php +++ b/pages/home.php @@ -30,7 +30,7 @@ redirectifnotloggedin();
-

count('accounts', ['OR' => ['acctstatus' => 2, 'acctstatus' => 3]]); ?>

+

count('accounts', ['OR' => ['acctstatus #LOCKED_OR_DISABLED' => 2, 'acctstatus #CHANGE_PASSWORD' => 3]]); ?>