This commit is contained in:
2026-06-09 23:05:35 +02:00
parent ee2fc42fff
commit eb2652f7e9
27 changed files with 665 additions and 538 deletions
+6 -6
View File
@@ -1,19 +1,19 @@
use crate::routes::user::dto::UserResponse;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(Deserialize, ToSchema)]
#[derive(Debug, Deserialize, ToSchema)]
pub struct LoginRequest {
pub username: String,
pub password: String,
}
#[derive(Serialize, ToSchema)]
#[derive(Debug, Serialize, ToSchema)]
pub struct LoginResponse {
pub token: String,
pub username: String,
}
#[derive(Serialize, ToSchema)]
pub struct CheckResponse {
pub authenticated: bool,
#[derive(Debug, Serialize, ToSchema)]
pub struct MeResponse {
pub user: UserResponse,
}
+16 -13
View File
@@ -1,14 +1,17 @@
use super::dto::{CheckResponse, LoginRequest, LoginResponse};
use super::dto::{LoginRequest, LoginResponse, MeResponse};
use crate::auth::token::create_jwt;
use crate::core::AppState;
use crate::http::context::CurrentUser;
use crate::http::error::HTTPError;
use crate::routes::user::mapper::user_model_to_user_response;
use axum::extract::State;
use axum::Json;
use sea_orm::ActiveModelBehavior;
#[utoipa::path(
post,
get,
path = "/auth/login",
request_body = LoginRequest,
responses(
(status = 200, description = "Login successful", body = LoginResponse),
(status = 401, description = "Unauthorized")
@@ -29,22 +32,20 @@ pub async fn login_user_pw(
let token = create_jwt(
user.id,
&user.username,
user.is_superuser,
&state.config.jwt.secret,
state.config.jwt.duration,
)
.map_err(|_| HTTPError::InternalServerError("Failed to create JWT token".to_string()))?;
Ok(Json(LoginResponse {
username: user.username,
token,
}))
Ok(Json(LoginResponse { token }))
}
#[utoipa::path(
post,
path = "/auth/check",
path = "/auth/me",
responses(
(status = 200, description = "Login successful", body = LoginResponse),
(status = 200, description = "Token valid", body = LoginResponse),
(status = 401, description = "Unauthorized")
),
security(
@@ -52,11 +53,13 @@ pub async fn login_user_pw(
),
tag = "Auth"
)]
pub async fn check(
pub async fn me(
State(_state): State<AppState>,
_user: CurrentUser,
) -> Result<Json<CheckResponse>, HTTPError> {
Ok(Json(CheckResponse {
authenticated: true,
CurrentUser(user): CurrentUser,
) -> Result<Json<MeResponse>, HTTPError> {
let user_response = user_model_to_user_response(user);
Ok(Json(MeResponse {
user: user_response,
}))
}
+2 -2
View File
@@ -1,10 +1,10 @@
use crate::http::OxRouter;
use crate::routes::auth::handlers;
use axum::routing::post;
use axum::routing::{get, post};
use axum::Router;
pub fn router() -> OxRouter {
Router::new()
.route("/auth/login", post(handlers::login_user_pw))
.route("/auth/check", post(handlers::check))
.route("/auth/me", get(handlers::me))
}
+15 -1
View File
@@ -34,10 +34,24 @@ pub async fn join(
));
};
let user_am = join_request_to_user_am(payload, state.init_token)?;
let user_am = {
let init_token_lock = state
.init_token
.read()
.map_err(|e| HTTPError::InternalServerError(e.to_string()))?;
join_request_to_user_am(payload, *init_token_lock)?
};
let user = state.repositories.user.create(user_am).await?;
if user.is_superuser {
let mut init_token_lock = state
.init_token
.write()
.map_err(|e| HTTPError::InternalServerError(e.to_string()))?;
*init_token_lock = None;
}
state
.repositories
.server
+4 -5
View File
@@ -9,13 +9,12 @@ pub fn join_request_to_user_am(
payload: JoinRequest,
superuser_token: Option<Uuid>,
) -> AnyResult<user::ActiveModel> {
let is_super_admin = match (payload.superuser_token.as_ref(), superuser_token) {
(Some(provided), Some(init)) => provided == &init.to_string(),
_ => false,
};
let mut is_super_admin = false;
if let (Some(provided), Some(init)) = (payload.superuser_token.as_ref(), superuser_token) {
is_super_admin = provided == &init.to_string();
}
Ok(user::ActiveModel {
id: Default::default(),
username: Set(payload.username),
password: Set(hash_password(&payload.password)?),
is_superuser: Set(is_super_admin),
+5 -4
View File
@@ -29,9 +29,10 @@ pub fn router() -> OxRouter {
// Routes publiques (ou gérant leur propre auth)
let api_routes = Router::new()
.merge(secure_routes)
.merge(auth::routes::router());
.merge(auth::routes::router())
.merge(core::routes::router());
Router::new().nest("/api", api_routes).merge(
SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", openapi::ApiDoc::openapi()),
)
Router::new()
.nest("/api", api_routes)
.merge(SwaggerUi::new("/swagger").url("/api-docs/openapi.json", openapi::ApiDoc::openapi()))
}
+2 -2
View File
@@ -7,7 +7,7 @@ use utoipa::{Modify, OpenApi};
#[openapi(
paths(
auth::handlers::login_user_pw,
auth::handlers::check,
auth::handlers::me,
user::handlers::get_all,
user::handlers::get_by_id,
user::handlers::create,
@@ -44,7 +44,7 @@ use utoipa::{Modify, OpenApi};
schemas(
auth::dto::LoginRequest,
auth::dto::LoginResponse,
auth::dto::CheckResponse,
auth::dto::MeResponse,
user::dto::UserResponse,
user::dto::CreateUserRequest,
user::dto::UpdateUserRequest,
+3 -3
View File
@@ -7,14 +7,14 @@ use uuid::Uuid;
pub struct CreateUserRequest {
pub username: String,
pub password: String,
pub pub_key: String,
pub pub_key: Option<String>,
pub is_superuser: bool,
}
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct UpdateUserRequest {
pub username: String,
pub pub_key: String,
pub pub_key: Option<String>,
pub is_superuser: bool,
}
@@ -22,7 +22,7 @@ pub struct UpdateUserRequest {
pub struct UserResponse {
pub id: Uuid,
pub username: String,
pub pub_key: String,
pub pub_key: Option<String>,
pub is_superuser: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,