From c427dd4bb6c364bc8d5e6b55d50f7c25abca0ef7 Mon Sep 17 00:00:00 2001 From: ghost Date: Fri, 26 Sep 2025 16:25:32 +0200 Subject: [PATCH] Wire appsettings.json Config into main: bind address and credential store population --- src/config.rs | 40 ++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/main.rs | 30 ++++++++++++++++++++++++++---- 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 src/config.rs diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..a268ccd --- /dev/null +++ b/src/config.rs @@ -0,0 +1,40 @@ +use serde::Deserialize; +use std::path::Path; + +#[derive(Debug, Deserialize, Clone)] +pub struct CredentialEntry { + pub username: String, + pub password: String, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct ServerOptions { + /// Listen address, e.g. "0.0.0.0:3478" + pub bind: String, + /// Optional TLS: cert/key paths (not used in MVP) + pub tls_cert: Option, + pub tls_key: Option, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct Config { + /// Server options + pub server: ServerOptions, + /// Initial credentials to populate the credential store + #[serde(default)] + pub credentials: Vec, +} + +impl Config { + /// Load configuration from a JSON file path + pub fn from_file>(p: P) -> anyhow::Result { + let s = std::fs::read_to_string(p)?; + let cfg: Config = serde_json::from_str(&s)?; + Ok(cfg) + } + + /// Try to load `appsettings.json` from current working directory as a convenience + pub fn load_default() -> anyhow::Result { + Self::from_file("appsettings.json") + } +} diff --git a/src/lib.rs b/src/lib.rs index 2865e6e..7c0bf5f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub mod auth; pub mod traits; pub mod models; pub mod alloc; +pub mod config; pub use crate::auth::*; pub use crate::stun::*; diff --git a/src/main.rs b/src/main.rs index addca6e..bf45d21 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use niom_turn::auth::InMemoryStore; use niom_turn::stun::{parse_message, build_401_response, find_message_integrity, validate_message_integrity, build_success_response, encode_xor_relayed_address}; use niom_turn::traits::CredentialStore; use niom_turn::alloc::AllocationManager; +use niom_turn::config::Config; #[tokio::main] async fn main() -> anyhow::Result<()> { @@ -16,12 +17,33 @@ async fn main() -> anyhow::Result<()> { info!("niom-turn starting"); - // config - let bind_addr: SocketAddr = "0.0.0.0:3478".parse()?; + // config: try to load appsettings.json, otherwise fall back to defaults + let cfg = match Config::load_default() { + Ok(c) => { + info!("loaded config from appsettings.json"); + c + } + Err(e) => { + info!("no appsettings.json found or failed to load: {} — using defaults", e); + // defaults + Config { + server: niom_turn::config::ServerOptions { + bind: "0.0.0.0:3478".to_string(), + tls_cert: None, + tls_key: None, + }, + credentials: vec![niom_turn::config::CredentialEntry { username: "testuser".into(), password: "secretpassword".into() }], + } + } + }; - // Initialize credential store (MVP demo user) + let bind_addr: SocketAddr = cfg.server.bind.parse()?; + + // Initialize credential store and populate from config let creds = InMemoryStore::new(); - creds.insert("testuser", "secretpassword"); + for c in cfg.credentials.iter() { + creds.insert(&c.username, &c.password); + } // UDP listener for TURN/STUN let udp = UdpSocket::bind(bind_addr).await?;