hermod_api/handlers/
mod.rs

1//! Contains HTTP Handlers that directly receive and respond to requests to the server.
2mod auth;
3mod form;
4mod health_check;
5mod qr_code;
6
7use actix_web::{
8    http::{header, HeaderValue, StatusCode},
9    HttpResponse, ResponseError,
10};
11pub use auth::*;
12pub use form::*;
13pub use health_check::*;
14pub use qr_code::*;
15
16use crate::services::auth::AuthenticationError;
17
18/// Alias used for all HTTP responses. Uses custom `ApplicationError` error handler.
19pub type ApplicationResponse = Result<HttpResponse, ApplicationError>;
20
21/// Error derived while handling an HTTP request
22#[derive(thiserror::Error)]
23pub enum ApplicationError {
24    #[error("Authentication failed.")]
25    AuthError(#[source] AuthenticationError),
26    #[error(transparent)]
27    UnexpectedError(#[from] anyhow::Error),
28    #[error("Not Found")]
29    NotFoundError(String),
30}
31
32impl ResponseError for ApplicationError {
33    fn error_response(&self) -> HttpResponse {
34        match self {
35            Self::UnexpectedError(_e) => HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR),
36            Self::AuthError(_e) => {
37                let mut response = HttpResponse::new(StatusCode::UNAUTHORIZED);
38                let header_value = HeaderValue::from_str(r#"Basic realm="publish""#).unwrap();
39                response
40                    .headers_mut()
41                    .insert(header::WWW_AUTHENTICATE, header_value);
42                response
43            }
44            Self::NotFoundError(_message) => HttpResponse::new(StatusCode::NOT_FOUND),
45        }
46    }
47}
48
49/// Creates an HTTP response with a JSON body constructed from any serializable input
50pub fn json_response(data: impl serde::Serialize) -> ApplicationResponse {
51    Ok(HttpResponse::Ok().json(data))
52}
53
54impl std::fmt::Debug for ApplicationError {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        crate::services::error::error_chain_fmt(self, f)
57    }
58}
59
60impl From<sqlx::Error> for ApplicationError {
61    fn from(e: sqlx::Error) -> Self {
62        Self::UnexpectedError(anyhow::anyhow!(e))
63    }
64}
65
66impl From<serde_json::Error> for ApplicationError {
67    fn from(e: serde_json::Error) -> Self {
68        Self::UnexpectedError(anyhow::anyhow!(e))
69    }
70}