diff --git a/src/communities/community.rs b/src/communities/community.rs index b5dd693..8d02bb4 100644 --- a/src/communities/community.rs +++ b/src/communities/community.rs @@ -8,13 +8,13 @@ use crate::data::communication::{CommunicationType, CommunicationValue}; use crate::util::file_util; use base64::{Engine as _, engine::general_purpose::STANDARD}; use json::JsonValue; +use json::number::Number; use json::object::Object; use rand::RngCore; use rand_core::OsRng; use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; -use uuid::Uuid; use x448::{PublicKey, Secret}; /// Permissions // uuid -> interactable/path/like/this/interactable_name:permission @@ -26,9 +26,9 @@ use x448::{PublicKey, Secret}; pub struct Community { name: String, - owner_id: Uuid, - members: Vec, - permissions: HashMap>, + owner_id: Arc>, + members: Vec, + permissions: HashMap>, roles: HashMap>, private_key: Secret, public_key: PublicKey, @@ -45,7 +45,7 @@ impl Community { let public_key = PublicKey::from(&private_key); Community { name: String::new(), - owner_id: Uuid::new_v4(), + owner_id: Arc::new(RwLock::new(0)), members: Vec::new(), permissions: HashMap::new(), roles: HashMap::new(), @@ -55,7 +55,7 @@ impl Community { connections: Arc::new(RwLock::new(HashMap::new())), } } - pub async fn create(name: String) -> Self { + pub async fn create(name: String, owner_id: i64) -> Self { let mut buf = [0u8; 56]; let mut rng = OsRng; rng.fill_bytes(&mut buf); @@ -63,7 +63,7 @@ impl Community { let public_key = PublicKey::from(&private_key); let c = Community { name, - owner_id: Uuid::new_v4(), + owner_id: Arc::new(RwLock::new(owner_id)), members: Vec::new(), permissions: HashMap::new(), roles: HashMap::new(), @@ -79,7 +79,7 @@ impl Community { pub async fn to_json(&self) -> JsonValue { let mut json = JsonValue::new_object(); json["name"] = self.name.clone().into(); - json["owner_id"] = self.owner_id.to_string().into(); + json["owner_id"] = (*self.owner_id.read().await as i64).into(); json["members"] = self .members .clone() @@ -96,7 +96,7 @@ impl Community { pub async fn frontend(&self) -> JsonValue { let mut json = JsonValue::new_object(); json["name"] = self.name.clone().into(); - json["owner_id"] = self.owner_id.to_string().into(); + json["owner_id"] = (*self.owner_id.read().await as i64).into(); json["members"] = self .members .clone() @@ -109,22 +109,31 @@ impl Community { json } - pub fn add_member(&mut self, member_id: Uuid) { + pub fn add_member(&mut self, member_id: i64) { self.members.push(member_id); } - pub fn remove_member(&mut self, member_id: Uuid) { + pub fn remove_member(&mut self, member_id: i64) { self.members.retain(|id| *id != member_id); } pub fn get_name(&self) -> &str { &self.name } + pub async fn get_owner_id(&self) -> i64 { + *self.owner_id.read().await + } + pub fn get_members(&self) -> Vec { + self.members.clone() + } pub fn get_private_key(&self) -> Secret { Secret::from_bytes(self.private_key.as_bytes()).unwrap() } pub fn get_public_key(&self) -> &PublicKey { &self.public_key } + pub async fn set_owner(self: Arc, owner_id: i64) { + *self.owner_id.write().await = owner_id; + } pub async fn add_connection(self: &Arc, other: Arc) { let mut vec = self .connections @@ -166,7 +175,7 @@ impl Community { } pub async fn get_interactables( &self, - user_id: i64, + _user_id: i64, ) -> Vec>> { self.interactables.read().await.clone() } @@ -191,10 +200,10 @@ impl Community { } pub async fn run_function( self: &mut Arc, - user_id: i64, + _user_id: i64, name: &str, path: &str, - function: &str, + _function: &str, cv: &CommunicationValue, ) -> CommunicationValue { if path.is_empty() { @@ -234,7 +243,10 @@ impl Community { pub async fn save(&self) { let mut json = Object::new(); json.insert("name", JsonValue::String(self.name.clone())); - json.insert("owner_id", JsonValue::String(self.owner_id.to_string())); + json.insert( + "owner_id", + JsonValue::Number(Number::from(*self.owner_id.read().await as i64)), + ); json.insert( "private_key", @@ -281,10 +293,10 @@ pub async fn load(name: &String) -> Option> { let user_data = file_util::load_file(&format!("communities/{}/", name), "users.json"); let user_json: JsonValue = json::parse(&user_data).unwrap(); let mut users = Vec::new(); - let mut permissions: HashMap> = HashMap::new(); + let mut permissions: HashMap> = HashMap::new(); for user in user_json.entries() { - let (str, json): (&str, &JsonValue) = user; + let (id, json): (&str, &JsonValue) = user; let perms_j = &json["permissions"]; let perms = Vec::new(); for _ in perms_j.entries() { @@ -292,7 +304,7 @@ pub async fn load(name: &String) -> Option> { // perms.push(perm_j.to_string()); } - let user_id = Uuid::parse_str(str).unwrap(); + let user_id: i64 = id.parse().unwrap_or(0); users.push(user_id); permissions.insert(user_id, perms); @@ -308,7 +320,7 @@ pub async fn load(name: &String) -> Option> { let community = Community { name: json_content["name"].as_str().unwrap().to_string(), - owner_id: Uuid::parse_str(json_content["owner_id"].as_str().unwrap()).unwrap(), + owner_id: Arc::new(RwLock::new(json_content["owner_id"].as_i64().unwrap_or(0))), members: users, roles, permissions, diff --git a/src/communities/community_manager.rs b/src/communities/community_manager.rs index a5cbb99..573913d 100644 --- a/src/communities/community_manager.rs +++ b/src/communities/community_manager.rs @@ -48,3 +48,12 @@ pub async fn save_communities() { pub async fn get_communities() -> Vec> { COMMUNITY_REGISTRY.lock().await.values().cloned().collect() } + +pub async fn rename_community(old_name: &str, new_name: &str) { + if let Some(community) = COMMUNITY_REGISTRY.lock().await.remove(old_name) { + COMMUNITY_REGISTRY + .lock() + .await + .insert(new_name.to_string(), community); + } +} diff --git a/src/gui/tui.rs b/src/gui/tui.rs index 05c2e57..064b63b 100644 --- a/src/gui/tui.rs +++ b/src/gui/tui.rs @@ -17,7 +17,6 @@ use crossterm::{ use once_cell::sync::Lazy; use ratatui::{ Frame, Terminal, - crossterm::event::poll, layout::{Constraint, Direction, Layout, Rect}, prelude::CrosstermBackend, style::Color, diff --git a/src/omikron/ping_pong_task.rs b/src/omikron/ping_pong_task.rs index 12e8d42..5a96a5a 100644 --- a/src/omikron/ping_pong_task.rs +++ b/src/omikron/ping_pong_task.rs @@ -1,6 +1,5 @@ use crate::APP_STATE; use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes}; -use crate::gui::log_panel::log_message; use crate::omikron::omikron_connection::OmikronConnection; use json::number::Number; use tokio::time::Instant; diff --git a/src/server/api.rs b/src/server/api.rs index 3d5deb1..257b377 100644 --- a/src/server/api.rs +++ b/src/server/api.rs @@ -141,22 +141,46 @@ pub async fn handle( if path_parts.len() >= 4 { match path_parts[3] { "add" => { - if body.is_none() { - "{\"type\":\"error\"}".to_string() - } else { - let name = body.unwrap()["name"].as_str().unwrap().to_string(); - let community = Arc::new(Community::create(name).await); + if let Some(body) = body { + let name = body["name"].as_str().unwrap().to_string(); + let user_id = body["owner"].as_i64().unwrap_or(0); + let community = Arc::new(Community::create(name, user_id).await); community_manager::add_community(community).await; "{\"type\":\"success\"}".to_string() + } else { + "{\"type\":\"error\"}".to_string() } } "remove" => { - if body.is_none() { - "{\"type\":\"error\"}".to_string() - } else { - let name = body.unwrap()["name"].as_str().unwrap().to_string(); + if let Some(body) = body { + let name = body["name"].as_str().unwrap().to_string(); community_manager::remove_community(&name).await; "{\"type\":\"success\"}".to_string() + } else { + "{\"type\":\"error\"}".to_string() + } + } + "change" => { + if path_parts.len() >= 5 { + match path_parts[4] { + "owner" => { + if let Some(body) = body { + let name = body["name"].as_str().unwrap().to_string(); + let owner = body["owner"].as_i64().unwrap_or(0); + community_manager::get_community(&name) + .await + .unwrap() + .set_owner(owner) + .await; + "{\"type\":\"success\"}".to_string() + } else { + "{\"type\":\"error\"}".to_string() + } + } + _ => "{\"type\":\"error\"}".to_string(), + } + } else { + "{\"type\":\"error\"}".to_string() } } "get" => { diff --git a/src/server/server.rs b/src/server/server.rs index a8c4ad1..b4449f2 100644 --- a/src/server/server.rs +++ b/src/server/server.rs @@ -465,7 +465,7 @@ pub async fn start(port: u16) -> bool { match tls_result { Ok(Some(tls_config)) => run_tls_server(port, tls_config).await, - Ok(None) => run_http_server(port).await, + Ok(_) => run_http_server(port).await, Err(e) => { log_message(format!("Fatal error during TLS config load: {}", e)); false diff --git a/src/util/chats_util.rs b/src/util/chats_util.rs index ed71bf5..73f1a00 100644 --- a/src/util/chats_util.rs +++ b/src/util/chats_util.rs @@ -1,6 +1,5 @@ use json::{self, JsonValue, array}; -use crate::gui::log_panel::log_message; use crate::users::contact::Contact; use crate::util::file_util::{load_file, save_file};