197 lines
11 KiB
PHP
197 lines
11 KiB
PHP
<?php
|
|
include 'auth.php';
|
|
bg_require_admin();
|
|
$page_title = bg_t('webpanel_users_setup') . ' - BastionGuard WebUI';
|
|
$active_page = 'web_users.php';
|
|
$editing = null;
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
csrf_validate();
|
|
$action = $_POST['action'] ?? '';
|
|
try {
|
|
if ($action === 'create') {
|
|
$username = trim($_POST['username'] ?? '');
|
|
$password = $_POST['password'] ?? '';
|
|
$confirm = $_POST['confirm'] ?? '';
|
|
$role = $_POST['role'] ?? 'user';
|
|
$email = trim($_POST['email'] ?? '');
|
|
if ($password !== $confirm) throw new RuntimeException(bg_t('confirm') . ': password mismatch.');
|
|
bg_create_user($username, $password, $role, $email);
|
|
bg_flash('success', bg_t('user_created'));
|
|
bg_redirect('web_users.php');
|
|
}
|
|
if ($action === 'update') {
|
|
$id = (int)($_POST['id'] ?? 0);
|
|
$username = trim($_POST['username'] ?? '');
|
|
$password = $_POST['password'] ?? '';
|
|
$confirm = $_POST['confirm'] ?? '';
|
|
$role = $_POST['role'] ?? 'user';
|
|
$email = trim($_POST['email'] ?? '');
|
|
if ($password !== '' && $password !== $confirm) throw new RuntimeException(bg_t('confirm') . ': password mismatch.');
|
|
bg_update_user($id, $username, $role, $password, $email);
|
|
if ($username === bg_current_user()) {
|
|
$_SESSION['user'] = $username;
|
|
$_SESSION['role'] = bg_normalize_role($role);
|
|
}
|
|
bg_flash('success', bg_t('user_updated'));
|
|
bg_redirect('web_users.php');
|
|
}
|
|
if ($action === 'delete') {
|
|
bg_delete_user((int)($_POST['id'] ?? 0));
|
|
bg_flash('success', bg_t('user_deleted'));
|
|
bg_redirect('web_users.php');
|
|
}
|
|
} catch (Throwable $e) {
|
|
bg_flash('danger', $e->getMessage());
|
|
bg_redirect('web_users.php');
|
|
}
|
|
}
|
|
|
|
$editId = isset($_GET['edit']) ? (int)$_GET['edit'] : 0;
|
|
if ($editId > 0) $editing = bg_user_by_id($editId);
|
|
$users = bg_users_all();
|
|
$adminCount = 0; $standardCount = 0;
|
|
foreach ($users as $u) { if (($u['role'] ?? 'user') === 'admin') $adminCount++; else $standardCount++; }
|
|
include 'includes/header.php';
|
|
include 'includes/sidebar.php';
|
|
?>
|
|
<div class="page-title web-users-title">
|
|
<div>
|
|
<span class="section-eyebrow"><i class="bi bi-people"></i> <?= bg_e(bg_t('system')) ?></span>
|
|
<h1><?= bg_e(bg_t('webpanel_users_setup')) ?></h1>
|
|
<p><?= bg_e(bg_t('users_setup_desc')) ?></p>
|
|
</div>
|
|
<div class="d-flex gap-2 flex-wrap justify-content-end">
|
|
<span class="badge text-bg-primary"><i class="bi bi-shield-check"></i> <?= bg_e(bg_t('admin')) ?>: <?= (int)$adminCount ?></span>
|
|
<span class="badge text-bg-secondary"><i class="bi bi-person"></i> <?= bg_e(bg_t('standard_user')) ?>: <?= (int)$standardCount ?></span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="web-users-hero card mb-4">
|
|
<div class="card-body d-flex align-items-center justify-content-between gap-3 flex-wrap">
|
|
<div class="d-flex align-items-center gap-3">
|
|
<div class="hero-icon"><i class="bi bi-people"></i></div>
|
|
<div>
|
|
<h5 class="mb-1"><?= bg_e(bg_t('current_user')) ?>: <?= bg_e(bg_current_user()) ?></h5>
|
|
<p class="mb-0 small-muted"><?= bg_e(bg_t(bg_current_user_is_admin() ? 'admin' : 'standard_user')) ?> · <?= bg_e(bg_t(bg_current_user_is_admin() ? 'current_admin_desc' : 'current_standard_desc')) ?></p>
|
|
</div>
|
|
</div>
|
|
<?php if (!$editing): ?>
|
|
<a class="btn btn-outline-primary" href="#user-form"><i class="bi bi-plus-circle"></i> <?= bg_e(bg_t('create_user')) ?></a>
|
|
<?php else: ?>
|
|
<a class="btn btn-outline-secondary" href="web_users.php"><i class="bi bi-x-circle"></i> <?= bg_e(bg_t('cancel')) ?></a>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4 web-users-grid">
|
|
<div class="col-lg-5">
|
|
<div class="card h-100 web-user-form-card" id="user-form">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-start justify-content-between gap-2 mb-3">
|
|
<div>
|
|
<span class="section-eyebrow"><i class="bi bi-key"></i> <?= bg_e($editing ? bg_t('edit_user') : bg_t('new_user')) ?></span>
|
|
<h5 class="mb-1"><?= bg_e($editing ? bg_t('edit_user') : bg_t('new_user')) ?></h5>
|
|
<p class="small-muted mb-0"><?= bg_e(bg_t('admin_required_desc')) ?></p>
|
|
</div>
|
|
<span class="badge <?= $editing ? 'text-bg-warning' : 'text-bg-success' ?>"><?= bg_e($editing ? bg_t('edit_user') : bg_t('create_user')) ?></span>
|
|
</div>
|
|
<form method="post" autocomplete="off" class="web-user-form">
|
|
<?php csrf_field(); ?>
|
|
<input type="hidden" name="action" value="<?= $editing ? 'update' : 'create' ?>">
|
|
<?php if ($editing): ?><input type="hidden" name="id" value="<?= (int)$editing['id'] ?>"><?php endif; ?>
|
|
<div class="mb-3">
|
|
<label class="form-label" for="web_username"><?= bg_e(bg_t('username')) ?></label>
|
|
<input class="form-control" id="web_username" name="username" value="<?= bg_e($editing['username'] ?? '') ?>" required>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label" for="web_email"><?= bg_e(bg_t('email_address')) ?></label>
|
|
<input class="form-control" id="web_email" name="email" type="email" value="<?= bg_e($editing['email'] ?? '') ?>" placeholder="admin@example.com">
|
|
<div class="form-hint"><?= bg_e(bg_t('admin_email_hint')) ?></div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label" for="web_role"><?= bg_e(bg_t('role')) ?></label>
|
|
<?php $r = $editing['role'] ?? 'user'; ?>
|
|
<div class="role-picker">
|
|
<label class="role-card <?= $r === 'admin' ? 'selected' : '' ?>">
|
|
<input type="radio" name="role" value="admin" <?= $r === 'admin' ? 'checked' : '' ?>>
|
|
<span><strong><?= bg_e(bg_t('admin')) ?></strong><small><?= bg_e(bg_language()==='en' ? 'Full access to WebPanel, users and BastionGuard configuration files.' : 'Accesso completo a WebPanel, utenti e file di configurazione BastionGuard.') ?></small></span>
|
|
</label>
|
|
<label class="role-card <?= $r === 'user' ? 'selected' : '' ?>">
|
|
<input type="radio" name="role" value="user" <?= $r === 'user' ? 'checked' : '' ?>>
|
|
<span><strong><?= bg_e(bg_t('standard_user')) ?></strong><small><?= bg_e(bg_language()==='en' ? 'Can use the WebUI but cannot edit BastionGuard configuration files.' : 'Può usare la WebUI ma non può modificare i file di configurazione BastionGuard.') ?></small></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="row g-2">
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="web_password"><?= bg_e($editing ? bg_t('optional_password') : bg_t('password')) ?></label>
|
|
<input class="form-control" id="web_password" name="password" type="password" <?= $editing ? '' : 'required' ?> minlength="8">
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="web_confirm"><?= bg_e(bg_t('confirm')) ?></label>
|
|
<input class="form-control" id="web_confirm" name="confirm" type="password" <?= $editing ? '' : 'required' ?> minlength="8">
|
|
</div>
|
|
</div>
|
|
<div class="d-flex gap-2 mt-3 flex-wrap">
|
|
<button class="btn btn-primary" type="submit"><i class="bi bi-save"></i> <?= bg_e($editing ? bg_t('save_user') : bg_t('create_user')) ?></button>
|
|
<?php if ($editing): ?><a class="btn btn-outline-secondary" href="web_users.php"><?= bg_e(bg_t('cancel')) ?></a><?php endif; ?>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-7">
|
|
<div class="card h-100 web-users-list-card">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between mb-3 gap-2 flex-wrap">
|
|
<div>
|
|
<span class="section-eyebrow"><i class="bi bi-shield-check"></i> <?= bg_e(bg_t('webpanel_users')) ?></span>
|
|
<h5 class="mb-0"><?= bg_e(bg_t('existing_users')) ?></h5>
|
|
</div>
|
|
<span class="badge text-bg-light"><?= count($users) ?> <?= bg_e(bg_t('webpanel_users')) ?></span>
|
|
</div>
|
|
<div class="table-responsive web-users-table-wrap">
|
|
<table class="table align-middle web-users-table">
|
|
<thead><tr><th><?= bg_e(bg_t('username')) ?></th><th><?= bg_e(bg_t('email_address')) ?></th><th><?= bg_e(bg_t('role')) ?></th><th><?= bg_e(bg_t('created_at')) ?></th><th class="text-end"><?= bg_e(bg_t('actions')) ?></th></tr></thead>
|
|
<tbody>
|
|
<?php foreach ($users as $u): ?>
|
|
<tr>
|
|
<td>
|
|
<div class="user-cell">
|
|
<span class="user-avatar"><?= bg_e(strtoupper(substr((string)$u['username'],0,1))) ?></span>
|
|
<div><strong><?= bg_e($u['username']) ?></strong><?php if ($u['username'] === bg_current_user()): ?><span class="badge text-bg-info ms-2"><?= bg_e(bg_t('current_user')) ?></span><?php endif; ?></div>
|
|
</div>
|
|
</td>
|
|
<td class="small-muted"><?= bg_e($u['email'] ?? '') ?></td>
|
|
<td><span class="badge <?= ($u['role'] ?? 'user') === 'admin' ? 'text-bg-primary' : 'text-bg-secondary' ?>"><?= bg_e(bg_t(($u['role'] ?? 'user') === 'admin' ? 'admin' : 'standard_user')) ?></span></td>
|
|
<td class="small-muted"><?= bg_e($u['created_at'] ?? '') ?></td>
|
|
<td class="text-end">
|
|
<div class="d-flex gap-2 justify-content-end flex-wrap">
|
|
<a class="btn btn-sm btn-outline-primary" href="web_users.php?edit=<?= (int)$u['id'] ?>"><i class="bi bi-pencil"></i> <?= bg_e(bg_t('edit_user')) ?></a>
|
|
<?php if ($u['username'] !== bg_current_user()): ?>
|
|
<form method="post" class="d-inline" data-confirm="<?= bg_e(bg_t('delete_user')) ?>?">
|
|
<?php csrf_field(); ?><input type="hidden" name="action" value="delete"><input type="hidden" name="id" value="<?= (int)$u['id'] ?>">
|
|
<button class="btn btn-sm btn-outline-danger" type="submit"><i class="bi bi-trash"></i> <?= bg_e(bg_t('delete')) ?></button>
|
|
</form>
|
|
<?php endif; ?>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
document.querySelectorAll('.role-card input').forEach(function(input){
|
|
input.addEventListener('change', function(){
|
|
document.querySelectorAll('.role-card').forEach(function(card){card.classList.toggle('selected', !!card.querySelector('input:checked'));});
|
|
});
|
|
});
|
|
</script>
|
|
<?php include 'includes/footer.php'; ?>
|