Files
bookmarkly2/user_settings.php

257 lines
12 KiB
PHP

<?php
$page_title = 'Manage Users - Bookmarkly';
// Add user-settings-page class to body for CSS targeting
$GLOBALS['body_class'] = 'user-settings-page';
require_once 'include/auth.php';
// --- Security Check: Only Admin can access this page ---
if (!isAdmin()) {
header('Location: index.php');
exit;
}
// Flash messages for feedback
$message = '';
$message_type = '';
if (isset($_SESSION['flash_message'])) {
$message = $_SESSION['flash_message']['text'];
$message_type = $_SESSION['flash_message']['type'];
unset($_SESSION['flash_message']);
}
// Handle POST requests for adding/deleting users
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
if ($action === 'add_user') {
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
$role = $_POST['role'] ?? 'user';
if (!empty($username) && !empty($password) && in_array($role, ['user', 'viewer', 'admin'])) {
// Check if username already exists
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
$stmt->execute([$username]);
if ($stmt->fetch()) {
$_SESSION['flash_message'] = ['text' => 'Username already exists.', 'type' => 'warning'];
} else {
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?)");
if ($stmt->execute([$username, $hashed_password, $role])) {
$_SESSION['flash_message'] = ['text' => 'User added successfully.', 'type' => 'success'];
} else {
$_SESSION['flash_message'] = ['text' => 'Error adding user.', 'type' => 'danger'];
}
}
} else {
$_SESSION['flash_message'] = ['text' => 'Username, password, and a valid role are required.', 'type' => 'warning'];
}
} elseif ($action === 'edit_user') {
$user_id = filter_input(INPUT_POST, 'user_id', FILTER_VALIDATE_INT);
$username = trim($_POST['username'] ?? '');
$role = $_POST['role'] ?? 'user';
$password = $_POST['password'] ?? ''; // Optional: for changing password
if ($user_id && !empty($username) && in_array($role, ['user', 'viewer', 'admin'])) {
// Check if new username already exists (and is not the current user)
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ? AND id != ?");
$stmt->execute([$username, $user_id]);
if ($stmt->fetch()) {
$_SESSION['flash_message'] = ['text' => 'Username already exists.', 'type' => 'warning'];
} else {
if (!empty($password)) {
// If password is provided, update it
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare("UPDATE users SET username = ?, role = ?, password = ? WHERE id = ?");
$stmt->execute([$username, $role, $hashed_password, $user_id]);
} else {
// Otherwise, update without changing password
$stmt = $pdo->prepare("UPDATE users SET username = ?, role = ? WHERE id = ?");
$stmt->execute([$username, $role, $user_id]);
}
$_SESSION['flash_message'] = ['text' => 'User updated successfully.', 'type' => 'success'];
}
} else {
$_SESSION['flash_message'] = ['text' => 'Invalid data for updating user.', 'type' => 'warning'];
}
} elseif ($action === 'delete_user') {
$user_id = filter_input(INPUT_POST, 'user_id', FILTER_VALIDATE_INT);
if ($user_id && $user_id != 1) { // Prevent admin from deleting themselves
$stmt = $pdo->prepare("DELETE FROM users WHERE id = ?");
if ($stmt->execute([$user_id])) {
$_SESSION['flash_message'] = ['text' => 'User deleted successfully.', 'type' => 'success'];
} else {
$_SESSION['flash_message'] = ['text' => 'Error deleting user.', 'type' => 'danger'];
}
} else {
$_SESSION['flash_message'] = ['text' => 'Invalid user or action not allowed.', 'type' => 'danger'];
}
}
header('Location: user_settings.php');
exit;
}
// Fetch all users for display
$users_stmt = $pdo->query("SELECT id, username, role FROM users ORDER BY username");
$users = $users_stmt->fetchAll();
require_once 'include/header.php';
?>
<div class="container mt-4">
<h1>Manage Users</h1>
<?php if ($message): ?>
<div class="alert alert-<?php echo $message_type; ?> alert-dismissible fade show" role="alert">
<?php echo htmlspecialchars($message); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<!-- Add User Form -->
<div class="card mb-4">
<div class="card-header">Add New User</div>
<div class="card-body">
<form action="user_settings.php" method="POST">
<input type="hidden" name="action" value="add_user">
<div class="row">
<div class="col-md-4 mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="col-md-4 mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<div class="col-md-2 mb-3">
<label for="role" class="form-label">Role</label>
<select class="form-select" id="role" name="role">
<option value="user" selected>User</option>
<option value="viewer">Viewer</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="col-md-2 d-flex align-items-end mb-3">
<button type="submit" class="btn btn-primary w-100">Add User</button>
</div>
</div>
</form>
</div>
</div>
<!-- User List -->
<div class="card">
<div class="card-header">Existing Users</div>
<div class="card-body">
<ul class="list-group">
<?php foreach ($users as $user): ?>
<li class="list-group-item d-flex justify-content-between align-items-center">
<div>
<span class="fw-bold"><?php echo htmlspecialchars($user['username']); ?></span>
<span class="badge bg-secondary ms-2"><?php echo htmlspecialchars($user['role']); ?></span>
</div>
<?php if ($user['id'] != 1): // Don't show delete for admin user ?>
<div>
<button class="btn btn-sm btn-outline-secondary me-2" data-bs-toggle="modal" data-bs-target="#editUserModal" data-user-id="<?php echo $user['id']; ?>" data-username="<?php echo htmlspecialchars($user['username']); ?>" data-role="<?php echo $user['role']; ?>">
Edit
</button>
<form action="user_settings.php" method="POST" class="d-inline" onsubmit="return confirm('Are you sure you want to delete this user?');">
<input type="hidden" name="action" value="delete_user">
<input type="hidden" name="user_id" value="<?php echo $user['id']; ?>">
<button type="submit" class="btn btn-sm btn-outline-danger">Delete</button>
</form>
</div>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</div>
</div>
<!-- Role Descriptions -->
<div class="card mt-4">
<div class="card-header"><?php echo translate('user_settings_roles_title'); ?></div>
<div class="card-body">
<dl class="row">
<dt class="col-sm-2"><?php echo translate('user_settings_role_admin'); ?></dt>
<dd class="col-sm-10"><?php echo translate('user_settings_role_admin_desc'); ?></dd>
<dt class="col-sm-2"><?php echo translate('user_settings_role_user'); ?></dt>
<dd class="col-sm-10"><?php echo translate('user_settings_role_user_desc'); ?></dd>
<dt class="col-sm-2"><?php echo translate('user_settings_role_viewer'); ?></dt>
<dd class="col-sm-10"><?php echo translate('user_settings_role_viewer_desc'); ?></dd>
</dl>
</div>
</div>
</div>
<!-- Edit User Modal -->
<div class="modal fade" id="editUserModal" tabindex="-1" aria-labelledby="editUserModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editUserModalLabel">Edit User</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form action="user_settings.php" method="POST">
<div class="modal-body">
<input type="hidden" name="action" value="edit_user">
<input type="hidden" id="edit-user-id" name="user_id">
<div class="mb-3">
<label for="edit-username" class="form-label">Username</label>
<input type="text" class="form-control" id="edit-username" name="username" required>
</div>
<div class="mb-3">
<label for="edit-role" class="form-label">Role</label>
<select class="form-select" id="edit-role" name="role">
<option value="user">User</option>
<option value="viewer">Viewer</option>
<option value="admin">Admin</option>
</select>
</div>
<div class="mb-3">
<label for="edit-password" class="form-label">New Password (optional)</label>
<input type="password" class="form-control" id="edit-password" name="password">
<div class="form-text">Leave blank to keep the current password.</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var editUserModal = document.getElementById('editUserModal');
editUserModal.addEventListener('show.bs.modal', function (event) {
var button = event.relatedTarget;
var userId = button.getAttribute('data-user-id');
var username = button.getAttribute('data-username');
var role = button.getAttribute('data-role');
var modalTitle = editUserModal.querySelector('.modal-title');
var userIdInput = editUserModal.querySelector('#edit-user-id');
var usernameInput = editUserModal.querySelector('#edit-username');
var roleInput = editUserModal.querySelector('#edit-role');
modalTitle.textContent = 'Edit User: ' + username;
userIdInput.value = userId;
usernameInput.value = username;
roleInput.value = role;
});
});
</script>
<?php require_once 'include/footer.php'; ?>