use std::sync::Arc; use axum::{Extension, Json, extract::Path}; use axum_auth::AuthBearer; use sqlx::{query_as, query}; use crate::{ errors::{JsonResult, ServiceError, StringResult, NoneResult}, State, }; use solarlib::colony::{User, UserData}; use super::ships::check_bearer; #[derive(Debug, Clone)] pub struct DbUser { pub id: i32, pub name: String, pub groups: Vec, pub ssh_authorized_keys: Vec, } #[derive(Debug)] struct DbMeta { pub uuid: String, pub hostname: String, } impl From for User { fn from(o: DbUser) -> Self { Self { name: o.name, groups: o.groups, ssh_authorized_keys: o.ssh_authorized_keys, } } } pub async fn list_users(state: Extension>) -> JsonResult> { let mut conn = state.conn.acquire().await?; let db_users = query_as!(DbUser, "SELECT * FROM seed_users") .fetch_all(&mut conn) .await?; let users = db_users .into_iter() .map(|u| u.into()) .collect::>(); let data = UserData { users }; Ok(Json(data)) } pub async fn create_user(Json(new_user): Json, state: Extension>, AuthBearer(token): AuthBearer) -> NoneResult { check_bearer(token)?; let mut conn = state.conn.acquire().await?; query!("INSERT INTO seed_users (name, groups, ssh_authorized_keys) VALUES ($1, $2, $3)", new_user.name, &new_user.groups, &new_user.ssh_authorized_keys) .execute(&mut conn) .await?; Ok(()) } pub async fn add_metadata(Path((uuid, hostname)): Path<(String, String)>, state: Extension>, AuthBearer(token): AuthBearer) -> NoneResult { check_bearer(token)?; let mut conn = state.conn.acquire().await?; query!("INSERT INTO planet_metadata (uuid, hostname) VALUES ($1, $2)", uuid, hostname).execute(&mut conn).await?; Ok(()) } pub async fn meta_data(Path(uuid): Path, state: Extension>) -> StringResult { let mut conn = state.conn.acquire().await?; let m = query_as!(DbMeta, "SELECT * FROM planet_metadata WHERE uuid=$1", uuid).fetch_one(&mut conn).await?; Ok(format!("instance-id: {}\nlocal-hostname: {}", m.uuid, m.hostname)) } pub async fn user_data(Path(_uuid): Path, state: Extension>) -> StringResult { let mut conn = state.conn.acquire().await?; let db_users = query_as!(DbUser, "SELECT * FROM seed_users").fetch_all(&mut conn).await?; let users = db_users.into_iter().map(|u| u.into()).collect::>(); let data = UserData { users }; Ok(format!("#cloud-config\n{}", serde_yaml::to_string(&data).unwrap())) }