2024-11-19 00:20:31 +08:00
|
|
|
mod config;
|
|
|
|
mod database;
|
|
|
|
mod secret;
|
2024-11-09 00:05:18 +08:00
|
|
|
|
2024-11-19 00:20:31 +08:00
|
|
|
use chrono::Duration;
|
|
|
|
use database::relational;
|
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
use rocket::{get, post, http::Status, launch, response::status, routes, serde::json::Json};
|
|
|
|
use std::sync::Arc;
|
|
|
|
use tokio::sync::Mutex;
|
2024-11-11 19:31:40 +08:00
|
|
|
|
2024-11-18 19:14:37 +08:00
|
|
|
static SQL: Lazy<Arc<Mutex<Option<relational::Database>>>> =
|
|
|
|
Lazy::new(|| Arc::new(Mutex::new(None)));
|
2024-11-09 00:05:18 +08:00
|
|
|
|
2024-11-18 19:14:37 +08:00
|
|
|
async fn init_sql(database: config::SqlConfig) -> Result<(), Box<dyn std::error::Error>> {
|
2024-11-19 00:20:31 +08:00
|
|
|
let database = relational::Database::link(database).await?;
|
|
|
|
*SQL.lock().await = Some(database);
|
2024-11-11 01:38:58 +08:00
|
|
|
Ok(())
|
2024-11-09 00:05:18 +08:00
|
|
|
}
|
2024-11-11 19:31:40 +08:00
|
|
|
|
2024-11-18 19:14:37 +08:00
|
|
|
async fn get_sql() -> Result<relational::Database, Box<dyn std::error::Error>> {
|
|
|
|
SQL.lock()
|
2024-11-11 13:45:02 +08:00
|
|
|
.await
|
|
|
|
.clone()
|
2024-11-19 00:20:31 +08:00
|
|
|
.ok_or_else(|| "Database not initialized".into())
|
2024-11-09 00:05:18 +08:00
|
|
|
}
|
2024-11-11 19:31:40 +08:00
|
|
|
|
2024-11-18 19:14:37 +08:00
|
|
|
#[post("/install", format = "json", data = "<data>")]
|
|
|
|
async fn install(data: Json<config::SqlConfig>) -> Result<status::Custom<String>, status::Custom<String>> {
|
|
|
|
relational::Database::initial_setup(data.into_inner()).await.map_err(|e| {
|
2024-11-11 13:45:02 +08:00
|
|
|
status::Custom(
|
|
|
|
Status::InternalServerError,
|
2024-11-19 00:20:31 +08:00
|
|
|
format!("Database initialization failed: {}", e),
|
2024-11-11 13:45:02 +08:00
|
|
|
)
|
2024-11-11 01:38:58 +08:00
|
|
|
})?;
|
2024-11-18 19:14:37 +08:00
|
|
|
|
|
|
|
Ok(status::Custom(
|
|
|
|
Status::Ok,
|
|
|
|
format!("Initialization successful"),
|
|
|
|
))
|
2024-11-09 00:05:18 +08:00
|
|
|
}
|
2024-11-11 19:31:40 +08:00
|
|
|
|
2024-11-18 01:09:28 +08:00
|
|
|
#[get("/system")]
|
|
|
|
async fn token_system() -> Result<status::Custom<String>, status::Custom<String>> {
|
|
|
|
let claims = secret::CustomClaims {
|
2024-11-19 00:20:31 +08:00
|
|
|
user_id: String::from("system"),
|
|
|
|
device_ua: String::from("system"),
|
2024-11-18 01:09:28 +08:00
|
|
|
};
|
2024-11-18 19:14:37 +08:00
|
|
|
let token = secret::generate_jwt(claims, Duration::seconds(1)).map_err(|e| {
|
|
|
|
status::Custom(
|
|
|
|
Status::InternalServerError,
|
2024-11-19 00:20:31 +08:00
|
|
|
format!("JWT generation failed: {}", e),
|
2024-11-18 19:14:37 +08:00
|
|
|
)
|
|
|
|
})?;
|
|
|
|
|
2024-11-19 00:20:31 +08:00
|
|
|
Ok(status::Custom(Status::Ok, token))
|
2024-11-18 01:09:28 +08:00
|
|
|
}
|
|
|
|
|
2024-11-09 00:05:18 +08:00
|
|
|
#[launch]
|
|
|
|
async fn rocket() -> _ {
|
2024-11-19 00:20:31 +08:00
|
|
|
let config = config::Config::read().expect("Failed to read config");
|
2024-11-18 19:14:37 +08:00
|
|
|
|
|
|
|
if config.info.install {
|
|
|
|
init_sql(config.sql_config)
|
2024-11-11 13:45:02 +08:00
|
|
|
.await
|
2024-11-19 00:20:31 +08:00
|
|
|
.expect("Failed to connect to database");
|
2024-11-18 19:14:37 +08:00
|
|
|
rocket::build()
|
|
|
|
.mount("/auth/token", routes![token_system])
|
|
|
|
} else {
|
|
|
|
rocket::build()
|
2024-11-19 00:20:31 +08:00
|
|
|
.mount("/", routes![install])
|
2024-11-18 19:14:37 +08:00
|
|
|
}
|
2024-11-11 13:45:02 +08:00
|
|
|
}
|