diff options
Diffstat (limited to 'src/routes/device.rs')
-rw-r--r-- | src/routes/device.rs | 137 |
1 files changed, 74 insertions, 63 deletions
diff --git a/src/routes/device.rs b/src/routes/device.rs index c85df1b..d39d98e 100644 --- a/src/routes/device.rs +++ b/src/routes/device.rs | |||
@@ -1,34 +1,34 @@ | |||
1 | use std::sync::Arc; | 1 | use crate::db::Device; |
2 | use crate::error::Error; | ||
2 | use axum::extract::State; | 3 | use axum::extract::State; |
3 | use axum::Json; | 4 | use axum::Json; |
4 | use axum::http::HeaderMap; | 5 | use mac_address::MacAddress; |
5 | use serde::{Deserialize, Serialize}; | 6 | use serde::{Deserialize, Serialize}; |
6 | use serde_json::{json, Value}; | 7 | use serde_json::{json, Value}; |
8 | use sqlx::types::ipnetwork::IpNetwork; | ||
9 | use std::{sync::Arc, str::FromStr}; | ||
7 | use tracing::{debug, info}; | 10 | use tracing::{debug, info}; |
8 | use crate::auth::auth; | ||
9 | use crate::db::Device; | ||
10 | use crate::error::Error; | ||
11 | 11 | ||
12 | pub async fn get(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<GetDevicePayload>) -> Result<Json<Value>, Error> { | 12 | pub async fn get( |
13 | info!("add device {}", payload.id); | 13 | State(state): State<Arc<crate::AppState>>, |
14 | let secret = headers.get("authorization"); | 14 | Json(payload): Json<GetDevicePayload>, |
15 | if auth(&state.config, secret).map_err(Error::Auth)? { | 15 | ) -> Result<Json<Value>, Error> { |
16 | let device = sqlx::query_as!( | 16 | info!("get device {}", payload.id); |
17 | Device, | 17 | let device = sqlx::query_as!( |
18 | r#" | 18 | Device, |
19 | SELECT id, mac, broadcast_addr, ip, times | 19 | r#" |
20 | FROM devices | 20 | SELECT id, mac, broadcast_addr, ip, times |
21 | WHERE id = $1; | 21 | FROM devices |
22 | "#, | 22 | WHERE id = $1; |
23 | payload.id | 23 | "#, |
24 | ).fetch_one(&state.db).await.map_err(Error::DB)?; | 24 | payload.id |
25 | ) | ||
26 | .fetch_one(&state.db) | ||
27 | .await?; | ||
25 | 28 | ||
26 | debug!("got device {:?}", device); | 29 | debug!("got device {:?}", device); |
27 | 30 | ||
28 | Ok(Json(json!(device))) | 31 | Ok(Json(json!(device))) |
29 | } else { | ||
30 | Err(Error::Generic) | ||
31 | } | ||
32 | } | 32 | } |
33 | 33 | ||
34 | #[derive(Deserialize)] | 34 | #[derive(Deserialize)] |
@@ -36,25 +36,31 @@ pub struct GetDevicePayload { | |||
36 | id: String, | 36 | id: String, |
37 | } | 37 | } |
38 | 38 | ||
39 | pub async fn put(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PutDevicePayload>) -> Result<Json<Value>, Error> { | 39 | pub async fn put( |
40 | info!("add device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip); | 40 | State(state): State<Arc<crate::AppState>>, |
41 | let secret = headers.get("authorization"); | 41 | Json(payload): Json<PutDevicePayload>, |
42 | if auth(&state.config, secret).map_err(Error::Auth)? { | 42 | ) -> Result<Json<Value>, Error> { |
43 | sqlx::query!( | 43 | info!( |
44 | r#" | 44 | "add device {} ({}, {}, {})", |
45 | INSERT INTO devices (id, mac, broadcast_addr, ip) | 45 | payload.id, payload.mac, payload.broadcast_addr, payload.ip |
46 | VALUES ($1, $2, $3, $4); | 46 | ); |
47 | "#, | 47 | |
48 | payload.id, | 48 | let ip = IpNetwork::from_str(&payload.ip)?; |
49 | payload.mac, | 49 | let mac = MacAddress::from_str(&payload.mac)?; |
50 | payload.broadcast_addr, | 50 | sqlx::query!( |
51 | payload.ip | 51 | r#" |
52 | ).execute(&state.db).await.map_err(Error::DB)?; | 52 | INSERT INTO devices (id, mac, broadcast_addr, ip) |
53 | VALUES ($1, $2, $3, $4); | ||
54 | "#, | ||
55 | payload.id, | ||
56 | mac, | ||
57 | payload.broadcast_addr, | ||
58 | ip | ||
59 | ) | ||
60 | .execute(&state.db) | ||
61 | .await?; | ||
53 | 62 | ||
54 | Ok(Json(json!(PutDeviceResponse { success: true }))) | 63 | Ok(Json(json!(PutDeviceResponse { success: true }))) |
55 | } else { | ||
56 | Err(Error::Generic) | ||
57 | } | ||
58 | } | 64 | } |
59 | 65 | ||
60 | #[derive(Deserialize)] | 66 | #[derive(Deserialize)] |
@@ -62,35 +68,40 @@ pub struct PutDevicePayload { | |||
62 | id: String, | 68 | id: String, |
63 | mac: String, | 69 | mac: String, |
64 | broadcast_addr: String, | 70 | broadcast_addr: String, |
65 | ip: String | 71 | ip: String, |
66 | } | 72 | } |
67 | 73 | ||
68 | #[derive(Serialize)] | 74 | #[derive(Serialize)] |
69 | pub struct PutDeviceResponse { | 75 | pub struct PutDeviceResponse { |
70 | success: bool | 76 | success: bool, |
71 | } | 77 | } |
72 | 78 | ||
73 | pub async fn post(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PostDevicePayload>) -> Result<Json<Value>, Error> { | 79 | pub async fn post( |
74 | info!("edit device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip); | 80 | State(state): State<Arc<crate::AppState>>, |
75 | let secret = headers.get("authorization"); | 81 | Json(payload): Json<PostDevicePayload>, |
76 | if auth(&state.config, secret).map_err(Error::Auth)? { | 82 | ) -> Result<Json<Value>, Error> { |
77 | let device = sqlx::query_as!( | 83 | info!( |
78 | Device, | 84 | "edit device {} ({}, {}, {})", |
79 | r#" | 85 | payload.id, payload.mac, payload.broadcast_addr, payload.ip |
80 | UPDATE devices | 86 | ); |
81 | SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4 | 87 | let ip = IpNetwork::from_str(&payload.ip)?; |
82 | RETURNING id, mac, broadcast_addr, ip, times; | 88 | let mac = MacAddress::from_str(&payload.mac)?; |
83 | "#, | 89 | let device = sqlx::query_as!( |
84 | payload.mac, | 90 | Device, |
85 | payload.broadcast_addr, | 91 | r#" |
86 | payload.ip, | 92 | UPDATE devices |
87 | payload.id | 93 | SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4 |
88 | ).fetch_one(&state.db).await.map_err(Error::DB)?; | 94 | RETURNING id, mac, broadcast_addr, ip, times; |
95 | "#, | ||
96 | mac, | ||
97 | payload.broadcast_addr, | ||
98 | ip, | ||
99 | payload.id | ||
100 | ) | ||
101 | .fetch_one(&state.db) | ||
102 | .await?; | ||
89 | 103 | ||
90 | Ok(Json(json!(device))) | 104 | Ok(Json(json!(device))) |
91 | } else { | ||
92 | Err(Error::Generic) | ||
93 | } | ||
94 | } | 105 | } |
95 | 106 | ||
96 | #[derive(Deserialize)] | 107 | #[derive(Deserialize)] |