2026-05-21 14:22:33 +03:00
|
|
|
use cot::db::Database;
|
2026-05-21 16:21:42 +03:00
|
|
|
use cot::json::Json;
|
|
|
|
|
use cot::response::IntoResponse;
|
|
|
|
|
use cot::router::method::openapi::api_get;
|
2026-05-21 14:22:33 +03:00
|
|
|
use cot::router::{Route, Router};
|
|
|
|
|
use cot::session::Session;
|
|
|
|
|
use cot::{App, Body};
|
2026-05-21 16:21:42 +03:00
|
|
|
use schemars::JsonSchema;
|
|
|
|
|
use serde::Serialize;
|
2026-05-21 14:22:33 +03:00
|
|
|
|
|
|
|
|
use crate::auth;
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
2026-05-21 16:21:42 +03:00
|
|
|
// JSON error helper
|
2026-05-21 14:22:33 +03:00
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
fn json_error(status: cot::http::StatusCode, message: &str) -> cot::response::Response {
|
|
|
|
|
let body = serde_json::json!({ "error": message });
|
|
|
|
|
cot::http::Response::builder()
|
|
|
|
|
.status(status)
|
|
|
|
|
.header(cot::http::header::CONTENT_TYPE, "application/json")
|
|
|
|
|
.body(Body::fixed(body.to_string()))
|
|
|
|
|
.expect("valid response")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// GET /api/me
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
2026-05-21 16:21:42 +03:00
|
|
|
#[derive(Debug, Serialize, JsonSchema)]
|
|
|
|
|
struct MeResponse {
|
|
|
|
|
id: i64,
|
|
|
|
|
name: String,
|
|
|
|
|
role: String,
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-21 14:22:33 +03:00
|
|
|
async fn me_handler(
|
|
|
|
|
session: Session,
|
|
|
|
|
db: Database,
|
|
|
|
|
) -> cot::Result<cot::response::Response> {
|
|
|
|
|
let Some(user) = auth::get_session_user(&session, &db).await else {
|
|
|
|
|
return Ok(json_error(
|
|
|
|
|
cot::http::StatusCode::UNAUTHORIZED,
|
|
|
|
|
"not authenticated",
|
|
|
|
|
));
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-21 16:21:42 +03:00
|
|
|
Json(MeResponse {
|
|
|
|
|
id: user.id,
|
|
|
|
|
name: user.name,
|
|
|
|
|
role: user.role.code().to_owned(),
|
|
|
|
|
})
|
|
|
|
|
.into_response()
|
2026-05-21 14:22:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
// App
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
pub struct ApiApp;
|
|
|
|
|
|
|
|
|
|
impl App for ApiApp {
|
|
|
|
|
fn name(&self) -> &'static str {
|
|
|
|
|
"api"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn router(&self) -> Router {
|
|
|
|
|
Router::with_urls([
|
2026-05-21 16:21:42 +03:00
|
|
|
Route::with_api_handler_and_name("/me", api_get(me_handler), "api_me"),
|
2026-05-21 14:22:33 +03:00
|
|
|
])
|
|
|
|
|
}
|
|
|
|
|
}
|