From b45a0475ed63b1298c05ee0cb76a1eb9b24c2b11 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 11:55:12 -0400 Subject: [PATCH] Added hashing --- src/callers/register.rs | 8 ++++++++ src/hashing/mod.rs | 16 ++++++++------- src/repo/mod.rs | 44 +++++++++++++++++++++++++++++++++++++++-- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index 610f49b..55a2691 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -1,5 +1,6 @@ use axum::{Json, http::StatusCode}; +use crate::hashing; use crate::repo; pub mod request { @@ -48,6 +49,7 @@ pub async fn register_user( email_verified: true, date_created: String::from("2025-01-01 12:00:00"), last_login: String::from("nil"), + salt_id: uuid::Uuid::nil(), }; match repo::user::exists(&pool, &user.username).await { @@ -61,6 +63,12 @@ pub async fn register_user( }), ) } else { + let salt_string = hashing::generate_salt().unwrap(); + let mut salt = icarus_models::user::salt::Salt::default(); + salt.salt = salt_string.as_str().to_string(); + salt.id = repo::salt::insert(&pool, &salt).await.unwrap(); + user.salt_id = salt.id; + match repo::user::insert(&pool, &user).await { Ok(id) => { user.id = id; diff --git a/src/hashing/mod.rs b/src/hashing/mod.rs index eb08d6d..1386d0c 100644 --- a/src/hashing/mod.rs +++ b/src/hashing/mod.rs @@ -9,17 +9,18 @@ use argon2::{ }; pub fn generate_salt() -> Result { + // Generate a random salt + // SaltString::generate uses OsRng internally for cryptographic security let salt = SaltString::generate(&mut OsRng); Ok(salt) } -pub fn hash_password(password: &String) -> Result { +pub fn hash_password( + password: &String, + salt: &SaltString, +) -> Result { let password_bytes = password.as_bytes(); - // Generate a random salt - // SaltString::generate uses OsRng internally for cryptographic security - let salt = generate_salt().unwrap(); - // Create an Argon2 instance with default parameters (recommended) // You could customize parameters here if needed, but defaults are strong let argon2 = Argon2::default(); @@ -27,7 +28,7 @@ pub fn hash_password(password: &String) -> Result match verify_password(&some_password, p.clone()) { Ok(res) => { assert_eq!(res, true); diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 951395f..049a840 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -29,8 +29,8 @@ pub mod user { ) -> Result { let row = sqlx::query( r#" - INSERT INTO "user" (username, password, email, phone, firstname, lastname, email_verified, status) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + INSERT INTO "user" (username, password, email, phone, firstname, lastname, email_verified, status, salt_id) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, date_created; "#) .bind(&user.username) @@ -41,6 +41,7 @@ pub mod user { .bind(&user.lastname) .bind(user.email_verified) .bind(&user.status) + .bind(user.salt_id) .fetch_one(pool) .await .map_err(|e| { @@ -62,3 +63,42 @@ pub mod user { } } } + +pub mod salt { + use sqlx::Row; + + #[derive(Debug, serde::Serialize, sqlx::FromRow)] + pub struct InsertedData { + pub id: uuid::Uuid, + } + + pub async fn insert( + pool: &sqlx::PgPool, + salt: &icarus_models::user::salt::Salt, + ) -> Result { + let row = sqlx::query( + r#" + INSERT INTO "salt" (salt) + VALUES ($1) + RETURNING id; + "#, + ) + .bind(&salt.salt) + .fetch_one(pool) + .await + .map_err(|e| { + eprintln!("Error inserting item: {}", e); + e + })?; + + let result = InsertedData { + id: row.try_get("id").map_err(|_e| sqlx::Error::RowNotFound)?, + }; + + if !result.id.is_nil() { + Ok(result.id) + } else { + Err(sqlx::Error::RowNotFound) + } + } +}