use actix_web::{get, web, HttpRequest, HttpResponse, Responder};
use uuid::Uuid;
use crate::api::api_error;
use crate::api::authorize_request;
use crate::api::ok_json_with_trace;
use crate::db::crud;
use crate::AppState;
#[get("/users/{id}")]
pub async fn get_user(
app_data: web::Data<AppState>,
req: HttpRequest,
path: web::Path<Uuid>, bearer: crate::api::BearerToken,
) -> impl Responder {
let target_user_id = path.into_inner();
let empty_payload = web::Bytes::new();
let claims = match authorize_request(&app_data, &req, &bearer, &empty_payload).await {
Ok(c) => c,
Err(resp) => return resp,
};
let can_read = claims.sub == target_user_id || claims.roles.iter().any(|r| r == "admin");
if !can_read {
return api_error(
actix_web::http::StatusCode::FORBIDDEN,
"INSUFFICIENT_PERMISSIONS",
"Insufficient permissions",
);
}
let Some(pool) = &app_data.db_pool else {
return HttpResponse::ServiceUnavailable()
.body("Database backend is disabled. Configure DATABASE_URL=sqlite://...");
};
match crud::get_user_by_id(pool, &target_user_id).await {
Ok(Some(user)) => ok_json_with_trace(&req, user),
Ok(None) => HttpResponse::NotFound().body("User not found"),
Err(_) => HttpResponse::InternalServerError().body("Database error"),
}
}