126 lines
5.2 KiB
PHP
126 lines
5.2 KiB
PHP
<?php
|
|
// Admin: list / add / edit / ban / delete users, reset passwords.
|
|
require_once __DIR__ . '/../lib/bootstrap.php';
|
|
$me = require_admin();
|
|
$d = db();
|
|
|
|
$msg = ''; $err = '';
|
|
$edit = (int)($_GET['edit'] ?? 0);
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
require_csrf();
|
|
$act = $_POST['act'] ?? '';
|
|
$uid = (int)($_POST['uid'] ?? 0);
|
|
|
|
if ($act === 'add') {
|
|
$n = trim((string)($_POST['username'] ?? ''));
|
|
$p = (string)($_POST['pass'] ?? '');
|
|
$a = (int)($_POST['is_admin'] ?? 0);
|
|
if (!valid_username($n)) $err = 'Bad username (3-16 alnum/underscore).';
|
|
elseif (strlen($p) < 4) $err = 'Password too short.';
|
|
elseif (username_taken($n)) $err = 'Username taken.';
|
|
else { user_create($n, $p, $a); $msg = 'User ' . $n . ' created.'; }
|
|
|
|
} elseif ($act === 'save' && $uid) {
|
|
$u = user_by_id($uid);
|
|
if (!$u) $err = 'No such user.';
|
|
else {
|
|
$tag = mb_substr(trim((string)($_POST['tagline'] ?? '')), 0, 80);
|
|
$loc = mb_substr(trim((string)($_POST['location'] ?? '')), 0, 40);
|
|
$adm = (int)($_POST['is_admin'] ?? 0);
|
|
$ban = (int)($_POST['is_banned'] ?? 0);
|
|
// never let an admin strip their own last-admin rights into a lockout
|
|
if ($uid === (int)$me['id'] && !$adm) {
|
|
$err = 'You cannot remove your own admin rights.';
|
|
} else {
|
|
$d->prepare("UPDATE users SET tagline=?,location=?,is_admin=?,is_banned=? WHERE id=?")
|
|
->execute([$tag, $loc, $adm, $ban, $uid]);
|
|
$msg = 'Saved ' . $u['username'] . '.';
|
|
$newpw = (string)($_POST['newpass'] ?? '');
|
|
if ($newpw !== '') {
|
|
if (strlen($newpw) < 4) $err = 'New password too short - not changed.';
|
|
else {
|
|
$d->prepare("UPDATE users SET pass_hash=? WHERE id=?")
|
|
->execute([password_hash($newpw, PASSWORD_DEFAULT), $uid]);
|
|
$msg .= ' Password reset.';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} elseif ($act === 'del' && $uid) {
|
|
if ($uid === (int)$me['id']) $err = 'You cannot delete yourself.';
|
|
else {
|
|
$u = user_by_id($uid);
|
|
$d->prepare("DELETE FROM users WHERE id=?")->execute([$uid]);
|
|
$msg = 'Deleted ' . ($u['username'] ?? '#' . $uid) . '.';
|
|
$edit = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
page_start('Admin: users', ['back' => '/admin/index.php']);
|
|
if ($err) p_err($err);
|
|
if ($msg) p_ok($msg);
|
|
|
|
// ---------- edit one user ----------
|
|
if ($edit && ($u = user_by_id($edit))) {
|
|
p_para('Editing: ' . $u['username'] . ' (#' . $u['id'] . ')');
|
|
p_form('/admin/users.php?edit=' . $edit, [
|
|
['name' => 'act', 'type' => 'hidden', 'value' => 'save'],
|
|
['name' => 'uid', 'type' => 'hidden', 'value' => (string)$u['id']],
|
|
['name' => 'tagline', 'label' => 'Tagline', 'value' => $u['tagline'], 'maxlength' => 80],
|
|
['name' => 'location', 'label' => 'Location', 'value' => $u['location'], 'maxlength' => 40],
|
|
['name' => 'is_admin', 'label' => 'Admin', 'type' => 'select',
|
|
'value' => (string)$u['is_admin'], 'options' => ['0' => 'no', '1' => 'yes']],
|
|
['name' => 'is_banned', 'label' => 'Banned', 'type' => 'select',
|
|
'value' => (string)$u['is_banned'], 'options' => ['0' => 'no', '1' => 'yes']],
|
|
['name' => 'newpass', 'label' => 'Reset password (blank=keep)', 'type' => 'password'],
|
|
], 'Save user');
|
|
p_form('/admin/users.php', [
|
|
['name' => 'act', 'type' => 'hidden', 'value' => 'del'],
|
|
['name' => 'uid', 'type' => 'hidden', 'value' => (string)$u['id']],
|
|
], 'DELETE user');
|
|
p_links([['/admin/users.php', 'Back to user list']]);
|
|
page_end();
|
|
exit;
|
|
}
|
|
|
|
// ---------- list ----------
|
|
$q = trim((string)($_POST['q'] ?? $_GET['q'] ?? ''));
|
|
$page = max(1, (int)($_GET['p'] ?? 1));
|
|
$off = ($page - 1) * PER_PAGE;
|
|
if ($q !== '') {
|
|
$s = $d->prepare("SELECT * FROM users WHERE username LIKE ? ORDER BY id LIMIT ? OFFSET ?");
|
|
$s->execute(['%' . $q . '%', PER_PAGE + 1, $off]);
|
|
} else {
|
|
$s = $d->prepare("SELECT * FROM users ORDER BY id LIMIT ? OFFSET ?");
|
|
$s->execute([PER_PAGE + 1, $off]);
|
|
}
|
|
$rows = $s->fetchAll();
|
|
$more = count($rows) > PER_PAGE;
|
|
if ($more) array_pop($rows);
|
|
|
|
foreach ($rows as $r) {
|
|
$tags = ($r['is_admin'] ? ' [admin]' : '') . ($r['is_banned'] ? ' [BANNED]' : '');
|
|
p_link('/admin/users.php', '#' . $r['id'] . ' ' . $r['username'] . $tags,
|
|
['edit' => $r['id']]);
|
|
}
|
|
if (!$rows) p_para('No users found.');
|
|
p_pager('/admin/users.php', $page, $more, $q !== '' ? ['q' => $q] : []);
|
|
|
|
p_rule();
|
|
p_form('/admin/users.php', [
|
|
['name' => 'q', 'label' => 'Search username', 'value' => $q, 'maxlength' => 16],
|
|
], 'Search');
|
|
p_rule();
|
|
p_para('Add a user:');
|
|
p_form('/admin/users.php', [
|
|
['name' => 'act', 'type' => 'hidden', 'value' => 'add'],
|
|
['name' => 'username', 'label' => 'Username', 'maxlength' => 16],
|
|
['name' => 'pass', 'label' => 'Password', 'type' => 'password'],
|
|
['name' => 'is_admin', 'label' => 'Admin', 'type' => 'select',
|
|
'options' => ['0' => 'no', '1' => 'yes']],
|
|
], 'Add user');
|
|
p_links([['/admin/index.php', 'Admin home']]);
|
|
page_end();
|