summaryrefslogblamecommitdiff
path: root/src/handlers/colonies.rs
blob: cc9ee0eae821b348c574d941b5da8a13b43e8545 (plain) (tree)
1
2
3
4
5
6
7
8

                   


                                           

            
                                                                 




                                       

                               







                                         





                         

























                                                                                     







































                                                                                                                                                            
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<String>,
    pub ssh_authorized_keys: Vec<String>,
}

#[derive(Debug)]
struct DbMeta {
    pub uuid: String,
    pub hostname: String,
}

impl From<DbUser> 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<Arc<State>>) -> JsonResult<Json<UserData>> {
    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::<Vec<User>>();

    let data = UserData { users };

    Ok(Json(data))
}

pub async fn create_user(Json(new_user): Json<User>, state: Extension<Arc<State>>, 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<Arc<State>>, 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<String>, state: Extension<Arc<State>>) -> 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<String>, state: Extension<Arc<State>>) -> 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::<Vec<User>>();

    let data = UserData { users };

    Ok(format!("#cloud-config\n{}", serde_yaml::to_string(&data).unwrap()))

}