From d3cf93fb6c9b7e0faf9b7907328f0a042009e164 Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Mon, 15 Apr 2024 20:33:32 +0200 Subject: Closes #35. Entry of Ip optional, error on ping request without saved ip --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/error.rs | 8 +++++++- src/routes/device.rs | 27 ++++++++++++++++----------- src/routes/start.rs | 9 +++++++-- src/services/ping.rs | 4 +++- src/storage.rs | 2 +- 7 files changed, 36 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5261edf..4b5d730 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1837,7 +1837,7 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "webol" -version = "0.4.0" +version = "0.4.1" dependencies = [ "axum", "axum-macros", diff --git a/Cargo.toml b/Cargo.toml index 1b7db8e..68ba060 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "webol" -version = "0.4.0" +version = "0.4.1" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/error.rs b/src/error.rs index 2d70592..b8a078b 100644 --- a/src/error.rs +++ b/src/error.rs @@ -46,11 +46,13 @@ pub enum Error { #[from] source: io::Error, }, + + #[error("No ip set for device but ping requested")] + NoIpOnPing, } impl IntoResponse for Error { fn into_response(self) -> Response { - // error!("{}", self.to_string()); let (status, error_message) = match self { Self::Json { source } => { error!("{source}"); @@ -80,6 +82,10 @@ impl IntoResponse for Error { Self::IpParse { source } => { error!("{source}"); (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") + }, + Self::NoIpOnPing => { + error!("Ping requested but no ip given"); + (StatusCode::BAD_REQUEST, "No Ip saved for requested device, but device started") } }; let body = Json(json!({ diff --git a/src/routes/device.rs b/src/routes/device.rs index 49361f2..f767eab 100644 --- a/src/routes/device.rs +++ b/src/routes/device.rs @@ -36,7 +36,7 @@ pub struct DPayload { id: String, mac: String, broadcast_addr: String, - ip: String, + ip: Option, } #[utoipa::path( @@ -48,15 +48,17 @@ pub struct DPayload { ), security((), ("api_key" = [])) )] -pub async fn put( - Json(payload): Json, -) -> Result, Error> { +pub async fn put(Json(payload): Json) -> Result, Error> { info!( - "add device {} ({}, {}, {})", + "add device {} ({}, {}, {:?})", payload.id, payload.mac, payload.broadcast_addr, payload.ip ); - let ip = IpNetwork::from_str(&payload.ip)?; + let ip = if let Some(ip_s) = payload.ip { + Some(IpNetwork::from_str(&ip_s)?) + } else { + None + }; let mac = MacAddress::from_str(&payload.mac)?; let device = Device { id: payload.id, @@ -79,14 +81,17 @@ pub async fn put( ), security((), ("api_key" = [])) )] -pub async fn post( - Json(payload): Json, -) -> Result, Error> { +pub async fn post(Json(payload): Json) -> Result, Error> { info!( - "edit device {} ({}, {}, {})", + "edit device {} ({}, {}, {:?})", payload.id, payload.mac, payload.broadcast_addr, payload.ip ); - let ip = IpNetwork::from_str(&payload.ip)?; + + let ip = if let Some(ip_s) = payload.ip { + Some(IpNetwork::from_str(&ip_s)?) + } else { + None + }; let mac = MacAddress::from_str(&payload.mac)?; let times = Device::read(&payload.id)?.times; diff --git a/src/routes/start.rs b/src/routes/start.rs index bbc6ab8..192a54a 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -69,6 +69,9 @@ fn send_wol( let dev_id = device.id.clone(); let uuid = if let Some(pl) = payload { if pl.ping.is_some_and(|ping| ping) { + if device.ip.is_none() { + return Err(Error::NoIpOnPing); + } Some(setup_ping(state, device)) } else { None @@ -86,8 +89,10 @@ fn send_wol( fn setup_ping(state: Arc, device: Device) -> String { let mut uuid: Option = None; + // Safe: Only called when ip is set + let ip = device.ip.unwrap(); for (key, value) in state.ping_map.clone() { - if value.ip == device.ip { + if value.ip == ip { debug!("service already exists"); uuid = Some(key); break; @@ -103,7 +108,7 @@ fn setup_ping(state: Arc, device: Device) -> String { state.ping_map.insert( uuid_gen.clone(), PingValue { - ip: device.ip, + ip, eta: get_eta(device.clone().times), online: false, }, diff --git a/src/services/ping.rs b/src/services/ping.rs index 1bf022d..4e0ffcf 100644 --- a/src/services/ping.rs +++ b/src/services/ping.rs @@ -28,7 +28,9 @@ pub async fn spawn( let mut msg: Option = None; while msg.is_none() { - let ping = surge_ping::ping(device.ip.ip(), &payload).await; + // Safe: Only called when ip is set + let ip = device.ip.unwrap(); + let ping = surge_ping::ping(ip.ip(), &payload).await; if let Err(ping) = ping { let ping_timeout = matches!(ping, surge_ping::SurgeError::Timeout { .. }); diff --git a/src/storage.rs b/src/storage.rs index 0da245b..52c2e60 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -18,7 +18,7 @@ pub struct Device { pub id: String, pub mac: MacAddress, pub broadcast_addr: String, - pub ip: IpNetwork, + pub ip: Option, pub times: Option>, } -- cgit v1.2.3