You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
1.6 KiB
59 lines
1.6 KiB
use std::str::FromStr;
|
|
use crate::db::user::{add_user, get_user_by_name, get_user_count, DbUserRole};
|
|
use anyhow::{anyhow, Result};
|
|
use serde::Deserialize;
|
|
use sqlx::SqlitePool;
|
|
use tracing::info;
|
|
|
|
const DEFAULT_TIMEZONE: i64 = -6 * 3600;
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct BootstrapData {
|
|
users: Vec<BootstrapUser>,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
struct BootstrapUser {
|
|
name: String,
|
|
role: String,
|
|
tz_offset: Option<String>,
|
|
}
|
|
|
|
pub async fn bootstrap_database(db: &SqlitePool) -> Result<()> {
|
|
|
|
let bootstrap_str = match std::env::var("BOOTSTRAP_DATA") {
|
|
Ok(s) => {
|
|
info!("bootstrap data found, updating db: {}", s);
|
|
s
|
|
},
|
|
Err(_) => {
|
|
info!("no Bootstrap data found");
|
|
return Ok(());
|
|
},
|
|
};
|
|
|
|
let data = ron::from_str::<BootstrapData>(&bootstrap_str)?;
|
|
|
|
if db_needs_users(db).await? {
|
|
for user in &data.users {
|
|
let role = DbUserRole::try_from_str(&user.role).ok_or(anyhow!("invalid role {}", user.role))?;
|
|
let tz = if let Some(tz) = &user.tz_offset {
|
|
i64::from_str(&tz).unwrap_or(DEFAULT_TIMEZONE)
|
|
} else { DEFAULT_TIMEZONE };
|
|
if get_user_by_name(db, &user.name).await?.is_none() {
|
|
let new_id = add_user(db, &user.name, role, tz).await?;
|
|
info!("bootstrap new user {}:{} ({})", new_id, user.name, user.role);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
Ok(())
|
|
}
|
|
|
|
async fn db_needs_users(db: &SqlitePool) -> Result<bool> {
|
|
let count = get_user_count(&db).await?;
|
|
|
|
Ok(count <= 0)
|
|
}
|