diff --git a/Cargo.lock b/Cargo.lock index cd355d5..1ac7c13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1747,7 +1747,7 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "pocket-relay" -version = "0.8.3" +version = "0.8.4" dependencies = [ "argon2", "axum", diff --git a/Cargo.toml b/Cargo.toml index 26021c5..164e230 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pocket-relay" -version = "0.8.3" +version = "0.8.4" description = "Pocket Relay Server" readme = "README.md" keywords = ["EA", "PocketRelay", "MassEffect"] @@ -71,8 +71,8 @@ parking_lot = "0.12.3" # Const safe HashMaps (Can be replaced with std HashMap after https://github.com/rust-lang/rust/issues/102575 is resolved) hashbrown = { version = "0.17.1", default-features = false, features = [ - "allocator-api2", - "inline-more", + "allocator-api2", + "inline-more", ] } uuid = { version = "^1", features = ["v4", "serde", "fast-rng"] } @@ -82,13 +82,7 @@ rand = "0.9" [dependencies.sea-orm] version = "^1" default-features = false -features = [ - "runtime-tokio-rustls", - "macros", - "with-chrono", - "with-json", - "sqlx-sqlite", -] +features = ["runtime-tokio-rustls", "macros", "with-chrono", "with-json", "sqlx-sqlite"] # SeaORM Migration [dependencies.sea-orm-migration] @@ -104,15 +98,7 @@ features = ["sink"] # Tokio async runtime [dependencies.tokio] version = "1" -features = [ - "fs", - "macros", - "net", - "parking_lot", - "rt-multi-thread", - "signal", - "sync", -] +features = ["fs", "macros", "net", "parking_lot", "rt-multi-thread", "signal", "sync"] # Axum web framework [dependencies.axum] diff --git a/src/database/mod.rs b/src/database/mod.rs index 75ce544..fdc0884 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -131,7 +131,7 @@ async fn init_database_admin(db: &DatabaseConnection, config: &Config) { if let Some(password) = &config.dashboard.super_password { // Ignore the password if empty - if !password.is_empty() { + if password.is_empty() { return; } @@ -151,3 +151,178 @@ async fn init_database_admin(db: &DatabaseConnection, config: &Config) { } } } + +#[cfg(test)] +mod test { + use sea_orm::{Database as SeaDatabase, DatabaseConnection}; + use sea_orm_migration::MigratorTrait; + + use crate::{ + config::{Config, DashboardConfig}, + database::{ + entities::{Player, PlayerRole}, + init_database_admin, + migration::Migrator, + }, + utils::hashing::verify_password, + }; + + async fn mock_db() -> DatabaseConnection { + let connection = SeaDatabase::connect("sqlite::memory:").await.unwrap(); + Migrator::up(&connection, None).await.unwrap(); + connection + } + + #[tokio::test] + async fn test_init_database_admin_apply_super_email() { + let db = mock_db().await; + let player = Player::create( + &db, + "test@test.com".to_string(), + "test".to_string(), + None, + crate::database::entities::PlayerRole::Default, + ) + .await + .unwrap(); + + assert_eq!(player.role, PlayerRole::Default); + assert_eq!(player.password, None); + + init_database_admin( + &db, + &Config { + dashboard: DashboardConfig { + super_email: Some("test@test.com".to_string()), + super_password: None, + ..Default::default() + }, + ..Default::default() + }, + ) + .await; + + let player = Player::by_email(&db, "test@test.com") + .await + .unwrap() + .expect("player should exist"); + assert_eq!(player.role, PlayerRole::SuperAdmin); + assert_eq!(player.password, None); + } + + #[tokio::test] + async fn test_init_database_admin_dont_apply_super_email() { + let db = mock_db().await; + let player = Player::create( + &db, + "test@test.com".to_string(), + "test".to_string(), + None, + crate::database::entities::PlayerRole::Default, + ) + .await + .unwrap(); + + assert_eq!(player.role, PlayerRole::Default); + assert_eq!(player.password, None); + + init_database_admin( + &db, + &Config { + dashboard: DashboardConfig { + super_email: Some("test1@test.com".to_string()), + super_password: None, + ..Default::default() + }, + ..Default::default() + }, + ) + .await; + + let player = Player::by_email(&db, "test@test.com") + .await + .unwrap() + .expect("player should exist"); + assert_eq!(player.role, PlayerRole::Default); + assert_eq!(player.password, None); + } + + #[tokio::test] + async fn test_init_database_admin_apply_super_email_password() { + let db = mock_db().await; + let player = Player::create( + &db, + "test@test.com".to_string(), + "test".to_string(), + None, + crate::database::entities::PlayerRole::Default, + ) + .await + .unwrap(); + + assert_eq!(player.role, PlayerRole::Default); + assert_eq!(player.password, None); + + let password = "test"; + + init_database_admin( + &db, + &Config { + dashboard: DashboardConfig { + super_email: Some("test@test.com".to_string()), + super_password: Some(password.to_string()), + ..Default::default() + }, + ..Default::default() + }, + ) + .await; + + let player = Player::by_email(&db, "test@test.com") + .await + .unwrap() + .expect("player should exist"); + assert_eq!(player.role, PlayerRole::SuperAdmin); + assert!(verify_password( + password, + &player.password.expect("password should be set") + )); + } + + #[tokio::test] + async fn test_init_database_admin_apply_super_email_skip_apply_empty_password() { + let db = mock_db().await; + let player = Player::create( + &db, + "test@test.com".to_string(), + "test".to_string(), + None, + crate::database::entities::PlayerRole::Default, + ) + .await + .unwrap(); + + assert_eq!(player.role, PlayerRole::Default); + assert_eq!(player.password, None); + + init_database_admin( + &db, + &Config { + dashboard: DashboardConfig { + super_email: Some("test@test.com".to_string()), + super_password: Some("".to_string()), + ..Default::default() + }, + ..Default::default() + }, + ) + .await; + + let player = Player::by_email(&db, "test@test.com") + .await + .unwrap() + .expect("player should exist"); + assert_eq!(player.role, PlayerRole::SuperAdmin); + assert_eq!(player.password, None); + } +}