mirror of
https://github.com/LibreQoE/LibreQoS.git
synced 2025-02-25 18:55:32 -06:00
feat: implement user management with CRUD operations and UI integration
This commit is contained in:
parent
512a1940fa
commit
78ce738841
@ -1 +1,120 @@
|
||||
// Placeholder for user management configuration
|
||||
$(document).ready(() => {
|
||||
loadUsers();
|
||||
|
||||
// Handle add user form submission
|
||||
$('#add-user-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
const username = $('#username').val();
|
||||
const password = $('#password').val();
|
||||
const role = $('#role').val();
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/local-api/addUser",
|
||||
data: JSON.stringify({
|
||||
username: username,
|
||||
password: password,
|
||||
role: role
|
||||
}),
|
||||
contentType: 'application/json',
|
||||
success: () => {
|
||||
$('#username').val('');
|
||||
$('#password').val('');
|
||||
loadUsers();
|
||||
},
|
||||
error: () => {
|
||||
alert('Failed to add user');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Handle edit user form submission
|
||||
$('#save-user-changes').on('click', function() {
|
||||
const username = $('#edit-username').val();
|
||||
const password = $('#edit-password').val();
|
||||
const role = $('#edit-role').val();
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/local-api/updateUser",
|
||||
data: JSON.stringify({
|
||||
username: username,
|
||||
password: password,
|
||||
role: role
|
||||
}),
|
||||
contentType: 'application/json',
|
||||
success: () => {
|
||||
$('#editUserModal').modal('hide');
|
||||
loadUsers();
|
||||
},
|
||||
error: () => {
|
||||
alert('Failed to update user');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function loadUsers() {
|
||||
$.get('/local-api/getUsers', (users) => {
|
||||
const userList = $('#users-list');
|
||||
userList.empty();
|
||||
|
||||
if (users.length === 0) {
|
||||
userList.html('<div class="alert alert-info">No users found</div>');
|
||||
return;
|
||||
}
|
||||
|
||||
const table = $('<table class="table table-striped">')
|
||||
.append('<thead><tr><th>Username</th><th>Role</th><th>Actions</th></tr></thead>');
|
||||
const tbody = $('<tbody>');
|
||||
|
||||
users.forEach(user => {
|
||||
const row = $('<tr>')
|
||||
.append(`<td>${user.username}</td>`)
|
||||
.append(`<td>${user.role}</td>`)
|
||||
.append(`<td>
|
||||
<button class="btn btn-sm btn-primary edit-user" data-username="${user.username}">
|
||||
<i class="fa fa-edit"></i> Edit
|
||||
</button>
|
||||
<button class="btn btn-sm btn-danger delete-user" data-username="${user.username}">
|
||||
<i class="fa fa-trash"></i> Delete
|
||||
</button>
|
||||
</td>`);
|
||||
|
||||
tbody.append(row);
|
||||
});
|
||||
|
||||
table.append(tbody);
|
||||
userList.append(table);
|
||||
|
||||
// Attach edit handlers
|
||||
$('.edit-user').on('click', function() {
|
||||
const username = $(this).data('username');
|
||||
const user = users.find(u => u.username === username);
|
||||
$('#edit-username').val(user.username);
|
||||
$('#edit-role').val(user.role);
|
||||
$('#editUserModal').modal('show');
|
||||
});
|
||||
|
||||
// Attach delete handlers
|
||||
$('.delete-user').on('click', function() {
|
||||
if (confirm('Are you sure you want to delete this user?')) {
|
||||
const username = $(this).data('username');
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/local-api/deleteUser",
|
||||
data: JSON.stringify({ username: username }),
|
||||
contentType: 'application/json',
|
||||
success: () => {
|
||||
loadUsers();
|
||||
},
|
||||
error: () => {
|
||||
alert('Failed to delete user');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}).fail(() => {
|
||||
$('#users-list').html('<div class="alert alert-danger">Failed to load users</div>');
|
||||
});
|
||||
}
|
||||
|
@ -47,6 +47,9 @@ pub fn local_api() -> Router {
|
||||
.route("/updateConfig", post(config::update_lqosd_config))
|
||||
.route("/updateNetworkAndDevices", post(config::update_network_and_devices))
|
||||
.route("/getUsers", get(config::get_users))
|
||||
.route("/addUser", post(config::add_user))
|
||||
.route("/updateUser", post(config::update_user))
|
||||
.route("/deleteUser", post(config::delete_user))
|
||||
.route("/circuitById", post(circuit::get_circuit_by_id))
|
||||
.route("/requestAnalysis/:ip", get(packet_analysis::request_analysis))
|
||||
.route("/pcapDump/:id", get(packet_analysis::pcap_dump))
|
||||
@ -67,4 +70,4 @@ pub fn local_api() -> Router {
|
||||
.route("/ltsCake/:seconds", get(lts::cake_period))
|
||||
.layer(CorsLayer::very_permissive())
|
||||
.route_layer(axum::middleware::from_fn(auth_layer))
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,11 @@ use axum::http::StatusCode;
|
||||
use lqos_config::{Config, ConfigShapedDevices, ShapedDevice, WebUser};
|
||||
use crate::node_manager::auth::LoginResult;
|
||||
use default_net::get_interfaces;
|
||||
use serde::Deserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use lqos_bus::{bus_request, BusRequest};
|
||||
use crate::shaped_devices_tracker::SHAPED_DEVICES;
|
||||
use lqos_config::authentication::{WebUser, WebUsers};
|
||||
|
||||
pub async fn admin_check(
|
||||
Extension(login): Extension<LoginResult>
|
||||
@ -119,13 +120,62 @@ pub async fn update_network_and_devices(
|
||||
"Ok".to_string()
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct UserRequest {
|
||||
username: String,
|
||||
password: String,
|
||||
role: String,
|
||||
}
|
||||
|
||||
pub async fn get_users(
|
||||
Extension(login): Extension<LoginResult>,
|
||||
) -> Result<Json<Vec<WebUser>>, StatusCode> {
|
||||
if login != LoginResult::Admin {
|
||||
return Err(StatusCode::FORBIDDEN);
|
||||
}
|
||||
let users = lqos_config::WebUsers::load_or_create()
|
||||
let users = WebUsers::load_or_create()
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
Ok(Json(users.get_users()))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn add_user(
|
||||
Extension(login): Extension<LoginResult>,
|
||||
Json(data): Json<UserRequest>,
|
||||
) -> Result<String, StatusCode> {
|
||||
if login != LoginResult::Admin {
|
||||
return Err(StatusCode::FORBIDDEN);
|
||||
}
|
||||
let mut users = WebUsers::load_or_create()
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
users.add_or_update_user(&data.username, &data.password, data.role.into())
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
Ok("User added".to_string())
|
||||
}
|
||||
|
||||
pub async fn update_user(
|
||||
Extension(login): Extension<LoginResult>,
|
||||
Json(data): Json<UserRequest>,
|
||||
) -> Result<String, StatusCode> {
|
||||
if login != LoginResult::Admin {
|
||||
return Err(StatusCode::FORBIDDEN);
|
||||
}
|
||||
let mut users = WebUsers::load_or_create()
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
users.add_or_update_user(&data.username, &data.password, data.role.into())
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
Ok("User updated".to_string())
|
||||
}
|
||||
|
||||
pub async fn delete_user(
|
||||
Extension(login): Extension<LoginResult>,
|
||||
Json(data): Json<UserRequest>,
|
||||
) -> Result<String, StatusCode> {
|
||||
if login != LoginResult::Admin {
|
||||
return Err(StatusCode::FORBIDDEN);
|
||||
}
|
||||
let mut users = WebUsers::load_or_create()
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
users.remove_user(&data.username)
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
Ok("User deleted".to_string())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user