Added several endpoints to devices, mostly there!

This commit is contained in:
rzuasti
2026-02-26 10:08:41 -05:00
parent 884738196b
commit c50cd81be9
3 changed files with 107 additions and 14 deletions
+11 -7
View File
@@ -1,6 +1,7 @@
use std::error::Error; use std::error::Error;
use axum::{Router, routing::get}; use axum::Router;
use axum::routing::{delete, get, put};
use log::{debug, info}; use log::{debug, info};
use tower_http::services::ServeDir; use tower_http::services::ServeDir;
@@ -13,16 +14,19 @@ pub async fn serve() -> Result<(), Box<dyn Error>> {
let static_files = ServeDir::new("./web"); let static_files = ServeDir::new("./web");
let router = Router::new() let router = Router::new()
.route("/", get(|| async { "hello" }))
.route("/api/devices", get(devices::list_devices))
.route("/api/notifications", get(notifications::list_notifications))
.route( .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( .route(
"/api/notifications/{id}/read_without_flagging", "/api/notifications/{id}/read_without_flagging",
get(notifications::read_notification_without_flagging), get(notifications::read_without_flagging),
) )
.nest_service("/web", static_files); .nest_service("/web", static_files);
info!("Web server starting at http://0.0.0.0:3000"); info!("Web server starting at http://0.0.0.0:3000");
+93 -2
View File
@@ -1,14 +1,17 @@
use std::collections::HashMap; use std::collections::HashMap;
use axum::extract::Path;
use axum::response::IntoResponse;
use axum::{Json, extract::Query, http::StatusCode}; use axum::{Json, extract::Query, http::StatusCode};
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use log::error; use log::{debug, error};
use serde::Deserialize;
use crate::{db, model::devices::Device}; use crate::{db, model::devices::Device};
use crate::web_server::utils; use crate::web_server::utils;
pub async fn list_devices( pub async fn list(
Query(params): Query<HashMap<String, String>>, Query(params): Query<HashMap<String, String>>,
) -> Result<Json<Vec<Device>>, StatusCode> { ) -> Result<Json<Vec<Device>>, StatusCode> {
let is_registered: Option<bool> = utils::parse_parameter_bool(&params, "is_registered"); let is_registered: Option<bool> = utils::parse_parameter_bool(&params, "is_registered");
@@ -34,3 +37,91 @@ pub async fn list_devices(
} }
} }
} }
pub async fn read(Path(mac_address): Path<String>) -> Result<Json<Device>, StatusCode> {
match db::devices::read(mac_address) {
Some(value) => Ok(Json(value)),
None => Err(StatusCode::NOT_FOUND),
}
}
pub async fn register(Json(payload): Json<RegisterDevicePayload>) -> 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<String>) -> 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,
}
+3 -5
View File
@@ -3,7 +3,7 @@ use log::error;
use crate::{db, model::notifications::Notification}; use crate::{db, model::notifications::Notification};
pub async fn read_notification(Path(id): Path<i64>) -> Result<Json<Notification>, StatusCode> { pub async fn read(Path(id): Path<i64>) -> Result<Json<Notification>, StatusCode> {
match db::notifications::mark_as_old(id) { match db::notifications::mark_as_old(id) {
Ok(_) => {} Ok(_) => {}
Err(err) => { Err(err) => {
@@ -18,16 +18,14 @@ pub async fn read_notification(Path(id): Path<i64>) -> Result<Json<Notification>
} }
} }
pub async fn read_notification_without_flagging( pub async fn read_without_flagging(Path(id): Path<i64>) -> Result<Json<Notification>, StatusCode> {
Path(id): Path<i64>,
) -> Result<Json<Notification>, StatusCode> {
match db::notifications::read(id) { match db::notifications::read(id) {
Some(value) => Ok(Json(value)), Some(value) => Ok(Json(value)),
None => Err(StatusCode::NOT_FOUND), None => Err(StatusCode::NOT_FOUND),
} }
} }
pub async fn list_notifications() -> Result<Json<Vec<Notification>>, StatusCode> { pub async fn list() -> Result<Json<Vec<Notification>>, StatusCode> {
match db::notifications::list() { match db::notifications::list() {
Ok(value) => Ok(Json(value)), Ok(value) => Ok(Json(value)),
Err(err) => { Err(err) => {