aboutsummaryrefslogtreecommitdiff
path: root/src/routes
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes')
-rw-r--r--src/routes/device.rs34
-rw-r--r--src/routes/mod.rs3
-rw-r--r--src/routes/start.rs39
-rw-r--r--src/routes/status.rs10
4 files changed, 60 insertions, 26 deletions
diff --git a/src/routes/device.rs b/src/routes/device.rs
index 025c7d0..1eeff0b 100644
--- a/src/routes/device.rs
+++ b/src/routes/device.rs
@@ -4,24 +4,26 @@ use axum::headers::HeaderMap;
4use axum::Json; 4use axum::Json;
5use serde::{Deserialize, Serialize}; 5use serde::{Deserialize, Serialize};
6use serde_json::{json, Value}; 6use serde_json::{json, Value};
7use tracing::info; 7use tracing::{debug, info};
8use crate::auth::auth; 8use crate::auth::auth;
9use crate::db::Device; 9use crate::db::Device;
10use crate::error::WebolError; 10use crate::error::WebolError;
11 11
12pub async fn get_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<GetDevicePayload>) -> Result<Json<Value>, WebolError> { 12pub async fn get_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<GetDevicePayload>) -> Result<Json<Value>, WebolError> {
13 info!("GET request"); 13 info!("add device {}", payload.id);
14 let secret = headers.get("authorization"); 14 let secret = headers.get("authorization");
15 if auth(secret).map_err(WebolError::Auth)? { 15 if auth(secret).map_err(WebolError::Auth)? {
16 let device = sqlx::query_as!( 16 let device = sqlx::query_as!(
17 Device, 17 Device,
18 r#" 18 r#"
19 SELECT id, mac, broadcast_addr 19 SELECT id, mac, broadcast_addr, ip
20 FROM devices 20 FROM devices
21 WHERE id = $1; 21 WHERE id = $1;
22 "#, 22 "#,
23 payload.id 23 payload.id
24 ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; 24 ).fetch_one(&state.db).await.map_err(WebolError::DB)?;
25
26 debug!("got device {:?}", device);
25 27
26 Ok(Json(json!(device))) 28 Ok(Json(json!(device)))
27 } else { 29 } else {
@@ -35,18 +37,19 @@ pub struct GetDevicePayload {
35} 37}
36 38
37pub async fn put_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PutDevicePayload>) -> Result<Json<Value>, WebolError> { 39pub async fn put_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PutDevicePayload>) -> Result<Json<Value>, WebolError> {
38 info!("PUT request"); 40 info!("add device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip);
39 let secret = headers.get("authorization"); 41 let secret = headers.get("authorization");
40 if auth(secret).map_err(WebolError::Auth)? { 42 if auth(secret).map_err(WebolError::Auth)? {
41 sqlx::query!( 43 sqlx::query!(
42 r#" 44 r#"
43 INSERT INTO devices (id, mac, broadcast_addr) 45 INSERT INTO devices (id, mac, broadcast_addr, ip)
44 VALUES ($1, $2, $3); 46 VALUES ($1, $2, $3, $4);
45 "#, 47 "#,
46 payload.id, 48 payload.id,
47 payload.mac, 49 payload.mac,
48 payload.broadcast_addr 50 payload.broadcast_addr,
49 ).execute(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; 51 payload.ip
52 ).execute(&state.db).await.map_err(WebolError::DB)?;
50 53
51 Ok(Json(json!(PutDeviceResponse { success: true }))) 54 Ok(Json(json!(PutDeviceResponse { success: true })))
52 } else { 55 } else {
@@ -59,6 +62,7 @@ pub struct PutDevicePayload {
59 id: String, 62 id: String,
60 mac: String, 63 mac: String,
61 broadcast_addr: String, 64 broadcast_addr: String,
65 ip: String
62} 66}
63 67
64#[derive(Serialize)] 68#[derive(Serialize)]
@@ -67,20 +71,21 @@ pub struct PutDeviceResponse {
67} 71}
68 72
69pub async fn post_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PostDevicePayload>) -> Result<Json<Value>, WebolError> { 73pub async fn post_device(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PostDevicePayload>) -> Result<Json<Value>, WebolError> {
70 info!("POST request"); 74 info!("edit device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip);
71 let secret = headers.get("authorization"); 75 let secret = headers.get("authorization");
72 if auth(secret).map_err(WebolError::Auth)? { 76 if auth(secret).map_err(WebolError::Auth)? {
73 let device = sqlx::query_as!( 77 let device = sqlx::query_as!(
74 Device, 78 Device,
75 r#" 79 r#"
76 UPDATE devices 80 UPDATE devices
77 SET mac = $1, broadcast_addr = $2 WHERE id = $3 81 SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4
78 RETURNING id, mac, broadcast_addr; 82 RETURNING id, mac, broadcast_addr, ip;
79 "#, 83 "#,
80 payload.mac, 84 payload.mac,
81 payload.broadcast_addr, 85 payload.broadcast_addr,
86 payload.ip,
82 payload.id 87 payload.id
83 ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; 88 ).fetch_one(&state.db).await.map_err(WebolError::DB)?;
84 89
85 Ok(Json(json!(device))) 90 Ok(Json(json!(device)))
86 } else { 91 } else {
@@ -93,4 +98,5 @@ pub struct PostDevicePayload {
93 id: String, 98 id: String,
94 mac: String, 99 mac: String,
95 broadcast_addr: String, 100 broadcast_addr: String,
96} \ No newline at end of file 101 ip: String,
102}
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index 12fbfab..d5ab0d6 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -1,2 +1,3 @@
1pub mod start; 1pub mod start;
2pub mod device; \ No newline at end of file 2pub mod device;
3pub mod status; \ No newline at end of file
diff --git a/src/routes/start.rs b/src/routes/start.rs
index 163d58c..271f924 100644
--- a/src/routes/start.rs
+++ b/src/routes/start.rs
@@ -4,26 +4,30 @@ use serde::{Deserialize, Serialize};
4use std::sync::Arc; 4use std::sync::Arc;
5use axum::extract::State; 5use axum::extract::State;
6use serde_json::{json, Value}; 6use serde_json::{json, Value};
7use tracing::info; 7use tracing::{debug, info};
8use uuid::Uuid;
8use crate::auth::auth; 9use crate::auth::auth;
9use crate::config::SETTINGS; 10use crate::config::SETTINGS;
10use crate::wol::{create_buffer, send_packet}; 11use crate::wol::{create_buffer, send_packet};
11use crate::db::Device; 12use crate::db::Device;
12use crate::error::WebolError; 13use crate::error::WebolError;
14use crate::services::ping::PingValue;
13 15
16#[axum_macros::debug_handler]
14pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<StartPayload>) -> Result<Json<Value>, WebolError> { 17pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<StartPayload>) -> Result<Json<Value>, WebolError> {
15 info!("POST request"); 18 info!("POST request");
16 let secret = headers.get("authorization"); 19 let secret = headers.get("authorization");
17 if auth(secret).map_err(WebolError::Auth)? { 20 let authorized = auth(secret).map_err(WebolError::Auth)?;
21 if authorized {
18 let device = sqlx::query_as!( 22 let device = sqlx::query_as!(
19 Device, 23 Device,
20 r#" 24 r#"
21 SELECT id, mac, broadcast_addr 25 SELECT id, mac, broadcast_addr, ip
22 FROM devices 26 FROM devices
23 WHERE id = $1; 27 WHERE id = $1;
24 "#, 28 "#,
25 payload.id 29 payload.id
26 ).fetch_one(&state.db).await.map_err(|err| WebolError::Server(Box::new(err)))?; 30 ).fetch_one(&state.db).await.map_err(WebolError::DB)?;
27 31
28 info!("starting {}", device.id); 32 info!("starting {}", device.id);
29 33
@@ -32,11 +36,23 @@ pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap
32 .unwrap_or("0.0.0.0:1111".to_string()); 36 .unwrap_or("0.0.0.0:1111".to_string());
33 37
34 let _ = send_packet( 38 let _ = send_packet(
35 &bind_addr.parse().map_err(|err| WebolError::Server(Box::new(err)))?, 39 &bind_addr.parse().map_err(WebolError::IpParse)?,
36 &device.broadcast_addr.parse().map_err(|err| WebolError::Server(Box::new(err)))?, 40 &device.broadcast_addr.parse().map_err(WebolError::IpParse)?,
37 create_buffer(&device.mac).map_err(|err| WebolError::Server(Box::new(err)))? 41 create_buffer(&device.mac)?
38 ).map_err(|err| WebolError::Server(Box::new(err))); 42 )?;
39 Ok(Json(json!(StartResponse { id: device.id, boot: true }))) 43
44 let uuid = if payload.ping.is_some_and(|ping| ping) {
45 let uuid_gen = Uuid::new_v4().to_string();
46 let uuid_genc = uuid_gen.clone();
47 tokio::spawn(async move {
48 debug!("init ping service");
49 state.ping_map.insert(uuid_gen.clone(), PingValue { ip: device.ip.clone(), online: false });
50
51 crate::services::ping::spawn(state.ping_send.clone(), device.ip, uuid_gen.clone(), &state.ping_map).await
52 });
53 Some(uuid_genc)
54 } else { None };
55 Ok(Json(json!(StartResponse { id: device.id, boot: true, uuid })))
40 } else { 56 } else {
41 Err(WebolError::Generic) 57 Err(WebolError::Generic)
42 } 58 }
@@ -45,11 +61,12 @@ pub async fn start(State(state): State<Arc<crate::AppState>>, headers: HeaderMap
45#[derive(Deserialize)] 61#[derive(Deserialize)]
46pub struct StartPayload { 62pub struct StartPayload {
47 id: String, 63 id: String,
48 _test: Option<bool>, 64 ping: Option<bool>,
49} 65}
50 66
51#[derive(Serialize)] 67#[derive(Serialize)]
52struct StartResponse { 68struct StartResponse {
53 id: String, 69 id: String,
54 boot: bool, 70 boot: bool,
55} \ No newline at end of file 71 uuid: Option<String>,
72}
diff --git a/src/routes/status.rs b/src/routes/status.rs
new file mode 100644
index 0000000..45f3e51
--- /dev/null
+++ b/src/routes/status.rs
@@ -0,0 +1,10 @@
1use std::sync::Arc;
2use axum::extract::{State, WebSocketUpgrade};
3use axum::response::Response;
4use crate::AppState;
5use crate::services::ping::status_websocket;
6
7#[axum_macros::debug_handler]
8pub async fn status(State(state): State<Arc<AppState>>, ws: WebSocketUpgrade) -> Response {
9 ws.on_upgrade(move |socket| status_websocket(socket, state))
10} \ No newline at end of file