style: cargo fmt --all
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
use axum::{http::StatusCode, response::{IntoResponse, Response}, Json};
|
||||
use axum::{
|
||||
Json,
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use domain::errors::DomainError;
|
||||
use serde_json::json;
|
||||
|
||||
pub struct AppError(DomainError);
|
||||
|
||||
impl From<DomainError> for AppError {
|
||||
fn from(e: DomainError) -> Self { Self(e) }
|
||||
fn from(e: DomainError) -> Self {
|
||||
Self(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for AppError {
|
||||
@@ -19,7 +25,10 @@ impl IntoResponse for AppError {
|
||||
DomainError::QuotaExceeded(msg) => (StatusCode::PAYLOAD_TOO_LARGE, msg.clone()),
|
||||
DomainError::Internal(msg) => {
|
||||
tracing::error!("Internal error: {msg}");
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Internal server error".to_string())
|
||||
(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
"Internal server error".to_string(),
|
||||
)
|
||||
}
|
||||
};
|
||||
(status, Json(json!({ "error": message }))).into_response()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
extract::FromRequestParts,
|
||||
http::{request::Parts, StatusCode},
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
extract::FromRequestParts,
|
||||
http::{StatusCode, request::Parts},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use domain::value_objects::SystemId;
|
||||
use serde_json::json;
|
||||
use crate::state::AppState;
|
||||
|
||||
pub struct JwtClaims {
|
||||
pub user_id: SystemId,
|
||||
@@ -16,21 +16,36 @@ pub struct JwtClaims {
|
||||
impl FromRequestParts<AppState> for JwtClaims {
|
||||
type Rejection = Response;
|
||||
|
||||
async fn from_request_parts(parts: &mut Parts, state: &AppState) -> Result<Self, Self::Rejection> {
|
||||
async fn from_request_parts(
|
||||
parts: &mut Parts,
|
||||
state: &AppState,
|
||||
) -> Result<Self, Self::Rejection> {
|
||||
let auth_header = parts
|
||||
.headers
|
||||
.get(axum::http::header::AUTHORIZATION)
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.ok_or_else(|| {
|
||||
(StatusCode::UNAUTHORIZED, Json(json!({ "error": "Missing Authorization header" }))).into_response()
|
||||
(
|
||||
StatusCode::UNAUTHORIZED,
|
||||
Json(json!({ "error": "Missing Authorization header" })),
|
||||
)
|
||||
.into_response()
|
||||
})?;
|
||||
|
||||
let token = auth_header.strip_prefix("Bearer ").ok_or_else(|| {
|
||||
(StatusCode::UNAUTHORIZED, Json(json!({ "error": "Invalid Authorization format" }))).into_response()
|
||||
(
|
||||
StatusCode::UNAUTHORIZED,
|
||||
Json(json!({ "error": "Invalid Authorization format" })),
|
||||
)
|
||||
.into_response()
|
||||
})?;
|
||||
|
||||
let (user_id, role) = state.token_issuer.verify(token).await.map_err(|_| {
|
||||
(StatusCode::UNAUTHORIZED, Json(json!({ "error": "Invalid or expired token" }))).into_response()
|
||||
(
|
||||
StatusCode::UNAUTHORIZED,
|
||||
Json(json!({ "error": "Invalid or expired token" })),
|
||||
)
|
||||
.into_response()
|
||||
})?;
|
||||
|
||||
Ok(JwtClaims { user_id, role })
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use axum::{
|
||||
extract::{rejection::JsonRejection, FromRequest, Request},
|
||||
Json,
|
||||
extract::{FromRequest, Request, rejection::JsonRejection},
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde_json::json;
|
||||
@@ -22,7 +22,11 @@ where
|
||||
.await
|
||||
.map(|Json(value)| ValidatedJson(value))
|
||||
.map_err(|rejection| {
|
||||
(StatusCode::UNPROCESSABLE_ENTITY, Json(json!({ "error": rejection.body_text() }))).into_response()
|
||||
(
|
||||
StatusCode::UNPROCESSABLE_ENTITY,
|
||||
Json(json!({ "error": rejection.body_text() })),
|
||||
)
|
||||
.into_response()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
use axum::{extract::State, http::StatusCode, Json};
|
||||
use crate::{
|
||||
errors::AppError,
|
||||
extractors::{JwtClaims, ValidatedJson},
|
||||
state::AppState,
|
||||
};
|
||||
use api_types::{
|
||||
requests::{LoginRequest, RegisterRequest},
|
||||
responses::{AuthResponse, UserResponse},
|
||||
};
|
||||
use application::identity::{RegisterUserCommand, LoginUserCommand, GetProfileQuery};
|
||||
use crate::{errors::AppError, extractors::{JwtClaims, ValidatedJson}, state::AppState};
|
||||
use application::identity::{GetProfileQuery, LoginUserCommand, RegisterUserCommand};
|
||||
use axum::{Json, extract::State, http::StatusCode};
|
||||
|
||||
#[utoipa::path(
|
||||
post, path = "/api/v1/auth/register",
|
||||
@@ -25,8 +29,18 @@ pub async fn register(
|
||||
password: req.password,
|
||||
};
|
||||
let user = state.register_handler.execute(cmd).await?;
|
||||
let token = state.token_issuer.issue(&user.id, "user").await.map_err(AppError::from)?;
|
||||
Ok((StatusCode::CREATED, Json(AuthResponse { token, user: UserResponse::from_domain(&user) })))
|
||||
let token = state
|
||||
.token_issuer
|
||||
.issue(&user.id, "user")
|
||||
.await
|
||||
.map_err(AppError::from)?;
|
||||
Ok((
|
||||
StatusCode::CREATED,
|
||||
Json(AuthResponse {
|
||||
token,
|
||||
user: UserResponse::from_domain(&user),
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
@@ -46,7 +60,10 @@ pub async fn login(
|
||||
password: req.password,
|
||||
};
|
||||
let (user, token) = state.login_handler.execute(cmd).await?;
|
||||
Ok(Json(AuthResponse { token, user: UserResponse::from_domain(&user) }))
|
||||
Ok(Json(AuthResponse {
|
||||
token,
|
||||
user: UserResponse::from_domain(&user),
|
||||
}))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
@@ -61,7 +78,9 @@ pub async fn me(
|
||||
State(state): State<AppState>,
|
||||
claims: JwtClaims,
|
||||
) -> Result<Json<UserResponse>, AppError> {
|
||||
let query = GetProfileQuery { user_id: claims.user_id };
|
||||
let query = GetProfileQuery {
|
||||
user_id: claims.user_id,
|
||||
};
|
||||
let user = state.get_profile_handler.execute(query).await?;
|
||||
Ok(Json(UserResponse::from_domain(&user)))
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use axum::{http::StatusCode, Json};
|
||||
use axum::{Json, http::StatusCode};
|
||||
use serde_json::json;
|
||||
|
||||
#[utoipa::path(get, path = "/health", responses((status = 200, description = "Service is healthy")))]
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use utoipa::{openapi::security::{Http, HttpAuthScheme, SecurityScheme}, Modify, OpenApi};
|
||||
use utoipa_scalar::{Scalar, Servable};
|
||||
use axum::Router;
|
||||
use crate::state::AppState;
|
||||
use axum::Router;
|
||||
use utoipa::{
|
||||
Modify, OpenApi,
|
||||
openapi::security::{Http, HttpAuthScheme, SecurityScheme},
|
||||
};
|
||||
use utoipa_scalar::{Scalar, Servable};
|
||||
|
||||
#[derive(OpenApi)]
|
||||
#[openapi(
|
||||
@@ -37,5 +40,8 @@ impl Modify for SecurityAddon {
|
||||
pub fn openapi_router() -> Router<AppState> {
|
||||
Router::new()
|
||||
.merge(Scalar::with_url("/scalar", ApiDoc::openapi()))
|
||||
.route("/api-docs/openapi.json", axum::routing::get(|| async { axum::Json(ApiDoc::openapi()) }))
|
||||
.route(
|
||||
"/api-docs/openapi.json",
|
||||
axum::routing::get(|| async { axum::Json(ApiDoc::openapi()) }),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
use axum::{routing::{get, post}, Router};
|
||||
use crate::{handlers::{auth, health}, openapi::openapi_router, state::AppState};
|
||||
use crate::{
|
||||
handlers::{auth, health},
|
||||
openapi::openapi_router,
|
||||
state::AppState,
|
||||
};
|
||||
use axum::{
|
||||
Router,
|
||||
routing::{get, post},
|
||||
};
|
||||
|
||||
pub fn api_v1_router() -> Router<AppState> {
|
||||
Router::new()
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use application::identity::{GetProfileHandler, LoginUserHandler, RegisterUserHandler};
|
||||
use std::sync::Arc;
|
||||
use application::identity::{RegisterUserHandler, LoginUserHandler, GetProfileHandler};
|
||||
|
||||
use domain::ports::{StoragePort, TokenIssuer};
|
||||
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub register_handler: Arc<RegisterUserHandler>,
|
||||
@@ -21,6 +20,12 @@ impl AppState {
|
||||
token_issuer: Arc<dyn TokenIssuer>,
|
||||
storage: Arc<dyn StoragePort>,
|
||||
) -> Self {
|
||||
Self { register_handler, login_handler, get_profile_handler, token_issuer, storage }
|
||||
Self {
|
||||
register_handler,
|
||||
login_handler,
|
||||
get_profile_handler,
|
||||
token_issuer,
|
||||
storage,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user