From 9cf69a3ab364431d4ac2de12551fa0b2987dfb72 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 13:01:15 -0400 Subject: [PATCH 01/12] repo module changes --- src/repo/service.rs | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/repo/service.rs b/src/repo/service.rs index 14ced65..b18128f 100644 --- a/src/repo/service.rs +++ b/src/repo/service.rs @@ -48,3 +48,49 @@ pub async fn get_passphrase( Err(err) => Err(err), } } + + +pub async fn get_with_username(pool: &sqlx::PgPool, username: &String) -> Result { + match sqlx::query( + r#"SELECT id, username, passphrase, created, last_login FROM "service_user" WHERE username = $1"# + ).bind(username) + .fetch_one(pool).await { + Ok(row) => { + 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")? + }; + + Ok(service_user) + } + Err(err) => { + Err(err) + } + } +} + +pub async fn insert(pool: &sqlx::PgPool, service_user: &textsender_models::user::ServiceUser) -> Result { + match sqlx::query( + r#"INSERT INTO "service_user" (username, passphrase, salt_id) + VALUES ($1, $2, $3) + RETURNING created + "# + ).bind(&service_user.username) + .bind(&service_user.passphrase) + .bind(service_user.salt_id) + .fetch_one(pool) + .await + { + Ok(row) => { + let created: time::OffsetDateTime = row.try_get("created")?; + Ok(created) + } + Err(err) => { + Err(err) + } + } +} -- 2.47.3 From a94f949ba422a13cfda7d2999906e4293dbdcfdc Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 13:01:29 -0400 Subject: [PATCH 02/12] Updating script --- migrations/20260607214210_init.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/migrations/20260607214210_init.sql b/migrations/20260607214210_init.sql index 86e6df9..6233efd 100644 --- a/migrations/20260607214210_init.sql +++ b/migrations/20260607214210_init.sql @@ -25,5 +25,6 @@ CREATE TABLE IF NOT EXISTS "service_user" ( username TEXT NOT NULL, passphrase TEXT NOT NULL, created TIMESTAMPTZ NOT NULL DEFAULT NOW(), - last_login timestamptz NULL + last_login timestamptz NULL, + salt_id UUID NOT NULL ); -- 2.47.3 From 4e8c4125fe34f6d83f838fbb16e7e1facb574600 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 13:02:06 -0400 Subject: [PATCH 03/12] Adding endpoint constant and making endpoint available --- src/callers/mod.rs | 2 ++ src/lib.rs | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/callers/mod.rs b/src/callers/mod.rs index c561eea..ace4865 100644 --- a/src/callers/mod.rs +++ b/src/callers/mod.rs @@ -8,4 +8,6 @@ pub mod endpoints { /// Endpoint for a user to login pub const LOGIN: &str = "/api/v1/login"; pub const DBTEST: &str = "/api/v1/test/db"; + /// Endpoint constant for service user registration + pub const REGISTER_SERVICE_USER: &str = "/api/v1/service/register"; } diff --git a/src/lib.rs b/src/lib.rs index e4bd359..c820ae5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,6 +97,10 @@ pub mod init { callers::endpoints::REGISTER, post(callers::register::register_user), ) + .route( + callers::endpoints::REGISTER_SERVICE_USER, + post(callers::register::register_service_user), + ) .route(callers::endpoints::LOGIN, post(callers::login::user_login)) .layer(cors::configure_cors().await) } -- 2.47.3 From 5bbc1acd277bab2e435bb135d4baa46cd976ec6b Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 13:03:14 -0400 Subject: [PATCH 04/12] Adding code for endpoint --- src/callers/register.rs | 50 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/callers/register.rs b/src/callers/register.rs index a16df74..60389eb 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -18,6 +18,26 @@ pub mod request { #[serde(skip_serializing_if = "Option::is_none")] pub lastname: Option, } + + #[derive(Default, Deserialize, Serialize, utoipa::ToSchema)] + pub struct RegisterServiceUserRequest { + pub username: String, + pub passphrase: String, + } + + impl RegisterServiceUserRequest { + 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.passphrase.is_empty() { + (true, Some(String::from("Passphrase is empty"))) + } else { + (false, None) + } + } + } } pub mod response { @@ -28,6 +48,12 @@ pub mod response { pub message: String, pub data: Vec, } + + #[derive(Default, Deserialize, Serialize, utoipa::ToSchema)] + pub struct RegisterServiceUserResponse { + pub message: String, + pub data: Vec + } } /// Endpoint to register a user @@ -160,3 +186,27 @@ async fn is_registration_enabled() -> Result { )) } } + +/// Endpoint to register a service user +pub async fn register_service_user( + axum::Extension(pool): axum::Extension, + Json(payload): Json, + ) -> (axum::http::StatusCode, axum::Json) { + let mut resp = response::RegisterServiceUserResponse { + ..Default::default() + }; + + let (res, msg) = payload.is_empty(); + if res { + resp.message = msg.unwrap(); + (axum::http::StatusCode::BAD_REQUEST, axum::Json(resp)) + } else { + match repo::salt::get_with_username(&pool, &payload.username) { + Ok(service_user) => { + } + Err(err) => { + } + } + (axum::http::StatusCode::NOT_IMPLEMENTED, axum::Json(resp)) + } +} -- 2.47.3 From a5e41116b809c4cf400e523e0ff78519c5bd50a5 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 13:29:06 -0400 Subject: [PATCH 05/12] More changes --- src/callers/register.rs | 50 +++++++++++++++++++++++++++++++++++------ src/repo/service.rs | 29 ++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index 60389eb..c124414 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -56,6 +56,13 @@ pub mod response { } } + +fn generate_the_salt() -> (argon2::password_hash::SaltString, textsender_models::user::Salt) { + let salt_string = hashing::generate_salt().unwrap(); + let salt = textsender_models::user::Salt::default(); + (salt_string, salt) +} + /// Endpoint to register a user #[utoipa::path( post, @@ -117,10 +124,11 @@ pub async fn register_user( } else { println!("Good to create"); println!("Generate salt string"); - let salt_string = hashing::generate_salt().unwrap(); - let mut salt = textsender_models::user::Salt::default(); - let generated_salt = salt_string; - salt.salt = generated_salt.to_string(); + // let salt_string = hashing::generate_salt().unwrap(); + // let mut salt = textsender_models::user::Salt::default(); + // let generated_salt = salt_string; + // salt.salt = generated_salt.to_string(); + let (generated_salt, mut salt) = generate_the_salt(); println!("Creating salt"); salt.id = repo::salt::insert(&pool, &salt).await.unwrap(); user.salt_id = salt.id; @@ -128,6 +136,7 @@ pub async fn register_user( hashing::hash_password(&user.password, &generated_salt).unwrap(); user.password = hashed_password; + println!("Creating user"); match repo::user::insert(&pool, &user).await { Ok((id, date_created)) => { @@ -201,12 +210,39 @@ pub async fn register_service_user( resp.message = msg.unwrap(); (axum::http::StatusCode::BAD_REQUEST, axum::Json(resp)) } else { - match repo::salt::get_with_username(&pool, &payload.username) { - Ok(service_user) => { + match repo::service::exists(&pool, &payload.username).await { + Ok(exists) => { + if exists { + resp.message = String::from("Invalid"); + (axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(resp)) + } else { + let (generate_salt, mut salt) = generate_the_salt(); + 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).unwrap(), + salt_id: salt.id, + ..Default::default() + }; + + println!("Creating user"); + + match repo::service::insert(&pool, &service_user).await { + Ok(created) => { + service_user.created = Some(created); + (axum::http::StatusCode::NOT_IMPLEMENTED, axum::Json(resp)) + } + Err(err) => { + resp.message = err.to_string(); + (axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(resp)) + } + } + } } Err(err) => { + resp.message = err.to_string(); + (axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(resp)) } } - (axum::http::StatusCode::NOT_IMPLEMENTED, axum::Json(resp)) } } diff --git a/src/repo/service.rs b/src/repo/service.rs index b18128f..2d39a19 100644 --- a/src/repo/service.rs +++ b/src/repo/service.rs @@ -94,3 +94,32 @@ pub async fn insert(pool: &sqlx::PgPool, service_user: &textsender_models::user: } } } + +pub async fn exists(pool: &sqlx::PgPool, service_username: &String) -> Result { + let result = sqlx::query( + r#" + SELECT 1 FROM "service_user" WHERE username = $1 + "#, + ) + .bind(service_username) + .fetch_optional(pool) + .await; + + match result { + Ok(r) => match r { + Some(row) => { + if row.is_empty() { + Ok(false) + } else { + Ok(true) + } + } + None => Ok(false), + }, + Err(e) => { + eprintln!("What??"); + eprintln!("Error: {e:?}"); + Err(e) + } + } +} -- 2.47.3 From 3c03e553c4bba4f0e597fd9d78cb1f0f0002a1fd Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 13:30:53 -0400 Subject: [PATCH 06/12] cargo fmt --- src/callers/register.rs | 42 +++++++++++++++++++++++++++-------------- src/repo/service.rs | 28 +++++++++++++++------------ 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index c124414..2a63283 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -28,7 +28,10 @@ pub mod request { impl RegisterServiceUserRequest { 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"))) + ( + 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.passphrase.is_empty() { @@ -52,12 +55,14 @@ pub mod response { #[derive(Default, Deserialize, Serialize, utoipa::ToSchema)] pub struct RegisterServiceUserResponse { pub message: String, - pub data: Vec + pub data: Vec, } } - -fn generate_the_salt() -> (argon2::password_hash::SaltString, textsender_models::user::Salt) { +fn generate_the_salt() -> ( + argon2::password_hash::SaltString, + textsender_models::user::Salt, +) { let salt_string = hashing::generate_salt().unwrap(); let salt = textsender_models::user::Salt::default(); (salt_string, salt) @@ -124,10 +129,7 @@ pub async fn register_user( } else { println!("Good to create"); println!("Generate salt string"); - // let salt_string = hashing::generate_salt().unwrap(); - // let mut salt = textsender_models::user::Salt::default(); - // let generated_salt = salt_string; - // salt.salt = generated_salt.to_string(); + let (generated_salt, mut salt) = generate_the_salt(); println!("Creating salt"); salt.id = repo::salt::insert(&pool, &salt).await.unwrap(); @@ -136,7 +138,6 @@ pub async fn register_user( hashing::hash_password(&user.password, &generated_salt).unwrap(); user.password = hashed_password; - println!("Creating user"); match repo::user::insert(&pool, &user).await { Ok((id, date_created)) => { @@ -200,7 +201,10 @@ async fn is_registration_enabled() -> Result { pub async fn register_service_user( axum::Extension(pool): axum::Extension, Json(payload): Json, - ) -> (axum::http::StatusCode, axum::Json) { +) -> ( + axum::http::StatusCode, + axum::Json, +) { let mut resp = response::RegisterServiceUserResponse { ..Default::default() }; @@ -214,13 +218,17 @@ pub async fn register_service_user( Ok(exists) => { if exists { resp.message = String::from("Invalid"); - (axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(resp)) + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(resp), + ) } else { let (generate_salt, mut salt) = generate_the_salt(); 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).unwrap(), + passphrase: hashing::hash_password(&payload.username, &generate_salt) + .unwrap(), salt_id: salt.id, ..Default::default() }; @@ -234,14 +242,20 @@ pub async fn register_service_user( } Err(err) => { resp.message = err.to_string(); - (axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(resp)) + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(resp), + ) } } } } Err(err) => { resp.message = err.to_string(); - (axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(resp)) + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(resp), + ) } } } diff --git a/src/repo/service.rs b/src/repo/service.rs index 2d39a19..1f98dcd 100644 --- a/src/repo/service.rs +++ b/src/repo/service.rs @@ -49,8 +49,10 @@ pub async fn get_passphrase( } } - -pub async fn get_with_username(pool: &sqlx::PgPool, username: &String) -> Result { +pub async fn get_with_username( + pool: &sqlx::PgPool, + username: &String, +) -> Result { match sqlx::query( r#"SELECT id, username, passphrase, created, last_login FROM "service_user" WHERE username = $1"# ).bind(username) @@ -73,25 +75,27 @@ pub async fn get_with_username(pool: &sqlx::PgPool, username: &String) -> Result } } -pub async fn insert(pool: &sqlx::PgPool, service_user: &textsender_models::user::ServiceUser) -> Result { +pub async fn insert( + pool: &sqlx::PgPool, + service_user: &textsender_models::user::ServiceUser, +) -> Result { match sqlx::query( r#"INSERT INTO "service_user" (username, passphrase, salt_id) VALUES ($1, $2, $3) RETURNING created - "# - ).bind(&service_user.username) - .bind(&service_user.passphrase) - .bind(service_user.salt_id) - .fetch_one(pool) - .await + "#, + ) + .bind(&service_user.username) + .bind(&service_user.passphrase) + .bind(service_user.salt_id) + .fetch_one(pool) + .await { Ok(row) => { let created: time::OffsetDateTime = row.try_get("created")?; Ok(created) } - Err(err) => { - Err(err) - } + Err(err) => Err(err), } } -- 2.47.3 From ebe53f51c9950e1180606076f1999e8123faef2b Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 13:49:58 -0400 Subject: [PATCH 07/12] Adding constant file --- src/callers/messages.rs | 1 + src/callers/mod.rs | 1 + src/callers/register.rs | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 src/callers/messages.rs diff --git a/src/callers/messages.rs b/src/callers/messages.rs new file mode 100644 index 0000000..1b8aa21 --- /dev/null +++ b/src/callers/messages.rs @@ -0,0 +1 @@ +pub const SUCCESSFUL_MESSAGE: &str = "Successful"; diff --git a/src/callers/mod.rs b/src/callers/mod.rs index ace4865..0de7e9b 100644 --- a/src/callers/mod.rs +++ b/src/callers/mod.rs @@ -1,5 +1,6 @@ pub mod common; pub mod login; +pub mod messages; pub mod register; pub mod endpoints { diff --git a/src/callers/register.rs b/src/callers/register.rs index 2a63283..e1046df 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -237,8 +237,10 @@ pub async fn register_service_user( match repo::service::insert(&pool, &service_user).await { Ok(created) => { + resp.message = String::from(super::messages::SUCCESSFUL_MESSAGE); service_user.created = Some(created); - (axum::http::StatusCode::NOT_IMPLEMENTED, axum::Json(resp)) + resp.data.push(service_user); + (axum::http::StatusCode::CREATED, axum::Json(resp)) } Err(err) => { resp.message = err.to_string(); -- 2.47.3 From 30f65bbb63ace1dd5b6adef23bae86ec9441dd3a Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 13:52:30 -0400 Subject: [PATCH 08/12] Test refactor --- tests/tests.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/tests/tests.rs b/tests/tests.rs index 7bd28bd..63e9a45 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -193,23 +193,8 @@ async fn test_register_user() { let app = init::routes().await.layer(axum::Extension(pool)); - match requests::register_user(&app).await { - Ok(response) => { - assert_eq!( - axum::http::StatusCode::CREATED, - response.status(), - "Status does not match {:?}", - response.status() - ); - let body = axum::body::to_bytes(response.into_body(), usize::MAX) - .await - .unwrap(); - let parsed_body: callers::register::response::Response = - serde_json::from_slice(&body).unwrap(); - assert!(parsed_body.data.len() > 0, "No data returned"); - - let returned_user = &parsed_body.data[0]; - + match register_user(&app).await { + Ok(returned_user) => { assert_eq!( TEST_USERNAME, returned_user.username, "Error with returned user" -- 2.47.3 From e1fc94c7e0bca2128274a2d7c437c83c0e3d0bab Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 14:19:27 -0400 Subject: [PATCH 09/12] Adding more code to the test --- tests/tests.rs | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/tests/tests.rs b/tests/tests.rs index 63e9a45..4753c91 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -75,6 +75,7 @@ mod db_mgr { pub mod requests { use tower::ServiceExt; // for `call`, `oneshot`, and `ready` + /// Function to call register user endpoint pub async fn register_user( app: &axum::Router, ) -> Result { @@ -95,6 +96,7 @@ pub mod requests { app.clone().oneshot(req).await } + /// Function to call login user endpoint pub async fn login_user( app: &axum::Router, username: &str, @@ -113,14 +115,55 @@ pub mod requests { app.clone().oneshot(req).await } + + /// Function to call register service user endpoint + pub async fn register_service_user( + app: &axum::Router, + ) -> Result { + let payload = serde_json::json!({ + "username": String::from(super::TEST_SERVICE_USERNAME), + "passphrase": String::from(super::TEST_SERVICE_PASSPHRASE), + }); + let req = axum::http::Request::builder() + .method(axum::http::Method::POST) + .uri(super::callers::endpoints::REGISTER_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 const TEST_FIRSTNAME: &str = "Billy"; +/// Test user lastname const TEST_LASTNAME: &str = "Bob"; +/// Test user username const TEST_USERNAME: &str = "BillyBob01"; +/// Test user password const TEST_PASSWORD: &str = "923ndcry392qryudx328qrdy328r"; +/// Test user phone number const TEST_PHONE_NUMBER: &str = "+10123456789"; +/// Test service username +const TEST_SERVICE_USERNAME: &str = "swoon"; +/// Test service passphrase +const TEST_SERVICE_PASSPHRASE: &str = "4n5cf349tfy34w857ty39wq45nfdq23"; + +async fn convert_response(response: axum::response::Response) -> Result +where + T: serde::de::DeserializeOwned, +{ + match axum::body::to_bytes(response.into_body(), usize::MAX).await { + Ok(body) => { + let resp: T = serde_json::from_slice(&body).unwrap(); + Ok(resp) + } + Err(err) => Err(std::io::Error::other(err.to_string())), + } +} + async fn register_user( app: &axum::Router, ) -> Result { @@ -258,3 +301,56 @@ async fn test_login_user() { } } } + +#[tokio::test] +async fn test_register_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 requests::register_service_user(&app).await { + Ok(response) => { + match convert_response::( + response, + ) + .await + { + Ok(resp) => { + assert!(resp.data.len() > 0, "No service user was created"); + let service_user = &resp.data[0]; + assert_eq!( + TEST_SERVICE_USERNAME, service_user.username, + "Service username does not match" + ); + } + 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 d693db71b13715003727f914a526235b665c40f9 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 14:31:13 -0400 Subject: [PATCH 10/12] bump: textsender_auth --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4ab5d6..3375204 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2213,7 +2213,7 @@ dependencies = [ [[package]] name = "textsender_auth" -version = "0.1.15" +version = "0.1.16" dependencies = [ "argon2", "async-std", diff --git a/Cargo.toml b/Cargo.toml index 3cc1795..9f6484a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "textsender_auth" -version = "0.1.15" +version = "0.1.16" edition = "2024" rust-version = "1.95" -- 2.47.3 From 93a51578c22cc33bb18ef2237447848362401fd9 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 14:31:46 -0400 Subject: [PATCH 11/12] Added doc gen for endpoint and made some improvements --- src/callers/register.rs | 113 ++++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 39 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index e1046df..a1e7158 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -198,6 +198,21 @@ async fn is_registration_enabled() -> Result { } /// Endpoint to register a service user +#[utoipa::path( + post, + path = super::endpoints::REGISTER_SERVICE_USER, + request_body( + content = request::RegisterServiceUserRequest, + description = "Data required to register service user", + content_type = "application/json" + ), + responses( + (status = 201, description = "Service user created", body = response::RegisterServiceUserResponse), + (status = 400, description = "Issue creating service user", body = response::RegisterServiceUserResponse), + (status = 406, description = "Cannot create service user", body = response::RegisterServiceUserResponse), + (status = 500, description = "Issue creating service user", body = response::RegisterServiceUserResponse), + ) +)] pub async fn register_service_user( axum::Extension(pool): axum::Extension, Json(payload): Json, @@ -209,56 +224,76 @@ pub async fn register_service_user( ..Default::default() }; + let registration_enabled = match is_registration_enabled().await { + Ok(value) => value, + Err(err) => { + eprintln!("Error: {err:?}"); + resp.message = String::from("Registration check failed"); + return ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + Json(resp) + ); + } + }; + let (res, msg) = payload.is_empty(); if res { resp.message = msg.unwrap(); (axum::http::StatusCode::BAD_REQUEST, axum::Json(resp)) } else { - match repo::service::exists(&pool, &payload.username).await { - Ok(exists) => { - if exists { - resp.message = String::from("Invalid"); + if registration_enabled { + match repo::service::exists(&pool, &payload.username).await { + Ok(exists) => { + if exists { + resp.message = String::from("Invalid"); + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(resp), + ) + } else { + let (generate_salt, mut salt) = generate_the_salt(); + 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) + .unwrap(), + salt_id: salt.id, + ..Default::default() + }; + + println!("Creating user"); + + match repo::service::insert(&pool, &service_user).await { + Ok(created) => { + resp.message = String::from(super::messages::SUCCESSFUL_MESSAGE); + service_user.created = Some(created); + resp.data.push(service_user); + (axum::http::StatusCode::CREATED, axum::Json(resp)) + } + Err(err) => { + resp.message = err.to_string(); + ( + axum::http::StatusCode::INTERNAL_SERVER_ERROR, + axum::Json(resp), + ) + } + } + } + } + Err(err) => { + resp.message = err.to_string(); ( axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::Json(resp), ) - } else { - let (generate_salt, mut salt) = generate_the_salt(); - 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) - .unwrap(), - salt_id: salt.id, - ..Default::default() - }; - - println!("Creating user"); - - match repo::service::insert(&pool, &service_user).await { - Ok(created) => { - resp.message = String::from(super::messages::SUCCESSFUL_MESSAGE); - service_user.created = Some(created); - resp.data.push(service_user); - (axum::http::StatusCode::CREATED, axum::Json(resp)) - } - Err(err) => { - resp.message = err.to_string(); - ( - axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(resp), - ) - } - } } } - Err(err) => { - resp.message = err.to_string(); - ( - axum::http::StatusCode::INTERNAL_SERVER_ERROR, - axum::Json(resp), - ) - } + } else { + resp.message = String::from("Registration is not enabled"); + ( + axum::http::StatusCode::NOT_ACCEPTABLE, + Json(resp), + ) } } } -- 2.47.3 From 0269f6b984b84892237f41eeaab54f7c0aa809c7 Mon Sep 17 00:00:00 2001 From: phoenix Date: Thu, 11 Jun 2026 14:31:58 -0400 Subject: [PATCH 12/12] cargo fmt --- src/callers/register.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/callers/register.rs b/src/callers/register.rs index a1e7158..e602e49 100644 --- a/src/callers/register.rs +++ b/src/callers/register.rs @@ -229,10 +229,7 @@ pub async fn register_service_user( Err(err) => { eprintln!("Error: {err:?}"); resp.message = String::from("Registration check failed"); - return ( - axum::http::StatusCode::INTERNAL_SERVER_ERROR, - Json(resp) - ); + return (axum::http::StatusCode::INTERNAL_SERVER_ERROR, Json(resp)); } }; @@ -290,10 +287,7 @@ pub async fn register_service_user( } } else { resp.message = String::from("Registration is not enabled"); - ( - axum::http::StatusCode::NOT_ACCEPTABLE, - Json(resp), - ) + (axum::http::StatusCode::NOT_ACCEPTABLE, Json(resp)) } } } -- 2.47.3