From 4fb9505f65a48fa62348ada3660c790e4d13cba9 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 3 Apr 2025 14:41:16 -0400 Subject: [PATCH 01/55] Updated .env.sample --- .env.sample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.sample b/.env.sample index 1625b7a..5cad34d 100644 --- a/.env.sample +++ b/.env.sample @@ -1,2 +1,2 @@ DATABASE_URL=postgres://username:password@localhost/database_name -TEST_DATABASE_URL=postgres://username:password@localhost/database_name_test +TEST_DATABASE_URL=postgres://icarus_op_test:password@localhost/icarus_auth_test -- 2.43.0 From 943d258cc03f9278fc662b7ada4ba808d6d08bfc Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 3 Apr 2025 15:13:45 -0400 Subject: [PATCH 02/55] Updated migration --- migrations/20250402221858_init_migrate.sql | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/migrations/20250402221858_init_migrate.sql b/migrations/20250402221858_init_migrate.sql index 8ddc1d3..9bf6818 100644 --- a/migrations/20250402221858_init_migrate.sql +++ b/migrations/20250402221858_init_migrate.sql @@ -1 +1,13 @@ -- Add migration script here +-- CREATE DATABASE icarus_auth_test; + +-- ALTER DATABASE icarus_auth_test OWNER TO icarus_op_test; + +CREATE EXTENSION IF NOT EXISTS pgcrypto; + +CREATE TABLE IF NOT EXISTS "user" ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + username TEXT NOT NULL, + password TEXT NOT NULL, + date_created TIMESTAMPTZ NOT NULL DEFAULT NOW() +); \ No newline at end of file -- 2.43.0 From 9cfec4fa27529cf67072295923813da5061bf17f Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 3 Apr 2025 15:21:13 -0400 Subject: [PATCH 03/55] Integrated migrations --- src/main.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main.rs b/src/main.rs index 3e254b3..a079bca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,6 +37,13 @@ async fn app() -> Router { .await .expect("Failed to create pool"); + // Run migrations using the sqlx::migrate! macro + // Assumes your migrations are in a ./migrations folder relative to Cargo.toml + sqlx::migrate!("./migrations") + .run(&pool) + .await + .expect("Failed to run migrations on testcontainer DB"); + routes().await.layer(axum::Extension(pool)) } -- 2.43.0 From 5943a3342cbc31cbe1a4fe3e7b5a7b9f74d51345 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 3 Apr 2025 15:52:24 -0400 Subject: [PATCH 04/55] Added uuid support --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index fac1e92..061d402 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,9 @@ tokio = { version = "1.44.1", features = ["rt-multi-thread"] } tracing-subscriber = { version = "0.3.19" } tower = { version = "0.5.2" } hyper = { version = "1.6.0" } -sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls"] } +sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls", "uuid"] } dotenvy = { version = "0.15.7" } +uuid = { version = "1.16.0" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } [dev-dependencies] -- 2.43.0 From 35c35660d8b5ea10eae03bbf4140328e3fc2aecd Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 3 Apr 2025 16:09:01 -0400 Subject: [PATCH 05/55] Added support to serialize uuid --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 061d402..80fcf2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ tower = { version = "0.5.2" } hyper = { version = "1.6.0" } sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls", "uuid"] } dotenvy = { version = "0.15.7" } -uuid = { version = "1.16.0" } +uuid = { version = "1.16.0", features = ["v4", "serde"] } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } [dev-dependencies] -- 2.43.0 From 07cd30f8976c561d0a5c56142626a66654d331e9 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 3 Apr 2025 16:09:57 -0400 Subject: [PATCH 06/55] Saving changes --- src/callers/register.rs | 44 +++++++++++++++++++++++++++++++++++++++-- src/models/common.rs | 3 +++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index 7a1299a..1330ef4 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -1,12 +1,52 @@ use axum::{Json, http::StatusCode}; +// use sqlx::{Executor, PgPool, Row, postgres::PgPoolOptions}; // Added Row for potential use use crate::models; pub async fn register_user( + axum::Extension(pool): axum::Extension, Json(payload): Json, ) -> (StatusCode, Json) { - let user = models::common::User { + let mut user = models::common::User { + id: uuid::Uuid::nil(), username: payload.username.clone(), + password: payload.password.clone(), }; - (StatusCode::CREATED, Json(user)) + + let insert_sql = "INSERT INTO \"user\" (username, password) VALUES ($1, $2) RETURNING id"; + println!("SQL: {:?}", insert_sql); + /* + sqlx::query(insert_sql) + .bind(&user.username) + .bind(&user.password) + .execute(&pool) + .await; + */ + + /* + let returned_id: uuid::Uuid = sqlx::query_scalar(insert_sql) + .bind(&user.username) + .bind(&user.password) + .fetch_one(&pool).await? // fetch_one expects exactly one row + */ + let id = match sqlx::query_scalar(insert_sql) + .bind(&user.username) // Bind the input message securely + .bind(&user.password) + .fetch_one(&pool) // Execute and expect exactly ONE row with ONE column back + .await + { + Ok(o) => o, + _ => { + uuid::Uuid::nil() + // (StatusCode::BAD_REQUEST, Json(user)) + } + }; + + if id != uuid::Uuid::nil() { + println!("User inserted."); + user.id = id; + (StatusCode::CREATED, Json(user)) + } else { + (StatusCode::BAD_REQUEST, Json(user)) + } } diff --git a/src/models/common.rs b/src/models/common.rs index cda15f2..6838cfb 100644 --- a/src/models/common.rs +++ b/src/models/common.rs @@ -3,9 +3,12 @@ use serde::{Deserialize, Serialize}; #[derive(Deserialize)] pub struct CreateUser { pub username: String, + pub password: String, } #[derive(Serialize)] pub struct User { + pub id: uuid::Uuid, pub username: String, + pub password: String, } -- 2.43.0 From 104b1827a6be6918a15cf6a7704ad577ef0d630e Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 3 Apr 2025 16:13:18 -0400 Subject: [PATCH 07/55] Updating migration commands --- run_migrations.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/run_migrations.txt b/run_migrations.txt index ae8892a..f29a9f8 100644 --- a/run_migrations.txt +++ b/run_migrations.txt @@ -1,3 +1,15 @@ cargo install sqlx-cli sqlx migrate add init_migration sqlx migrate run + +# Create +sqlx database create + +# Drop +sqlx database drop + +# setup +sqlx database setup + +# Reset +sqlx database reset \ No newline at end of file -- 2.43.0 From aec7fff676a163f812806198ea93694c99b021d1 Mon Sep 17 00:00:00 2001 From: KD Date: Thu, 3 Apr 2025 16:40:02 -0400 Subject: [PATCH 08/55] Updated instructions --- run_migrations.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/run_migrations.txt b/run_migrations.txt index f29a9f8..66d3518 100644 --- a/run_migrations.txt +++ b/run_migrations.txt @@ -1,3 +1,7 @@ +# Make sure role has CREATEDB +ALTER ROLE username_that_needs_permission CREATEDB; + +# Install migrations cargo install sqlx-cli sqlx migrate add init_migration sqlx migrate run @@ -12,4 +16,4 @@ sqlx database drop sqlx database setup # Reset -sqlx database reset \ No newline at end of file +sqlx database reset -- 2.43.0 From 6c2d7264dc1dd7b084b65dee5ba7b0ad2b692be1 Mon Sep 17 00:00:00 2001 From: KD Date: Thu, 3 Apr 2025 16:51:35 -0400 Subject: [PATCH 09/55] Removing code --- src/main.rs | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/main.rs b/src/main.rs index a079bca..64534e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,11 +2,9 @@ use axum::{ Router, routing::{get, post}, }; -// use std::net::SocketAddr; use icarus_auth::callers; use icarus_auth::config; -// use sqlx::Postgres; #[tokio::main] async fn main() { @@ -52,14 +50,9 @@ mod tests { use super::*; use axum::{ body::Body, - // extract::connect_info::MockConnectInfo, http::{Request, StatusCode}, }; use http_body_util::BodyExt; - // use http_body_util::BodyExt; // for `collect` - // use serde_json::{Value, json}; - // use tokio::net::TcpListener; - // use tower::{Service, ServiceExt}; // for `call`, `oneshot`, and `ready` use tower::ServiceExt; // for `call`, `oneshot`, and `ready` #[tokio::test] @@ -80,23 +73,6 @@ mod tests { assert_eq!(response.status(), StatusCode::OK); - /* - match response.into_body().collect().await { - Ok(o) => { - let parsed: String = match String::from_utf8(o.to_bytes()) { - Ok(s) => s, - Err(err) => { - String::new() - } - }; - } - Err(err) => { - assert!(false, - "Error: {:?}", err.to_string()); - } - } - */ - let body = response.into_body().collect().await.unwrap().to_bytes(); assert_eq!(&body[..], b"Hello, World!"); } -- 2.43.0 From dba7d23a40abe07066e9d5d4b7b04931a4e117c0 Mon Sep 17 00:00:00 2001 From: KD Date: Thu, 3 Apr 2025 16:57:31 -0400 Subject: [PATCH 10/55] Updating workflow changes --- .gitea/workflows/workflow.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index acfa95b..bf591c4 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -78,8 +78,8 @@ jobs: echo "Running database migrations..." # ===> IMPORTANT: Replace placeholder below with your actual migration command <=== # Example: Install and run sqlx-cli - # cargo install sqlx-cli --no-default-features --features native-tls,postgres - # sqlx database setup --database-url $TEST_DATABASE_URL + cargo install sqlx-cli --no-default-features --features native-tls,postgres + sqlx database setup --database-url $TEST_DATABASE_URL # Example: Install and run diesel_cli # cargo install diesel_cli --no-default-features --features postgres -- 2.43.0 From fe97131e7c53f17aa488cf803588419d7af40843 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 3 Apr 2025 17:27:57 -0400 Subject: [PATCH 11/55] Workflow changes --- .gitea/workflows/workflow.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index bf591c4..992cc5e 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -76,17 +76,8 @@ jobs: SSH_AUTH_SOCK: ${{ env.SSH_AUTH_SOCK }} run: | echo "Running database migrations..." - # ===> IMPORTANT: Replace placeholder below with your actual migration command <=== - # Example: Install and run sqlx-cli cargo install sqlx-cli --no-default-features --features native-tls,postgres sqlx database setup --database-url $TEST_DATABASE_URL - - # Example: Install and run diesel_cli - # cargo install diesel_cli --no-default-features --features postgres - # diesel migration run --database-url $TEST_DATABASE_URL - - # echo "[Placeholder] Your migration command goes here." - # ===> End of Placeholder <=== - name: Run tests env: # Define TEST_DATABASE_URL for tests to use @@ -159,4 +150,3 @@ jobs: eval $(ssh-agent -s) ssh-add -v ~/.ssh/icarus_models_deploy_key cargo build --release - -- 2.43.0 From b8e5b65704b71dba3c12bff0b0c09adae105d061 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 10:09:54 -0400 Subject: [PATCH 12/55] Added dependencies to hash passwords --- Cargo.toml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 80fcf2e..f699178 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,9 +14,11 @@ hyper = { version = "1.6.0" } sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls", "uuid"] } dotenvy = { version = "0.15.7" } uuid = { version = "1.16.0", features = ["v4", "serde"] } +argon2 = { version = "0.5.3", features = ["std"] } # Use the latest 0.5.x version +rand = { version = "0.9" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } [dev-dependencies] -http-body-util = "0.1.3" +http-body-util = { version = "0.1.3" } reqwest = { version = "0.12.5", features = ["json"] } # For making HTTP requests in tests -once_cell = "1.19" # Useful for lazy initialization in tests/app setup +once_cell = { version = "1.19" } # Useful for lazy initialization in tests/app setup -- 2.43.0 From 6eed51a87653a839e273b4645b9e351fd67f9637 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 10:29:36 -0400 Subject: [PATCH 13/55] Added hashing code --- src/hashing/mod.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 2 files changed, 74 insertions(+) create mode 100644 src/hashing/mod.rs diff --git a/src/hashing/mod.rs b/src/hashing/mod.rs new file mode 100644 index 0000000..eb7ed39 --- /dev/null +++ b/src/hashing/mod.rs @@ -0,0 +1,73 @@ +use argon2::{ + Argon2, // The Argon2 algorithm struct + PasswordVerifier, + password_hash::{ + PasswordHasher, + SaltString, + rand_core::OsRng, // Secure random number generator + }, +}; + +pub fn hash_password(password: &String) -> Result { + let password_bytes = password.as_bytes(); + + // Generate a random salt + // SaltString::generate uses OsRng internally for cryptographic security + let salt = SaltString::generate(&mut OsRng); + + // Create an Argon2 instance with default parameters (recommended) + // You could customize parameters here if needed, but defaults are strong + let argon2 = Argon2::default(); + + // Hash the password with the salt + // The output is a PasswordHash string format that includes algorithm, version, + // parameters, salt, and the hash itself. + let password_hash = argon2.hash_password(password_bytes, &salt)?.to_string(); + + Ok(password_hash) +} + +pub fn verify_password( + password_attempt: &String, + stored_hash: String, +) -> Result { + let password_bytes = password_attempt.as_bytes(); + + // Parse the stored hash string + // This extracts the salt, parameters, and hash digest + let parsed_hash = argon2::PasswordHash::new(stored_hash.as_str())?; + + // Create an Argon2 instance (it will use the parameters from the parsed hash) + let argon2 = Argon2::default(); + + // Verify the password against the parsed hash + // This automatically uses the correct salt and parameters embedded in `parsed_hash` + match argon2.verify_password(password_bytes, &parsed_hash) { + Ok(()) => Ok(true), // Passwords match + Err(argon2::password_hash::Error::Password) => Ok(false), // Passwords don't match + Err(e) => Err(e), // Some other error occurred (e.g., invalid hash format) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_hash_password() { + let some_password = String::from("somethingrandom"); + match hash_password(&some_password) { + Ok(p) => match verify_password(&some_password, p.clone()) { + Ok(res) => { + assert_eq!(res, true); + } + Err(err) => { + assert!(false, "Error: {:?}", err.to_string()); + } + }, + Err(eerr) => { + assert!(false, "Error: {:?}", eerr.to_string()); + } + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 641a39d..f1f9d66 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod callers; pub mod config; +pub mod hashing; pub mod models; mod keys { -- 2.43.0 From 92ef6a5064f9a4afc2f875f4c66f4b29bdbc9dd2 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 10:31:20 -0400 Subject: [PATCH 14/55] Updated migrations --- migrations/20250402221858_init_migrate.sql | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/migrations/20250402221858_init_migrate.sql b/migrations/20250402221858_init_migrate.sql index 9bf6818..16796d7 100644 --- a/migrations/20250402221858_init_migrate.sql +++ b/migrations/20250402221858_init_migrate.sql @@ -1,8 +1,4 @@ -- Add migration script here --- CREATE DATABASE icarus_auth_test; - --- ALTER DATABASE icarus_auth_test OWNER TO icarus_op_test; - CREATE EXTENSION IF NOT EXISTS pgcrypto; CREATE TABLE IF NOT EXISTS "user" ( @@ -10,4 +6,4 @@ CREATE TABLE IF NOT EXISTS "user" ( username TEXT NOT NULL, password TEXT NOT NULL, date_created TIMESTAMPTZ NOT NULL DEFAULT NOW() -); \ No newline at end of file +); -- 2.43.0 From 9d42981cd4cd4de3d2a7b91fc2b89708a099eed5 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 11:11:46 -0400 Subject: [PATCH 15/55] Updated icarus_models --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f699178..c014972 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ dotenvy = { version = "0.15.7" } uuid = { version = "1.16.0", features = ["v4", "serde"] } argon2 = { version = "0.5.3", features = ["std"] } # Use the latest 0.5.x version rand = { version = "0.9" } -icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.2.0" } +icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.3.0" } [dev-dependencies] http-body-util = { version = "0.1.3" } -- 2.43.0 From 24feec56af03723eb352dcda9dd38612fdaadbd4 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 11:12:00 -0400 Subject: [PATCH 16/55] Cleanup --- src/callers/register.rs | 62 +++++++++++++++++------------------------ src/lib.rs | 1 + src/models/common.rs | 2 +- src/repo/mod.rs | 20 +++++++++++++ 4 files changed, 48 insertions(+), 37 deletions(-) create mode 100644 src/repo/mod.rs diff --git a/src/callers/register.rs b/src/callers/register.rs index 1330ef4..4436a98 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -1,52 +1,42 @@ use axum::{Json, http::StatusCode}; -// use sqlx::{Executor, PgPool, Row, postgres::PgPoolOptions}; // Added Row for potential use use crate::models; +use crate::repo; + +mod response { + use serde::{Deserialize, Serialize}; + + use crate::models; + + #[derive(Deserialize, Serialize)] + pub struct Response { + pub message: String, + pub data: models::common::User, + } +} pub async fn register_user( axum::Extension(pool): axum::Extension, Json(payload): Json, -) -> (StatusCode, Json) { +) -> (StatusCode, Json) { let mut user = models::common::User { id: uuid::Uuid::nil(), username: payload.username.clone(), password: payload.password.clone(), }; - let insert_sql = "INSERT INTO \"user\" (username, password) VALUES ($1, $2) RETURNING id"; - println!("SQL: {:?}", insert_sql); - /* - sqlx::query(insert_sql) - .bind(&user.username) - .bind(&user.password) - .execute(&pool) - .await; - */ - - /* - let returned_id: uuid::Uuid = sqlx::query_scalar(insert_sql) - .bind(&user.username) - .bind(&user.password) - .fetch_one(&pool).await? // fetch_one expects exactly one row - */ - let id = match sqlx::query_scalar(insert_sql) - .bind(&user.username) // Bind the input message securely - .bind(&user.password) - .fetch_one(&pool) // Execute and expect exactly ONE row with ONE column back - .await - { - Ok(o) => o, - _ => { - uuid::Uuid::nil() - // (StatusCode::BAD_REQUEST, Json(user)) + match repo::user::insert(&pool, &user).await { + Ok(id) => { + println!("User inserted."); + user.id = id; + (StatusCode::CREATED, Json(response::Response{ + message: String::from("User inserted"), + data: user, + })) } - }; - - if id != uuid::Uuid::nil() { - println!("User inserted."); - user.id = id; - (StatusCode::CREATED, Json(user)) - } else { - (StatusCode::BAD_REQUEST, Json(user)) + Err(err) => (StatusCode::BAD_REQUEST, Json(response::Response{ + message: err.to_string(), + data: user, + })) } } diff --git a/src/lib.rs b/src/lib.rs index f1f9d66..ab8bf15 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ pub mod callers; pub mod config; pub mod hashing; pub mod models; +pub mod repo; mod keys { pub const DBURL: &str = "DATABASE_URL"; diff --git a/src/models/common.rs b/src/models/common.rs index 6838cfb..8bf5ab7 100644 --- a/src/models/common.rs +++ b/src/models/common.rs @@ -6,7 +6,7 @@ pub struct CreateUser { pub password: String, } -#[derive(Serialize)] +#[derive(Deserialize, Serialize)] pub struct User { pub id: uuid::Uuid, pub username: String, diff --git a/src/repo/mod.rs b/src/repo/mod.rs new file mode 100644 index 0000000..95d3c7a --- /dev/null +++ b/src/repo/mod.rs @@ -0,0 +1,20 @@ +pub mod user { + use crate::models; + + pub async fn insert( + pool: &sqlx::PgPool, + user: &models::common::User, + ) -> Result { + let insert_sql = "INSERT INTO \"user\" (username, password) VALUES ($1, $2) RETURNING id"; + + match sqlx::query_scalar(insert_sql) + .bind(&user.username) // Bind the input message securely + .bind(&user.password) + .fetch_one(pool) // Execute and expect exactly ONE row with ONE column back + .await + { + Ok(o) => Ok(o), + Err(err) => Err(err), // _ => uuid::Uuid::nil(), + } + } +} -- 2.43.0 From 5cd45aa643fcdb09f8ed0025427fc3762a9b819a Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 11:15:55 -0400 Subject: [PATCH 17/55] Removed print statement --- src/callers/register.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index 4436a98..0a569d4 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -27,7 +27,6 @@ pub async fn register_user( match repo::user::insert(&pool, &user).await { Ok(id) => { - println!("User inserted."); user.id = id; (StatusCode::CREATED, Json(response::Response{ message: String::from("User inserted"), -- 2.43.0 From 32e6355040faec9a1d7b4fa9a7315685e68a7624 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 11:16:43 -0400 Subject: [PATCH 18/55] Code formatting --- src/callers/register.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index 0a569d4..1462583 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -28,14 +28,20 @@ pub async fn register_user( match repo::user::insert(&pool, &user).await { Ok(id) => { user.id = id; - (StatusCode::CREATED, Json(response::Response{ - message: String::from("User inserted"), - data: user, - })) + ( + StatusCode::CREATED, + Json(response::Response { + message: String::from("User inserted"), + data: user, + }), + ) } - Err(err) => (StatusCode::BAD_REQUEST, Json(response::Response{ - message: err.to_string(), - data: user, - })) + Err(err) => ( + StatusCode::BAD_REQUEST, + Json(response::Response { + message: err.to_string(), + data: user, + }), + ), } } -- 2.43.0 From 08d35c36805db40448311b74aa3e60de5bccaa70 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 11:21:49 -0400 Subject: [PATCH 19/55] Updated helpful instructions --- run_migrations.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/run_migrations.txt b/run_migrations.txt index 66d3518..927b280 100644 --- a/run_migrations.txt +++ b/run_migrations.txt @@ -3,6 +3,12 @@ ALTER ROLE username_that_needs_permission CREATEDB; # Install migrations cargo install sqlx-cli + +# Make sure to populate DATABASE_URL with correct value. +# By default, the DATABASE_URL found in .env file will be used +export DATABASE_URL="postgres://icarus_op_test:password@localhost/icarus_auth_test" + +# init sqlx migrate add init_migration sqlx migrate run -- 2.43.0 From c9f17b936f08efa3cfbfac4aee9e3285d48287f7 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 18:59:46 -0400 Subject: [PATCH 20/55] Added test for register endpoint with transactions --- src/main.rs | 137 ++++++++++++++++++++++++++++++++++--------- src/models/common.rs | 2 +- 2 files changed, 110 insertions(+), 29 deletions(-) diff --git a/src/main.rs b/src/main.rs index 64534e0..63a0e79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,3 @@ -use axum::{ - Router, - routing::{get, post}, -}; - use icarus_auth::callers; use icarus_auth::config; @@ -11,7 +6,7 @@ async fn main() { // initialize tracing tracing_subscriber::fmt::init(); - let app = app().await; + let app = init::app().await; // run our app with hyper, listening globally on port 3000 let url = config::get_full(); @@ -19,30 +14,46 @@ async fn main() { axum::serve(listener, app).await.unwrap(); } -async fn routes() -> Router { - // build our application with a route - Router::new() - .route(callers::endpoints::DBTEST, get(callers::common::db_ping)) - .route(callers::endpoints::ROOT, get(callers::common::root)) - .route( - callers::endpoints::REGISTER, - post(callers::register::register_user), - ) +mod db { + pub async fn migrations(pool: &sqlx::PgPool) { + // Run migrations using the sqlx::migrate! macro + // Assumes your migrations are in a ./migrations folder relative to Cargo.toml + sqlx::migrate!("./migrations") + .run(pool) + .await + .expect("Failed to run migrations on testcontainer DB"); + } } -async fn app() -> Router { - let pool = icarus_auth::db_pool::create_pool() - .await - .expect("Failed to create pool"); +mod init { + use axum::{ + Router, + routing::{get, post}, + }; - // Run migrations using the sqlx::migrate! macro - // Assumes your migrations are in a ./migrations folder relative to Cargo.toml - sqlx::migrate!("./migrations") - .run(&pool) - .await - .expect("Failed to run migrations on testcontainer DB"); + use crate::callers; + use crate::db; - routes().await.layer(axum::Extension(pool)) + pub async fn routes() -> Router { + // build our application with a route + Router::new() + .route(callers::endpoints::DBTEST, get(callers::common::db_ping)) + .route(callers::endpoints::ROOT, get(callers::common::root)) + .route( + callers::endpoints::REGISTER, + post(callers::register::register_user), + ) + } + + pub async fn app() -> Router { + let pool = icarus_auth::db_pool::create_pool() + .await + .expect("Failed to create pool"); + + db::migrations(&pool).await; + + routes().await.layer(axum::Extension(pool)) + } } #[cfg(test)] @@ -53,11 +64,13 @@ mod tests { http::{Request, StatusCode}, }; use http_body_util::BodyExt; + // use reqwest; + use serde_json::json; use tower::ServiceExt; // for `call`, `oneshot`, and `ready` #[tokio::test] - async fn hello_world() { - let app = app().await; + async fn test_hello_world() { + let app = init::app().await; // `Router` implements `tower::Service>` so we can // call it like any tower service, no need to run an HTTP server. @@ -76,4 +89,72 @@ mod tests { let body = response.into_body().collect().await.unwrap().to_bytes(); assert_eq!(&body[..], b"Hello, World!"); } + + #[tokio::test] + async fn test_register_user() { + let pool = icarus_auth::db_pool::create_pool() + .await + .expect("Failed to create pool"); + db::migrations(&pool).await; + + let mut tx = pool.begin().await.unwrap(); + let app = init::routes().await.layer(axum::Extension(pool)); + + let usr = icarus_auth::models::common::CreateUser { + username: String::from("somethingsss"), + password: String::from("Raindown!"), + }; + + /* + let client = reqwest::Client::new(); + let url = icarus_auth::callers::endpoints::REGISTER; + let response = app.oneshot( + println!("Errr") + ) + .await.unwrap(); + */ + + /* + match client.post(url).json(&usr).send().await { + Ok(response) => {} + Err(err) => { + assert!(false, "Error: {:?}", err.to_string()); + } + } + */ + + let payload = json!({ + "username": usr.username, + "password": usr.password, + }); + + assert!(true, "Info: {:?}", payload); + println!("Info: {:?}", payload); + + let response = app + .oneshot( + Request::builder() + .method(axum::http::Method::POST) + .uri(callers::endpoints::REGISTER) + .header(axum::http::header::CONTENT_TYPE, "application/json") + // .body(Body::new(axum::Json(usr))) + // .body(Body::empty()) + .body(Body::from(payload.to_string())) + // .body(Body::from("{\"username\": \"sssss\",\"theanswer\"}")) + .unwrap(), + ) + .await; + // .unwrap(); + + match response { + Ok(resp) => { + assert_eq!(resp.status(), StatusCode::CREATED, "Message: {:?}", resp); + } + Err(err) => { + assert!(false, "Error: {:?}", err.to_string()); + } + }; + + tx.rollback().await.unwrap(); + } } diff --git a/src/models/common.rs b/src/models/common.rs index 8bf5ab7..7b978d5 100644 --- a/src/models/common.rs +++ b/src/models/common.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; -#[derive(Deserialize)] +#[derive(Deserialize, Serialize)] pub struct CreateUser { pub username: String, pub password: String, -- 2.43.0 From 63ecc90bb597ae0a38bb0b7c3f5810192874f9a7 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 19:02:01 -0400 Subject: [PATCH 21/55] Cleanup --- src/main.rs | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/main.rs b/src/main.rs index 63a0e79..dcf1074 100644 --- a/src/main.rs +++ b/src/main.rs @@ -97,7 +97,7 @@ mod tests { .expect("Failed to create pool"); db::migrations(&pool).await; - let mut tx = pool.begin().await.unwrap(); + let tx = pool.begin().await.unwrap(); let app = init::routes().await.layer(axum::Extension(pool)); let usr = icarus_auth::models::common::CreateUser { @@ -105,46 +105,21 @@ mod tests { password: String::from("Raindown!"), }; - /* - let client = reqwest::Client::new(); - let url = icarus_auth::callers::endpoints::REGISTER; - let response = app.oneshot( - println!("Errr") - ) - .await.unwrap(); - */ - - /* - match client.post(url).json(&usr).send().await { - Ok(response) => {} - Err(err) => { - assert!(false, "Error: {:?}", err.to_string()); - } - } - */ - let payload = json!({ "username": usr.username, "password": usr.password, }); - assert!(true, "Info: {:?}", payload); - println!("Info: {:?}", payload); - let response = app .oneshot( Request::builder() .method(axum::http::Method::POST) .uri(callers::endpoints::REGISTER) .header(axum::http::header::CONTENT_TYPE, "application/json") - // .body(Body::new(axum::Json(usr))) - // .body(Body::empty()) .body(Body::from(payload.to_string())) - // .body(Body::from("{\"username\": \"sssss\",\"theanswer\"}")) .unwrap(), ) .await; - // .unwrap(); match response { Ok(resp) => { -- 2.43.0 From 076fbad5785682d9acef90df1a20104fbe4d5640 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 19:17:15 -0400 Subject: [PATCH 22/55] Added --- src/main.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index dcf1074..f4d0849 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,10 +64,16 @@ mod tests { http::{Request, StatusCode}, }; use http_body_util::BodyExt; - // use reqwest; + use serde::{Deserialize, Serialize}; use serde_json::json; use tower::ServiceExt; // for `call`, `oneshot`, and `ready` + #[derive(Deserialize, Serialize)] + struct Response { + pub message: String, + pub data: icarus_auth::models::common::User, + } + #[tokio::test] async fn test_hello_world() { let app = init::app().await; @@ -106,8 +112,8 @@ mod tests { }; let payload = json!({ - "username": usr.username, - "password": usr.password, + "username": &usr.username, + "password": &usr.password, }); let response = app @@ -124,6 +130,15 @@ mod tests { match response { Ok(resp) => { assert_eq!(resp.status(), StatusCode::CREATED, "Message: {:?}", resp); + let body = axum::body::to_bytes(resp.into_body(), usize::MAX) + .await + .unwrap(); + let parsed_body: Response = serde_json::from_slice(&body).unwrap(); + + assert_eq!( + usr.username, parsed_body.data.username, + "Usernames do not match" + ); } Err(err) => { assert!(false, "Error: {:?}", err.to_string()); -- 2.43.0 From 791ba56c040ee11d36d302aed1d59da26cf03afb Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 21:40:04 -0400 Subject: [PATCH 23/55] Added id check --- src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.rs b/src/main.rs index dfe28f5..f6ed812 100644 --- a/src/main.rs +++ b/src/main.rs @@ -220,6 +220,8 @@ mod tests { .unwrap(); let parsed_body: Response = serde_json::from_slice(&body).unwrap(); + assert_eq!(false, parsed_body.data.id.is_nil(), "Id is not populated"); + assert_eq!( usr.username, parsed_body.data.username, "Usernames do not match" -- 2.43.0 From cec7765096ba80b324f9a23bd15c943cfaf2c9d1 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 22:17:33 -0400 Subject: [PATCH 24/55] Saving changes --- src/callers/register.rs | 22 +++++++++++++++++++++- src/main.rs | 15 ++++++++++----- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index 1462583..b09c883 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -3,7 +3,27 @@ use axum::{Json, http::StatusCode}; use crate::models; use crate::repo; -mod response { +pub mod request { + use serde::{Deserialize, Serialize}; + + #[derive(Default, Deserialize, Serialize)] + pub struct Request { + #[serde(skip_serializing_if = "String::is_empty")] + pub username: String, + #[serde(skip_serializing_if = "String::is_empty")] + pub password: String, + #[serde(skip_serializing_if = "String::is_empty")] + pub email: String, + #[serde(skip_serializing_if = "String::is_empty")] + pub phone: String, + #[serde(skip_serializing_if = "String::is_empty")] + pub firstname: String, + #[serde(skip_serializing_if = "String::is_empty")] + pub lastname: String, + } +} + +pub mod response { use serde::{Deserialize, Serialize}; use crate::models; diff --git a/src/main.rs b/src/main.rs index f6ed812..9c6b015 100644 --- a/src/main.rs +++ b/src/main.rs @@ -191,10 +191,9 @@ mod tests { let app = init::routes().await.layer(axum::Extension(pool)); - let usr = icarus_auth::models::common::CreateUser { - username: String::from("somethingsss"), - password: String::from("Raindown!"), - }; + let mut usr = icarus_auth::callers::register::request::Request::default(); + usr.username = String::from("somethingsss"); + usr.password = String::from("Raindown!"); let payload = json!({ "username": &usr.username, @@ -214,7 +213,13 @@ mod tests { match response { Ok(resp) => { - assert_eq!(resp.status(), StatusCode::CREATED, "Message: {:?}", resp); + assert_eq!( + resp.status(), + StatusCode::CREATED, + "Message: {:?} {:?}", + resp, + usr.username + ); let body = axum::body::to_bytes(resp.into_body(), usize::MAX) .await .unwrap(); -- 2.43.0 From af72d791108686d887d97bcf7000080f2904fd5c Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 22:29:21 -0400 Subject: [PATCH 25/55] Switched to request --- src/callers/register.rs | 2 +- src/main.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index b09c883..8bf5285 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -37,7 +37,7 @@ pub mod response { pub async fn register_user( axum::Extension(pool): axum::Extension, - Json(payload): Json, + Json(payload): Json, ) -> (StatusCode, Json) { let mut user = models::common::User { id: uuid::Uuid::nil(), diff --git a/src/main.rs b/src/main.rs index 9c6b015..82fc7e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -198,6 +198,10 @@ mod tests { let payload = json!({ "username": &usr.username, "password": &usr.password, + "email": "dev@null.com", + "phone": "1234567890", + "firstname": "Bob", + "lastname": "Smith", }); let response = app -- 2.43.0 From 83f0e777c93c56ec5e93fbe232e6ce7614d1fb02 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 22:33:32 -0400 Subject: [PATCH 26/55] Changes --- src/main.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 82fc7e4..cf14000 100644 --- a/src/main.rs +++ b/src/main.rs @@ -65,16 +65,9 @@ mod tests { http::{Request, StatusCode}, }; use http_body_util::BodyExt; - use serde::{Deserialize, Serialize}; use serde_json::json; use tower::ServiceExt; // for `call`, `oneshot`, and `ready` - #[derive(Deserialize, Serialize)] - struct Response { - pub message: String, - pub data: icarus_auth::models::common::User, - } - mod db_mgr { use std::str::FromStr; @@ -227,7 +220,8 @@ mod tests { let body = axum::body::to_bytes(resp.into_body(), usize::MAX) .await .unwrap(); - let parsed_body: Response = serde_json::from_slice(&body).unwrap(); + let parsed_body: callers::register::response::Response = + serde_json::from_slice(&body).unwrap(); assert_eq!(false, parsed_body.data.id.is_nil(), "Id is not populated"); -- 2.43.0 From 550947f051e013a2d42287b1178b7d1b8352df17 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 22:39:42 -0400 Subject: [PATCH 27/55] Changing data of response --- src/callers/register.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index 8bf5285..fee223f 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -31,7 +31,7 @@ pub mod response { #[derive(Deserialize, Serialize)] pub struct Response { pub message: String, - pub data: models::common::User, + pub data: Vec, } } @@ -52,7 +52,7 @@ pub async fn register_user( StatusCode::CREATED, Json(response::Response { message: String::from("User inserted"), - data: user, + data: vec![user], }), ) } @@ -60,7 +60,7 @@ pub async fn register_user( StatusCode::BAD_REQUEST, Json(response::Response { message: err.to_string(), - data: user, + data: vec![user], }), ), } -- 2.43.0 From bf0be8e9545cafd1dc259a6b9412800fd0e94947 Mon Sep 17 00:00:00 2001 From: phoenix Date: Fri, 4 Apr 2025 22:47:24 -0400 Subject: [PATCH 28/55] Test refactor --- src/main.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index cf14000..252cf9d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -184,17 +184,22 @@ mod tests { let app = init::routes().await.layer(axum::Extension(pool)); - let mut usr = icarus_auth::callers::register::request::Request::default(); - usr.username = String::from("somethingsss"); - usr.password = String::from("Raindown!"); + let usr = icarus_auth::callers::register::request::Request { + username: String::from("somethingsss"), + password: String::from("Raindown!"), + email: String::from("dev@null.com"), + phone: String::from("1234567890"), + firstname: String::from("Bob"), + lastname: String::from("Smith"), + }; let payload = json!({ "username": &usr.username, "password": &usr.password, - "email": "dev@null.com", - "phone": "1234567890", - "firstname": "Bob", - "lastname": "Smith", + "email": &usr.email, + "phone": &usr.phone, + "firstname": &usr.firstname, + "lastname": &usr.lastname, }); let response = app @@ -222,11 +227,12 @@ mod tests { .unwrap(); let parsed_body: callers::register::response::Response = serde_json::from_slice(&body).unwrap(); + let returned_usr = &parsed_body.data[0]; - assert_eq!(false, parsed_body.data.id.is_nil(), "Id is not populated"); + assert_eq!(false, returned_usr.id.is_nil(), "Id is not populated"); assert_eq!( - usr.username, parsed_body.data.username, + usr.username, returned_usr.username, "Usernames do not match" ); } -- 2.43.0 From fc7ecacf0e22aec1601bb215271298c800f04f7d Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 00:02:19 -0400 Subject: [PATCH 29/55] Updated dependencies --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7cbd4f0..93038fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,11 +11,12 @@ tokio = { version = "1.44.1", features = ["rt-multi-thread"] } tracing-subscriber = { version = "0.3.19" } tower = { version = "0.5.2" } hyper = { version = "1.6.0" } -sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls", "uuid"] } +sqlx = { version = "0.8.3", features = ["postgres", "runtime-tokio-native-tls", "time", "uuid"] } dotenvy = { version = "0.15.7" } uuid = { version = "1.16.0", features = ["v4", "serde"] } argon2 = { version = "0.5.3", features = ["std"] } # Use the latest 0.5.x version rand = { version = "0.9" } +time = { version = "0.3.41", features = ["macros", "serde"] } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.3.0" } [dev-dependencies] -- 2.43.0 From cfe292cd89d90159398f67fe7fa1c660f6f6fcf8 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 00:02:29 -0400 Subject: [PATCH 30/55] Added code --- src/callers/register.rs | 15 ++++++++----- src/repo/mod.rs | 50 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index fee223f..a17d2bc 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -1,6 +1,5 @@ use axum::{Json, http::StatusCode}; -use crate::models; use crate::repo; pub mod request { @@ -26,12 +25,10 @@ pub mod request { pub mod response { use serde::{Deserialize, Serialize}; - use crate::models; - #[derive(Deserialize, Serialize)] pub struct Response { pub message: String, - pub data: Vec, + pub data: Vec, } } @@ -39,10 +36,18 @@ pub async fn register_user( axum::Extension(pool): axum::Extension, Json(payload): Json, ) -> (StatusCode, Json) { - let mut user = models::common::User { + let mut user = icarus_models::user::User { id: uuid::Uuid::nil(), username: payload.username.clone(), password: payload.password.clone(), + email: payload.email.clone(), + phone: payload.phone.clone(), + firstname: payload.firstname.clone(), + lastname: payload.lastname.clone(), + status: String::from("Active"), + email_verified: true, + date_created: String::from("2025-01-01 12:00:00"), + last_login: String::from("nil"), }; match repo::user::insert(&pool, &user).await { diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 95d3c7a..17a544f 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -1,20 +1,64 @@ pub mod user { - use crate::models; + // use crate::models; + // use serde::Serialize; + + #[derive(Debug, serde::Serialize, sqlx::FromRow)] + pub struct InsertedData { + pub id: uuid::Uuid, + pub date_created: Option, + // pub email: String, + } pub async fn insert( pool: &sqlx::PgPool, - user: &models::common::User, + user: &icarus_models::user::User, ) -> Result { - let insert_sql = "INSERT INTO \"user\" (username, password) VALUES ($1, $2) RETURNING id"; + let result = sqlx::query_as!( + InsertedData, + r#" + INSERT INTO "user" (username, password, email, phone, firstname, lastname, email_verified, status, date_created) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW()) + RETURNING id, date_created; + "#, + &user.username, // Bind the input message securely + &user.password, + &user.email, + &user.phone, + &user.firstname, + &user.lastname, + user.email_verified, + user.status + ) + .fetch_one(pool) + .await + .map_err(|e| { + eprintln!("Error inserting item: {}", e); + e + }); + + match result { + Ok(id) => Ok(id.id), + Err(err) => Err(err), + } + + /* + let insert_sql = "INSERT INTO \"user\" (username, password, email, phone, firstname, lastname, email_verified, status) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id"; match sqlx::query_scalar(insert_sql) .bind(&user.username) // Bind the input message securely .bind(&user.password) + .bind(&user.email) + .bind(&user.phone) + .bind(&user.firstname) + .bind(&user.lastname) + .bind(user.email_verified) + .bind(&user.status) .fetch_one(pool) // Execute and expect exactly ONE row with ONE column back .await { Ok(o) => Ok(o), Err(err) => Err(err), // _ => uuid::Uuid::nil(), } + */ } } -- 2.43.0 From 5e46a163dcea4fe317812e8d34df6e89129bc427 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 00:02:37 -0400 Subject: [PATCH 31/55] Updated migrations --- migrations/20250402221858_init_migrate.sql | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/migrations/20250402221858_init_migrate.sql b/migrations/20250402221858_init_migrate.sql index 16796d7..887dd05 100644 --- a/migrations/20250402221858_init_migrate.sql +++ b/migrations/20250402221858_init_migrate.sql @@ -5,5 +5,12 @@ CREATE TABLE IF NOT EXISTS "user" ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), username TEXT NOT NULL, password TEXT NOT NULL, - date_created TIMESTAMPTZ NOT NULL DEFAULT NOW() + email TEXT NOT NULL, + phone TEXT NOT NULL, + firstname TEXT NOT NULL, + lastname TEXT NOT NULL, + email_verified BOOL NOT NULL, + date_created TIMESTAMPTZ NULL DEFAULT NOW(), + status TEXT NOT NULL, + last_login TEXT NULL ); -- 2.43.0 From 2577332612b6dbb7d790a0f1e44b30db068ae8e8 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 00:10:00 -0400 Subject: [PATCH 32/55] Updated migrations --- migrations/20250402221858_init_migrate.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/migrations/20250402221858_init_migrate.sql b/migrations/20250402221858_init_migrate.sql index 887dd05..814c3cd 100644 --- a/migrations/20250402221858_init_migrate.sql +++ b/migrations/20250402221858_init_migrate.sql @@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS "user" ( firstname TEXT NOT NULL, lastname TEXT NOT NULL, email_verified BOOL NOT NULL, - date_created TIMESTAMPTZ NULL DEFAULT NOW(), + date_created TIMESTAMPTZ NOT NULL DEFAULT NOW(), status TEXT NOT NULL, - last_login TEXT NULL + last_login TIMESTAMPTZ NULL DEFAULT NOW() ); -- 2.43.0 From dc1f417c4f118d2e031748493b3176a85eeecff7 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 00:10:11 -0400 Subject: [PATCH 33/55] Minor refactoring --- src/main.rs | 4 ++++ src/repo/mod.rs | 30 +++--------------------------- 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index 252cf9d..6487049 100644 --- a/src/main.rs +++ b/src/main.rs @@ -235,6 +235,10 @@ mod tests { usr.username, returned_usr.username, "Usernames do not match" ); + assert!( + !returned_usr.date_created.is_empty(), + "Date Created is empty" + ); } Err(err) => { assert!(false, "Error: {:?}", err.to_string()); diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 17a544f..7f3ce8f 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -1,12 +1,8 @@ pub mod user { - // use crate::models; - // use serde::Serialize; - #[derive(Debug, serde::Serialize, sqlx::FromRow)] pub struct InsertedData { pub id: uuid::Uuid, pub date_created: Option, - // pub email: String, } pub async fn insert( @@ -16,11 +12,11 @@ pub mod user { let result = sqlx::query_as!( InsertedData, r#" - INSERT INTO "user" (username, password, email, phone, firstname, lastname, email_verified, status, date_created) - VALUES ($1, $2, $3, $4, $5, $6, $7, $8, NOW()) + INSERT INTO "user" (username, password, email, phone, firstname, lastname, email_verified, status) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, date_created; "#, - &user.username, // Bind the input message securely + &user.username, &user.password, &user.email, &user.phone, @@ -40,25 +36,5 @@ pub mod user { Ok(id) => Ok(id.id), Err(err) => Err(err), } - - /* - let insert_sql = "INSERT INTO \"user\" (username, password, email, phone, firstname, lastname, email_verified, status) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id"; - - match sqlx::query_scalar(insert_sql) - .bind(&user.username) // Bind the input message securely - .bind(&user.password) - .bind(&user.email) - .bind(&user.phone) - .bind(&user.firstname) - .bind(&user.lastname) - .bind(user.email_verified) - .bind(&user.status) - .fetch_one(pool) // Execute and expect exactly ONE row with ONE column back - .await - { - Ok(o) => Ok(o), - Err(err) => Err(err), // _ => uuid::Uuid::nil(), - } - */ } } -- 2.43.0 From 0661d3ffe6dc76d1b084d004d25e0ad8e9bc38e2 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 00:24:23 -0400 Subject: [PATCH 34/55] Saving changes --- src/repo/mod.rs | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 7f3ce8f..48d6b59 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -1,4 +1,6 @@ pub mod user { + use sqlx::Row; + #[derive(Debug, serde::Serialize, sqlx::FromRow)] pub struct InsertedData { pub id: uuid::Uuid, @@ -9,32 +11,38 @@ pub mod user { pool: &sqlx::PgPool, user: &icarus_models::user::User, ) -> Result { - let result = sqlx::query_as!( - InsertedData, + 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) RETURNING id, date_created; - "#, - &user.username, - &user.password, - &user.email, - &user.phone, - &user.firstname, - &user.lastname, - user.email_verified, - user.status - ) + "#) + .bind(&user.username) + .bind(&user.password) + .bind(&user.email) + .bind(&user.phone) + .bind(&user.firstname) + .bind(&user.lastname) + .bind(user.email_verified) + .bind(&user.status) .fetch_one(pool) .await .map_err(|e| { eprintln!("Error inserting item: {}", e); e - }); + })?; - match result { - Ok(id) => Ok(id.id), - Err(err) => Err(err), + let result = InsertedData { + id: row.try_get("id").map_err(|_e| sqlx::Error::RowNotFound)?, + date_created: row + .try_get("date_created") + .map_err(|_e| sqlx::Error::RowNotFound)?, + }; + + if !result.id.is_nil() { + Ok(result.id) + } else { + Err(sqlx::Error::RowNotFound) } } } -- 2.43.0 From 7ee160b2db849be032598444135be1ec6bf43ca5 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 00:56:32 -0400 Subject: [PATCH 35/55] More refactoring --- src/callers/register.rs | 41 +++++++++++++++++++++++++++++++---------- src/repo/mod.rs | 20 ++++++++++++++++++++ 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index a17d2bc..a966c01 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -50,16 +50,37 @@ pub async fn register_user( last_login: String::from("nil"), }; - match repo::user::insert(&pool, &user).await { - Ok(id) => { - user.id = id; - ( - StatusCode::CREATED, - Json(response::Response { - message: String::from("User inserted"), - data: vec![user], - }), - ) + match repo::user::exists(&pool, &user.username).await { + Ok(res) => { + if res { + return ( + StatusCode::NOT_FOUND, + Json(response::Response { + message: String::from("Error"), + data: vec![user], + }), + ); + } else { + match repo::user::insert(&pool, &user).await { + Ok(id) => { + user.id = id; + ( + StatusCode::CREATED, + Json(response::Response { + message: String::from("User inserted"), + data: vec![user], + }), + ) + } + Err(err) => ( + StatusCode::BAD_REQUEST, + Json(response::Response { + message: err.to_string(), + data: vec![user], + }), + ), + } + } } Err(err) => ( StatusCode::BAD_REQUEST, diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 48d6b59..744ced5 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -7,6 +7,26 @@ pub mod user { pub date_created: Option, } + pub async fn exists(pool: &sqlx::PgPool, username: &String) -> Result { + let result = sqlx::query( + r#" + SELECT 1 FROM "user" WHERE username = $1 + "#, + ) + .bind(&username) + .fetch_optional(pool) + .await; + + match result { + Ok(r) => Ok(r.is_some()), + Err(e) => { + println!("Error: {:?}", e.to_string()); + // Err(e) + Err(e) + } + } + } + pub async fn insert( pool: &sqlx::PgPool, user: &icarus_models::user::User, -- 2.43.0 From 948b08d4c70ba6eb049d0c26a91d5701a50eddeb Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 00:57:44 -0400 Subject: [PATCH 36/55] Cleanup --- src/repo/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 744ced5..709c7fd 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -19,11 +19,7 @@ pub mod user { match result { Ok(r) => Ok(r.is_some()), - Err(e) => { - println!("Error: {:?}", e.to_string()); - // Err(e) - Err(e) - } + Err(e) => Err(e), } } -- 2.43.0 From f6f2370fee1e8a9959d4222e0989da217e4c4c5b Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 01:01:39 -0400 Subject: [PATCH 37/55] Warning fixes --- src/callers/register.rs | 4 ++-- src/repo/mod.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index a966c01..610f49b 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -53,13 +53,13 @@ pub async fn register_user( match repo::user::exists(&pool, &user.username).await { Ok(res) => { if res { - return ( + ( StatusCode::NOT_FOUND, Json(response::Response { message: String::from("Error"), data: vec![user], }), - ); + ) } else { match repo::user::insert(&pool, &user).await { Ok(id) => { diff --git a/src/repo/mod.rs b/src/repo/mod.rs index 709c7fd..951395f 100644 --- a/src/repo/mod.rs +++ b/src/repo/mod.rs @@ -13,7 +13,7 @@ pub mod user { SELECT 1 FROM "user" WHERE username = $1 "#, ) - .bind(&username) + .bind(username) .fetch_optional(pool) .await; -- 2.43.0 From 973159bc465272301fba2aa56dc0ebcb5ebfeca2 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 01:06:49 -0400 Subject: [PATCH 38/55] Updated gitea workflow --- .gitea/workflows/workflow.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index 2303b81..41c0fab 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -19,6 +19,7 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: 1.85.0 + - name: Code check - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key @@ -95,6 +96,7 @@ jobs: with: toolchain: 1.85.0 - run: rustup component add rustfmt + - name: Code formatting - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key @@ -114,6 +116,7 @@ jobs: with: toolchain: 1.85.0 - run: rustup component add clippy + - name: Warnings - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key @@ -132,6 +135,7 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: 1.85.0 + - name: Build - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key -- 2.43.0 From 68d8d057b10dc0ff4b5277cf86d2efcf4b71ec33 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 01:13:41 -0400 Subject: [PATCH 39/55] Workflow fix --- .gitea/workflows/workflow.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index 41c0fab..2303b81 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -19,7 +19,6 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: 1.85.0 - - name: Code check - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key @@ -96,7 +95,6 @@ jobs: with: toolchain: 1.85.0 - run: rustup component add rustfmt - - name: Code formatting - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key @@ -116,7 +114,6 @@ jobs: with: toolchain: 1.85.0 - run: rustup component add clippy - - name: Warnings - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key @@ -135,7 +132,6 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: 1.85.0 - - name: Build - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key -- 2.43.0 From 5e683c1b48b193d7da24047823e2c6e4c879e361 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 11:41:02 -0400 Subject: [PATCH 40/55] Updated migrations --- migrations/20250402221858_init_migrate.sql | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/migrations/20250402221858_init_migrate.sql b/migrations/20250402221858_init_migrate.sql index 814c3cd..8fe068c 100644 --- a/migrations/20250402221858_init_migrate.sql +++ b/migrations/20250402221858_init_migrate.sql @@ -12,5 +12,11 @@ CREATE TABLE IF NOT EXISTS "user" ( email_verified BOOL NOT NULL, date_created TIMESTAMPTZ NOT NULL DEFAULT NOW(), status TEXT NOT NULL, - last_login TIMESTAMPTZ NULL DEFAULT NOW() + last_login TIMESTAMPTZ NULL DEFAULT NOW(), + salt_id UUID NOT NULL +); + +CREATE TABLE IF NOT EXISTS "salt" ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + salt TEXT NOT NULL ); -- 2.43.0 From d6699c27424cabcc9848a53aa1ca0398f23ad3cd Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 11:41:22 -0400 Subject: [PATCH 41/55] Moved salt generation code --- src/hashing/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hashing/mod.rs b/src/hashing/mod.rs index eb7ed39..eb08d6d 100644 --- a/src/hashing/mod.rs +++ b/src/hashing/mod.rs @@ -8,12 +8,17 @@ use argon2::{ }, }; +pub fn generate_salt() -> Result { + let salt = SaltString::generate(&mut OsRng); + Ok(salt) +} + pub fn hash_password(password: &String) -> Result { let password_bytes = password.as_bytes(); // Generate a random salt // SaltString::generate uses OsRng internally for cryptographic security - let salt = SaltString::generate(&mut OsRng); + let salt = generate_salt().unwrap(); // Create an Argon2 instance with default parameters (recommended) // You could customize parameters here if needed, but defaults are strong -- 2.43.0 From 7644d7c2d8e129f4cd4106ea5fe95b01e2d2e149 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 11:54:57 -0400 Subject: [PATCH 42/55] Updated icarus_models --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 93038fa..5cc386f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ uuid = { version = "1.16.0", features = ["v4", "serde"] } argon2 = { version = "0.5.3", features = ["std"] } # Use the latest 0.5.x version rand = { version = "0.9" } time = { version = "0.3.41", features = ["macros", "serde"] } -icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.3.0" } +icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.3.0-devel-255aff414a-111" } [dev-dependencies] http-body-util = { version = "0.1.3" } -- 2.43.0 From b45a0475ed63b1298c05ee0cb76a1eb9b24c2b11 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 11:55:12 -0400 Subject: [PATCH 43/55] 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) + } + } +} -- 2.43.0 From 7aa18dc843c7cba7d801e692aa02be672ea4b6ad Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 12:02:25 -0400 Subject: [PATCH 44/55] Hashing password --- src/callers/register.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index 55a2691..b8f53d8 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -65,9 +65,13 @@ 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(); + let generated_salt = salt_string; + salt.salt = generated_salt.to_string(); salt.id = repo::salt::insert(&pool, &salt).await.unwrap(); user.salt_id = salt.id; + let hashed_password = + hashing::hash_password(&user.password, &generated_salt).unwrap(); + user.password = hashed_password; match repo::user::insert(&pool, &user).await { Ok(id) => { -- 2.43.0 From aa42fead5d524eba0f903689e6e1dabd938c59f0 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 12:04:34 -0400 Subject: [PATCH 45/55] Removing last_login init --- src/callers/register.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index b8f53d8..fa45994 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -48,7 +48,7 @@ pub async fn register_user( status: String::from("Active"), email_verified: true, date_created: String::from("2025-01-01 12:00:00"), - last_login: String::from("nil"), + last_login: String::new(), salt_id: uuid::Uuid::nil(), }; -- 2.43.0 From 832f024356258e1833036548929214a5f5eb49d7 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 12:29:15 -0400 Subject: [PATCH 46/55] Code refactoring --- src/callers/register.rs | 2 +- src/lib.rs | 1 - src/models/common.rs | 14 -------------- src/models/mod.rs | 1 - 4 files changed, 1 insertion(+), 17 deletions(-) delete mode 100644 src/models/common.rs delete mode 100644 src/models/mod.rs diff --git a/src/callers/register.rs b/src/callers/register.rs index fa45994..b279bb7 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -47,7 +47,7 @@ pub async fn register_user( lastname: payload.lastname.clone(), status: String::from("Active"), email_verified: true, - date_created: String::from("2025-01-01 12:00:00"), + date_created: time::OffsetDateTime::now_utc().to_string(), last_login: String::new(), salt_id: uuid::Uuid::nil(), }; diff --git a/src/lib.rs b/src/lib.rs index 891aac4..1e67995 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,6 @@ pub mod callers; pub mod config; pub mod hashing; -pub mod models; pub mod repo; pub mod keys { diff --git a/src/models/common.rs b/src/models/common.rs deleted file mode 100644 index 7b978d5..0000000 --- a/src/models/common.rs +++ /dev/null @@ -1,14 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[derive(Deserialize, Serialize)] -pub struct CreateUser { - pub username: String, - pub password: String, -} - -#[derive(Deserialize, Serialize)] -pub struct User { - pub id: uuid::Uuid, - pub username: String, - pub password: String, -} diff --git a/src/models/mod.rs b/src/models/mod.rs deleted file mode 100644 index 34994bf..0000000 --- a/src/models/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod common; -- 2.43.0 From 07f112909d9d03b648c52c196d499b3f45fe9538 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 12:33:45 -0400 Subject: [PATCH 47/55] Updated icarus_model --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5cc386f..a96587a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ uuid = { version = "1.16.0", features = ["v4", "serde"] } argon2 = { version = "0.5.3", features = ["std"] } # Use the latest 0.5.x version rand = { version = "0.9" } time = { version = "0.3.41", features = ["macros", "serde"] } -icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.3.0-devel-255aff414a-111" } +icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.3.0-devel-d476b128cb-111" } [dev-dependencies] http-body-util = { version = "0.1.3" } -- 2.43.0 From 7721efe3821ce04350811a18f0a3f0b53c424066 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 12:33:54 -0400 Subject: [PATCH 48/55] Saving changes --- src/callers/register.rs | 4 ++-- src/main.rs | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index b279bb7..5e9837a 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -47,8 +47,8 @@ pub async fn register_user( lastname: payload.lastname.clone(), status: String::from("Active"), email_verified: true, - date_created: time::OffsetDateTime::now_utc().to_string(), - last_login: String::new(), + date_created: Some(time::OffsetDateTime::now_utc()), + last_login: None, salt_id: uuid::Uuid::nil(), }; diff --git a/src/main.rs b/src/main.rs index 6487049..da52960 100644 --- a/src/main.rs +++ b/src/main.rs @@ -235,10 +235,7 @@ mod tests { usr.username, returned_usr.username, "Usernames do not match" ); - assert!( - !returned_usr.date_created.is_empty(), - "Date Created is empty" - ); + assert!(returned_usr.date_created.is_some(), "Date Created is empty"); } Err(err) => { assert!(false, "Error: {:?}", err.to_string()); -- 2.43.0 From 5b34b9f4d05b8caa104bfac781a17dcc440f8dd6 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 13:02:11 -0400 Subject: [PATCH 49/55] Updated icarus_models --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index a96587a..e50313a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ uuid = { version = "1.16.0", features = ["v4", "serde"] } argon2 = { version = "0.5.3", features = ["std"] } # Use the latest 0.5.x version rand = { version = "0.9" } time = { version = "0.3.41", features = ["macros", "serde"] } -icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.3.0-devel-d476b128cb-111" } +icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.3.0-devel-e9d73c391e-111" } [dev-dependencies] http-body-util = { version = "0.1.3" } -- 2.43.0 From 5f6033bd0f86895860917942ea38472bddb17026 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 13:02:19 -0400 Subject: [PATCH 50/55] Fixed issue --- src/callers/register.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index 5e9837a..b9d07e4 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -79,7 +79,7 @@ pub async fn register_user( ( StatusCode::CREATED, Json(response::Response { - message: String::from("User inserted"), + message: String::from("User created"), data: vec![user], }), ) -- 2.43.0 From 21e7a19ce46ffba6de55ed5b38645fd1e0f3c43d Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 13:11:24 -0400 Subject: [PATCH 51/55] Added minimum rust version --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index e50313a..5c4316b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ name = "icarus_auth" version = "0.1.1" edition = "2024" +rust-version = "1.85" [dependencies] axum = { version = "0.8.3" } -- 2.43.0 From e71307b62ecfe8a215d1b34e0cce048400b6e053 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 13:14:53 -0400 Subject: [PATCH 52/55] Version bump --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5c4316b..83dda4e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "icarus_auth" -version = "0.1.1" +version = "0.2.0" edition = "2024" rust-version = "1.85" -- 2.43.0 From b7bc501851245888d3a16f956bac56a5cd0b34e8 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 13:22:33 -0400 Subject: [PATCH 53/55] Updated dependencies --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 83dda4e..9d17bdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "icarus_auth" version = "0.2.0" edition = "2024" -rust-version = "1.85" +rust-version = "1.86" [dependencies] axum = { version = "0.8.3" } -- 2.43.0 From 5077f3c0cf6838e2c8e26f2d45599c5ca7c8dfcd Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 13:32:24 -0400 Subject: [PATCH 54/55] Updated rust version in workflow --- .gitea/workflows/tag_release.yml | 2 +- .gitea/workflows/workflow.yml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/tag_release.yml b/.gitea/workflows/tag_release.yml index 0ef5ff7..ca7ddef 100644 --- a/.gitea/workflows/tag_release.yml +++ b/.gitea/workflows/tag_release.yml @@ -19,7 +19,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 components: cargo - name: Extract Version from Cargo.toml diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index 2303b81..557a245 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key @@ -53,7 +53,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 # --- Add this step for explicit verification --- - name: Verify Docker Environment run: | @@ -93,7 +93,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 - run: rustup component add rustfmt - run: | mkdir -p ~/.ssh @@ -112,7 +112,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 - run: rustup component add clippy - run: | mkdir -p ~/.ssh @@ -131,7 +131,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: 1.85.0 + toolchain: 1.86.0 - run: | mkdir -p ~/.ssh echo "${{ secrets.MYREPO_TOKEN }}" > ~/.ssh/icarus_models_deploy_key -- 2.43.0 From c470d42bb6e0180cf0bf927d86e1bc427b3f53d2 Mon Sep 17 00:00:00 2001 From: phoenix Date: Sat, 5 Apr 2025 14:49:50 -0400 Subject: [PATCH 55/55] Updated icarus_models --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9d17bdf..59fd2d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ uuid = { version = "1.16.0", features = ["v4", "serde"] } argon2 = { version = "0.5.3", features = ["std"] } # Use the latest 0.5.x version rand = { version = "0.9" } time = { version = "0.3.41", features = ["macros", "serde"] } -icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.3.0-devel-e9d73c391e-111" } +icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.4.0" } [dev-dependencies] http-body-util = { version = "0.1.3" } -- 2.43.0