diff --git a/Cargo.lock b/Cargo.lock index 0ff3dcd..9754286 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,6 +160,7 @@ dependencies = [ "hyper-util", "iso8601", "rand 0.9.1", + "rand_core 0.6.4", "serde", "serde_json", "sha2", diff --git a/Cargo.toml b/Cargo.toml index e608fe5..d009f55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,4 +24,5 @@ hex = "0.4.3" sha2 = "0.10.8" chrono = "0.4.33" iso8601 = { version = "0.6.2", features = ["chrono", "serde"] } -rand = "0.9.1" \ No newline at end of file +rand = "0.9.1" +rand_core = { version = "0.6.4", features = ["getrandom"] } diff --git a/src/app/hash.rs b/src/app/hash.rs index 3faed1e..e23d7d2 100644 --- a/src/app/hash.rs +++ b/src/app/hash.rs @@ -1,22 +1,21 @@ use argon2::{password_hash::SaltString, Argon2, PasswordHash, PasswordHasher, PasswordVerifier}; +use rand_core::OsRng; #[derive(Debug, Clone)] pub struct Hasher { - salt: SaltString, argon2: Argon2<'static>, } impl Hasher { - pub fn new(salt: &str) -> Self { + pub fn new() -> Self { Self { - salt: SaltString::from_b64(salt).unwrap(), argon2: Argon2::default(), } } pub fn hash(&self, password: &str) -> String { self.argon2 - .hash_password(password.as_bytes(), &self.salt) + .hash_password(password.as_bytes(), &SaltString::generate(&mut OsRng)) .unwrap() .to_string() } @@ -30,7 +29,7 @@ impl Hasher { impl Default for Hasher { fn default() -> Self { - Self::new(super::DEFAULT_SALT) + Self::new() } } diff --git a/src/app/mod.rs b/src/app/mod.rs index 33edf9c..6d07984 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -1,7 +1,6 @@ mod admin; mod algorithm; mod checkin; -mod config; mod hash; mod sign; mod spare; @@ -12,7 +11,6 @@ use api::{APICollection, API}; use axum::{extract::State, response::Response, routing::post, Json, Router}; use checkin::CheckinAPI; use chrono::{DateTime, TimeDelta, Utc}; -use config::Config; use hash::Hasher; use serde::{Deserialize, Serialize}; use sign::Signer; @@ -21,9 +19,7 @@ use sqlx::{migrate::MigrateDatabase, Sqlite, SqlitePool}; use tower_http::{cors::CorsLayer, trace::TraceLayer}; use user::UserAPI; -const DEFAULT_SECRET: &str = "mysecret"; - -const DEFAULT_SALT: &str = "YmFzZXNhbHQ"; +use crate::config::Config; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] enum CheckinStatus { @@ -69,7 +65,7 @@ pub fn app(pool: SqlitePool, cfg: Config) -> Router { .layer(TraceLayer::new_for_http()) .with_state(AppState { database_pool: pool, - password_hasher: Hasher::new(&cfg.salt), + password_hasher: Hasher::new(), signer: Signer::new(&cfg.secret), }) } diff --git a/src/app/sign.rs b/src/app/sign.rs index 7c13ec0..1e6304c 100644 --- a/src/app/sign.rs +++ b/src/app/sign.rs @@ -3,6 +3,8 @@ use chrono::{DateTime, Utc}; use hmac::{Hmac, Mac}; use sha2::Sha256; +use crate::config::Config; + type HmacSha256 = Hmac; #[derive(Debug, Clone)] @@ -12,7 +14,7 @@ pub struct Signer { impl Default for Signer { fn default() -> Self { - Self::new(super::DEFAULT_SECRET) + Self::new(&Config::default().secret) } } diff --git a/src/app/config.rs b/src/config.rs similarity index 56% rename from src/app/config.rs rename to src/config.rs index 428c1ea..6f88afe 100644 --- a/src/app/config.rs +++ b/src/config.rs @@ -4,15 +4,18 @@ use serde::{Deserialize, Serialize}; #[serde(default, deny_unknown_fields)] pub struct Config { pub secret: String, - pub salt: String, - // TODO: Add configuration options } impl Default for Config { fn default() -> Self { Self { - secret: String::from(super::DEFAULT_SECRET), - salt: String::from(super::DEFAULT_SALT), + secret: String::from("mysecret"), } } } + +impl Config { + pub fn parse_cfg(path: &str) -> Self { + serde_json::from_str(std::fs::read_to_string(path).unwrap().as_str()).unwrap() + } +} diff --git a/src/main.rs b/src/main.rs index 0b18311..06dc7da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,11 @@ -use app::{app, connect_pool}; - mod app; +mod config; + +use app::{app, connect_pool}; +use config::Config; const DATABASE_URL: &str = "sqlite://db/sqlite.db"; +const CONFIG_PATH: &str = "cfg/config.json"; #[tokio::main] async fn main() { @@ -11,7 +14,7 @@ async fn main() { tracing::info!("Starting application"); let app = app( connect_pool(DATABASE_URL).await, - Default::default(), + Config::parse_cfg(CONFIG_PATH), ); let listener = tokio::net::TcpListener::bind("0.0.0.0:80").await.unwrap();