use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; use crate::server::omikron_manager::get_random_omikron; use crate::sql::sql; use crate::sql::user_online_tracker::get_iota_primary_omikron_connection; use crate::util::file_util::load_file; use crate::{get_public_key, log}; use crate::{ sql::sql::{get_by_user_id, get_omikron_by_id}, util::crypto_helper::public_key_to_base64, }; use actix_web::HttpResponse; use actix_web::body::BoxBody; use actix_web::http::StatusCode; use base64::Engine as _; use json::JsonValue; use json::number::Number; pub async fn handle(path: &str, body_string: Option) -> HttpResponse { let path_parts: Vec<&str> = path.split("/").filter(|s| !s.is_empty()).collect(); let _body: Option = if body_string.is_some() { if let Ok(body_json) = json::parse(&body_string.unwrap()) { Some(body_json) } else { None } } else { None }; log!("Path parts: {:?}", path_parts); let (status, body_text) = match path_parts.as_slice() { ["api", "download", "iota_frontend"] => { let file = load_file("downloads", "iota_frontend.zip"); (StatusCode::OK, file) } ["api", "get", "omikron"] => { if let Ok(omikron_conn) = get_random_omikron().await { if let Ok((public_key, ip_address)) = sql::get_omikron_by_id(omikron_conn.get_omikron_id().await).await { ( StatusCode::OK, format!( "{{\"id\": {}, \"public_key\": \"{}\", \"ip_address\": \"{}\"}}", omikron_conn.get_omikron_id().await, public_key, ip_address ), ) } else { ( StatusCode::INTERNAL_SERVER_ERROR, "selected an invalid omikron".to_string(), ) } } else { ( StatusCode::NOT_FOUND, "couldn't find online omikron".to_string(), ) } } ["api", "get", "omikron", id] => { let id = id.parse::().unwrap_or(0); if id == 0 { not_found() } else if let Ok((public_key, ip_address)) = get_omikron_by_id(id).await { ( StatusCode::OK, format!( "{{\"id\": {}, \"public_key\": \"{}\", \"ip_address\": \"{}\"}}", id, public_key, ip_address ), ) } else if let Some(omikron_id) = get_iota_primary_omikron_connection(id) { if let Ok((public_key, ip_address)) = get_omikron_by_id(omikron_id).await { ( StatusCode::OK, format!( "{{\"id\": {}, \"public_key\": \"{}\", \"ip_address\": \"{}\"}}", omikron_id, public_key, ip_address ), ) } else { not_found() } } else if let Ok((_, iota_id, _, _, _, _, _, _, _, _, _, _)) = get_by_user_id(id).await { if let Some(omikron_id) = get_iota_primary_omikron_connection(iota_id) { if let Ok((public_key, ip_address)) = get_omikron_by_id(omikron_id).await { ( StatusCode::OK, format!( "{{\"id\": {}, \"public_key\": \"{}\", \"ip_address\": \"{}\"}}", omikron_id, public_key, ip_address ), ) } else { not_found() } } else { not_found() } } else { not_found() } } ["api", "get", "id", username] => { 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(DataTypes::user_id, JsonValue::Number(Number::from(id))) .add_data(DataTypes::iota_id, JsonValue::Number(Number::from(iota_id))) .add_data( DataTypes::sub_level, JsonValue::Number(Number::from(sub_level)), ) .add_data(DataTypes::sub_end, JsonValue::Number(Number::from(sub_end))); (StatusCode::OK, cv.to_json().to_string()) } else { ( StatusCode::OK, CommunicationValue::new(CommunicationType::error_not_found) .to_json() .to_string(), ) } } ["api", "get", "public_key"] => (StatusCode::OK, public_key_to_base64(&get_public_key())), ["api", "get", "user", id] => { 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(DataTypes::user_id, JsonValue::Number(Number::from(id))) .add_data(DataTypes::iota_id, JsonValue::Number(Number::from(iota_id))) .add_data( DataTypes::sub_level, JsonValue::Number(Number::from(sub_level)), ) .add_data(DataTypes::sub_end, JsonValue::Number(Number::from(sub_end))); 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, cv.to_json().to_string()) } else { ( StatusCode::OK, CommunicationValue::new(CommunicationType::error_not_found) .to_json() .to_string(), ) } } _ => ( StatusCode::INTERNAL_SERVER_ERROR, CommunicationValue::new(CommunicationType::error) .to_json() .to_string(), ), }; let body_bytes = body_text.to_string().into_bytes(); let body = BoxBody::new(body_bytes.clone()); HttpResponse::new(status).set_body(body) } pub fn bad_request() -> (StatusCode, String) { (StatusCode::BAD_REQUEST, "400 Bad Request".to_string()) } pub fn not_found() -> (StatusCode, String) { (StatusCode::NOT_FOUND, "404 Not Found".to_string()) }