From 0147ab0488b9a9c4c3536db1f761553cbf2666f3 Mon Sep 17 00:00:00 2001 From: cypherkitty Date: Sun, 5 Jan 2025 02:51:42 -0800 Subject: [PATCH] 1. Sync: code separation 2. Bring Id52Bit --- meta-secret/Cargo.toml | 2 + meta-secret/core/Cargo.toml | 2 + meta-secret/core/src/crypto/utils.rs | 45 +++++++++++++++++- .../node/app/meta_app/meta_client_service.rs | 2 +- .../core/src/node/app/sync/global_index.rs | 43 +++++++++++++++-- .../core/src/node/app/sync/sync_gateway.rs | 24 +++++++--- .../src/node/common/model/device/common.rs | 4 +- .../node/common/model/device/device_link.rs | 2 +- meta-secret/core/src/node/common/model/mod.rs | 2 +- .../core/src/node/common/model/secret.rs | 6 +-- .../core/src/node/common/model/vault/vault.rs | 7 +++ .../descriptors/shared_secret_descriptor.rs | 6 +-- meta-secret/core/src/node/server/request.rs | 3 +- .../core/src/node/server/server_app.rs | 46 ++++++++----------- .../core/src/node/server/server_data_sync.rs | 5 +- 15 files changed, 147 insertions(+), 52 deletions(-) diff --git a/meta-secret/Cargo.toml b/meta-secret/Cargo.toml index 263419c..ed6f9a8 100644 --- a/meta-secret/Cargo.toml +++ b/meta-secret/Cargo.toml @@ -20,6 +20,8 @@ exclude = [ thiserror = "2.0.9" anyhow = "1.0.95" +derive_more = { version = "1.0.0", features = ["full"] } + # Logging and tracing tracing = "0.1.41" tracing-subscriber = { version = "0.3.19" } diff --git a/meta-secret/core/Cargo.toml b/meta-secret/core/Cargo.toml index 7f6a031..31f4fef 100644 --- a/meta-secret/core/Cargo.toml +++ b/meta-secret/core/Cargo.toml @@ -23,6 +23,8 @@ target = "x86_64-unknown-linux-gnu" thiserror.workspace = true anyhow.workspace = true +derive_more.workspace = true + async-trait.workspace = true flume.workspace = true async-mutex.workspace = true diff --git a/meta-secret/core/src/crypto/utils.rs b/meta-secret/core/src/crypto/utils.rs index 033d754..6fc870d 100644 --- a/meta-secret/core/src/crypto/utils.rs +++ b/meta-secret/core/src/crypto/utils.rs @@ -21,6 +21,47 @@ pub fn generate_hash() -> String { hex::encode(hasher.finalize()) } +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[wasm_bindgen(getter_with_clone)] +pub struct Id52bit { + pub text: String, +} + +impl Id52bit { + pub fn generate() -> Self { + let mut rng = rand::thread_rng(); + + let random_u64: u64 = rng.gen::() & 0xFFFFFFFFFFFF; + + let hex_num = Self::hex(random_u64); + Self { text: hex_num } + } + + pub fn take(&self, n: usize) -> String { + self.text.chars().take(n).collect::() + } + + fn hex(n: u64) -> String { + let hex_string = format!("{:x}", n); + + // Calculate the length of each part (rounded down) + let part_length = hex_string.len() / 3; + + // Split the string into four parts using slicing + let (part1, rest) = hex_string.split_at(part_length); + let (part2, part3) = rest.split_at(part_length); + + format!("{}-{}-{}", part1, part2, part3) + } +} + +impl IdString for Id52bit { + fn id_str(self) -> String { + self.text + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[wasm_bindgen(getter_with_clone)] @@ -44,7 +85,7 @@ impl From for U64IdUrlEnc { } impl IdString for U64IdUrlEnc { - fn id_str(&self) -> String { + fn id_str(self) -> String { self.text.base64_str() } } @@ -76,7 +117,7 @@ impl From for UuidUrlEnc { } impl IdString for UuidUrlEnc { - fn id_str(&self) -> String { + fn id_str(self) -> String { self.text.base64_str() } } diff --git a/meta-secret/core/src/node/app/meta_app/meta_client_service.rs b/meta-secret/core/src/node/app/meta_app/meta_client_service.rs index 75e676e..4b74779 100644 --- a/meta-secret/core/src/node/app/meta_app/meta_client_service.rs +++ b/meta-secret/core/src/node/app/meta_app/meta_client_service.rs @@ -235,7 +235,7 @@ pub mod fixture { let state_provider = MetaClientStateProviderFixture::generate(); let dt_fxr = MetaClientDataTransferFixture::generate(); - let sync_gateway = SyncGatewayFixture::from(&base); + let sync_gateway = SyncGatewayFixture::from(base); let client = Arc::new(MetaClientService { data_transfer: dt_fxr.client.clone(), diff --git a/meta-secret/core/src/node/app/sync/global_index.rs b/meta-secret/core/src/node/app/sync/global_index.rs index 74744e9..e0bec47 100644 --- a/meta-secret/core/src/node/app/sync/global_index.rs +++ b/meta-secret/core/src/node/app/sync/global_index.rs @@ -1,4 +1,6 @@ use crate::node::common::model::device::common::DeviceData; +use crate::node::db::descriptors::global_index_descriptor::GlobalIndexDescriptor; +use crate::node::db::descriptors::object_descriptor::ObjectDescriptor; use crate::node::db::events::generic_log_event::GenericKvLogEvent; use crate::node::db::objects::global_index::ClientPersistentGlobalIndex; use crate::node::db::objects::persistent_object::PersistentObject; @@ -38,9 +40,17 @@ impl GlobalIndexDbSync { } } -impl GlobalIndexDbSync { - pub async fn get_gi_request(&self) -> Result { - let gi_free_id = self.p_gi.free_id().await?; +pub struct GlobalIndexDbSyncRequest { + pub p_obj: Arc>, + pub sender: DeviceData, +} + +impl GlobalIndexDbSyncRequest { + const GI_DESC: ObjectDescriptor = ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::Index); + + /// Get a free global index id, to sync from + pub async fn get(&self) -> Result { + let gi_free_id = self.p_obj.find_free_id_by_obj_desc(Self::GI_DESC).await?; Ok(GlobalIndexRequest { sender: self.sender.clone(), @@ -48,3 +58,30 @@ impl GlobalIndexDbSync { }) } } + +#[cfg(test)] +mod test { + use crate::meta_tests::fixture_util::fixture::FixtureRegistry; + use crate::node::app::sync::global_index::GlobalIndexDbSyncRequest; + use crate::node::db::descriptors::global_index_descriptor::GlobalIndexDescriptor; + use crate::node::db::descriptors::object_descriptor::ToObjectDescriptor; + use crate::node::db::events::object_id::ObjectId; + use anyhow::Result; + + #[tokio::test] + async fn test_gi_request() -> Result<()> { + let fixture = FixtureRegistry::empty(); + + let db_sync_request = GlobalIndexDbSyncRequest { + p_obj: fixture.state.p_obj.client.clone(), + sender: fixture.state.device_creds.client.device, + }; + + let sync = db_sync_request.get().await?; + + let expected_id = ObjectId::unit(GlobalIndexDescriptor::Index.to_obj_desc()); + assert_eq!(expected_id, sync.global_index); + + Ok(()) + } +} diff --git a/meta-secret/core/src/node/app/sync/sync_gateway.rs b/meta-secret/core/src/node/app/sync/sync_gateway.rs index 1f991bd..702f02e 100644 --- a/meta-secret/core/src/node/app/sync/sync_gateway.rs +++ b/meta-secret/core/src/node/app/sync/sync_gateway.rs @@ -3,7 +3,7 @@ use std::time::Duration; use tracing::{debug, error, info, instrument}; -use crate::node::app::sync::global_index::GlobalIndexDbSync; +use crate::node::app::sync::global_index::{GlobalIndexDbSync, GlobalIndexDbSyncRequest}; use crate::node::common::model::device::common::{DeviceData, DeviceId}; use crate::node::common::model::user::common::UserId; use crate::node::common::model::user::user_creds::UserCredentials; @@ -239,20 +239,32 @@ impl SyncGateway { #[instrument(skip(self))] async fn download_global_index(&self, sender: DeviceData) -> Result<()> { - let gi_sync = GlobalIndexDbSync::new(self.p_obj.clone(), sender.clone()); - - let sync_request = gi_sync.get_gi_request().await?.to_sync_request(); - + let data_sync_request = self.build_sync_request(&sender).await?; + let DataEventsResponse(new_gi_events) = self .server_dt .dt - .send_to_service_and_get(DataSyncRequest::SyncRequest(sync_request)) + .send_to_service_and_get(data_sync_request) .await? .to_data()?; + let gi_sync = GlobalIndexDbSync::new(self.p_obj.clone(), sender.clone()); gi_sync.save(new_gi_events).await } + pub async fn build_sync_request(&self, sender: &DeviceData) -> Result { + let data_sync_request = { + let db_sync_request = GlobalIndexDbSyncRequest { + p_obj: self.p_obj.clone(), + sender: sender.clone(), + }; + let gi_sync_request = db_sync_request.get().await?; + let sync_request = SyncRequest::from(gi_sync_request); + DataSyncRequest::from(sync_request) + }; + Ok(data_sync_request) + } + #[instrument(skip(self))] async fn sync_shared_secrets( &self, diff --git a/meta-secret/core/src/node/common/model/device/common.rs b/meta-secret/core/src/node/common/model/device/common.rs index 474b879..6392286 100644 --- a/meta-secret/core/src/node/common/model/device/common.rs +++ b/meta-secret/core/src/node/common/model/device/common.rs @@ -13,7 +13,7 @@ pub struct DeviceId(pub U64IdUrlEnc); #[wasm_bindgen] impl DeviceId { - pub fn as_str(&self) -> String { + pub fn as_str(self) -> String { self.0.id_str() } } @@ -25,7 +25,7 @@ impl DeviceId { impl Display for DeviceId { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.as_str()) + write!(f, "{}", self.clone().as_str()) } } diff --git a/meta-secret/core/src/node/common/model/device/device_link.rs b/meta-secret/core/src/node/common/model/device/device_link.rs index 2813e11..cd828a4 100644 --- a/meta-secret/core/src/node/common/model/device/device_link.rs +++ b/meta-secret/core/src/node/common/model/device/device_link.rs @@ -33,7 +33,7 @@ impl From for DeviceLinkId { } impl IdString for DeviceLinkId { - fn id_str(&self) -> String { + fn id_str(self) -> String { String::try_from(&self.0).unwrap() } } diff --git a/meta-secret/core/src/node/common/model/mod.rs b/meta-secret/core/src/node/common/model/mod.rs index 32f3f58..b0c8967 100644 --- a/meta-secret/core/src/node/common/model/mod.rs +++ b/meta-secret/core/src/node/common/model/mod.rs @@ -64,7 +64,7 @@ impl From for WasmApplicationState { } pub trait IdString { - fn id_str(&self) -> String; + fn id_str(self) -> String; } #[cfg(test)] diff --git a/meta-secret/core/src/node/common/model/secret.rs b/meta-secret/core/src/node/common/model/secret.rs index dc8988e..d24f822 100644 --- a/meta-secret/core/src/node/common/model/secret.rs +++ b/meta-secret/core/src/node/common/model/secret.rs @@ -22,7 +22,7 @@ pub struct SsDistributionId { } impl IdString for SsDistributionId { - fn id_str(&self) -> String { + fn id_str(self) -> String { [self.receiver.as_str(), self.pass_id.id.id_str()].join("|") } } @@ -36,7 +36,7 @@ pub struct SsDistributionClaimId { } impl IdString for SsDistributionClaimId { - fn id_str(&self) -> String { + fn id_str(self) -> String { [self.id.0.clone(), self.pass_id.id.id_str()].join("|") } } @@ -49,7 +49,7 @@ pub struct SsDistributionClaimDbId { } impl IdString for SsDistributionClaimDbId { - fn id_str(&self) -> String { + fn id_str(self) -> String { [self.distribution_id.id_str(), self.claim_id.id_str()].join("|") } } diff --git a/meta-secret/core/src/node/common/model/vault/vault.rs b/meta-secret/core/src/node/common/model/vault/vault.rs index 909b7e2..1994fce 100644 --- a/meta-secret/core/src/node/common/model/vault/vault.rs +++ b/meta-secret/core/src/node/common/model/vault/vault.rs @@ -7,6 +7,7 @@ use crate::node::common::model::user::common::{UserData, UserDataMember, UserDat use crate::node::common::model::vault::vault_data::{VaultData, WasmVaultData}; use std::fmt::Display; use wasm_bindgen::prelude::wasm_bindgen; +use crate::crypto::utils::Id52bit; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -31,7 +32,13 @@ impl Display for VaultName { } } +#[wasm_bindgen] impl VaultName { + pub fn generate() -> Self { + let id_str = Id52bit::generate().text; + Self(id_str) + } + pub fn test() -> VaultName { VaultName::from("q") } diff --git a/meta-secret/core/src/node/db/descriptors/shared_secret_descriptor.rs b/meta-secret/core/src/node/db/descriptors/shared_secret_descriptor.rs index 273ab95..903e568 100644 --- a/meta-secret/core/src/node/db/descriptors/shared_secret_descriptor.rs +++ b/meta-secret/core/src/node/db/descriptors/shared_secret_descriptor.rs @@ -37,11 +37,11 @@ impl ObjectType for SharedSecretDescriptor { impl SharedSecretDescriptor { pub fn as_id_str(&self) -> String { match self { - SharedSecretDescriptor::SsDistribution(event_id) => event_id.id_str(), + SharedSecretDescriptor::SsDistribution(event_id) => event_id.clone().id_str(), SharedSecretDescriptor::SsLog(vault_name) => vault_name.to_string(), SharedSecretDescriptor::SsDeviceLog(device_id) => device_id.to_string(), - SharedSecretDescriptor::SsDistributionStatus(id) => id.id_str(), - SharedSecretDescriptor::SsClaim(db_id) => db_id.id_str(), + SharedSecretDescriptor::SsDistributionStatus(id) => id.clone().id_str(), + SharedSecretDescriptor::SsClaim(db_id) => db_id.clone().id_str(), } } } diff --git a/meta-secret/core/src/node/server/request.rs b/meta-secret/core/src/node/server/request.rs index c605c7c..eefc252 100644 --- a/meta-secret/core/src/node/server/request.rs +++ b/meta-secret/core/src/node/server/request.rs @@ -2,9 +2,10 @@ use crate::node::common::model::device::common::DeviceData; use crate::node::common::model::user::common::UserData; use crate::node::db::events::object_id::ObjectId; use crate::node::db::objects::persistent_vault::VaultTail; +use derive_more::From; use serde::{Deserialize, Serialize}; -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, From, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum SyncRequest { GlobalIndex(GlobalIndexRequest), diff --git a/meta-secret/core/src/node/server/server_app.rs b/meta-secret/core/src/node/server/server_app.rs index 136cfb9..4cc59d7 100644 --- a/meta-secret/core/src/node/server/server_app.rs +++ b/meta-secret/core/src/node/server/server_app.rs @@ -80,17 +80,21 @@ impl ServerApp { info!("Started ServerApp with: {:?}", &server_creds.device); while let Ok(sync_message) = self.server_dt.dt.service_receive().await { - let result = self + let response_result = self .handle_client_request(server_creds.clone(), sync_message.clone()) .await; - if let Err(err) = &result { - error!( - "Failed handling incoming request: {:?}, with error: {}", - sync_message, err - ); - } - result? + match response_result { + Ok(response) => { + self.server_dt.dt.send_to_client(response).await; + } + Err(err) => { + error!( + "Failed handling incoming request: {:?}, with error: {}", + sync_message, err + ); + } + } } Ok(()) @@ -101,21 +105,18 @@ impl ServerApp { &self, server_creds: DeviceCredentials, sync_message: DataSyncRequest, - ) -> Result<()> { + ) -> Result { match sync_message { DataSyncRequest::SyncRequest(request) => { let new_events = self .handle_sync_request(request, server_creds.device.device_id.clone()) .await?; - - self.server_dt - .dt - .send_to_client(DataSyncResponse::Data(DataEventsResponse(new_events))) - .await; + Ok(DataSyncResponse::Data(DataEventsResponse(new_events))) } DataSyncRequest::Event(event) => { info!("Received new event: {:?}", event); self.data_sync.handle(server_creds.device, event).await?; + Ok(DataSyncResponse::Empty) } DataSyncRequest::ServerTailRequest(user) => { let p_device_log = PersistentDeviceLog { @@ -141,11 +142,9 @@ impl ServerApp { }; let data_sync_response = DataSyncResponse::ServerTailResponse(response); - - self.server_dt.dt.send_to_client(data_sync_response).await; + Ok(data_sync_response) } } - Ok(()) } pub async fn handle_sync_request( @@ -215,9 +214,7 @@ mod test { use crate::node::db::descriptors::shared_secret_descriptor::SharedSecretDescriptor; use crate::node::db::objects::persistent_vault::PersistentVault; use anyhow::bail; - use std::thread; use std::time::Duration; - use tokio::runtime::Builder; use tracing::{info, Instrument}; #[tokio::test] @@ -227,7 +224,7 @@ mod test { let registry = FixtureRegistry::extended().await?; - run_server(®istry).await?; + init_server(®istry).await?; info!("Executing 'sign up' claim"); let client_p_obj = registry.state.base.empty.p_obj.client.clone(); @@ -325,16 +322,9 @@ mod test { Ok(()) } - async fn run_server(registry: &FixtureRegistry) -> anyhow::Result<()> { + async fn init_server(registry: &FixtureRegistry) -> anyhow::Result<()> { let server_app = registry.state.server_app.server_app.clone(); server_app.init().await?; - - thread::spawn(move || { - let rt = Builder::new_multi_thread().enable_all().build().unwrap(); - rt.block_on(async { server_app.run().instrument(server_span()).await }) - }); - async_std::task::sleep(Duration::from_secs(1)).await; - Ok(()) } } diff --git a/meta-secret/core/src/node/server/server_data_sync.rs b/meta-secret/core/src/node/server/server_data_sync.rs index fb973ff..8695a2f 100644 --- a/meta-secret/core/src/node/server/server_data_sync.rs +++ b/meta-secret/core/src/node/server/server_data_sync.rs @@ -1,6 +1,8 @@ use std::cmp::PartialEq; use std::sync::Arc; +use derive_more::From; + use crate::node::common::model::device::common::{DeviceData, DeviceId}; use crate::node::common::model::secret::{SecretDistributionType, SsDistributionStatus}; use crate::node::common::model::user::common::UserData; @@ -38,7 +40,7 @@ pub struct ServerSyncGateway { pub p_obj: Arc>, } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, From, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum DataSyncRequest { SyncRequest(SyncRequest), @@ -49,6 +51,7 @@ pub enum DataSyncRequest { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum DataSyncResponse { + Empty, Data(DataEventsResponse), ServerTailResponse(ServerTailResponse), }