From 2ba30db3e614889cb3b90213decf1299657ef99a Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 15:53:18 -0400 Subject: [PATCH 01/19] Adding constant for login service endpoint --- src/callers/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/callers/mod.rs b/src/callers/mod.rs index 0de7e9b..a8b5883 100644 --- a/src/callers/mod.rs +++ b/src/callers/mod.rs @@ -11,4 +11,6 @@ pub mod endpoints { pub const DBTEST: &str = "/api/v1/test/db"; /// Endpoint constant for service user registration pub const REGISTER_SERVICE_USER: &str = "/api/v1/service/register"; + /// Endpoint constant for service login user + pub const LOGIN_SERVICE_USER: &str = "/api/v1/service/login"; } -- 2.47.3 From 317c61a9d2f0e3364038de4428ca5ac6d86dff7c Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 16:14:23 -0400 Subject: [PATCH 02/19] Removing script --- migrations/schema.sql | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 migrations/schema.sql diff --git a/migrations/schema.sql b/migrations/schema.sql deleted file mode 100644 index 05395e1..0000000 --- a/migrations/schema.sql +++ /dev/null @@ -1,32 +0,0 @@ --- CREATE EXTENSION IF NOT EXISTS pgcrypto; --- CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; --- --- DROP TABLE IF EXISTS "user" CASCADE; --- DROP TABLE IF EXISTS "salt" CASCADE; --- DROP TABLE IF EXISTS "service_user" CASCADE; --- --- CREATE TABLE IF NOT EXISTS "user" ( --- id UUID PRIMARY KEY DEFAULT gen_random_uuid(), --- first_name TEXT NOT NULL, --- last_name TEXT NOT NULL, --- phone_number TEXT NOT NULL, --- username TEXT NOT NULL, --- password TEXT NOT NULL, --- created TIMESTAMPTZ NOT NULL DEFAULT NOW(), --- last_login TIMESTAMPTZ NOT 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 --- ); --- --- CREATE TABLE IF NOT EXISTS "service_user" ( --- id UUID PRIMARY KEY DEFAULT gen_random_uuid(), --- username TEXT NOT NULL, --- passphrase TEXT NOT NULL, --- created TIMESTAMPTZ NOT NULL DEFAULT NOW(), --- last_login timestamptz NULL --- ); -- 2.47.3 From 5e1d70128b40d5f36b47ef513ad45f0baf9128a1 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 16:20:13 -0400 Subject: [PATCH 03/19] Adding service user login endpoint --- src/callers/login.rs | 166 +++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 ++ src/repo/service.rs | 33 +++++++++ 3 files changed, 203 insertions(+) diff --git a/src/callers/login.rs b/src/callers/login.rs index 83e6cff..01bb6c4 100644 --- a/src/callers/login.rs +++ b/src/callers/login.rs @@ -9,6 +9,29 @@ pub mod request { pub username: String, pub password: String, } + + #[derive(Deserialize, utoipa::ToSchema)] + pub struct ServiceUserLoginRequest { + pub username: String, + pub passphrase: String, + } + + impl ServiceUserLoginRequest { + pub fn is_empty(&self) -> (bool, Option) { + if self.username.is_empty() && self.passphrase.is_empty() { + ( + true, + Some(String::from("Username and passphrase are empty")), + ) + } else if self.username.is_empty() { + (true, Some(String::from("Username is empty"))) + } else if self.username.is_empty() { + (true, Some(String::from("Passphrase is empty"))) + } else { + (false, None) + } + } + } } pub mod response { @@ -19,6 +42,12 @@ pub mod response { pub data: Vec, } + #[derive(Default, Deserialize, Serialize, utoipa::ToSchema)] + pub struct ServiceUserLoginResponse { + pub message: String, + pub data: Vec, + } + pub async fn extract( response: axum::response::Response, ) -> Result { @@ -160,3 +189,140 @@ pub async fn user_login( } } } + +/// Endpoint for service user login +#[utoipa::path( + post, + path = super::endpoints::LOGIN_SERVICE_USER, + request_body( + content = request::ServiceUserLoginRequest, + description = "Data required for service user to lgoin", + content_type = "application/json" + ), + responses( + (status = 201, description = "Service uuser login successful", body = response::ServiceUserLoginResponse), + (status = 400, description = "Bad data", body = response::ServiceUserLoginResponse), + (status = 500, description = "Something went wrong", body = response::ServiceUserLoginResponse) + ) +)] +pub async fn service_user_login( + axum::Extension(pool): axum::Extension, + axum::Json(payload): axum::Json, +) -> (axum::http::StatusCode, axum::Json) { + if payload.username.is_empty() || payload.passphrase.is_empty() { + let reason = if payload.username.is_empty() { + String::from("Username not provided") + } else { + String::from("Passphrase not provided") + }; + + ( + axum::http::StatusCode::BAD_REQUEST, + axum::Json(response::LoginResponse { + message: reason, + data: Vec::new(), + }), + ) + } else { + match repo::service::exists(&pool, &payload.username).await { + Ok(exists) => { + if !exists { + println!("User does not exists"); + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(response::LoginResponse { + message: String::from("Unable to login"), + data: Vec::new(), + }), + ) + } else { + let service_user = + match repo::service::get_with_username(&pool, &payload.username).await { + Ok(service_user) => service_user, + Err(_err) => { + return ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(response::LoginResponse { + message: String::from("Unable to login"), + data: Vec::new(), + }), + ); + } + }; + let hashed_password = service_user.passphrase.clone(); + + match hashing::verify_password(&payload.passphrase, hashed_password) { + Ok(matches) => { + if matches { + // Create token + let key = textsender_models::envy::environment::get_secret_key() + .await + .value; + let (token_literal, duration) = + token_stuff::create_token(&key, &service_user.id).unwrap(); + + if token_stuff::verify_token(&key, &token_literal) { + let current_time = time::OffsetDateTime::now_utc(); + let _ = repo::service::update_last_login( + &pool, + &service_user, + ¤t_time, + ) + .await; + + ( + axum::http::StatusCode::OK, + axum::Json(response::LoginResponse { + message: String::from( + super::messages::SUCCESSFUL_MESSAGE, + ), + data: vec![textsender_models::token::LoginResult { + user_id: service_user.id, + access_token: token_literal, + token_type: String::from( + textsender_models::token::TOKEN_TYPE, + ), + issued_at: duration, + ..Default::default() + }], + }), + ) + } else { + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(response::LoginResponse { + message: String::from("Invalid attempt"), + data: Vec::new(), + }), + ) + } + } else { + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(response::LoginResponse { + message: String::from("Invalid attempt"), + data: Vec::new(), + }), + ) + } + } + Err(err) => ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(response::LoginResponse { + message: err.to_string(), + data: Vec::new(), + }), + ), + } + } + } + Err(err) => ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(response::LoginResponse { + message: err.to_string(), + data: Vec::new(), + }), + ), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index c820ae5..af64ea5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,6 +102,10 @@ pub mod init { post(callers::register::register_service_user), ) .route(callers::endpoints::LOGIN, post(callers::login::user_login)) + .route( + callers::endpoints::LOGIN_SERVICE_USER, + post(callers::login::service_user_login), + ) .layer(cors::configure_cors().await) } diff --git a/src/repo/service.rs b/src/repo/service.rs index 1f98dcd..e237100 100644 --- a/src/repo/service.rs +++ b/src/repo/service.rs @@ -75,6 +75,39 @@ pub async fn get_with_username( } } +pub async fn update_last_login( + pool: &sqlx::PgPool, + service_user: &textsender_models::user::ServiceUser, + time: &time::OffsetDateTime, +) -> Result { + let result = sqlx::query( + r#" + UPDATE "service_user" SET last_login = $1 WHERE id = $2 RETURNING last_login + "#, + ) + .bind(time) + .bind(service_user.id) + .fetch_optional(pool) + .await + .map_err(|e| { + eprintln!("Error updating time: {e}"); + e + }); + + match result { + Ok(row) => match row { + Some(r) => { + let last_login: time::OffsetDateTime = r + .try_get("last_login") + .map_err(|_e| sqlx::Error::RowNotFound)?; + Ok(last_login) + } + None => Err(sqlx::Error::RowNotFound), + }, + Err(err) => Err(err), + } +} + pub async fn insert( pool: &sqlx::PgPool, service_user: &textsender_models::user::ServiceUser, -- 2.47.3 From be6b933765b44fe3d4d7bea5bca76b09d491dd46 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 16:27:44 -0400 Subject: [PATCH 04/19] Fixing service registration that has no id --- src/callers/register.rs | 3 ++- src/repo/service.rs | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index e602e49..8344803 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -261,9 +261,10 @@ pub async fn register_service_user( println!("Creating user"); match repo::service::insert(&pool, &service_user).await { - Ok(created) => { + Ok((service_user_id, created)) => { resp.message = String::from(super::messages::SUCCESSFUL_MESSAGE); service_user.created = Some(created); + service_user.id = service_user_id; resp.data.push(service_user); (axum::http::StatusCode::CREATED, axum::Json(resp)) } diff --git a/src/repo/service.rs b/src/repo/service.rs index e237100..dfea463 100644 --- a/src/repo/service.rs +++ b/src/repo/service.rs @@ -111,11 +111,11 @@ pub async fn update_last_login( pub async fn insert( pool: &sqlx::PgPool, service_user: &textsender_models::user::ServiceUser, -) -> Result { +) -> Result<(uuid::Uuid, time::OffsetDateTime), sqlx::Error> { match sqlx::query( r#"INSERT INTO "service_user" (username, passphrase, salt_id) VALUES ($1, $2, $3) - RETURNING created + RETURNING id, created "#, ) .bind(&service_user.username) @@ -125,8 +125,9 @@ pub async fn insert( .await { Ok(row) => { + let id: uuid::Uuid = row.try_get("id")?; let created: time::OffsetDateTime = row.try_get("created")?; - Ok(created) + Ok((id, created)) } Err(err) => Err(err), } -- 2.47.3 From da7df3bb667d9a7ec112f49e86777339abc79c61 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:06:22 -0400 Subject: [PATCH 05/19] The endpoint is working --- src/callers/login.rs | 10 +++++++++- src/callers/register.rs | 2 +- src/repo/service.rs | 17 ++++++++++++++--- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/callers/login.rs b/src/callers/login.rs index 01bb6c4..45dca0e 100644 --- a/src/callers/login.rs +++ b/src/callers/login.rs @@ -236,10 +236,12 @@ pub async fn service_user_login( }), ) } else { + println!("Good to create"); let service_user = match repo::service::get_with_username(&pool, &payload.username).await { Ok(service_user) => service_user, - Err(_err) => { + Err(err) => { + eprintln!("Error: {err:?}"); return ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(response::LoginResponse { @@ -249,12 +251,16 @@ pub async fn service_user_login( ); } }; + println!("Service user: {service_user:?}"); + println!("Payload: {:?}", payload.passphrase); let hashed_password = service_user.passphrase.clone(); + println!("Hash password: {hashed_password:?}"); match hashing::verify_password(&payload.passphrase, hashed_password) { Ok(matches) => { if matches { // Create token + println!("Creating token"); let key = textsender_models::envy::environment::get_secret_key() .await .value; @@ -288,6 +294,7 @@ pub async fn service_user_login( }), ) } else { + eprintln!("Invalid token"); ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(response::LoginResponse { @@ -297,6 +304,7 @@ pub async fn service_user_login( ) } } else { + eprintln!("No match"); ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(response::LoginResponse { diff --git a/src/callers/register.rs b/src/callers/register.rs index 8344803..3474d75 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -252,7 +252,7 @@ pub async fn register_service_user( salt.id = repo::salt::insert(&pool, &salt).await.unwrap(); let mut service_user = textsender_models::user::ServiceUser { username: payload.username.clone(), - passphrase: hashing::hash_password(&payload.username, &generate_salt) + passphrase: hashing::hash_password(&payload.passphrase, &generate_salt) .unwrap(), salt_id: salt.id, ..Default::default() diff --git a/src/repo/service.rs b/src/repo/service.rs index dfea463..678b560 100644 --- a/src/repo/service.rs +++ b/src/repo/service.rs @@ -54,17 +54,28 @@ pub async fn get_with_username( username: &String, ) -> Result { match sqlx::query( - r#"SELECT id, username, passphrase, created, last_login FROM "service_user" WHERE username = $1"# + r#"SELECT id, username, passphrase, created, last_login, salt_id FROM "service_user" WHERE username = $1"# ).bind(username) .fetch_one(pool).await { Ok(row) => { + let last_login: Option = match row.try_get("last_login") { + Ok(login) => { + Some(login) + } + Err(err) => { + eprintln!("Error: {err:?}"); + None + } + }; + let service_user = textsender_models::user::ServiceUser { id: row.try_get("id")?, username: row.try_get("username")?, passphrase: row.try_get("passphrase")?, created: row.try_get("created")?, - last_login: row.try_get("last_login")?, - salt_id: row.try_get("salt_id")? + // last_login: + salt_id: row.try_get("salt_id")?, + ..Default::default() }; Ok(service_user) -- 2.47.3 From cbd9392f5a98ee4364a39dc547ec44d5f80218de Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:06:40 -0400 Subject: [PATCH 06/19] bump: postgresql ci --- .gitea/workflows/workflow.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/workflow.yml b/.gitea/workflows/workflow.yml index c2cc7d7..a926d91 100644 --- a/.gitea/workflows/workflow.yml +++ b/.gitea/workflows/workflow.yml @@ -35,7 +35,7 @@ jobs: # --- Add database service definition --- services: postgres: - image: postgres:18.3-alpine + image: postgres:18.4-alpine env: # Use secrets for DB init, with fallbacks for flexibility POSTGRES_USER: ${{ secrets.DB_TEST_USER || 'testuser' }} -- 2.47.3 From a6d70e3155e1425c2b66fa4aefd6c8d19148ac32 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:17:17 -0400 Subject: [PATCH 07/19] Added test --- tests/tests.rs | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/tests/tests.rs b/tests/tests.rs index 4753c91..dd0c2fe 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -133,6 +133,22 @@ pub mod requests { app.clone().oneshot(req).await } + + + pub async fn login_service_user(app: &axum::Router, username: &String, passphrase: &String) -> Result { + let payload = serde_json::json!({ + "username": username, + "passphrase": passphrase, + }); + let req = axum::http::Request::builder() + .method(axum::http::Method::POST) + .uri(super::callers::endpoints::LOGIN_SERVICE_USER) + .header(axum::http::header::CONTENT_TYPE, "application/json") + .body(axum::body::Body::from(payload.to_string())) + .unwrap(); + + app.clone().oneshot(req).await + } } /// Test user firstname @@ -216,6 +232,52 @@ async fn login_user( } } +async fn register_service_user(app: &axum::Router,) -> Result { + match requests::register_service_user(&app).await { + Ok(response) => { + if axum::http::StatusCode::CREATED != response.status() { + Err(std::io::Error::other(format!( + "Status code is off {:?}", + response.status() + ))) + } else { + match convert_response::(response).await { + Ok(service_user) => { + Ok(service_user) + } + Err(err) => { + Err(err) + } + } + } + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } +} + +async fn login_service_user(app: &axum::Router, username: &String, passphrase: &String) -> Result { + match requests::login_service_user(&app, username, passphrase).await { + Ok(response) => { + if axum::http::StatusCode::OK != response.status() { + Err(std::io::Error::other(format!( + "Status code is off {:?}", + response.status() + ))) + } else { + match convert_response::(response).await { + Ok(service_user) => { + Ok(service_user) + } + Err(err) => { + Err(err) + } + } + } + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } +} + #[tokio::test] async fn test_register_user() { let tm_pool = db_mgr::get_pool().await.unwrap(); @@ -354,3 +416,49 @@ async fn test_register_service_user() { } } } + +#[tokio::test] +async fn test_login_service_user() { + let tm_pool = db_mgr::get_pool().await.unwrap(); + let db_name = db_mgr::generate_db_name().await; + + match db_mgr::create_database(&tm_pool, &db_name).await { + Ok(_) => { + println!("Success"); + } + Err(e) => { + assert!(false, "Error: {:?}", e.to_string()); + } + } + + let pool = db_mgr::connect_to_db(&db_name).await.unwrap(); + + db::init::migrations(&pool).await; + + let app = init::routes().await.layer(axum::Extension(pool)); + + match register_service_user(&app).await { + Ok(user) => match login_service_user(&app, &user.username, TEST_SERVICE_PASSPHRASE).await { + Ok(login_result) => { + assert_eq!( + false, + login_result.access_token.is_empty(), + "Access token is empty when it should not be" + ); + } + Err(err) => { + assert!(false, "Error: {err:?}"); + } + }, + Err(err) => { + assert!(false, "Error: {err:?}"); + } + } + + match db_mgr::drop_database(&tm_pool, &db_name).await { + Ok(()) => {} + Err(err) => { + assert!(false, "Error: {err:?}"); + } + } +} -- 2.47.3 From a1cfaa280905bb8628238e7f3362834323daa0c7 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:18:19 -0400 Subject: [PATCH 08/19] Change type of function parameter --- tests/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index dd0c2fe..39d5a6d 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -135,7 +135,7 @@ pub mod requests { } - pub async fn login_service_user(app: &axum::Router, username: &String, passphrase: &String) -> Result { + pub async fn login_service_user(app: &axum::Router, username: &str, passphrase: &str) -> Result { let payload = serde_json::json!({ "username": username, "passphrase": passphrase, @@ -255,7 +255,7 @@ async fn register_service_user(app: &axum::Router,) -> Result Result { +async fn login_service_user(app: &axum::Router, username: &str, passphrase: &str) -> Result { match requests::login_service_user(&app, username, passphrase).await { Ok(response) => { if axum::http::StatusCode::OK != response.status() { -- 2.47.3 From 968f16ee470cc3f3c5180eced76b6fa2a5439831 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:18:30 -0400 Subject: [PATCH 09/19] cargo fmt --- tests/tests.rs | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index 39d5a6d..8808bca 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -134,8 +134,11 @@ pub mod requests { app.clone().oneshot(req).await } - - pub async fn login_service_user(app: &axum::Router, username: &str, passphrase: &str) -> Result { + pub async fn login_service_user( + app: &axum::Router, + username: &str, + passphrase: &str, + ) -> Result { let payload = serde_json::json!({ "username": username, "passphrase": passphrase, @@ -232,7 +235,9 @@ async fn login_user( } } -async fn register_service_user(app: &axum::Router,) -> Result { +async fn register_service_user( + app: &axum::Router, +) -> Result { match requests::register_service_user(&app).await { Ok(response) => { if axum::http::StatusCode::CREATED != response.status() { @@ -242,12 +247,8 @@ async fn register_service_user(app: &axum::Router,) -> Result(response).await { - Ok(service_user) => { - Ok(service_user) - } - Err(err) => { - Err(err) - } + Ok(service_user) => Ok(service_user), + Err(err) => Err(err), } } } @@ -255,7 +256,11 @@ async fn register_service_user(app: &axum::Router,) -> Result Result { +async fn login_service_user( + app: &axum::Router, + username: &str, + passphrase: &str, +) -> Result { match requests::login_service_user(&app, username, passphrase).await { Ok(response) => { if axum::http::StatusCode::OK != response.status() { @@ -265,12 +270,8 @@ async fn login_service_user(app: &axum::Router, username: &str, passphrase: &str ))) } else { match convert_response::(response).await { - Ok(service_user) => { - Ok(service_user) - } - Err(err) => { - Err(err) - } + Ok(service_user) => Ok(service_user), + Err(err) => Err(err), } } } -- 2.47.3 From f85ed17e6ea0d3b231eeb17277ebc2cdd2045e4a Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:19:45 -0400 Subject: [PATCH 10/19] Fix warning --- src/repo/service.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/repo/service.rs b/src/repo/service.rs index 678b560..5617d98 100644 --- a/src/repo/service.rs +++ b/src/repo/service.rs @@ -73,9 +73,8 @@ pub async fn get_with_username( username: row.try_get("username")?, passphrase: row.try_get("passphrase")?, created: row.try_get("created")?, - // last_login: + last_login, salt_id: row.try_get("salt_id")?, - ..Default::default() }; Ok(service_user) -- 2.47.3 From 514ec697e8648a676d66f9cf53830d0318576607 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:25:02 -0400 Subject: [PATCH 11/19] Test change --- tests/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests.rs b/tests/tests.rs index 8808bca..b7811a1 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -439,7 +439,7 @@ async fn test_login_service_user() { let app = init::routes().await.layer(axum::Extension(pool)); match register_service_user(&app).await { - Ok(user) => match login_service_user(&app, &user.username, TEST_SERVICE_PASSPHRASE).await { + Ok(user) => match login_service_user(&app, TEST_SERVICE_USERNAME, TEST_SERVICE_PASSPHRASE).await { Ok(login_result) => { assert_eq!( false, -- 2.47.3 From 5b85b5b469151aef409d6961a4a411b67c59092a Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:28:57 -0400 Subject: [PATCH 12/19] Test changes --- tests/tests.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index b7811a1..6096b65 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -439,18 +439,20 @@ async fn test_login_service_user() { let app = init::routes().await.layer(axum::Extension(pool)); match register_service_user(&app).await { - Ok(user) => match login_service_user(&app, TEST_SERVICE_USERNAME, TEST_SERVICE_PASSPHRASE).await { - Ok(login_result) => { - assert_eq!( - false, - login_result.access_token.is_empty(), - "Access token is empty when it should not be" - ); + Ok(_user) => { + match login_service_user(&app, TEST_SERVICE_USERNAME, TEST_SERVICE_PASSPHRASE).await { + Ok(login_result) => { + assert_eq!( + false, + login_result.access_token.is_empty(), + "Access token is empty when it should not be" + ); + } + Err(err) => { + assert!(false, "Error: {err:?}"); + } } - Err(err) => { - assert!(false, "Error: {err:?}"); - } - }, + } Err(err) => { assert!(false, "Error: {err:?}"); } -- 2.47.3 From 97a0efa588f178532010113ea72a81bc0eb768f1 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:32:39 -0400 Subject: [PATCH 13/19] Test fix --- tests/tests.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/tests.rs b/tests/tests.rs index 6096b65..75c71f1 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -439,7 +439,9 @@ async fn test_login_service_user() { let app = init::routes().await.layer(axum::Extension(pool)); match register_service_user(&app).await { - Ok(_user) => { + Ok(user) => { + assert_eq!(false, user.id.is_nil(), "The service user id should not be nil"); + /* match login_service_user(&app, TEST_SERVICE_USERNAME, TEST_SERVICE_PASSPHRASE).await { Ok(login_result) => { assert_eq!( @@ -452,6 +454,7 @@ async fn test_login_service_user() { assert!(false, "Error: {err:?}"); } } + */ } Err(err) => { assert!(false, "Error: {err:?}"); -- 2.47.3 From 0be21519a605b611b39448c5e242d978eabf7d98 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:33:49 -0400 Subject: [PATCH 14/19] Test fixes --- tests/tests.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/tests.rs b/tests/tests.rs index 75c71f1..7aa86e0 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -440,7 +440,11 @@ async fn test_login_service_user() { match register_service_user(&app).await { Ok(user) => { - assert_eq!(false, user.id.is_nil(), "The service user id should not be nil"); + assert_eq!( + false, + user.id.is_nil(), + "The service user id should not be nil" + ); /* match login_service_user(&app, TEST_SERVICE_USERNAME, TEST_SERVICE_PASSPHRASE).await { Ok(login_result) => { -- 2.47.3 From e1f2bff83239b30e584128a693e5ca24f2714fc4 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:37:09 -0400 Subject: [PATCH 15/19] Unused function --- tests/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tests.rs b/tests/tests.rs index 7aa86e0..e490996 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -256,7 +256,7 @@ async fn register_service_user( } } -async fn login_service_user( +async fn _login_service_user( app: &axum::Router, username: &str, passphrase: &str, -- 2.47.3 From e4f6e95a7941b00a27757407085d41bcde5a14d8 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:51:15 -0400 Subject: [PATCH 16/19] Maybe this time --- src/callers/login.rs | 24 +++++++++++++--------- tests/tests.rs | 49 ++++++++++++++++++++++++++++++++------------ 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/callers/login.rs b/src/callers/login.rs index 45dca0e..2926593 100644 --- a/src/callers/login.rs +++ b/src/callers/login.rs @@ -45,7 +45,8 @@ pub mod response { #[derive(Default, Deserialize, Serialize, utoipa::ToSchema)] pub struct ServiceUserLoginResponse { pub message: String, - pub data: Vec, + // TODO: Change this to login result + pub data: Vec, } pub async fn extract( @@ -208,7 +209,10 @@ pub async fn user_login( pub async fn service_user_login( axum::Extension(pool): axum::Extension, axum::Json(payload): axum::Json, -) -> (axum::http::StatusCode, axum::Json) { +) -> ( + axum::http::StatusCode, + axum::Json, +) { if payload.username.is_empty() || payload.passphrase.is_empty() { let reason = if payload.username.is_empty() { String::from("Username not provided") @@ -218,7 +222,7 @@ pub async fn service_user_login( ( axum::http::StatusCode::BAD_REQUEST, - axum::Json(response::LoginResponse { + axum::Json(response::ServiceUserLoginResponse { message: reason, data: Vec::new(), }), @@ -230,7 +234,7 @@ pub async fn service_user_login( println!("User does not exists"); ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(response::LoginResponse { + axum::Json(response::ServiceUserLoginResponse { message: String::from("Unable to login"), data: Vec::new(), }), @@ -244,7 +248,7 @@ pub async fn service_user_login( eprintln!("Error: {err:?}"); return ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(response::LoginResponse { + axum::Json(response::ServiceUserLoginResponse { message: String::from("Unable to login"), data: Vec::new(), }), @@ -278,7 +282,7 @@ pub async fn service_user_login( ( axum::http::StatusCode::OK, - axum::Json(response::LoginResponse { + axum::Json(response::ServiceUserLoginResponse { message: String::from( super::messages::SUCCESSFUL_MESSAGE, ), @@ -297,7 +301,7 @@ pub async fn service_user_login( eprintln!("Invalid token"); ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(response::LoginResponse { + axum::Json(response::ServiceUserLoginResponse { message: String::from("Invalid attempt"), data: Vec::new(), }), @@ -307,7 +311,7 @@ pub async fn service_user_login( eprintln!("No match"); ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(response::LoginResponse { + axum::Json(response::ServiceUserLoginResponse { message: String::from("Invalid attempt"), data: Vec::new(), }), @@ -316,7 +320,7 @@ pub async fn service_user_login( } Err(err) => ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(response::LoginResponse { + axum::Json(response::ServiceUserLoginResponse { message: err.to_string(), data: Vec::new(), }), @@ -326,7 +330,7 @@ pub async fn service_user_login( } Err(err) => ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(response::LoginResponse { + axum::Json(response::ServiceUserLoginResponse { message: err.to_string(), data: Vec::new(), }), diff --git a/tests/tests.rs b/tests/tests.rs index e490996..83b5b96 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -221,13 +221,16 @@ async fn login_user( response.status() ))) } else { - match axum::body::to_bytes(response.into_body(), usize::MAX).await { - Ok(body) => { - let parsed_body: callers::login::response::LoginResponse = - serde_json::from_slice(&body).unwrap(); - Ok(parsed_body.data[0].clone()) + match convert_response::(response).await { + Ok(response) => { + if response.data.len() > 0 { + let user = response.data[0].clone(); + Ok(user) + } else { + Err(std::io::Error::other("No data returned")) + } } - Err(err) => Err(std::io::Error::other(err.to_string())), + Err(err) => Err(err), } } } @@ -246,8 +249,19 @@ async fn register_service_user( response.status() ))) } else { - match convert_response::(response).await { - Ok(service_user) => Ok(service_user), + match convert_response::( + response, + ) + .await + { + Ok(response) => { + if response.data.len() > 0 { + let service_user = response.data[0].clone(); + Ok(service_user) + } else { + Err(std::io::Error::other("No data returned")) + } + } Err(err) => Err(err), } } @@ -256,7 +270,7 @@ async fn register_service_user( } } -async fn _login_service_user( +async fn login_service_user( app: &axum::Router, username: &str, passphrase: &str, @@ -269,8 +283,19 @@ async fn _login_service_user( response.status() ))) } else { - match convert_response::(response).await { - Ok(service_user) => Ok(service_user), + match convert_response::( + response, + ) + .await + { + Ok(response) => { + if response.data.len() > 0 { + let login_result = response.data[0].clone(); + Ok(login_result) + } else { + Err(std::io::Error::other("No data returned")) + } + } Err(err) => Err(err), } } @@ -445,7 +470,6 @@ async fn test_login_service_user() { user.id.is_nil(), "The service user id should not be nil" ); - /* match login_service_user(&app, TEST_SERVICE_USERNAME, TEST_SERVICE_PASSPHRASE).await { Ok(login_result) => { assert_eq!( @@ -458,7 +482,6 @@ async fn test_login_service_user() { assert!(false, "Error: {err:?}"); } } - */ } Err(err) => { assert!(false, "Error: {err:?}"); -- 2.47.3 From 795d50d346761c458ab7149dc1e7de35524f5e28 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:56:03 -0400 Subject: [PATCH 17/19] Cleanup --- tests/tests.rs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index 83b5b96..bd2cba1 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -194,13 +194,16 @@ async fn register_user( response.status() ))) } else { - match axum::body::to_bytes(response.into_body(), usize::MAX).await { - Ok(body) => { - let parsed_body: callers::register::response::Response = - serde_json::from_slice(&body).unwrap(); - Ok(parsed_body.data[0].clone()) + match convert_response::(response).await { + Ok(response) => { + if response.data.len() > 0 { + let user = response.data[0].clone(); + Ok(user) + } else { + Err(std::io::Error::other("No data returned")) + } } - Err(err) => Err(std::io::Error::other(err.to_string())), + Err(err) => Err(err), } } } -- 2.47.3 From 0209a93ede5ec3ba5074259575d9fba3036b1578 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:56:23 -0400 Subject: [PATCH 18/19] Cleanup --- src/callers/login.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/callers/login.rs b/src/callers/login.rs index 2926593..443c2ae 100644 --- a/src/callers/login.rs +++ b/src/callers/login.rs @@ -45,7 +45,6 @@ pub mod response { #[derive(Default, Deserialize, Serialize, utoipa::ToSchema)] pub struct ServiceUserLoginResponse { pub message: String, - // TODO: Change this to login result pub data: Vec, } -- 2.47.3 From c33327697b9346ac3eb1be88e6d444c12d38db7d Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 17:58:02 -0400 Subject: [PATCH 19/19] textsender_auth --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3375204..bdcb6ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2213,7 +2213,7 @@ dependencies = [ [[package]] name = "textsender_auth" -version = "0.1.16" +version = "0.1.17" dependencies = [ "argon2", "async-std", diff --git a/Cargo.toml b/Cargo.toml index 9f6484a..d942b84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "textsender_auth" -version = "0.1.16" +version = "0.1.17" edition = "2024" rust-version = "1.95" -- 2.47.3