Fix: /api/auth/me now returns anonymous user instead of 401

This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2026-02-04 14:10:05 -03:00
parent e7fbf0ce46
commit 1fb1feff56

View file

@ -55,15 +55,16 @@ pub struct LoginResponse {
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct CurrentUserResponse { pub struct CurrentUserResponse {
pub id: String, pub id: Option<String>,
pub username: String, pub username: Option<String>,
pub email: Option<String>, pub email: Option<String>,
pub first_name: Option<String>, pub first_name: Option<String>,
pub last_name: Option<String>, pub last_name: Option<String>,
pub display_name: Option<String>, pub display_name: Option<String>,
pub roles: Vec<String>, pub roles: Option<Vec<String>>,
pub organization_id: Option<String>, pub organization_id: Option<String>,
pub avatar_url: Option<String>, pub avatar_url: Option<String>,
pub is_anonymous: bool,
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
@ -372,35 +373,46 @@ pub async fn logout(
} }
pub async fn get_current_user( pub async fn get_current_user(
State(state): State<Arc<AppState>>, State(_state): State<Arc<AppState>>,
headers: axum::http::HeaderMap, headers: axum::http::HeaderMap,
) -> Result<Json<CurrentUserResponse>, (StatusCode, Json<ErrorResponse>)> { ) -> Json<CurrentUserResponse> {
let session_token = headers let session_token = headers
.get(header::AUTHORIZATION) .get(header::AUTHORIZATION)
.and_then(|v| v.to_str().ok()) .and_then(|v| v.to_str().ok())
.and_then(|auth| auth.strip_prefix("Bearer ")) .and_then(|auth| auth.strip_prefix("Bearer "));
.ok_or_else(|| {
warn!("get_current_user: Missing authorization header");
(
StatusCode::UNAUTHORIZED,
Json(ErrorResponse {
error: "Missing authorization token".to_string(),
details: None,
}),
)
})?;
if session_token.is_empty() { match session_token {
warn!("get_current_user: Empty authorization token"); None => {
return Err(( info!("get_current_user: no authorization header - returning anonymous user");
StatusCode::UNAUTHORIZED, Json(CurrentUserResponse {
Json(ErrorResponse { id: None,
error: "Invalid authorization token".to_string(), username: None,
details: None, email: None,
}), first_name: None,
)); last_name: None,
display_name: None,
roles: None,
organization_id: None,
avatar_url: None,
is_anonymous: true,
})
} }
Some(token) if token.is_empty() => {
info!("get_current_user: empty authorization token - returning anonymous user");
Json(CurrentUserResponse {
id: None,
username: None,
email: None,
first_name: None,
last_name: None,
display_name: None,
roles: None,
organization_id: None,
avatar_url: None,
is_anonymous: true,
})
}
Some(session_token) => {
info!("get_current_user: looking up session token (len={}, prefix={}...)", info!("get_current_user: looking up session token (len={}, prefix={}...)",
session_token.len(), session_token.len(),
&session_token[..std::cmp::min(20, session_token.len())]); &session_token[..std::cmp::min(20, session_token.len())]);
@ -409,30 +421,35 @@ pub async fn get_current_user(
if let Some(user_data) = cache.get(session_token) { if let Some(user_data) = cache.get(session_token) {
info!("get_current_user: found cached session for user: {}", user_data.email); info!("get_current_user: found cached session for user: {}", user_data.email);
Json(CurrentUserResponse {
return Ok(Json(CurrentUserResponse { id: Some(user_data.user_id.clone()),
id: user_data.user_id.clone(), username: Some(user_data.username.clone()),
username: user_data.username.clone(),
email: Some(user_data.email.clone()), email: Some(user_data.email.clone()),
first_name: user_data.first_name.clone(), first_name: user_data.first_name.clone(),
last_name: user_data.last_name.clone(), last_name: user_data.last_name.clone(),
display_name: user_data.display_name.clone(), display_name: user_data.display_name.clone(),
roles: user_data.roles.clone(), roles: Some(user_data.roles.clone()),
organization_id: user_data.organization_id.clone(), organization_id: user_data.organization_id.clone(),
avatar_url: None, avatar_url: None,
})); is_anonymous: false,
})
} else {
info!("get_current_user: session not found in cache - returning anonymous user");
Json(CurrentUserResponse {
id: None,
username: None,
email: None,
first_name: None,
last_name: None,
display_name: None,
roles: None,
organization_id: None,
avatar_url: None,
is_anonymous: true,
})
}
}
} }
drop(cache);
warn!("get_current_user: session not found in cache");
Err((
StatusCode::UNAUTHORIZED,
Json(ErrorResponse {
error: "Session expired or invalid. Please log in again.".to_string(),
details: None,
}),
))
} }
pub async fn refresh_token( pub async fn refresh_token(