diff options
-rw-r--r-- | src/auth.rs | 35 | ||||
-rw-r--r-- | src/config.rs | 10 | ||||
-rw-r--r-- | src/extractors.rs | 24 | ||||
-rw-r--r-- | src/main.rs | 4 | ||||
-rw-r--r-- | src/routes/start.rs | 2 |
5 files changed, 47 insertions, 28 deletions
diff --git a/src/auth.rs b/src/auth.rs new file mode 100644 index 0000000..1f4518a --- /dev/null +++ b/src/auth.rs | |||
@@ -0,0 +1,35 @@ | |||
1 | use crate::AppState; | ||
2 | use axum::{ | ||
3 | extract::{Request, State}, | ||
4 | http::{HeaderMap, StatusCode}, | ||
5 | middleware::Next, | ||
6 | response::Response, | ||
7 | }; | ||
8 | use serde::Deserialize; | ||
9 | |||
10 | #[derive(Debug, Clone, Deserialize)] | ||
11 | pub enum Methods { | ||
12 | Key, | ||
13 | None, | ||
14 | } | ||
15 | |||
16 | pub async fn auth( | ||
17 | State(state): State<AppState>, | ||
18 | headers: HeaderMap, | ||
19 | request: Request, | ||
20 | next: Next, | ||
21 | ) -> Result<Response, StatusCode> { | ||
22 | let auth = state.config.auth; | ||
23 | match auth.method { | ||
24 | Methods::Key => { | ||
25 | if let Some(secret) = headers.get("authorization") { | ||
26 | if !(auth.secret.as_str() == secret) { return Err(StatusCode::UNAUTHORIZED); }; | ||
27 | let response = next.run(request).await; | ||
28 | Ok(response) | ||
29 | } else { | ||
30 | return Err(StatusCode::UNAUTHORIZED); | ||
31 | } | ||
32 | } | ||
33 | Methods::None => Ok(next.run(request).await), | ||
34 | } | ||
35 | } | ||
diff --git a/src/config.rs b/src/config.rs index 9605361..9636af4 100644 --- a/src/config.rs +++ b/src/config.rs | |||
@@ -1,14 +1,22 @@ | |||
1 | use config::File; | 1 | use config::File; |
2 | use serde::Deserialize; | 2 | use serde::Deserialize; |
3 | 3 | ||
4 | use crate::auth; | ||
5 | |||
4 | #[derive(Debug, Clone, Deserialize)] | 6 | #[derive(Debug, Clone, Deserialize)] |
5 | pub struct Config { | 7 | pub struct Config { |
6 | pub database_url: String, | 8 | pub database_url: String, |
7 | pub apikey: String, | ||
8 | pub serveraddr: String, | 9 | pub serveraddr: String, |
9 | pub pingtimeout: i64, | 10 | pub pingtimeout: i64, |
10 | pub pingthreshold: i64, | 11 | pub pingthreshold: i64, |
11 | pub timeoffset: i8, | 12 | pub timeoffset: i8, |
13 | pub auth: Auth, | ||
14 | } | ||
15 | |||
16 | #[derive(Debug, Clone, Deserialize)] | ||
17 | pub struct Auth { | ||
18 | pub method: auth::Methods, | ||
19 | pub secret: String, | ||
12 | } | 20 | } |
13 | 21 | ||
14 | impl Config { | 22 | impl Config { |
diff --git a/src/extractors.rs b/src/extractors.rs deleted file mode 100644 index 4d441e9..0000000 --- a/src/extractors.rs +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | use axum::{ | ||
2 | extract::{Request, State}, | ||
3 | http::{HeaderMap, StatusCode}, | ||
4 | middleware::Next, | ||
5 | response::Response, | ||
6 | }; | ||
7 | |||
8 | use crate::AppState; | ||
9 | |||
10 | pub async fn auth( | ||
11 | State(state): State<AppState>, | ||
12 | headers: HeaderMap, | ||
13 | request: Request, | ||
14 | next: Next, | ||
15 | ) -> Result<Response, StatusCode> { | ||
16 | let secret = headers.get("authorization"); | ||
17 | match secret { | ||
18 | Some(token) if token == state.config.apikey.as_str() => { | ||
19 | let response = next.run(request).await; | ||
20 | Ok(response) | ||
21 | } | ||
22 | _ => Err(StatusCode::UNAUTHORIZED), | ||
23 | } | ||
24 | } | ||
diff --git a/src/main.rs b/src/main.rs index 75f491a..43957ff 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -29,7 +29,7 @@ use utoipa_swagger_ui::SwaggerUi; | |||
29 | mod config; | 29 | mod config; |
30 | mod db; | 30 | mod db; |
31 | mod error; | 31 | mod error; |
32 | mod extractors; | 32 | mod auth; |
33 | mod routes; | 33 | mod routes; |
34 | mod services; | 34 | mod services; |
35 | mod wol; | 35 | mod wol; |
@@ -126,7 +126,7 @@ async fn main() -> color_eyre::eyre::Result<()> { | |||
126 | ) | 126 | ) |
127 | .route("/device/:id", get(device::get)) | 127 | .route("/device/:id", get(device::get)) |
128 | .route("/status", get(status::status)) | 128 | .route("/status", get(status::status)) |
129 | .route_layer(from_fn_with_state(shared_state.clone(), extractors::auth)) | 129 | .route_layer(from_fn_with_state(shared_state.clone(), auth::auth)) |
130 | .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())) |
131 | .with_state(Arc::new(shared_state)); | 131 | .with_state(Arc::new(shared_state)); |
132 | 132 | ||
diff --git a/src/routes/start.rs b/src/routes/start.rs index fa226d8..c61d5a3 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs | |||
@@ -63,7 +63,7 @@ pub async fn start_payload( | |||
63 | #[utoipa::path( | 63 | #[utoipa::path( |
64 | post, | 64 | post, |
65 | path = "/start/{id}", | 65 | path = "/start/{id}", |
66 | request_body = Payload, | 66 | request_body = Option<Payload>, |
67 | responses( | 67 | responses( |
68 | (status = 200, description = "Start the device with the given id", body = [Response]) | 68 | (status = 200, description = "Start the device with the given id", body = [Response]) |
69 | ), | 69 | ), |