mabel/src/routes/admin.rs

44 lines
1.3 KiB
Rust

use axum::extract::State;
use axum::http::StatusCode;
use axum::Json;
use serde_json::{json, Value};
use std::sync::Arc;
use crate::auth::{hash, random};
use crate::error::AppError;
use crate::roles::ROLE_SUPERADMIN;
use crate::state::AppState;
pub async fn bootstrap(State(state): State<Arc<AppState>>) -> Result<Json<Value>, AppError> {
// Only allow this request if the user table is completely empty!
let empty = sqlx::query!(
"SELECT CASE WHEN EXISTS(SELECT 1 FROM users) THEN false ELSE true END AS empty;"
)
.map(|row| row.empty.unwrap_or(true))
.fetch_one(&state.database)
.await?;
if empty {
return Err(AppError::ClientError {
status: StatusCode::BAD_REQUEST,
code: "already-setup".into(),
message: "The instance was already bootstrapped".into(),
});
}
let username = "admin";
let password = random();
sqlx::query!(
r#"INSERT INTO users ( name, display_name, password, roles ) VALUES ( $1, $2, $3, $4 ) RETURNING id"#,
username,
"Administrator",
hash(&password)?,
&[ROLE_SUPERADMIN],
)
.fetch_one(&state.database)
.await?;
Ok(Json(json!({"username": username, "password": password})))
}