From 016fa3a31f8847d3f52800941b7f8fe5ef872240 Mon Sep 17 00:00:00 2001 From: FxQnLr Date: Thu, 15 Feb 2024 19:29:48 +0100 Subject: Closes #15. No usable Error message right now --- src/auth.rs | 49 +++++++++++++--------------------------- src/error.rs | 19 +++++++++------- src/routes/device.rs | 63 +++++++++++++++++++++++++++++++++++++--------------- src/routes/start.rs | 2 +- 4 files changed, 72 insertions(+), 61 deletions(-) diff --git a/src/auth.rs b/src/auth.rs index eb4d1bf..22f87e7 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,49 +1,30 @@ -use axum::http::{StatusCode, HeaderValue}; -use axum::http::header::ToStrError; -use tracing::{debug, error, trace}; -use crate::auth::Error::{MissingSecret, WrongSecret}; +use axum::http::HeaderValue; +use tracing::{debug, trace}; use crate::config::Config; +use crate::error::Error; -pub fn auth(config: &Config, secret: Option<&HeaderValue>) -> Result { +pub fn auth(config: &Config, secret: Option<&HeaderValue>) -> Result { debug!("auth request with secret {:?}", secret); - if let Some(value) = secret { - trace!("value exists"); + let res = if let Some(value) = secret { + trace!("auth value exists"); let key = &config.apikey; if value.to_str()? == key.as_str() { debug!("successful auth"); - Ok(true) + Response::Success } else { debug!("unsuccessful auth (wrong secret)"); - Err(WrongSecret) + Response::WrongSecret } } else { debug!("unsuccessful auth (no secret)"); - Err(MissingSecret) - } + Response::MissingSecret + }; + Ok(res) } -#[derive(Debug, thiserror::Error)] -pub enum Error { - #[error("wrong secret")] +#[derive(Debug)] +pub enum Response { + Success, WrongSecret, - #[error("missing secret")] - MissingSecret, - #[error("parse error: {source}")] - HeaderToStr { - #[from] - source: ToStrError - } -} - -impl Error { - pub fn get(self) -> (StatusCode, &'static str) { - match self { - Self::WrongSecret => (StatusCode::UNAUTHORIZED, "Wrong credentials"), - Self::MissingSecret => (StatusCode::BAD_REQUEST, "Missing credentials"), - Self::HeaderToStr { source } => { - error!("auth: {}", source); - (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") - }, - } - } + MissingSecret } diff --git a/src/error.rs b/src/error.rs index 4f1bedd..63b214e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,4 @@ -use crate::auth::Error as AuthError; +use axum::http::header::ToStrError; use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; use axum::Json; @@ -11,12 +11,6 @@ pub enum Error { #[error("generic error")] Generic, - #[error("auth: {source}")] - Auth { - #[from] - source: AuthError, - }, - #[error("db: {source}")] Db { #[from] @@ -29,6 +23,12 @@ pub enum Error { source: std::num::ParseIntError, }, + #[error("header parse: {source}")] + ParseHeader { + #[from] + source: ToStrError, + }, + #[error("io: {source}")] Io { #[from] @@ -40,7 +40,6 @@ impl IntoResponse for Error { fn into_response(self) -> Response { error!("{}", self.to_string()); let (status, error_message) = match self { - Self::Auth { source } => source.get(), Self::Generic => (StatusCode::INTERNAL_SERVER_ERROR, ""), Self::Db { source } => { error!("{source}"); @@ -50,6 +49,10 @@ impl IntoResponse for Error { error!("{source}"); (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") } + Self::ParseHeader { source } => { + error!("{source}"); + (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") + } Self::ParseInt { source } => { error!("{source}"); (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") diff --git a/src/routes/device.rs b/src/routes/device.rs index aa52cf7..5ca574a 100644 --- a/src/routes/device.rs +++ b/src/routes/device.rs @@ -1,18 +1,23 @@ -use std::sync::Arc; +use crate::auth::auth; +use crate::db::Device; +use crate::error::Error; use axum::extract::State; -use axum::Json; use axum::http::HeaderMap; +use axum::Json; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; +use std::sync::Arc; use tracing::{debug, info}; -use crate::auth::auth; -use crate::db::Device; -use crate::error::Error; -pub async fn get(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, Error> { +pub async fn get( + State(state): State>, + headers: HeaderMap, + Json(payload): Json, +) -> Result, Error> { info!("add device {}", payload.id); let secret = headers.get("authorization"); - if auth(&state.config, secret)? { + let authorized = matches!(auth(&state.config, secret)?, crate::auth::Response::Success); + if authorized { let device = sqlx::query_as!( Device, r#" @@ -21,7 +26,9 @@ pub async fn get(State(state): State>, headers: HeaderMap, WHERE id = $1; "#, payload.id - ).fetch_one(&state.db).await?; + ) + .fetch_one(&state.db) + .await?; debug!("got device {:?}", device); @@ -36,10 +43,18 @@ pub struct GetDevicePayload { id: String, } -pub async fn put(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, Error> { - info!("add device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip); +pub async fn put( + State(state): State>, + headers: HeaderMap, + Json(payload): Json, +) -> Result, Error> { + info!( + "add device {} ({}, {}, {})", + payload.id, payload.mac, payload.broadcast_addr, payload.ip + ); let secret = headers.get("authorization"); - if auth(&state.config, secret)? { + let authorized = matches!(auth(&state.config, secret)?, crate::auth::Response::Success); + if authorized { sqlx::query!( r#" INSERT INTO devices (id, mac, broadcast_addr, ip) @@ -49,7 +64,9 @@ pub async fn put(State(state): State>, headers: HeaderMap, payload.mac, payload.broadcast_addr, payload.ip - ).execute(&state.db).await?; + ) + .execute(&state.db) + .await?; Ok(Json(json!(PutDeviceResponse { success: true }))) } else { @@ -62,18 +79,26 @@ pub struct PutDevicePayload { id: String, mac: String, broadcast_addr: String, - ip: String + ip: String, } #[derive(Serialize)] pub struct PutDeviceResponse { - success: bool + success: bool, } -pub async fn post(State(state): State>, headers: HeaderMap, Json(payload): Json) -> Result, Error> { - info!("edit device {} ({}, {}, {})", payload.id, payload.mac, payload.broadcast_addr, payload.ip); +pub async fn post( + State(state): State>, + headers: HeaderMap, + Json(payload): Json, +) -> Result, Error> { + info!( + "edit device {} ({}, {}, {})", + payload.id, payload.mac, payload.broadcast_addr, payload.ip + ); let secret = headers.get("authorization"); - if auth(&state.config, secret)? { + let authorized = matches!(auth(&state.config, secret)?, crate::auth::Response::Success); + if authorized { let device = sqlx::query_as!( Device, r#" @@ -85,7 +110,9 @@ pub async fn post(State(state): State>, headers: HeaderMap, payload.broadcast_addr, payload.ip, payload.id - ).fetch_one(&state.db).await?; + ) + .fetch_one(&state.db) + .await?; Ok(Json(json!(device))) } else { diff --git a/src/routes/start.rs b/src/routes/start.rs index 66b7cb4..ec4f98f 100644 --- a/src/routes/start.rs +++ b/src/routes/start.rs @@ -20,7 +20,7 @@ pub async fn start( ) -> Result, Error> { info!("POST request"); let secret = headers.get("authorization"); - let authorized = auth(&state.config, secret)?; + let authorized = matches!(auth(&state.config, secret)?, crate::auth::Response::Success); if authorized { let device = sqlx::query_as!( Device, -- cgit v1.2.3