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 From fbb8cbc9f36975c4a414c9485347515d16f42333 Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Mon, 15 Apr 2024 21:04:58 +0200 Subject: Added register docs to README --- README.md | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 03779a1..cf536c4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ # webol - ## Config Default `config.toml`: ```toml @@ -12,9 +11,7 @@ timeoffset = 0 # i8 method = "none" # "none"|"key" secret = "" # String ``` - ## Docker - minimal `docker-compose.yaml`: ```yaml services: @@ -27,3 +24,38 @@ services: - ./logs:/logs network_mode: host ``` +## Register Device +A device is registered with a PUT request to the server with a JSON representation of the device as payload. +| field | description | example | +|--------------|------------------------------------------------------------------------|-------------------| +| server-ip | ip of the webol server, including its port | webol.local:7229 | +| secret | secret set in the server settings | password | +| device-id | any string, "name" of the device | foo | +| mac-address | mac address of the device | 12:34:56:AB:CD:EF | +| broadcast-ip | broadcast ip of the network, including the port Wake-on-Lan listens on | 10.0.1.255:7 | +| device-ip | (**optional**) ip of the device, used for ping feature | 10.0.1.47 | + +Examples using curl with and without authentification enabled on the server. +### With Authentification +```sh +curl -X PUT http:///device \ + -H 'Authorization: ' \ + -H 'Content-Type: application/json' \ + -d '{ + "id": "", + "mac": "", + "broadcast_addr": "", + "ip": "" + }' +``` +### Without Authentification +```sh +curl -X PUT http:///device \ + -H 'Content-Type: application/json' \ + -d '{ + "id": "", + "mac": "", + "broadcast_addr": "", + "ip": "" + }' +``` -- cgit v1.2.3 From 7876dd605a8e4b595436035a87a5151be187c01d Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Mon, 15 Apr 2024 21:09:16 +0200 Subject: Added Usage (start request) to README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index cf536c4..e84d646 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ services: - ./logs:/logs network_mode: host ``` +# Usage ## Register Device A device is registered with a PUT request to the server with a JSON representation of the device as payload. | field | description | example | @@ -59,3 +60,8 @@ curl -X PUT http:///device \ "ip": "" }' ``` +## Start Device +The easiest way to start a device is using a GET request with its id: +```sh +curl http:///start/ +``` \ No newline at end of file -- cgit v1.2.3