Files
oxspeak_server/src/routes/auth/handlers.rs
T
2026-08-16 13:00:29 +02:00

131 lines
3.6 KiB
Rust

use crate::auth::token::create_jwt;
use crate::core::AppState;
use crate::domain::dto::auth::{LoginRequest, LoginResponse, MeResponse};
use crate::http::context::CurrentUser;
use crate::http::error::HTTPError;
use crate::routes::user::mapper::user_model_to_user_response;
use axum::Json;
use axum::extract::State;
use axum_extra::extract::CookieJar;
use axum_extra::extract::cookie::{Cookie, SameSite};
use sea_orm::ActiveModelBehavior;
#[utoipa::path(
post,
path = "/auth/bearer-login",
request_body = LoginRequest,
responses(
(status = 200, description = "Login successful", body = LoginResponse),
(status = 401, description = "Unauthorized")
),
tag = "Auth"
)]
pub async fn login_bearer(
State(state): State<AppState>,
Json(payload): Json<LoginRequest>,
) -> Result<Json<LoginResponse>, HTTPError> {
let user = state
.repositories
.user
.check_password(&payload.username, &payload.password)
.await
.map_err(|_| HTTPError::Unauthorized)?;
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 { token }))
}
#[utoipa::path(
post,
path = "/auth/login",
request_body = LoginRequest,
responses(
(status = 200, description = "Login successful with cookie set", body = LoginResponse),
(status = 401, description = "Unauthorized")
),
tag = "Auth"
)]
pub async fn login_cookie(
State(state): State<AppState>,
jar: CookieJar,
Json(payload): Json<LoginRequest>,
) -> Result<(CookieJar, Json<LoginResponse>), HTTPError> {
let user = state
.repositories
.user
.check_password(&payload.username, &payload.password)
.await
.map_err(|_| HTTPError::Unauthorized)?;
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()))?;
// Création du cookie sécurisé contenant le token JWT
let cookie = Cookie::build(("token", token.clone()))
.path("/")
.http_only(true)
.same_site(SameSite::Lax)
.secure(false) // Mettez à true si vous forcez le HTTPS en production
.build();
let updated_jar = jar.add(cookie);
Ok((updated_jar, Json(LoginResponse { token })))
}
#[utoipa::path(
post,
path = "/auth/logout",
responses(
(status = 200, description = "Logout successful")
),
tag = "Auth"
)]
pub async fn logout_cookie(jar: CookieJar) -> Result<CookieJar, HTTPError> {
// On crée un cookie expiré en lui donnant une durée négative de 1 seconde (ou Duration::ZERO)
let cookie = Cookie::build(("token", ""))
.path("/")
.max_age(time::Duration::seconds(-1))
.build();
let updated_jar = jar.add(cookie);
Ok(updated_jar)
}
#[utoipa::path(
post,
path = "/auth/me",
responses(
(status = 200, description = "Token valid", body = LoginResponse),
(status = 401, description = "Unauthorized")
),
security(
("bearerAuth" = [])
),
tag = "Auth"
)]
pub async fn me(
State(_state): State<AppState>,
CurrentUser(user): CurrentUser,
) -> Result<Json<MeResponse>, HTTPError> {
let user_response = user_model_to_user_response(user);
Ok(Json(MeResponse {
user: user_response,
}))
}