pub mod middleware;
pub mod oidc;
pub mod session;
use crate::state::AuthState;
pub async fn descubrimiento_al_arrancar(auth: &AuthState) -> Option<String> {
match oidc::discovery_cached(auth).await {
Ok(_) => None,
Err(error) => Some(format!(
"no se pudo descubrir el proveedor de identidad al arrancar; se reintentará en el primer login: {error}"
)),
}
}
#[cfg(test)]
mod tests {
use axum::http::StatusCode;
use crate::api::api_router;
use crate::test_support::{
emisor_caido, estado_oidc_con_emisor, get, proveedor_falso::ProveedorFalso,
router_oidc_con_emisor,
};
#[tokio::test]
async fn un_descubrimiento_fallido_no_impide_arrancar() {
let estado = estado_oidc_con_emisor(&emisor_caido()).await;
let auth = estado
.auth
.as_ref()
.expect("en modo Oidc hay estado de autenticación");
let aviso = super::descubrimiento_al_arrancar(auth).await;
let aviso = aviso.expect("un descubrimiento fallido debe producir un aviso");
assert!(
aviso.contains("descubrimiento"),
"el aviso no declara el fallo del descubrimiento: {aviso}"
);
assert!(
aviso.contains("proveedor"),
"el aviso no nombra al proveedor de identidad: {aviso}"
);
let router = api_router(estado);
let salud = get(router, "/api/v1/health").await;
assert_eq!(
salud.status(),
StatusCode::OK,
"un proveedor caído no puede impedir que la salud conteste"
);
}
#[tokio::test]
async fn el_primer_login_reintenta_el_descubrimiento_y_lo_cachea() {
let proveedor = ProveedorFalso::servir().await;
let router = router_oidc_con_emisor(&proveedor.issuer).await;
let primera = get(router.clone(), "/api/v1/auth/login").await;
assert_eq!(
primera.status(),
StatusCode::FOUND,
"el login debe redirigir"
);
assert_eq!(
proveedor.peticiones_de_descubrimiento().await,
1,
"el primer login debe pedir el descubrimiento"
);
let segunda = get(router, "/api/v1/auth/login").await;
assert_eq!(
segunda.status(),
StatusCode::FOUND,
"el login debe redirigir"
);
assert_eq!(
proveedor.peticiones_de_descubrimiento().await,
1,
"el segundo login NO debe repetir la petición: el resultado debe estar cacheado"
);
}
}