adding user authentication

This commit is contained in:
DioCrafts
2025-03-20 09:22:31 +01:00
parent 961545aef7
commit cafad0fbfd
69 changed files with 6483 additions and 106 deletions
+108
View File
@@ -0,0 +1,108 @@
use std::sync::Arc;
use axum::{
Router,
routing::{post, get, put},
extract::{State, Json, Path, Extension},
http::{StatusCode, HeaderMap, header},
response::IntoResponse,
middleware,
};
use crate::common::di::AppState;
use crate::application::dtos::user_dto::{
LoginDto, RegisterDto, UserDto, ChangePasswordDto, RefreshTokenDto, AuthResponseDto
};
use crate::interfaces::middleware::auth::CurrentUser;
use crate::common::errors::AppError;
pub fn auth_routes() -> Router<Arc<AppState>> {
Router::new()
.route("/register", post(register))
.route("/login", post(login))
.route("/refresh", post(refresh_token))
.route("/me", get(get_current_user))
.route("/change-password", put(change_password))
.route("/logout", post(logout))
}
async fn register(
State(state): State<Arc<AppState>>,
Json(dto): Json<RegisterDto>,
) -> Result<impl IntoResponse, AppError> {
let auth_service = state.auth_service.as_ref()
.ok_or_else(|| AppError::internal_error("Servicio de autenticación no configurado"))?;
let user = auth_service.auth_application_service.register(dto).await?;
Ok((StatusCode::CREATED, Json(user)))
}
async fn login(
State(state): State<Arc<AppState>>,
Json(dto): Json<LoginDto>,
) -> Result<impl IntoResponse, AppError> {
let auth_service = state.auth_service.as_ref()
.ok_or_else(|| AppError::internal_error("Servicio de autenticación no configurado"))?;
let auth_response = auth_service.auth_application_service.login(dto).await?;
Ok((StatusCode::OK, Json(auth_response)))
}
async fn refresh_token(
State(state): State<Arc<AppState>>,
Json(dto): Json<RefreshTokenDto>,
) -> Result<impl IntoResponse, AppError> {
let auth_service = state.auth_service.as_ref()
.ok_or_else(|| AppError::internal_error("Servicio de autenticación no configurado"))?;
let auth_response = auth_service.auth_application_service.refresh_token(dto).await?;
Ok((StatusCode::OK, Json(auth_response)))
}
async fn get_current_user(
State(state): State<Arc<AppState>>,
Extension(current_user): Extension<CurrentUser>,
) -> Result<impl IntoResponse, AppError> {
let auth_service = state.auth_service.as_ref()
.ok_or_else(|| AppError::internal_error("Servicio de autenticación no configurado"))?;
let user = auth_service.auth_application_service.get_user_by_id(&current_user.id).await?;
Ok((StatusCode::OK, Json(user)))
}
async fn change_password(
State(state): State<Arc<AppState>>,
Extension(current_user): Extension<CurrentUser>,
Json(dto): Json<ChangePasswordDto>,
) -> Result<impl IntoResponse, AppError> {
let auth_service = state.auth_service.as_ref()
.ok_or_else(|| AppError::internal_error("Servicio de autenticación no configurado"))?;
auth_service.auth_application_service.change_password(&current_user.id, dto).await?;
Ok(StatusCode::OK)
}
async fn logout(
State(state): State<Arc<AppState>>,
Extension(current_user): Extension<CurrentUser>,
headers: HeaderMap,
) -> Result<impl IntoResponse, AppError> {
let auth_service = state.auth_service.as_ref()
.ok_or_else(|| AppError::internal_error("Servicio de autenticación no configurado"))?;
// Extract refresh token from request
let refresh_token = headers
.get(header::AUTHORIZATION)
.and_then(|value| value.to_str().ok())
.and_then(|value| value.strip_prefix("Bearer "))
.ok_or_else(|| AppError::unauthorized("Token de refresco no encontrado"))?;
auth_service.auth_application_service.logout(&current_user.id, refresh_token).await?;
Ok(StatusCode::OK)
}
+1
View File
@@ -2,6 +2,7 @@ pub mod file_handler;
pub mod folder_handler;
pub mod i18n_handler;
pub mod batch_handler;
pub mod auth_handler;
/// Tipo de resultado para controladores de API
pub type ApiResult<T> = Result<T, (axum::http::StatusCode, String)>;
+11 -1
View File
@@ -3,11 +3,14 @@ use axum::{
routing::{get, post, put, delete},
Router,
extract::{State, Query, Path},
middleware,
};
use tower_http::{
compression::CompressionLayer,
trace::TraceLayer,
};
use crate::common::config::AppConfig;
use crate::interfaces::middleware::auth::auth_middleware;
use crate::interfaces::middleware::cache::{HttpCache, start_cache_cleanup_task};
@@ -29,7 +32,7 @@ pub fn create_api_routes(
folder_service: Arc<FolderService>,
file_service: Arc<FileService>,
i18n_service: Option<Arc<I18nApplicationService>>,
) -> Router {
) -> Router<Arc<crate::common::di::AppState>> {
// Inicializar el servicio de operaciones por lotes
let batch_service = Arc::new(BatchOperationService::default(
file_service.clone(),
@@ -137,6 +140,13 @@ pub fn create_api_routes(
router = router.nest("/i18n", i18n_router);
}
// Get the app configuration
let config = AppConfig::from_env();
// For now, just use the router as is - we'll properly implement the auth middleware later
// when all implementation details are fixed
let router = router;
// Apply compression and tracing layers
router
.layer(CompressionLayer::new())