diff options
author | FxQnLr <[email protected]> | 2024-04-08 10:42:47 +0200 |
---|---|---|
committer | FxQnLr <[email protected]> | 2024-04-08 10:42:47 +0200 |
commit | d8060da1180545df5d03a76cd2860191ecf87507 (patch) | |
tree | be0c7812bd4a9a1ad6c8529072516a4a572ff17f | |
parent | 8dca7e83519b6c3531653cdedf60b2a14e1035b7 (diff) | |
download | webol-d8060da1180545df5d03a76cd2860191ecf87507.tar webol-d8060da1180545df5d03a76cd2860191ecf87507.tar.gz webol-d8060da1180545df5d03a76cd2860191ecf87507.zip |
Closes #23. Start request id parameter put in path
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Cargo.lock | 2 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/main.rs | 13 | ||||
-rw-r--r-- | src/routes/device.rs | 4 | ||||
-rw-r--r-- | src/routes/start.rs | 76 |
6 files changed, 83 insertions, 15 deletions
@@ -14,6 +14,7 @@ target/ | |||
14 | config.* | 14 | config.* |
15 | 15 | ||
16 | .idea | 16 | .idea |
17 | .lapce | ||
17 | 18 | ||
18 | logs/ | 19 | logs/ |
19 | *.log | 20 | *.log |
@@ -2588,7 +2588,7 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" | |||
2588 | 2588 | ||
2589 | [[package]] | 2589 | [[package]] |
2590 | name = "webol" | 2590 | name = "webol" |
2591 | version = "0.3.3" | 2591 | version = "0.3.4" |
2592 | dependencies = [ | 2592 | dependencies = [ |
2593 | "axum", | 2593 | "axum", |
2594 | "axum-macros", | 2594 | "axum-macros", |
@@ -1,6 +1,6 @@ | |||
1 | [package] | 1 | [package] |
2 | name = "webol" | 2 | name = "webol" |
3 | version = "0.3.3" | 3 | version = "0.3.4" |
4 | edition = "2021" | 4 | edition = "2021" |
5 | 5 | ||
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
diff --git a/src/main.rs b/src/main.rs index 00fc6ce..75f491a 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -11,8 +11,8 @@ use axum::{ | |||
11 | }; | 11 | }; |
12 | use dashmap::DashMap; | 12 | use dashmap::DashMap; |
13 | use sqlx::PgPool; | 13 | use sqlx::PgPool; |
14 | use time::UtcOffset; | ||
15 | use std::{env, sync::Arc}; | 14 | use std::{env, sync::Arc}; |
15 | use time::UtcOffset; | ||
16 | use tokio::sync::broadcast::{channel, Sender}; | 16 | use tokio::sync::broadcast::{channel, Sender}; |
17 | use tracing::{info, level_filters::LevelFilter}; | 17 | use tracing::{info, level_filters::LevelFilter}; |
18 | use tracing_subscriber::{ | 18 | use tracing_subscriber::{ |
@@ -38,13 +38,15 @@ mod wol; | |||
38 | #[openapi( | 38 | #[openapi( |
39 | paths( | 39 | paths( |
40 | start::start, | 40 | start::start, |
41 | start::start_payload, | ||
41 | device::get, | 42 | device::get, |
42 | device::get_path, | 43 | device::get_payload, |
43 | device::post, | 44 | device::post, |
44 | device::put, | 45 | device::put, |
45 | ), | 46 | ), |
46 | components( | 47 | components( |
47 | schemas( | 48 | schemas( |
49 | start::PayloadOld, | ||
48 | start::Payload, | 50 | start::Payload, |
49 | start::Response, | 51 | start::Response, |
50 | device::PutDevicePayload, | 52 | device::PutDevicePayload, |
@@ -116,12 +118,13 @@ async fn main() -> color_eyre::eyre::Result<()> { | |||
116 | }; | 118 | }; |
117 | 119 | ||
118 | let app = Router::new() | 120 | let app = Router::new() |
119 | .route("/start", post(start::start)) | 121 | .route("/start", post(start::start_payload)) |
122 | .route("/start/:id", post(start::start)) | ||
120 | .route( | 123 | .route( |
121 | "/device", | 124 | "/device", |
122 | post(device::post).get(device::get).put(device::put), | 125 | post(device::post).get(device::get_payload).put(device::put), |
123 | ) | 126 | ) |
124 | .route("/device/:id", get(device::get_path)) | 127 | .route("/device/:id", get(device::get)) |
125 | .route("/status", get(status::status)) | 128 | .route("/status", get(status::status)) |
126 | .route_layer(from_fn_with_state(shared_state.clone(), extractors::auth)) | 129 | .route_layer(from_fn_with_state(shared_state.clone(), extractors::auth)) |
127 | .merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi())) | 130 | .merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi())) |
diff --git a/src/routes/device.rs b/src/routes/device.rs index d01d9f0..bbc832d 100644 --- a/src/routes/device.rs +++ b/src/routes/device.rs | |||
@@ -20,7 +20,7 @@ use utoipa::ToSchema; | |||
20 | security(("api_key" = [])) | 20 | security(("api_key" = [])) |
21 | )] | 21 | )] |
22 | #[deprecated] | 22 | #[deprecated] |
23 | pub async fn get( | 23 | pub async fn get_payload( |
24 | State(state): State<Arc<crate::AppState>>, | 24 | State(state): State<Arc<crate::AppState>>, |
25 | Json(payload): Json<GetDevicePayload>, | 25 | Json(payload): Json<GetDevicePayload>, |
26 | ) -> Result<Json<Value>, Error> { | 26 | ) -> Result<Json<Value>, Error> { |
@@ -53,7 +53,7 @@ pub async fn get( | |||
53 | ), | 53 | ), |
54 | security(("api_key" = [])) | 54 | security(("api_key" = [])) |
55 | )] | 55 | )] |
56 | pub async fn get_path( | 56 | pub async fn get( |
57 | State(state): State<Arc<crate::AppState>>, | 57 | State(state): State<Arc<crate::AppState>>, |
58 | Path(path): Path<String>, | 58 | Path(path): Path<String>, |
59 | ) -> Result<Json<Value>, Error> { | 59 | ) -> Result<Json<Value>, Error> { |
diff --git a/src/routes/start.rs b/src/routes/start.rs index ef6e8f2..fa226d8 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs | |||
@@ -2,27 +2,28 @@ use crate::db::Device; | |||
2 | use crate::error::Error; | 2 | use crate::error::Error; |
3 | use crate::services::ping::Value as PingValue; | 3 | use crate::services::ping::Value as PingValue; |
4 | use crate::wol::{create_buffer, send_packet}; | 4 | use crate::wol::{create_buffer, send_packet}; |
5 | use axum::extract::State; | 5 | use axum::extract::{Path, State}; |
6 | use axum::Json; | 6 | use axum::Json; |
7 | use serde::{Deserialize, Serialize}; | 7 | use serde::{Deserialize, Serialize}; |
8 | use serde_json::{json, Value}; | 8 | use serde_json::{json, Value}; |
9 | use utoipa::ToSchema; | ||
10 | use std::sync::Arc; | 9 | use std::sync::Arc; |
11 | use tracing::{debug, info}; | 10 | use tracing::{debug, info}; |
11 | use utoipa::ToSchema; | ||
12 | use uuid::Uuid; | 12 | use uuid::Uuid; |
13 | 13 | ||
14 | #[utoipa::path( | 14 | #[utoipa::path( |
15 | post, | 15 | post, |
16 | path = "/start", | 16 | path = "/start", |
17 | request_body = Payload, | 17 | request_body = PayloadOld, |
18 | responses( | 18 | responses( |
19 | (status = 200, description = "List matching todos by query", body = [Response]) | 19 | (status = 200, description = "List matching todos by query", body = [Response]) |
20 | ), | 20 | ), |
21 | security(("api_key" = [])) | 21 | security(("api_key" = [])) |
22 | )] | 22 | )] |
23 | pub async fn start( | 23 | #[deprecated] |
24 | pub async fn start_payload( | ||
24 | State(state): State<Arc<crate::AppState>>, | 25 | State(state): State<Arc<crate::AppState>>, |
25 | Json(payload): Json<Payload>, | 26 | Json(payload): Json<PayloadOld>, |
26 | ) -> Result<Json<Value>, Error> { | 27 | ) -> Result<Json<Value>, Error> { |
27 | info!("POST request"); | 28 | info!("POST request"); |
28 | let device = sqlx::query_as!( | 29 | let device = sqlx::query_as!( |
@@ -59,6 +60,63 @@ pub async fn start( | |||
59 | }))) | 60 | }))) |
60 | } | 61 | } |
61 | 62 | ||
63 | #[utoipa::path( | ||
64 | post, | ||
65 | path = "/start/{id}", | ||
66 | request_body = Payload, | ||
67 | responses( | ||
68 | (status = 200, description = "Start the device with the given id", body = [Response]) | ||
69 | ), | ||
70 | params( | ||
71 | ("id" = String, Path, description = "Device id") | ||
72 | ), | ||
73 | security(("api_key" = [])) | ||
74 | )] | ||
75 | pub async fn start( | ||
76 | State(state): State<Arc<crate::AppState>>, | ||
77 | Path(id): Path<String>, | ||
78 | payload: Option<Json<Payload>>, | ||
79 | ) -> Result<Json<Value>, Error> { | ||
80 | info!("Start request for {id}"); | ||
81 | let device = sqlx::query_as!( | ||
82 | Device, | ||
83 | r#" | ||
84 | SELECT id, mac, broadcast_addr, ip, times | ||
85 | FROM devices | ||
86 | WHERE id = $1; | ||
87 | "#, | ||
88 | id | ||
89 | ) | ||
90 | .fetch_one(&state.db) | ||
91 | .await?; | ||
92 | |||
93 | info!("starting {}", device.id); | ||
94 | |||
95 | let bind_addr = "0.0.0.0:0"; | ||
96 | |||
97 | let _ = send_packet( | ||
98 | bind_addr, | ||
99 | &device.broadcast_addr, | ||
100 | &create_buffer(&device.mac.to_string())?, | ||
101 | )?; | ||
102 | let dev_id = device.id.clone(); | ||
103 | let uuid = if let Some(pl) = payload { | ||
104 | if pl.ping.is_some_and(|ping| ping) { | ||
105 | Some(setup_ping(state, device)) | ||
106 | } else { | ||
107 | None | ||
108 | } | ||
109 | } else { | ||
110 | None | ||
111 | }; | ||
112 | |||
113 | Ok(Json(json!(Response { | ||
114 | id: dev_id, | ||
115 | boot: true, | ||
116 | uuid | ||
117 | }))) | ||
118 | } | ||
119 | |||
62 | fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String { | 120 | fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String { |
63 | let mut uuid: Option<String> = None; | 121 | let mut uuid: Option<String> = None; |
64 | for (key, value) in state.ping_map.clone() { | 122 | for (key, value) in state.ping_map.clone() { |
@@ -99,11 +157,17 @@ fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String { | |||
99 | } | 157 | } |
100 | 158 | ||
101 | #[derive(Deserialize, ToSchema)] | 159 | #[derive(Deserialize, ToSchema)] |
102 | pub struct Payload { | 160 | #[deprecated] |
161 | pub struct PayloadOld { | ||
103 | id: String, | 162 | id: String, |
104 | ping: Option<bool>, | 163 | ping: Option<bool>, |
105 | } | 164 | } |
106 | 165 | ||
166 | #[derive(Deserialize, ToSchema)] | ||
167 | pub struct Payload { | ||
168 | ping: Option<bool>, | ||
169 | } | ||
170 | |||
107 | #[derive(Serialize, ToSchema)] | 171 | #[derive(Serialize, ToSchema)] |
108 | pub struct Response { | 172 | pub struct Response { |
109 | id: String, | 173 | id: String, |