From c50cd81be93289e68666fb9f29eb324df8b41bcf Mon Sep 17 00:00:00 2001 From: rzuasti Date: Thu, 26 Feb 2026 10:08:41 -0500 Subject: [PATCH] Added several endpoints to devices, mostly there! --- backend/src/web_server.rs | 18 +++-- backend/src/web_server/devices.rs | 95 ++++++++++++++++++++++++- backend/src/web_server/notifications.rs | 8 +-- 3 files changed, 107 insertions(+), 14 deletions(-) diff --git a/backend/src/web_server.rs b/backend/src/web_server.rs index 6a875df..7d81fe0 100644 --- a/backend/src/web_server.rs +++ b/backend/src/web_server.rs @@ -1,6 +1,7 @@ use std::error::Error; -use axum::{Router, routing::get}; +use axum::Router; +use axum::routing::{delete, get, put}; use log::{debug, info}; use tower_http::services::ServeDir; @@ -13,16 +14,19 @@ pub async fn serve() -> Result<(), Box> { let static_files = ServeDir::new("./web"); let router = Router::new() - .route("/", get(|| async { "hello" })) - .route("/api/devices", get(devices::list_devices)) - .route("/api/notifications", get(notifications::list_notifications)) .route( - "/api/notifications/{id}", - get(notifications::read_notification), + "/", + get(|| async { "Go to /web for the UI or to /api for the better UI." }), ) + .route("/api/devices", get(devices::list)) + .route("/api/devices", put(devices::register)) + .route("/api/devices/{mac_address}", delete(devices::unregister)) + .route("/api/devices/{mac_address}", get(devices::read)) + .route("/api/notifications", get(notifications::list)) + .route("/api/notifications/{id}", get(notifications::read)) .route( "/api/notifications/{id}/read_without_flagging", - get(notifications::read_notification_without_flagging), + get(notifications::read_without_flagging), ) .nest_service("/web", static_files); info!("Web server starting at http://0.0.0.0:3000"); diff --git a/backend/src/web_server/devices.rs b/backend/src/web_server/devices.rs index 375b407..fe8132a 100644 --- a/backend/src/web_server/devices.rs +++ b/backend/src/web_server/devices.rs @@ -1,14 +1,17 @@ use std::collections::HashMap; +use axum::extract::Path; +use axum::response::IntoResponse; use axum::{Json, extract::Query, http::StatusCode}; use chrono::{DateTime, Utc}; -use log::error; +use log::{debug, error}; +use serde::Deserialize; use crate::{db, model::devices::Device}; use crate::web_server::utils; -pub async fn list_devices( +pub async fn list( Query(params): Query>, ) -> Result>, StatusCode> { let is_registered: Option = utils::parse_parameter_bool(¶ms, "is_registered"); @@ -34,3 +37,91 @@ pub async fn list_devices( } } } + +pub async fn read(Path(mac_address): Path) -> Result, StatusCode> { + match db::devices::read(mac_address) { + Some(value) => Ok(Json(value)), + None => Err(StatusCode::NOT_FOUND), + } +} + +pub async fn register(Json(payload): Json) -> impl IntoResponse { + debug!( + "Device registration received: mac_address={}, owner={}, device_type={}", + payload.mac_address, payload.owner, payload.device_type + ); + + let mut device = match db::devices::read(payload.mac_address) { + Some(value) => value, + None => { + return ( + axum::http::StatusCode::NOT_FOUND, + "Device not found or could not be read", + ); + } + }; + + if device.is_registered { + return ( + axum::http::StatusCode::CONFLICT, + "Device already registered", + ); + } + + device.is_registered = true; + device.owner = payload.owner; + device.device_type = payload.device_type; + + match db::devices::update(device) { + Ok(_) => (axum::http::StatusCode::CREATED, "Device registered"), + Err(err) => { + error!("Error registering device in the database: {}", err); + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + "Error registering device in the server, check your logs", + ) + } + } +} + +pub async fn unregister(Path(mac_address): Path) -> impl IntoResponse { + let mut device = match db::devices::read(mac_address) { + Some(value) => value, + None => { + return ( + axum::http::StatusCode::NOT_FOUND, + "Device not found or could not be read", + ); + } + }; + + if !device.is_registered { + return ( + axum::http::StatusCode::CONFLICT, + "Device not registered, you cannot un-register it again", + ); + } + + device.is_registered = false; + device.owner = "".to_string(); + device.device_type = "".to_string(); + + match db::devices::update(device) { + Ok(_) => (axum::http::StatusCode::OK, "Device un-registered"), + Err(err) => { + error!("Error updating device in the database: {}", err); + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + "Error updating device in the server, check your logs", + ) + } + } +} + +// Payload structs +#[derive(Deserialize)] +pub struct RegisterDevicePayload { + mac_address: String, + owner: String, + device_type: String, +} diff --git a/backend/src/web_server/notifications.rs b/backend/src/web_server/notifications.rs index f29dd2a..f871920 100644 --- a/backend/src/web_server/notifications.rs +++ b/backend/src/web_server/notifications.rs @@ -3,7 +3,7 @@ use log::error; use crate::{db, model::notifications::Notification}; -pub async fn read_notification(Path(id): Path) -> Result, StatusCode> { +pub async fn read(Path(id): Path) -> Result, StatusCode> { match db::notifications::mark_as_old(id) { Ok(_) => {} Err(err) => { @@ -18,16 +18,14 @@ pub async fn read_notification(Path(id): Path) -> Result } } -pub async fn read_notification_without_flagging( - Path(id): Path, -) -> Result, StatusCode> { +pub async fn read_without_flagging(Path(id): Path) -> Result, StatusCode> { match db::notifications::read(id) { Some(value) => Ok(Json(value)), None => Err(StatusCode::NOT_FOUND), } } -pub async fn list_notifications() -> Result>, StatusCode> { +pub async fn list() -> Result>, StatusCode> { match db::notifications::list() { Ok(value) => Ok(Json(value)), Err(err) => {