diff --git a/Cargo.lock b/Cargo.lock index cde530d..9dddfca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1761,6 +1761,7 @@ dependencies = [ "async-sqlx-session", "chrono", "dotenv", + "rand_core", "serde", "sqlx", "tokio", diff --git a/Cargo.toml b/Cargo.toml index 4c85982..0acfacc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ argon2 = "0.4" askama = "0.11" actix-web = "4.0" +rand_core = { version = "0.6", features = ["std"] } serde = { version = "1.0", features = ["derive"] } async-sqlx-session = { version = "0.4", default-features = false, features = ["pg"] } tokio = { version = "1.18", features = [ diff --git a/src/config.rs b/src/config.rs index ea27b45..5f6d29c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -27,7 +27,6 @@ pub struct Config { pub listen_addr: SocketAddr, pub admin_pass: String, pub connection_string: String, - pub secret: String, pub log_level: Option, } diff --git a/src/database.rs b/src/database.rs index 7a9eff3..61695a9 100644 --- a/src/database.rs +++ b/src/database.rs @@ -17,18 +17,18 @@ */ use crate::{task, templates}; -use argon2::Argon2; -use argon2::PasswordHasher; +use argon2::password_hash::{rand_core::OsRng, SaltString}; +use argon2::{Argon2, PasswordHasher}; use sqlx::postgres::{PgConnectOptions, PgConnectionInfo, PgPoolOptions}; use sqlx::Executor; use sqlx::{ConnectOptions, PgPool}; use tracing::info; use tracing::log::LevelFilter; -pub struct Database(PgPool, String); +pub struct Database(PgPool); impl Database { - pub async fn connect(conn_string: &str, secret: &str) -> anyhow::Result { + pub async fn connect(conn_string: &str) -> anyhow::Result { let mut connect_options: PgConnectOptions = conn_string.parse()?; connect_options.log_statements(LevelFilter::Debug); info!("Connecting to the database"); @@ -41,7 +41,7 @@ impl Database { ); conn.execute(include_str!("sql/schema.sql")).await?; - Ok(Self(pool, secret.to_string())) + Ok(Self(pool)) } pub fn pool(&self) -> PgPool { @@ -76,9 +76,9 @@ impl Database { // TODO: change the category of the task inside the db } - fn hash(&self, password: &str) -> Result { + fn hash(&self, password: &str, salt: SaltString) -> Result { let argon2 = Argon2::default(); - let hash = argon2.hash_password(password.as_bytes(), &self.1); + let hash = argon2.hash_password(password.as_bytes(), &salt); if let Ok(ref hash) = hash { if let Some(ref hash) = hash.hash { return Ok(hash.to_string()); @@ -89,16 +89,19 @@ impl Database { } pub async fn register(&self, username: &str, password: &str) { - let hash = self.hash(password); + let salt = SaltString::generate(&mut OsRng); + let hash = self.hash(password, salt); if let Err(_) = hash { return; } tracing::debug!("{}", hash.unwrap()); - // TODO: insert into DB + // TODO: insert the salt and hash into the DB } pub async fn login(&self, username: &str, password: &str) { - let hash = self.hash(password); + // TODO: get the salt from the DB + let salt = SaltString::generate(&mut OsRng); + let hash = self.hash(password, salt); if let Err(_) = hash { return; } diff --git a/src/main.rs b/src/main.rs index c5de35e..32cb22c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,7 +47,7 @@ async fn main() -> anyhow::Result<()> { info!(concat!("Initializing - tmtd ", env!("CARGO_PKG_VERSION"))); let (ctx, _) = broadcast::channel(1); - let database = Arc::new(Database::connect(&cfg.connection_string, &cfg.secret).await?); + let database = Arc::new(Database::connect(&cfg.connection_string).await?); let session_store = PostgresSessionStore::from_client(database.pool()).with_table_name("sessions"); session_store.migrate().await?; diff --git a/tmtd_example.toml b/tmtd_example.toml index ce0672f..55d9ed9 100644 --- a/tmtd_example.toml +++ b/tmtd_example.toml @@ -4,9 +4,6 @@ listen_addr = "127.0.0.1:8080" admin_pass = "changeme" # Address of the postgress database connection_string = "postgres://tmtd@localhost/tmtd" -# Secret for the password hasher -# Must be atleast 4 bytes long, atleast 16 bytes (22 characters) are reccomended -secret = "changeme" # OPTIONAL # The tmtd log level, defaults to info when none is given