use std::env; use axum::{response::Response, Router, routing::post}; use serde::Deserialize; use tower_cookies::{Cookies, Cookie}; use crate::{types::{extract::{Check, CheckResult, Json, AdminUser, Log}, http::ResponseCode}, admin, database}; #[derive(Deserialize)] struct AdminAuthRequest { secret: String, } impl Check for AdminAuthRequest { fn check(&self) -> CheckResult { Ok(()) } } async fn auth(cookies: Cookies, Json(body) : Json) -> Response { let check = env::var("SECRET").unwrap_or("admin".to_string()); if check != body.secret { return ResponseCode::BadRequest.text("Invalid admin secret") } let mut cookie = Cookie::new("admin", admin::regen_secret().await); cookie.set_secure(false); cookie.set_http_only(false); cookie.set_path("/"); cookies.add(cookie); ResponseCode::Success.text("Successfully logged in") } #[derive(Deserialize)] struct QueryRequest { query: String, } impl Check for QueryRequest { fn check(&self) -> CheckResult { Ok(()) } } async fn query(_: AdminUser, Json(body) : Json) -> Response { match database::query(body.query) { Ok(changes) => ResponseCode::Success.text(&format!("Query executed successfully. {} lines changed.", changes)), Err(err) => ResponseCode::InternalServerError.text(&format!("{}", err)) } } async fn posts(_: AdminUser, _: Log) -> Response { admin::generate_posts() } async fn users(_: AdminUser, _: Log) -> Response { admin::generate_users() } async fn sessions(_: AdminUser, _: Log) -> Response { admin::generate_sessions() } async fn check(check: Option, _: Log) -> Response { if check.is_none() { ResponseCode::Success.text("false") } else { ResponseCode::Success.text("true") } } pub fn router() -> Router { Router::new() .route("/auth", post(auth)) .route("/query", post(query)) .route("/posts", post(posts)) .route("/users", post(users)) .route("/sessions", post(sessions)) .route("/check", post(check)) }