feat: add user management API with endpoint to retrieve current user information
This commit is contained in:
@@ -2,6 +2,7 @@ pub mod tag {
|
||||
/// Health tag constant
|
||||
pub const HEALTH_TAG: &str = "Health";
|
||||
pub const AUTH_TAG: &str = "Authentication";
|
||||
pub const USER_TAG: &str = "User";
|
||||
}
|
||||
|
||||
#[derive(utoipa::OpenApi)]
|
||||
@@ -11,16 +12,21 @@ pub mod tag {
|
||||
// Authentication paths
|
||||
crate::routes::api::auth::login::login,
|
||||
crate::routes::api::auth::init_admin::init_admin,
|
||||
// User management paths
|
||||
crate::routes::api::restricted::user::me::get_user_info,
|
||||
),
|
||||
components(
|
||||
schemas(crate::routes::api::health::info::HealthInfo),
|
||||
// Authentication schemas
|
||||
schemas(crate::routes::api::auth::login::LoginRequest),
|
||||
schemas(crate::routes::api::auth::init_admin::AdminInitRequest),
|
||||
// User management schemas
|
||||
schemas(crate::routes::api::restricted::user::me::UserInfo),
|
||||
),
|
||||
tags(
|
||||
(name = tag::HEALTH_TAG, description = "Health information API"),
|
||||
(name = tag::AUTH_TAG, description = "Authentication API")
|
||||
(name = tag::AUTH_TAG, description = "Authentication API"),
|
||||
(name = tag::USER_TAG, description = "User management API")
|
||||
)
|
||||
)]
|
||||
pub struct ApiDoc;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
pub mod user;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::Router;
|
||||
@@ -6,8 +8,7 @@ use crate::{middlewares::require_auth::require_auth, routes::AppState};
|
||||
|
||||
pub fn get_restricted_router(state: Arc<AppState>) -> Router {
|
||||
Router::new()
|
||||
//
|
||||
//
|
||||
.nest("/user", user::get_user_router(state.clone()))
|
||||
.layer(axum::middleware::from_fn_with_state(
|
||||
state.clone(),
|
||||
require_auth,
|
||||
|
||||
13
apps/api/src/routes/api/restricted/user.rs
Normal file
13
apps/api/src/routes/api/restricted/user.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
pub mod me;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::Router;
|
||||
|
||||
use crate::routes::AppState;
|
||||
|
||||
pub fn get_user_router(state: Arc<AppState>) -> Router {
|
||||
Router::new()
|
||||
.route("/me", axum::routing::get(me::get_user_info))
|
||||
.with_state(state)
|
||||
}
|
||||
64
apps/api/src/routes/api/restricted/user/me.rs
Normal file
64
apps/api/src/routes/api/restricted/user/me.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
Extension, Json,
|
||||
extract::State,
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::error;
|
||||
|
||||
use crate::{
|
||||
middlewares::request_info::RequestInfo,
|
||||
routes::{AppState, api::openapi::tag::USER_TAG},
|
||||
};
|
||||
|
||||
/// System health information
|
||||
#[derive(Serialize, Deserialize, utoipa::ToSchema)]
|
||||
pub struct UserInfo {
|
||||
/// User ID
|
||||
pub id: uuid::Uuid,
|
||||
/// Username
|
||||
pub username: String,
|
||||
}
|
||||
|
||||
/// Get current user information
|
||||
///
|
||||
/// Returns the information of the currently authenticated user.
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/user/me",
|
||||
responses(
|
||||
(status = 200, description = "User information retrieved successfully", body = UserInfo),
|
||||
(status = 401, description = "Unauthorized"),
|
||||
(status = 500, description = "Internal server error"),
|
||||
),
|
||||
tag = USER_TAG,
|
||||
)]
|
||||
pub async fn get_user_info(
|
||||
State(app_state): State<Arc<AppState>>,
|
||||
request_info: Extension<Arc<RequestInfo>>,
|
||||
) -> Response {
|
||||
let user_id = match request_info.user_id {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
error!("User ID not found in request info");
|
||||
return (StatusCode::UNAUTHORIZED).into_response();
|
||||
}
|
||||
};
|
||||
|
||||
match app_state.service.user.get_user_by_id(user_id, None).await {
|
||||
Ok(user) => {
|
||||
let user_info = UserInfo {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
};
|
||||
(StatusCode::OK, Json(user_info)).into_response()
|
||||
}
|
||||
Err(err) => {
|
||||
error!("Error fetching user info: {}", err);
|
||||
(StatusCode::INTERNAL_SERVER_ERROR).into_response()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user