2026-02-26 08:31:48 -05:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
2026-02-26 10:08:41 -05:00
|
|
|
use axum::extract::Path;
|
|
|
|
|
use axum::response::IntoResponse;
|
2026-02-26 08:31:48 -05:00
|
|
|
use axum::{Json, extract::Query, http::StatusCode};
|
|
|
|
|
use chrono::{DateTime, Utc};
|
2026-02-26 10:08:41 -05:00
|
|
|
use log::{debug, error};
|
|
|
|
|
use serde::Deserialize;
|
2026-02-26 08:31:48 -05:00
|
|
|
|
|
|
|
|
use crate::{db, model::devices::Device};
|
|
|
|
|
|
|
|
|
|
use crate::web_server::utils;
|
|
|
|
|
|
2026-02-26 10:08:41 -05:00
|
|
|
pub async fn list(
|
2026-02-26 08:31:48 -05:00
|
|
|
Query(params): Query<HashMap<String, String>>,
|
|
|
|
|
) -> Result<Json<Vec<Device>>, StatusCode> {
|
|
|
|
|
let is_registered: Option<bool> = utils::parse_parameter_bool(¶ms, "is_registered");
|
|
|
|
|
let last_seen_from: Option<DateTime<Utc>> =
|
|
|
|
|
utils::parse_parameter_date(¶ms, "last_seen_from");
|
|
|
|
|
let last_seen_to: Option<DateTime<Utc>> = utils::parse_parameter_date(¶ms, "last_seen_to");
|
|
|
|
|
let owner: Option<String> = utils::parse_parameter_string(¶ms, "owner");
|
|
|
|
|
let device_type: Option<String> = utils::parse_parameter_string(¶ms, "device_type");
|
|
|
|
|
let vendor: Option<String> = utils::parse_parameter_string(¶ms, "vendor");
|
|
|
|
|
|
|
|
|
|
match db::devices::list_devices(
|
|
|
|
|
is_registered,
|
|
|
|
|
last_seen_from,
|
|
|
|
|
last_seen_to,
|
|
|
|
|
owner,
|
|
|
|
|
device_type,
|
|
|
|
|
vendor,
|
|
|
|
|
) {
|
|
|
|
|
Ok(value) => Ok(Json(value)),
|
|
|
|
|
Err(err) => {
|
|
|
|
|
error!("Error listing devices: {}", err);
|
|
|
|
|
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-02-26 10:08:41 -05:00
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
}
|