use axum::{debug_handler, Json}; use models::Credentials; use utoipa_axum::{router::OpenApiRouter, routes}; use crate::{api::description::AUTH_TAG, errors::ApiError}; use super::AuthBackendType; pub mod models; // expose the OpenAPI to parent module pub fn router() -> OpenApiRouter { OpenApiRouter::new() .routes(routes!(authorize)) .routes(routes!(logout)) } #[debug_handler] #[utoipa::path( post, path = "/login", summary = "Authenticate as user", description = "Authenticate as user and receive a JWT auth token.", request_body(content = Credentials, description = "User credentials", content_type = "application/json"), responses( (status = OK, body = String, description = "Successfully logged in (JWT Token in body)"), (status = UNAUTHORIZED, description = "Invalid credentials or unauthorized user") ), tag = AUTH_TAG)] pub async fn authorize( mut auth_session: AuthBackendType, Json(credentials): Json, ) -> Result { let token = match auth_session.authenticate(credentials).await { Ok(Some(_user)) => { if let Some(token) = auth_session.get_auth_token() { token } else { return Err(ApiError::InvalidCredentials); } } Ok(None) => return Err(ApiError::InvalidCredentials), Err(_) => return Err(ApiError::InvalidCredentials), }; Ok(token) } #[debug_handler] #[utoipa::path( post, path = "/logout", summary = "Logout", description = "Log the currently logged in user out.", responses( (status = OK, description = "Logout successful") ), tag = AUTH_TAG)] pub async fn logout(mut auth_session: AuthBackendType) -> Result<(), ApiError> { auth_session.logout().await?; Ok(()) }