From d51b2f73a2d2ef459a8fc04da0c72769b317b185 Mon Sep 17 00:00:00 2001 From: Alex Emmet <111742636+Alex-Emmet@users.noreply.github.com> Date: Tue, 13 Jan 2026 22:57:48 +0100 Subject: [PATCH] register process optional value handlin in the sql database --- src/data/communication.rs | 8 ++ src/server/api.rs | 158 ++++++++++++++++--------------- src/server/omikron_connection.rs | 92 +++++++++++++----- src/sql/sql.rs | 90 ++++++++++-------- 4 files changed, 205 insertions(+), 143 deletions(-) diff --git a/src/data/communication.rs b/src/data/communication.rs index 4dd6d43..de68e6b 100644 --- a/src/data/communication.rs +++ b/src/data/communication.rs @@ -10,6 +10,7 @@ pub enum DataTypes { error_type, accepted_ids, uuid, + register_id, settings, settings_name, chat_partner_id, @@ -92,6 +93,7 @@ impl DataTypes { match normalized.as_str() { "errortype" => DataTypes::error_type, "chatpartnerid" => DataTypes::chat_partner_id, + "registerid" => DataTypes::register_id, "uuid" => DataTypes::uuid, "settings" => DataTypes::settings, "settingsname" => DataTypes::settings_name, @@ -174,6 +176,7 @@ impl DataTypes { #[allow(non_camel_case_types, dead_code)] pub enum CommunicationType { error, + error_internal, error_invalid_data, error_invalid_user_id, error_invalid_omikron_id, @@ -211,6 +214,8 @@ pub enum CommunicationType { register_response, identification, identification_response, + register_iota, + register_iota_success, ping, pong, add_chat, @@ -273,6 +278,7 @@ impl CommunicationType { "function" => CommunicationType::function, "update" => CommunicationType::update, "createuser" => CommunicationType::create_user, + "errorinternal" => CommunicationType::error_internal, "errorinvaliddata" => CommunicationType::error_invalid_data, "errorinvaliduserid" => CommunicationType::error_invalid_user_id, "errorinvalidomikronid" => CommunicationType::error_invalid_omikron_id, @@ -310,6 +316,8 @@ impl CommunicationType { "registerresponse" => CommunicationType::register_response, "identification" => CommunicationType::identification, "identificationresponse" => CommunicationType::identification_response, + "registeriota" => CommunicationType::register_iota, + "registeriotasuccess" => CommunicationType::register_iota_success, "ping" => CommunicationType::ping, "pong" => CommunicationType::pong, "addchat" => CommunicationType::add_chat, diff --git a/src/server/api.rs b/src/server/api.rs index 69077a4..9d77b5b 100644 --- a/src/server/api.rs +++ b/src/server/api.rs @@ -9,6 +9,7 @@ use crate::{ util::crypto_helper::public_key_to_base64, }; use axum::http::HeaderValue; +use base64::Engine as _; use http_body_util::Full; use hyper::body::Bytes; use hyper::{HeaderMap, Response as HttpResponse, StatusCode}; @@ -112,29 +113,29 @@ pub async fn handle( } // get/id/ "id" => { - let username = path_parts[2]; - if username.is_empty() { - not_found() + if path_parts.len() != 4 { + bad_request() } else { - if let Ok(( - id, - iota_id, - username, - display, - status, - about, - avatar, - sub_level, - sub_end, - public_key, - _, - _, - )) = sql::get_by_username(username).await - { - ( - StatusCode::OK, - "application/json", - CommunicationValue::new(CommunicationType::success) + let username = path_parts[3]; + if username.is_empty() { + not_found() + } else { + if let Ok(( + id, + iota_id, + username, + _, + _, + _, + _, + sub_level, + sub_end, + public_key, + _, + _, + )) = sql::get_by_username(username).await + { + let cv = CommunicationValue::new(CommunicationType::success) .add_data_str(DataTypes::username, username) .add_data_str(DataTypes::public_key, public_key) .add_data( @@ -145,10 +146,6 @@ pub async fn handle( DataTypes::iota_id, JsonValue::Number(Number::from(iota_id)), ) - .add_data_str(DataTypes::display, display) - .add_data_str(DataTypes::status, status) - .add_data_str(DataTypes::about, about) - .add_data_str(DataTypes::avatar, avatar) .add_data( DataTypes::sub_level, JsonValue::Number(Number::from(sub_level)), @@ -156,18 +153,17 @@ pub async fn handle( .add_data( DataTypes::sub_end, JsonValue::Number(Number::from(sub_end)), - ) - .to_json() - .to_string(), - ) - } else { - ( - StatusCode::OK, - "application/json", - CommunicationValue::new(CommunicationType::error_not_found) - .to_json() - .to_string(), - ) + ); + (StatusCode::OK, "application/json", cv.to_json().to_string()) + } else { + ( + StatusCode::OK, + "application/json", + CommunicationValue::new(CommunicationType::error_not_found) + .to_json() + .to_string(), + ) + } } } } @@ -177,30 +173,30 @@ pub async fn handle( public_key_to_base64(&get_public_key()), ), "user" => { - let id = path_parts[2]; - let id: i64 = id.parse().unwrap_or(0); - if id == 0 { + if path_parts.len() != 4 { bad_request() } else { - if let Ok(( - id, - iota_id, - username, - display, - status, - about, - avatar, - sub_level, - sub_end, - public_key, - _, - _, - )) = sql::get_by_user_id(id).await - { - ( - StatusCode::OK, - "application/json", - CommunicationValue::new(CommunicationType::success) + let id = path_parts[3]; + let id: i64 = id.parse().unwrap_or(0); + if id == 0 { + bad_request() + } else { + if let Ok(( + id, + iota_id, + username, + display, + status, + about, + avatar, + sub_level, + sub_end, + public_key, + _, + _, + )) = sql::get_by_user_id(id).await + { + let mut cv = CommunicationValue::new(CommunicationType::success) .add_data_str(DataTypes::username, username) .add_data_str(DataTypes::public_key, public_key) .add_data( @@ -211,10 +207,6 @@ pub async fn handle( DataTypes::iota_id, JsonValue::Number(Number::from(iota_id)), ) - .add_data_str(DataTypes::display, display) - .add_data_str(DataTypes::status, status) - .add_data_str(DataTypes::about, about) - .add_data_str(DataTypes::avatar, avatar) .add_data( DataTypes::sub_level, JsonValue::Number(Number::from(sub_level)), @@ -222,18 +214,32 @@ pub async fn handle( .add_data( DataTypes::sub_end, JsonValue::Number(Number::from(sub_end)), - ) - .to_json() - .to_string(), - ) - } else { - ( - StatusCode::OK, - "application/json", - CommunicationValue::new(CommunicationType::error_not_found) - .to_json() - .to_string(), - ) + ); + if let Some(display) = display { + cv = cv.add_data_str(DataTypes::display, display); + } + if let Some(status) = status { + cv = cv.add_data_str(DataTypes::status, status); + } + if let Some(about) = about { + cv = cv.add_data_str(DataTypes::about, about); + } + if let Some(avatar) = avatar { + cv = cv.add_data_str( + DataTypes::avatar, + base64::engine::general_purpose::STANDARD.encode(avatar), + ); + } + (StatusCode::OK, "application/json", cv.to_json().to_string()) + } else { + ( + StatusCode::OK, + "application/json", + CommunicationValue::new(CommunicationType::error_not_found) + .to_json() + .to_string(), + ) + } } } } diff --git a/src/server/omikron_connection.rs b/src/server/omikron_connection.rs index 98b6f00..80e50fc 100644 --- a/src/server/omikron_connection.rs +++ b/src/server/omikron_connection.rs @@ -186,7 +186,8 @@ impl OmikronConnection { self.send_message( &CommunicationValue::new(CommunicationType::identification_response) - .with_id(cv.get_id()), + .with_id(cv.get_id()) + .add_data(DataTypes::accepted, JsonValue::Boolean(true)), ) .await; } else { @@ -311,10 +312,6 @@ impl OmikronConnection { DataTypes::iota_id, JsonValue::Number(Number::from(iota_id)), ) - .add_data_str(DataTypes::display, display) - .add_data_str(DataTypes::status, status) - .add_data_str(DataTypes::about, about) - .add_data_str(DataTypes::avatar, avatar) .add_data( DataTypes::sub_level, JsonValue::Number(Number::from(sub_level)), @@ -324,6 +321,20 @@ impl OmikronConnection { JsonValue::Number(Number::from(sub_end)), ); + if let Some(display) = display { + response = response.add_data_str(DataTypes::display, display); + } + if let Some(status) = status { + response = response.add_data_str(DataTypes::status, status); + } + if let Some(about) = about { + response = response.add_data_str(DataTypes::about, about); + } + if let Some(avatar) = avatar { + response = + response.add_data_str(DataTypes::avatar, STANDARD.encode(avatar)); + } + let user_status = user_online_tracker::get_user_status(id).await; let iota_connections = user_online_tracker::get_iota_omikron_connections(iota_id) @@ -386,10 +397,6 @@ impl OmikronConnection { DataTypes::iota_id, JsonValue::Number(Number::from(iota_id)), ) - .add_data_str(DataTypes::display, display) - .add_data_str(DataTypes::status, status) - .add_data_str(DataTypes::about, about) - .add_data_str(DataTypes::avatar, avatar) .add_data( DataTypes::sub_level, JsonValue::Number(Number::from(sub_level)), @@ -399,6 +406,20 @@ impl OmikronConnection { JsonValue::Number(Number::from(sub_end)), ); + if let Some(display) = display { + response = response.add_data_str(DataTypes::display, display); + } + if let Some(status) = status { + response = response.add_data_str(DataTypes::status, status); + } + if let Some(about) = about { + response = response.add_data_str(DataTypes::about, about); + } + if let Some(avatar) = avatar { + response = + response.add_data_str(DataTypes::avatar, STANDARD.encode(avatar)); + } + let user_status = user_online_tracker::get_user_status(id).await; let iota_connections = user_online_tracker::get_iota_omikron_connections(iota_id) @@ -570,23 +591,44 @@ impl OmikronConnection { return; } if cv.is_type(CommunicationType::complete_register_iota) { - if let (Some(iota_id), Some(public_key)) = ( - cv.get_data(DataTypes::iota_id).and_then(|v| v.as_i64()), - cv.get_data(DataTypes::public_key).and_then(|v| v.as_str()), - ) { - match sql::register_complete_iota(iota_id, public_key.to_string()).await { - Ok(_) => { - let response = CommunicationValue::new(CommunicationType::success) - .with_id(cv.get_id()); - self.send_message(&response).await; + let iota_id_opt = cv.get_data(DataTypes::iota_id).and_then(|v| v.as_i64()); + + if let Some(public_key) = cv.get_data(DataTypes::public_key).and_then(|v| v.as_str()) { + if let Some(iota_id) = iota_id_opt { + // Existing logic to update iota + match sql::register_complete_iota(iota_id, public_key.to_string()).await { + Ok(_) => { + let response = CommunicationValue::new(CommunicationType::success) + .with_id(cv.get_id()); + self.send_message(&response).await; + } + Err(e) => { + self.send_message( + &CommunicationValue::new(CommunicationType::error) + .with_id(cv.get_id()) + .add_data_str(DataTypes::error_type, e.to_string()), + ) + .await; + } } - Err(e) => { - self.send_message( - &CommunicationValue::new(CommunicationType::error) - .with_id(cv.get_id()) - .add_data_str(DataTypes::error_type, e.to_string()), - ) - .await; + } else { + // New logic to create iota and return id + match sql::create_new_iota(public_key.to_string()).await { + Ok(new_iota_id) => { + let response = + CommunicationValue::new(CommunicationType::complete_register_iota) + .with_id(cv.get_id()) + .add_data(DataTypes::iota_id, JsonValue::from(new_iota_id)); + self.send_message(&response).await; + } + Err(e) => { + self.send_message( + &CommunicationValue::new(CommunicationType::error) + .with_id(cv.get_id()) + .add_data_str(DataTypes::error_type, e.to_string()), + ) + .await; + } } } } else { diff --git a/src/sql/sql.rs b/src/sql/sql.rs index bd3d283..abb9c8d 100644 --- a/src/sql/sql.rs +++ b/src/sql/sql.rs @@ -150,10 +150,10 @@ pub async fn get_by_username( i64, i64, String, - String, - String, - String, - String, + Option, + Option, + Option, + Option>, i32, i64, String, @@ -177,10 +177,10 @@ pub async fn get_by_username( let id: i64 = row.get("id"); let iota_id: i64 = row.get("iota_id"); let username: String = row.get("username"); - let display: Vec = row.get("display"); - let status: Vec = row.get("status"); - let about: Vec = row.get("about"); - let avatar: Vec = row.get("avatar"); + let display: Option> = row.get("display"); + let status: Option> = row.get("status"); + let about: Option> = row.get("about"); + let avatar: Option> = row.get("avatar"); let sub_level: i32 = row.get("sub_level"); let sub_end: i64 = row.get("sub_end"); let public_key: String = row.get("public_key"); @@ -191,10 +191,10 @@ pub async fn get_by_username( id, iota_id, username, - String::from_utf8_lossy(&display).to_string(), - String::from_utf8_lossy(&status).to_string(), - String::from_utf8_lossy(&about).to_string(), - String::from_utf8_lossy(&avatar).to_string(), + display.map(|d| String::from_utf8_lossy(&d).to_string()), + status.map(|s| String::from_utf8_lossy(&s).to_string()), + about.map(|a| String::from_utf8_lossy(&a).to_string()), + avatar, sub_level, sub_end, public_key, @@ -213,10 +213,10 @@ pub async fn get_by_user_id( i64, i64, String, - String, - String, - String, - String, + Option, + Option, + Option, + Option>, i32, i64, String, @@ -240,10 +240,10 @@ pub async fn get_by_user_id( let id: i64 = row.get("id"); let iota_id: i64 = row.get("iota_id"); let username: String = row.get("username"); - let display: Vec = row.get("display"); - let status: Vec = row.get("status"); - let about: Vec = row.get("about"); - let avatar: Vec = row.get("avatar"); + let display: Option> = row.get("display"); + let status: Option> = row.get("status"); + let about: Option> = row.get("about"); + let avatar: Option> = row.get("avatar"); let sub_level: i32 = row.get("sub_level"); let sub_end: i64 = row.get("sub_end"); let public_key: String = row.get("public_key"); @@ -254,10 +254,10 @@ pub async fn get_by_user_id( id, iota_id, username, - String::from_utf8_lossy(&display).to_string(), - String::from_utf8_lossy(&status).to_string(), - String::from_utf8_lossy(&about).to_string(), - String::from_utf8_lossy(&avatar).to_string(), + display.map(|d| String::from_utf8_lossy(&d).to_string()), + status.map(|s| String::from_utf8_lossy(&s).to_string()), + about.map(|a| String::from_utf8_lossy(&a).to_string()), + avatar, sub_level, sub_end, public_key, @@ -276,10 +276,10 @@ pub async fn get_users_by_iota_id( i64, i64, String, - String, - String, - String, - String, + Option, + Option, + Option, + Option>, i32, i64, String, @@ -303,10 +303,10 @@ pub async fn get_users_by_iota_id( let id: i64 = row.get("id"); let iota_id: i64 = row.get("iota_id"); let username: String = row.get("username"); - let display: Vec = row.get("display"); - let status: Vec = row.get("status"); - let about: Vec = row.get("about"); - let avatar: Vec = row.get("avatar"); + let display: Option> = row.get("display"); + let status: Option> = row.get("status"); + let about: Option> = row.get("about"); + let avatar: Option> = row.get("avatar"); let sub_level: i32 = row.get("sub_level"); let sub_end: i64 = row.get("sub_end"); let public_key: String = row.get("public_key"); @@ -317,10 +317,10 @@ pub async fn get_users_by_iota_id( id, iota_id, username, - String::from_utf8_lossy(&display).to_string(), - String::from_utf8_lossy(&status).to_string(), - String::from_utf8_lossy(&about).to_string(), - String::from_utf8_lossy(&avatar).to_string(), + display.map(|d| String::from_utf8_lossy(&d).to_string()), + status.map(|s| String::from_utf8_lossy(&s).to_string()), + about.map(|a| String::from_utf8_lossy(&a).to_string()), + avatar, sub_level, sub_end, public_key, @@ -477,9 +477,9 @@ pub async fn print_users() -> Result<(), Box> { let id: i64 = row.get("id"); let iota_id: i64 = row.get("iota_id"); let username: String = row.get("username"); - let display: Vec = row.get("display"); - let status: Vec = row.get("status"); - let about: Vec = row.get("about"); + let display: Option> = row.get("display"); + let status: Option> = row.get("status"); + let about: Option> = row.get("about"); let sub_level: i32 = row.get("sub_level"); let sub_end: i64 = row.get("sub_end"); @@ -489,9 +489,9 @@ pub async fn print_users() -> Result<(), Box> { id, iota_id, username, - String::from_utf8_lossy(&display), - String::from_utf8_lossy(&status), - String::from_utf8_lossy(&about), + display.map_or("".to_string(), |d| String::from_utf8_lossy(&d).to_string()), + status.map_or("".to_string(), |s| String::from_utf8_lossy(&s).to_string()), + about.map_or("".to_string(), |a| String::from_utf8_lossy(&a).to_string()), sub_level, sub_end ) @@ -504,6 +504,12 @@ pub async fn print_users() -> Result<(), Box> { // ========================================================================================== // IOTA // ========================================================================================== +pub async fn create_new_iota(public_key: String) -> Result { + let new_id = get_register_id().await as i64; + register_complete_iota(new_id, public_key).await?; + Ok(new_id) +} + pub async fn register_complete_iota(id: i64, public_key: String) -> Result<(), sqlx::Error> { let db_lock = SQL_DB.read().await; let pool = db_lock.as_ref().expect("Database pool is not initialized");