summaryrefslogtreecommitdiff
path: root/src/routes/device.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/routes/device.rs')
-rw-r--r--src/routes/device.rs137
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 @@
1use std::sync::Arc; 1use crate::db::Device;
2use crate::error::Error;
2use axum::extract::State; 3use axum::extract::State;
3use axum::Json; 4use axum::Json;
4use axum::http::HeaderMap; 5use mac_address::MacAddress;
5use serde::{Deserialize, Serialize}; 6use serde::{Deserialize, Serialize};
6use serde_json::{json, Value}; 7use serde_json::{json, Value};
8use sqlx::types::ipnetwork::IpNetwork;
9use std::{sync::Arc, str::FromStr};
7use tracing::{debug, info}; 10use tracing::{debug, info};
8use crate::auth::auth;
9use crate::db::Device;
10use crate::error::Error;
11 11
12pub async fn get(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<GetDevicePayload>) -> Result<Json<Value>, Error> { 12pub 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
39pub async fn put(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PutDevicePayload>) -> Result<Json<Value>, Error> { 39pub 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)]
69pub struct PutDeviceResponse { 75pub struct PutDeviceResponse {
70 success: bool 76 success: bool,
71} 77}
72 78
73pub async fn post(State(state): State<Arc<crate::AppState>>, headers: HeaderMap, Json(payload): Json<PostDevicePayload>) -> Result<Json<Value>, Error> { 79pub 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)]