use crate::{
config::{Config, DashboardConfig, RuntimeConfig, ServicesConfig},
services::Services,
utils::hashing::hash_password,
};
use database::{self, DatabaseConnection, Player, PlayerRole};
use log::{error, info};
use tokio::join;
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const EXTERNAL_HOST: &str = "gosredirector.ea.com";
pub struct GlobalState {
pub db: DatabaseConnection,
pub services: Services,
pub config: RuntimeConfig,
}
static mut GLOBAL_STATE: Option<GlobalState> = None;
impl GlobalState {
pub async fn init(config: Config) {
let admin_email = config.dashboard;
let services_config = ServicesConfig {
retriever: config.retriever,
};
let runtime_config = RuntimeConfig {
ports: config.ports,
galaxy_at_war: config.galaxy_at_war,
menu_message: config.menu_message,
};
let (db, services) = join!(
Self::init_database(admin_email),
Services::init(services_config)
);
unsafe {
GLOBAL_STATE = Some(GlobalState {
db,
services,
config: runtime_config,
});
}
}
async fn init_database(config: DashboardConfig) -> DatabaseConnection {
let db = database::init().await;
info!("Connected to database..");
Self::init_database_admin(&db, config).await;
db
}
async fn init_database_admin(db: &DatabaseConnection, config: DashboardConfig) {
let admin_email = match config.super_email {
Some(value) => value,
None => return,
};
let player = match Player::by_email(db, &admin_email).await {
Ok(Some(value)) => value,
Ok(None) => return,
Err(err) => {
error!("Failed to find player to provide super admin: {:?}", err);
return;
}
};
let player = match player.set_role(db, PlayerRole::SuperAdmin).await {
Ok(value) => value,
Err(err) => {
error!("Failed to assign super admin role: {:?}", err);
return;
}
};
if let Some(password) = config.super_password {
let password = hash_password(&password).expect("Failed to hash super user password");
let matches = match &player.password {
Some(value) => value.eq(&password),
None => false,
};
if !matches {
if let Err(err) = player.set_password(db, password).await {
error!("Failed to set super admin password: {:?}", err)
} else {
info!("Updated super admin password")
}
}
}
}
pub fn database() -> DatabaseConnection {
match unsafe { &GLOBAL_STATE } {
Some(value) => value.db.clone(),
None => panic!("Global state not initialized"),
}
}
pub fn services() -> &'static Services {
match unsafe { &GLOBAL_STATE } {
Some(value) => &value.services,
None => panic!("Global state not initialized"),
}
}
pub fn config() -> &'static RuntimeConfig {
match unsafe { &GLOBAL_STATE } {
Some(value) => &value.config,
None => panic!("Global state not initialized"),
}
}
}