diff --git a/core/src/crypto/utils.rs b/core/src/crypto/utils.rs index e835f8f5..51fd4d3b 100644 --- a/core/src/crypto/utils.rs +++ b/core/src/crypto/utils.rs @@ -1,7 +1,9 @@ use rand::{distributions::Alphanumeric, Rng}; use sha2::{Digest, Sha256}; use uuid::Uuid; + use crate::crypto::encoding::base64::Base64Text; +use crate::node::db::events::object_descriptor::{ObjectDescriptorFqdn, ObjectDescriptorId}; const SEED_LENGTH: usize = 64; @@ -36,52 +38,24 @@ pub fn generate_uuid_b64_url_enc(value: String) -> String { Base64Text::from(uuid.as_bytes().as_slice()).base64_text } -pub struct IdStrGenerator { - +pub trait NextId { + fn next_id(&self) -> ObjectDescriptorId; } -impl IdStrGenerator { - /// Convert a string to a base64 url encoded uuid - pub fn next_id_str(curr_id_or_name: &str) -> String { - //let hash = Sha256::digest(str.as_bytes()); - //let uuid = Uuid::from_slice(&hash.as_slice()[..16]).unwrap(); - //Base64Text::from(uuid.as_bytes().as_slice()) - //Base64Text::from(uuid.as_bytes().as_slice()) - let next = if curr_id_or_name.contains("::") { - let parts: Vec<&str> = curr_id_or_name.split("::").collect(); - let next_counter: usize = parts[1].parse().unwrap(); - format!("{}::{:?}", parts[0], next_counter + 1) - } else { - format!("{}::{}", curr_id_or_name, 0) - }; - - //Base64Text::from(next) - next +impl NextId for ObjectDescriptorFqdn { + fn next_id(&self) -> ObjectDescriptorId { + ObjectDescriptorId { + fqdn: self.clone(), + counter: 0, + } } } -#[cfg(test)] -mod test { - - #[test] - fn to_id_test() { - //let id = to_id("yay"); - //let expected_uuid = uuid!("f6078ebe-0c2f-08c2-25c0-349aef2fe062").as_ref().as_bytes(); - //let expected_uuid = String::from_utf8(expected_uuid.to_vec()).unwrap(); - //let expected_uuid = Base64Text::from(expected_uuid.as_ref()); - //assert_eq!(expected_uuid, id) - - let id_0 = next_id("qwe:qwe"); - println!("{}", id_0); - let id_0 = next_id(id_0.as_str()); - println!("{}", id_0); - let id_0 = next_id(id_0.as_str()); - println!("{}", id_0); - let id_0 = next_id(id_0.as_str()); - println!("{}", id_0); - let id_0 = next_id(id_0.as_str()); - println!("{}", id_0); - let id_0 = next_id(id_0.as_str()); - println!("{}", id_0); +impl NextId for ObjectDescriptorId { + fn next_id(self) -> ObjectDescriptorId { + ObjectDescriptorId { + counter: self.counter + 1, + ..self + } } } diff --git a/core/src/node/app/sync_gateway.rs b/core/src/node/app/sync_gateway.rs index 881f3235..fa31dc7f 100644 --- a/core/src/node/app/sync_gateway.rs +++ b/core/src/node/app/sync_gateway.rs @@ -3,16 +3,16 @@ use std::time::Duration; use tracing::{debug, error, info, instrument, Instrument}; -use crate::node::app::device_creds_manager::DeviceCredentialsManager; use crate::node::common::model::device::DeviceCredentials; -use crate::node::db::events::common::{LogEventKeyBasedRecord, ObjectCreator, SharedSecretObject}; +use crate::node::db::events::common::SharedSecretObject; use crate::node::db::events::db_tail::{DbTail, ObjectIdDbEvent}; use crate::node::db::events::generic_log_event::GenericKvLogEvent; use crate::node::db::events::global_index::GlobalIndexObject; use crate::node::db::events::kv_log_event::{KvKey, KvLogEvent}; use crate::node::db::events::local::DbTailObject; -use crate::node::db::events::object_descriptor::ObjectDescriptor; -use crate::node::db::events::object_id::{IdGen, ObjectId}; +use crate::node::db::events::object_descriptor::{ObjectDescriptor}; +use crate::node::db::events::object_descriptor::global_index::GlobalIndexDescriptor; +use crate::node::db::events::object_id::{Next, ObjectId, UnitId}; use crate::node::db::generic_db::KvLogEventRepo; use crate::node::db::read_db::read_db_service::ReadDbServiceProxy; use crate::node::db::read_db::store::vault_store::VaultStore; @@ -77,12 +77,12 @@ impl SyncGateway { let sync_request = { let vault_id_request = match &new_db_tail.vault_id { - ObjectIdDbEvent::Empty { unit_id } => unit_id.clone(), + ObjectIdDbEvent::Empty { obj_desc } => ObjectId::unit(obj_desc), ObjectIdDbEvent::Id { tail_id } => tail_id.next(), }; let meta_pass_id_request = match &new_db_tail.meta_pass_id { - ObjectIdDbEvent::Empty { unit_id } => unit_id.clone(), + ObjectIdDbEvent::Empty { obj_desc } => ObjectId::unit(obj_desc), ObjectIdDbEvent::Id { tail_id } => tail_id.next(), }; @@ -119,11 +119,21 @@ impl SyncGateway { match new_event { GenericKvLogEvent::GlobalIndex(gi_obj) => { + if let GlobalIndexObject::Update { event } = gi_obj { - let gi_record = event.value; - let gi_obj_id = ObjectId::Unit { id: gi_record.vault_id }; + let vault_unit_id = event.value; + let idx_desc = ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::VaultIndex { + vault_id: vault_unit_id.clone() + }); + let vault_idx_evt = GenericKvLogEvent::GlobalIndex(GlobalIndexObject::VaultIndex { - event: KvLogEvent::new_global_index_event(&gi_obj_id, gi_obj_id., GlobalIndexDescriptor::VaultIndex), + event: KvLogEvent { + key: KvKey { + obj_id: UnitId::unit(&idx_desc), + obj_desc: idx_desc, + }, + value: vault_unit_id, + } }); self.persistent_object.repo.save_event(vault_idx_evt) @@ -138,7 +148,7 @@ impl SyncGateway { latest_meta_pass_id = ObjectIdDbEvent::Id { tail_id: key.clone() } }, GenericKvLogEvent::SharedSecret(SharedSecretObject::Audit { event }) => { - latest_audit_tail = Some(event.value) + latest_audit_tail = Some(ObjectId::from(event.value)) } _ => { //ignore any non global event @@ -249,7 +259,7 @@ impl SyncGateway { async fn get_new_tail_for_an_obj(&self, db_tail_obj: &ObjectIdDbEvent) -> ObjectIdDbEvent { match db_tail_obj { - ObjectIdDbEvent::Empty { unit_id } => self + ObjectIdDbEvent::Empty { obj_desc } => self .persistent_object .find_tail_id(unit_id.clone()) .await diff --git a/core/src/node/db/actions/recover.rs b/core/src/node/db/actions/recover.rs index cca5604c..7c0404b2 100644 --- a/core/src/node/db/actions/recover.rs +++ b/core/src/node/db/actions/recover.rs @@ -162,7 +162,7 @@ mod test { panic!("Invalid event"); }; - assert_eq!(recovery_request_desc.to_id(), event.value.id_str()); + assert_eq!(recovery_request_desc.to_fqdn(), event.value.id_str()); } { diff --git a/core/src/node/db/events/common.rs b/core/src/node/db/events/common.rs index 6776fa08..049d453b 100644 --- a/core/src/node/db/events/common.rs +++ b/core/src/node/db/events/common.rs @@ -1,20 +1,21 @@ use crate::crypto::encoding::base64::Base64Text; use crate::models::password_recovery_request::PasswordRecoveryRequest; -use crate::models::{Base64EncodedText, MetaPasswordDoc, SecretDistributionDocData, UserSignature, VaultDoc}; -use crate::node::db::events::kv_log_event::{KvKey, KvLogEvent}; -use crate::node::db::events::object_descriptor::ObjectDescriptor; -use crate::node::db::events::object_id::ObjectId; +use crate::models::{MetaPasswordDoc, SecretDistributionDocData}; +use crate::node::common::model::user::UserDataCandidate; +use crate::node::db::events::generic_log_event::ObjIdExtractor; +use crate::node::db::events::kv_log_event::KvLogEvent; +use crate::node::db::events::object_id::{ArtifactId, GenesisId, ObjectId, UnitId}; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum MemPoolObject { - JoinRequest { event: KvLogEvent }, + JoinRequest { event: KvLogEvent }, } -impl MemPoolObject { - pub fn key(&self) -> &KvKey { +impl ObjIdExtractor for MemPoolObject { + fn obj_id(&self) -> ObjectId { match self { - MemPoolObject::JoinRequest { event } => &event.key, + MemPoolObject::JoinRequest { event } => ObjectId::from(event.key.obj_id.clone()) } } } @@ -22,17 +23,17 @@ impl MemPoolObject { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum MetaPassObject { - Unit { event: KvLogEvent<()> }, - Genesis { event: KvLogEvent }, - Update { event: KvLogEvent }, + Unit { event: KvLogEvent }, + Genesis { event: KvLogEvent }, + Update { event: KvLogEvent }, } -impl MetaPassObject { - pub fn key(&self) -> &KvKey { +impl ObjIdExtractor for MetaPassObject { + fn obj_id(&self) -> ObjectId { match self { - MetaPassObject::Unit { event } => &event.key, - MetaPassObject::Genesis { event } => &event.key, - MetaPassObject::Update { event } => &event.key, + MetaPassObject::Unit { event } => ObjectId::from(event.key.obj_id.clone()), + MetaPassObject::Genesis { event } => ObjectId::from(event.key.obj_id.clone()), + MetaPassObject::Update { event } => ObjectId::from(event.key.obj_id.clone()) } } } @@ -41,34 +42,30 @@ impl MetaPassObject { #[serde(rename_all = "camelCase")] pub enum SharedSecretObject { Split { - event: KvLogEvent, + event: KvLogEvent, }, Recover { - event: KvLogEvent, + event: KvLogEvent, }, RecoveryRequest { - event: KvLogEvent, + event: KvLogEvent, }, Audit { - event: KvLogEvent, + event: KvLogEvent, }, } -impl SharedSecretObject { - pub fn key(&self) -> &KvKey { +impl ObjIdExtractor for SharedSecretObject { + fn obj_id(&self) -> ObjectId { match self { - SharedSecretObject::Split { event } => &event.key, - SharedSecretObject::Recover { event } => &event.key, - SharedSecretObject::RecoveryRequest { event } => &event.key, - SharedSecretObject::Audit { event } => &event.key, + SharedSecretObject::Split { event } => ObjectId::from(event.key.obj_id.clone()), + SharedSecretObject::Recover { event } => ObjectId::from(event.key.obj_id.clone()), + SharedSecretObject::RecoveryRequest { event } => ObjectId::from(event.key.obj_id.clone()), + SharedSecretObject::Audit { event } => ObjectId::from(event.key.obj_id.clone()) } } } -pub trait LogEventKeyBasedRecord { - fn key(&self) -> &KvKey; -} - #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct PublicKeyRecord { @@ -81,8 +78,3 @@ impl From for PublicKeyRecord { } } -pub trait ObjectCreator { - fn unit(value: T) -> Self; - fn genesis(obj_desc: &ObjectDescriptor) -> Self; -} - diff --git a/core/src/node/db/events/db_tail.rs b/core/src/node/db/events/db_tail.rs index b0a50e3b..f5057217 100644 --- a/core/src/node/db/events/db_tail.rs +++ b/core/src/node/db/events/db_tail.rs @@ -1,4 +1,5 @@ -use crate::node::db::events::object_id::ObjectId; +use crate::node::db::events::object_descriptor::ObjectDescriptor; +use crate::node::db::events::object_id::{ArtifactId, ObjectId, UnitId}; #[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -15,6 +16,6 @@ pub struct DbTail { #[serde(rename_all = "camelCase")] #[serde(tag = "__db_tail_obj")] pub enum ObjectIdDbEvent { - Empty { unit_id: ObjectId }, + Empty { obj_desc: ObjectDescriptor }, Id { tail_id: ObjectId }, } diff --git a/core/src/node/db/events/generic_log_event.rs b/core/src/node/db/events/generic_log_event.rs index c61ffbb8..4f59ce09 100644 --- a/core/src/node/db/events/generic_log_event.rs +++ b/core/src/node/db/events/generic_log_event.rs @@ -1,8 +1,9 @@ -use crate::node::db::events::common::{LogEventKeyBasedRecord, MemPoolObject, MetaPassObject, SharedSecretObject}; +use crate::node::db::events::common::{MemPoolObject, MetaPassObject, SharedSecretObject}; use crate::node::db::events::error::ErrorMessage; use crate::node::db::events::global_index::GlobalIndexObject; -use crate::node::db::events::kv_log_event::{KvKey, KvLogEvent}; +use crate::node::db::events::kv_log_event::{GenericKvKey, KvLogEvent}; use crate::node::db::events::local::{DbTailObject, DeviceCredentialsObject}; +use crate::node::db::events::object_id::{ArtifactId, ObjectId}; use crate::node::db::events::vault_event::VaultObject; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -19,20 +20,28 @@ pub enum GenericKvLogEvent { DeviceCredentials(DeviceCredentialsObject), DbTail(DbTailObject), - Error { event: KvLogEvent }, + Error { event: KvLogEvent }, } -impl LogEventKeyBasedRecord for GenericKvLogEvent { - fn key(&self) -> &KvKey { +pub trait ObjIdExtractor { + fn obj_id(&self) -> ObjectId; +} + +pub trait KeyExtractor { + fn key(&self) -> GenericKvKey; +} + +impl ObjIdExtractor for GenericKvLogEvent { + fn obj_id(&self) -> ObjectId { match self { - GenericKvLogEvent::GlobalIndex(gi_obj) => gi_obj.key(), - GenericKvLogEvent::Vault(vault_obj) => vault_obj.key(), - GenericKvLogEvent::MetaPass(pass_obj) => pass_obj.key(), - GenericKvLogEvent::SharedSecret(obj) => obj.key(), - GenericKvLogEvent::MemPool(mem_pool_obj) => mem_pool_obj.key(), - GenericKvLogEvent::Error { event } => &event.key, - GenericKvLogEvent::DeviceCredentials(obj) => &obj.event.key, - GenericKvLogEvent::DbTail(obj) => &obj.event.key + GenericKvLogEvent::GlobalIndex(obj) => obj.obj_id(), + GenericKvLogEvent::Vault(obj) => obj.obj_id(), + GenericKvLogEvent::MetaPass(obj) => obj.obj_id(), + GenericKvLogEvent::SharedSecret(obj) => obj.obj_id(), + GenericKvLogEvent::MemPool(obj) => obj.obj_id(), + GenericKvLogEvent::DeviceCredentials(obj) => obj.obj_id(), + GenericKvLogEvent::DbTail(obj) => obj.obj_id(), + GenericKvLogEvent::Error { event } => event.key.obj_id.clone(), } } } diff --git a/core/src/node/db/events/global_index.rs b/core/src/node/db/events/global_index.rs index a892af9a..e6f3d415 100644 --- a/core/src/node/db/events/global_index.rs +++ b/core/src/node/db/events/global_index.rs @@ -1,24 +1,36 @@ use crate::node::db::events::common::PublicKeyRecord; -use crate::node::db::events::generic_log_event::UnitEventEmptyValue; -use crate::node::db::events::kv_log_event::{KvKey, KvLogEvent}; +use crate::node::db::events::generic_log_event::{KeyExtractor, ObjIdExtractor, UnitEventEmptyValue}; +use crate::node::db::events::kv_log_event::{GenericKvKey, KvKey, KvLogEvent}; +use crate::node::db::events::object_id::{ArtifactId, GenesisId, ObjectId, UnitId}; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum GlobalIndexObject { - Unit { event: KvLogEvent<()> }, - Genesis { event: KvLogEvent }, + Unit { event: KvLogEvent }, + Genesis { event: KvLogEvent }, - Update { event: KvLogEvent }, - VaultIndex { event: KvLogEvent }, + Update { event: KvLogEvent }, + VaultIndex { event: KvLogEvent }, } -impl GlobalIndexObject { - pub fn key(&self) -> &KvKey { +impl ObjIdExtractor for GlobalIndexObject { + fn obj_id(&self) -> ObjectId { match self { - GlobalIndexObject::Unit { event } => &event.key, - GlobalIndexObject::Genesis { event } => &event.key, - GlobalIndexObject::Update { event } => &event.key, - GlobalIndexObject::VaultIndex { event } => &event.key + GlobalIndexObject::Unit { event } => ObjectId::from(event.key.obj_id.clone()), + GlobalIndexObject::Genesis { event } => ObjectId::from(event.key.obj_id.clone()), + GlobalIndexObject::Update { event } => ObjectId::from(event.key.obj_id.clone()), + GlobalIndexObject::VaultIndex { event } => ObjectId::from(event.key.obj_id.clone()) + } + } +} + +impl KeyExtractor for GlobalIndexObject { + fn key(&self) -> GenericKvKey { + match self { + GlobalIndexObject::Unit { event } => GenericKvKey::from(event.key.clone()), + GlobalIndexObject::Genesis { event } => GenericKvKey::from(event.key.clone()), + GlobalIndexObject::Update { event } => GenericKvKey::from(event.key.clone()), + GlobalIndexObject::VaultIndex { event } => GenericKvKey::from(event.key.clone()) } } } @@ -38,9 +50,3 @@ impl GlobalIndexObject { } } } - -#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GlobalIndexRecord { - pub vault_id: String, -} diff --git a/core/src/node/db/events/kv_log_event.rs b/core/src/node/db/events/kv_log_event.rs index 173eb435..88052c6d 100644 --- a/core/src/node/db/events/kv_log_event.rs +++ b/core/src/node/db/events/kv_log_event.rs @@ -1,25 +1,25 @@ use crate::node::common::model::user::UserDataCandidate; -use crate::node::db::events::common::{ObjectCreator, PublicKeyRecord}; -use crate::node::db::events::global_index::GlobalIndexRecord; -use crate::node::db::events::object_descriptor::{GlobalIndexDescriptor, ObjectDescriptor}; -use crate::node::db::events::object_id::{Next, ObjectId}; +use crate::node::db::events::common::PublicKeyRecord; +use crate::node::db::events::object_descriptor::global_index::GlobalIndexDescriptor; +use crate::node::db::events::object_descriptor::ObjectDescriptor; +use crate::node::db::events::object_id::{ArtifactId, GenesisId, Next, UnitId}; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct KvLogEvent { - pub key: KvKey, +pub struct KvLogEvent { + pub key: KvKey, pub value: T, } -impl KvLogEvent { - pub fn genesis(obj_desc: &ObjectDescriptor, server_pk: &PublicKeyRecord) -> KvLogEvent { +impl KvLogEvent { + pub fn genesis(obj_desc: &ObjectDescriptor, server_pk: &PublicKeyRecord) -> KvLogEvent { KvLogEvent { key: KvKey::genesis(obj_desc), value: server_pk.clone(), } } - pub fn vault_unit(user_sig: &UserDataCandidate) -> KvLogEvent { + pub fn vault_unit(user_sig: &UserDataCandidate) -> KvLogEvent { let obj_desc = &ObjectDescriptor::vault(user_sig.data.vault_name.clone()); KvLogEvent { key: KvKey::unit(obj_desc), @@ -27,57 +27,73 @@ impl KvLogEvent { } } - pub fn global_index_unit() -> KvLogEvent<()> { + pub fn global_index_unit() -> KvLogEvent { KvLogEvent { key: KvKey::unit(&ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::Index)), value: (), } } - pub fn global_index_genesis(server_pk: &PublicKeyRecord) -> KvLogEvent { + pub fn global_index_genesis(server_pk: &PublicKeyRecord) -> KvLogEvent { Self::genesis(&ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::Index), server_pk) } } -impl KvLogEvent { - pub fn new_global_index_event(tail_id: &ObjectId, vault_id: &IdStr,) -> KvLogEvent { - let key = KvKey { - obj_id: tail_id.clone(), - obj_desc: ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::Index), - }; +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub enum GenericKvKey { + UnitKey { key: KvKey }, + GenesisKey { key: KvKey }, + ArtifactKey { key: KvKey }, +} - KvLogEvent { - key, - value: GlobalIndexRecord { - vault_id: vault_id.id.clone(), - }, - } +impl From> for GenericKvKey { + fn from(unit_key: KvKey) -> Self { + GenericKvKey::UnitKey { key: unit_key } + } +} + +impl From> for GenericKvKey { + fn from(genesis_key: KvKey) -> Self { + GenericKvKey::GenesisKey { key: genesis_key } + } +} + +impl From> for GenericKvKey { + fn from(artifact_key: KvKey) -> Self { + GenericKvKey::ArtifactKey { key: artifact_key } } } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct KvKey { - pub obj_id: ObjectId, +pub struct KvKey { + pub obj_id: Id, pub obj_desc: ObjectDescriptor, } -impl ObjectCreator<&ObjectDescriptor> for KvKey { - fn unit(obj_desc: &ObjectDescriptor) -> Self { +impl KvKey { + pub fn unit(obj_desc: &ObjectDescriptor) -> Self { Self { - obj_id: ObjectId::unit(obj_desc), + obj_id: UnitId::unit(obj_desc), obj_desc: obj_desc.clone(), } } +} - fn genesis(obj_desc: &ObjectDescriptor) -> Self { - Self::unit(obj_desc).next() +impl KvKey { + pub fn genesis(obj_desc: &ObjectDescriptor) -> Self { + let unit_id = KvKey::unit(obj_desc); + Self { + obj_id: unit_id.next().obj_id, + obj_desc: ObjectDescriptor::MemPool, + } } } -impl Next for KvKey { - fn next(&self) -> Self { - Self { +impl Next> for KvKey { + fn next(&self) -> KvKey { + KvKey { obj_id: self.obj_id.next(), obj_desc: self.obj_desc.clone(), } diff --git a/core/src/node/db/events/local.rs b/core/src/node/db/events/local.rs index ef1909c8..7b3ed853 100644 --- a/core/src/node/db/events/local.rs +++ b/core/src/node/db/events/local.rs @@ -1,14 +1,20 @@ use crate::node::common::model::device::DeviceCredentials; -use crate::node::db::events::common::ObjectCreator; use crate::node::db::events::db_tail::DbTail; -use crate::node::db::events::generic_log_event::UnitEvent; +use crate::node::db::events::generic_log_event::{ObjIdExtractor, UnitEvent}; use crate::node::db::events::kv_log_event::{KvKey, KvLogEvent}; use crate::node::db::events::object_descriptor::ObjectDescriptor; +use crate::node::db::events::object_id::{ObjectId, UnitId}; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct DeviceCredentialsObject { - pub event: KvLogEvent + pub event: KvLogEvent +} + +impl ObjIdExtractor for DeviceCredentialsObject { + fn obj_id(&self) -> ObjectId { + ObjectId::from(self.event.key.clone()) + } } impl UnitEvent for DeviceCredentialsObject { @@ -25,7 +31,13 @@ impl UnitEvent for DeviceCredentialsObject { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct DbTailObject { - pub event: KvLogEvent + pub event: KvLogEvent +} + +impl ObjIdExtractor for DbTailObject { + fn obj_id(&self) -> ObjectId { + ObjectId::from(self.event.key.clone()) + } } impl UnitEvent for DbTailObject { diff --git a/core/src/node/db/events/object_descriptor.rs b/core/src/node/db/events/object_descriptor.rs index b5da21f5..87d8df63 100644 --- a/core/src/node/db/events/object_descriptor.rs +++ b/core/src/node/db/events/object_descriptor.rs @@ -1,6 +1,5 @@ -use crate::crypto::utils; -use crate::models::{MetaPasswordId, SecretDistributionDocData, SecretDistributionType}; -use crate::node::common::model::device::DeviceId; +use crate::node::db::events::object_descriptor::global_index::GlobalIndexDescriptor; +use crate::node::db::events::object_descriptor::shared_secret::SharedSecretDescriptor; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -47,88 +46,21 @@ pub enum ObjectDescriptor { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub enum GlobalIndexDescriptor { - Index, - /// An id of a vault. We have global index to keep track and being able to iterate over all vaults, - /// and to be able to check if a particular vault exists we ned to have vault index - VaultIndex -} - -impl GlobalIndexDescriptor { - pub fn as_id_str(&self) -> String { - match self { - GlobalIndexDescriptor::Index => String::from("index"), - GlobalIndexDescriptor::VaultIndex => String::from("vault_idx") - } - } +pub struct ObjectDescriptorFqdn { + pub obj_type: String, + pub obj_instance: String, } #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub enum SharedSecretDescriptor { - Split(SharedSecretEventId), - Recover(SharedSecretEventId), - RecoveryRequest(SharedSecretEventId), -} - -impl SharedSecretDescriptor { - pub fn as_id_str(&self) -> String { - match self { - SharedSecretDescriptor::Split(event_id) => event_id.as_id_str(), - SharedSecretDescriptor::Recover(event_id) => event_id.as_id_str(), - SharedSecretDescriptor::RecoveryRequest(event_id) => event_id.as_id_str(), - } - } -} - -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SharedSecretEventId { - pub vault_name: String, - pub meta_pass_id: MetaPasswordId, - pub receiver: DeviceId -} - -impl SharedSecretEventId { - pub fn as_id_str(&self) -> String { - let pattern = [ - self.vault_name.as_str(), - self.meta_pass_id.id.as_str(), - self.receiver.to_string().as_str(), - ]; - pattern.join("-") - } -} - -impl From<&SecretDistributionDocData> for ObjectDescriptor { - fn from(secret_distribution: &SecretDistributionDocData) -> Self { - let vault_name = secret_distribution.meta_password.meta_password.vault.vault_name.clone(); - let device_id = secret_distribution - .secret_message - .receiver - .vault - .device - .as_ref() - .clone(); - - let meta_pass_id = secret_distribution.meta_password.meta_password.id.as_ref().clone(); - let ss_event_id = SharedSecretEventId { - vault_name, - meta_pass_id, - receiver: device_id, - }; - match secret_distribution.distribution_type { - SecretDistributionType::Split => ObjectDescriptor::SharedSecret(SharedSecretDescriptor::Split(ss_event_id)), - SecretDistributionType::Recover => { - ObjectDescriptor::SharedSecret(SharedSecretDescriptor::Recover(ss_event_id)) - } - } - } +pub struct ObjectDescriptorId { + pub fqdn: ObjectDescriptorFqdn, + pub counter: usize, } impl ObjectDescriptor { - pub fn to_id(&self) -> String { - utils::next_id(self.fqdn().as_str()) + pub fn to_fqdn(&self) -> ObjectDescriptorFqdn { + self.fqdn() } pub fn vault(vault_name: String) -> ObjectDescriptor { @@ -138,8 +70,11 @@ impl ObjectDescriptor { impl ObjectDescriptor { /// Fully Qualified Domain Name - unique domain name of an object - pub fn fqdn(&self) -> String { - format!("{}:{}", self.object_type(), self.object_name()) + pub fn fqdn(&self) -> ObjectDescriptorFqdn { + ObjectDescriptorFqdn { + obj_type: self.object_type(), + obj_instance: self.object_name(), + } } pub fn object_name(&self) -> String { @@ -155,7 +90,6 @@ impl ObjectDescriptor { ObjectDescriptor::MetaPassword { vault_name } => vault_name.clone(), ObjectDescriptor::DeviceCredsIndex => String::from("index"), ObjectDescriptor::GlobalIndex(desc) => desc.as_id_str() - } } } @@ -166,18 +100,18 @@ impl ToString for ObjectDescriptor { } } -impl ObjectDescriptor { - pub fn object_type(&self) -> String { +pub trait ObjectType { + fn object_type(&self) -> String; +} + +impl ObjectType for ObjectDescriptor { + fn object_type(&self) -> String { match self { - ObjectDescriptor::GlobalIndex { .. } => String::from("GlobalIndex"), + ObjectDescriptor::GlobalIndex(gi_desc) => gi_desc.object_type(), ObjectDescriptor::MemPool { .. } => String::from("MemPool"), ObjectDescriptor::Vault { .. } => String::from("Vault"), - ObjectDescriptor::SharedSecret(ss_desc) => match ss_desc { - SharedSecretDescriptor::Split(_) => String::from("SSSplit"), - SharedSecretDescriptor::Recover(_) => String::from("SSRecover"), - SharedSecretDescriptor::RecoveryRequest(_) => String::from("SSRecoveryRequest"), - }, + ObjectDescriptor::SharedSecret(ss_desc) => ss_desc.object_type(), ObjectDescriptor::SharedSecretAudit { .. } => String::from("SSAudit"), @@ -188,17 +122,136 @@ impl ObjectDescriptor { } } +pub mod global_index { + use crate::crypto::utils; + use crate::node::db::events::object_descriptor::ObjectType; + use crate::node::db::events::object_id::UnitId; + + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + pub enum GlobalIndexDescriptor { + Index, + /// An id of a vault. We have global index to keep track and being able to iterate over all vaults, + /// and to be able to check if a particular vault exists we ned to have vault index + VaultIndex { vault_id: UnitId }, + } + + impl ObjectType for GlobalIndexDescriptor { + fn object_type(&self) -> String { + match self { + GlobalIndexDescriptor::Index => String::from("GlobalIndex"), + GlobalIndexDescriptor::VaultIndex { .. } => String::from("VaultIdx") + } + } + } + + impl GlobalIndexDescriptor { + pub fn as_id_str(&self) -> String { + match self { + GlobalIndexDescriptor::Index => String::from("index"), + GlobalIndexDescriptor::VaultIndex { vault_id } => { + let json_str = serde_json::to_string(&vault_id.id).unwrap(); + utils::generate_uuid_b64_url_enc(json_str) + } + } + } + } +} + +pub mod shared_secret { + use crate::models::{MetaPasswordId, SecretDistributionDocData, SecretDistributionType}; + use crate::node::common::model::device::DeviceId; + use crate::node::db::events::object_descriptor::{ObjectDescriptor, ObjectType}; + + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + pub enum SharedSecretDescriptor { + Split(SharedSecretEventId), + Recover(SharedSecretEventId), + RecoveryRequest(SharedSecretEventId), + } + + impl ObjectType for SharedSecretDescriptor { + fn object_type(&self) -> String { + match self { + SharedSecretDescriptor::Split(_) => String::from("SSSplit"), + SharedSecretDescriptor::Recover(_) => String::from("SSRecover"), + SharedSecretDescriptor::RecoveryRequest(_) => String::from("SSRecoveryRequest"), + } + } + } + + impl SharedSecretDescriptor { + pub fn as_id_str(&self) -> String { + match self { + SharedSecretDescriptor::Split(event_id) => event_id.as_id_str(), + SharedSecretDescriptor::Recover(event_id) => event_id.as_id_str(), + SharedSecretDescriptor::RecoveryRequest(event_id) => event_id.as_id_str(), + } + } + } + + #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + pub struct SharedSecretEventId { + pub vault_name: String, + pub meta_pass_id: MetaPasswordId, + pub receiver: DeviceId, + } + + impl SharedSecretEventId { + pub fn as_id_str(&self) -> String { + let pattern = [ + self.vault_name.as_str(), + self.meta_pass_id.id.as_str(), + self.receiver.to_string().as_str(), + ]; + pattern.join("-") + } + } + + impl From<&SecretDistributionDocData> for ObjectDescriptor { + fn from(secret_distribution: &SecretDistributionDocData) -> Self { + let vault_name = secret_distribution.meta_password.meta_password.vault.vault_name.clone(); + let device_id = secret_distribution + .secret_message + .receiver + .vault + .device + .as_ref() + .clone(); + + let meta_pass_id = secret_distribution.meta_password.meta_password.id.as_ref().clone(); + let ss_event_id = SharedSecretEventId { + vault_name, + meta_pass_id, + receiver: device_id, + }; + match secret_distribution.distribution_type { + SecretDistributionType::Split => { + ObjectDescriptor::SharedSecret(SharedSecretDescriptor::Split(ss_event_id)) + }, + SecretDistributionType::Recover => { + ObjectDescriptor::SharedSecret(SharedSecretDescriptor::Recover(ss_event_id)) + } + } + } + } +} + #[cfg(test)] mod test { use crate::crypto::keys::{KeyManager, OpenBox, SecretBox}; - use crate::models::{MetaPasswordId}; + use crate::models::MetaPasswordId; use crate::node::common::model::device::DeviceId; - use crate::node::db::events::object_descriptor::{GlobalIndexDescriptor, ObjectDescriptor, SharedSecretDescriptor, SharedSecretEventId}; + use crate::node::db::events::object_descriptor::global_index::GlobalIndexDescriptor; + use crate::node::db::events::object_descriptor::ObjectDescriptor; + use crate::node::db::events::object_descriptor::shared_secret::{SharedSecretDescriptor, SharedSecretEventId}; #[test] fn test_global_index() { let obj_desc = ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::Index); - assert_eq!(String::from("GlobalIndex:index::0"), obj_desc.to_id()) + assert_eq!(String::from("GlobalIndex:index::0"), obj_desc.to_fqdn()) } #[test] @@ -206,7 +259,7 @@ mod test { let obj_desc = ObjectDescriptor::Vault { vault_name: String::from("test"), }; - assert_eq!(String::from("Vault:test::0"), obj_desc.to_id()) + assert_eq!(String::from("Vault:test::0"), obj_desc.to_fqdn()) } #[test] @@ -214,7 +267,7 @@ mod test { let obj_desc = ObjectDescriptor::MetaPassword { vault_name: String::from("test"), }; - assert_eq!(String::from("MetaPass:test::0"), obj_desc.to_id()) + assert_eq!(String::from("MetaPass:test::0"), obj_desc.to_fqdn()) } #[test] @@ -231,6 +284,6 @@ mod test { let obj_desc = ObjectDescriptor::SharedSecret(SharedSecretDescriptor::Split(event_id)); let expected = format!("SSSplit:test_vault-{}::0", device_id.to_string()); - assert_eq!(expected, obj_desc.to_id()) + assert_eq!(expected, obj_desc.to_fqdn()) } } diff --git a/core/src/node/db/events/object_id.rs b/core/src/node/db/events/object_id.rs index 00f48b0a..3b5a4286 100644 --- a/core/src/node/db/events/object_id.rs +++ b/core/src/node/db/events/object_id.rs @@ -1,8 +1,8 @@ use serde_derive::{Deserialize, Serialize}; -use crate::crypto::utils::IdStrGenerator; -use crate::node::db::events::common::ObjectCreator; -use crate::node::db::events::object_descriptor::{GlobalIndexDescriptor, ObjectDescriptor}; +use crate::crypto::utils::NextId; +use crate::node::db::events::object_descriptor::{ObjectDescriptor, ObjectDescriptorId}; +use crate::node::db::events::object_descriptor::global_index::GlobalIndexDescriptor; #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -13,6 +13,10 @@ pub enum ObjectId { Artifact(ArtifactId), } +pub trait Next { + fn next(self) -> To; +} + /// In category theory, a unit type is a fundamental concept that arises in the study of types and functions. /// It is often denoted as the unit object, represented by the symbol "1" or "Unit." /// The unit type serves as a foundational element within category theory, @@ -21,146 +25,133 @@ pub enum ObjectId { /// Same here, Unit is a initial request to create/initialize an object, it's step zero. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct UnitId(String); - -impl From for GenesisId { - fn from(unit_id: UnitId) -> Self { - Self { - id: IdStrGenerator::next_id_str(unit_id.0.as_str()), - unit_id, - } - } -} - -/// Next step after Unit is Genesis, it's a first step in object initialization, -/// it contains digital signature and public key of the actor (for instance it could be meta secret server) that -/// is responsible to create a persistent object -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct GenesisId { - id: String, - unit_id: UnitId +pub struct UnitId { + pub id: ObjectDescriptorId, } -impl From for ArtifactId { - fn from(genesis_id: GenesisId) -> Self { - Self { - id: IdStrGenerator::next_id_str(genesis_id.id.as_str()), - prev_id: genesis_id.id, - unit_id: genesis_id.unit_id, +impl Next for UnitId { + fn next(self) -> GenesisId { + GenesisId { + id: self.id.next_id(), + unit_id: self, } } } -/// Any regular request or update event in the objects' lifetime -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ArtifactId { - id: String, - prev_id: String, - unit_id: UnitId -} - -/// Generate next artifact from the previous one -impl From for ArtifactId { - fn from(curr: ArtifactId) -> Self { - Self { - id: IdStrGenerator::next_id_str(curr.id.as_str()), - prev_id: curr.id, - unit_id: curr.unit_id, - } +impl From for ObjectId { + fn from(value: UnitId) -> Self { + ObjectId::Unit(value) } } -pub trait Next { - fn next(&self) -> Self; +impl From for ObjectId { + fn from(value: GenesisId) -> Self { + ObjectId::Genesis(value) + } } -impl Next for ObjectId { - fn next( self) -> ObjectId { - match self { - ObjectId::Unit(unit_id) => { - ObjectId::Genesis(GenesisId::from(unit_id)) - } - ObjectId::Genesis(genesis_id) => { - ObjectId::Artifact(ArtifactId::from(genesis_id)) - } - ObjectId::Artifact(artifact_id) => { - ObjectId::Artifact(ArtifactId::from(artifact_id)) - } - } +impl From for ObjectId { + fn from(value: ArtifactId) -> Self { + ObjectId::Artifact(value) } } impl ObjectId { - pub fn unit_id(&self) -> UnitId { - match self { - ObjectId::Unit(unit_id) => unit_id.clone(), - ObjectId::Genesis(genesis_id) => genesis_id.unit_id.clone(), - ObjectId::Artifact(artifact_id) => artifact_id.unit_id.clone() - } + pub fn unit(obj_desc: &ObjectDescriptor) -> Self { + ObjectId::Unit(UnitId::unit(obj_desc)) } +} - pub fn id_str(&self) -> String { +impl Next for ObjectId { + fn next(self) -> ObjectId { match self { - ObjectId::Unit(unit_id) => unit_id.0.clone(), - ObjectId::Genesis(genesis_id) => genesis_id.id.clone(), - ObjectId::Artifact(artifact_id) => artifact_id.id.clone(), + ObjectId::Unit(unit_id) => ObjectId::from(unit_id.next()), + ObjectId::Genesis(genesis_id) => ObjectId::from(genesis_id.next()), + ObjectId::Artifact(artifact_id) => ObjectId::from(artifact_id.next()) } } +} - pub fn db_tail() -> ObjectId { - ObjectId::unit(&ObjectDescriptor::DbTail) +impl UnitId { + pub fn unit(obj_descriptor: &ObjectDescriptor) -> UnitId { + let fqdn = obj_descriptor.to_fqdn(); + UnitId { id: fqdn.next_id() } } - pub fn global_index_unit() -> ObjectId { - ObjectId::unit(&ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::Index)) + pub fn db_tail() -> UnitId { + UnitId::unit(&ObjectDescriptor::DbTail) } - pub fn global_index_genesis() -> ObjectId { - ObjectId::genesis(&ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::Index)) + pub fn global_index() -> UnitId { + UnitId::unit(&ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::Index)) } - pub fn vault_unit(vault_name: &str) -> Self { + pub fn vault_unit(vault_name: &str) -> UnitId { let vault_desc = ObjectDescriptor::Vault { vault_name: vault_name.to_string(), }; - ObjectId::unit(&vault_desc) + UnitId::unit(&vault_desc) } pub fn meta_pass_unit(vault_name: &str) -> Self { let vault_desc = ObjectDescriptor::MetaPassword { vault_name: vault_name.to_string(), }; - ObjectId::unit(&vault_desc) + UnitId::unit(&vault_desc) } pub fn mempool_unit() -> Self { - ObjectId::unit(&ObjectDescriptor::MemPool) + UnitId::unit(&ObjectDescriptor::MemPool) + } +} + +/// Next step after Unit is Genesis, it's a first step in object initialization, +/// it contains digital signature and public key of the actor (for instance it could be meta secret server) that +/// is responsible to create a persistent object +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GenesisId { + id: ObjectDescriptorId, + unit_id: UnitId, +} + +impl Next for GenesisId { + fn next(self) -> ArtifactId { + ArtifactId { + id: self.id.next_id(), + prev_id: self.id, + unit_id: self.unit_id, + } } } -impl ObjectCreator<&ObjectDescriptor> for ObjectId { - fn unit(obj_descriptor: &ObjectDescriptor) -> Self { - let unit_id = obj_descriptor.to_id(); - Self::Unit(UnitId(unit_id)) +impl GenesisId { + pub fn genesis(obj_desc: &ObjectDescriptor) -> GenesisId { + let unit_id = UnitId::unit(obj_desc); + unit_id.next() } - fn genesis(obj_desc: &ObjectDescriptor) -> Self { - Self::unit(obj_desc).next() + pub fn global_index_genesis() -> GenesisId { + GenesisId::genesis(&ObjectDescriptor::GlobalIndex(GlobalIndexDescriptor::Index)) } } -#[cfg(test)] -mod test { - use crate::node::db::events::common::ObjectCreator; - use crate::node::db::events::object_descriptor::ObjectDescriptor; - use crate::node::db::events::object_id::ObjectId; - - #[test] - fn json_parsing_test() { - let obj_id = ObjectId::unit(&ObjectDescriptor::Vault { vault_name: String::from("test")}); - let obj_id_json = serde_json::to_string(&obj_id).unwrap(); - println!("{}", obj_id_json); +/// Any regular request or update event in the objects' lifetime +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ArtifactId { + id: ObjectDescriptorId, + prev_id: ObjectDescriptorId, + unit_id: UnitId, +} + +/// Generate next artifact from the previous one +impl Next for ArtifactId { + fn next(self) -> ArtifactId { + ArtifactId { + id: self.id.next_id(), + prev_id: self.id, + unit_id: self.unit_id, + } } } diff --git a/core/src/node/db/events/vault_event.rs b/core/src/node/db/events/vault_event.rs index d895b9e1..f113d049 100644 --- a/core/src/node/db/events/vault_event.rs +++ b/core/src/node/db/events/vault_event.rs @@ -1,33 +1,35 @@ use crate::node::common::model::user::UserDataCandidate; use crate::node::common::model::vault::VaultData; use crate::node::db::events::common::PublicKeyRecord; -use crate::node::db::events::kv_log_event::{KvKey, KvLogEvent}; +use crate::node::db::events::generic_log_event::ObjIdExtractor; +use crate::node::db::events::kv_log_event::KvLogEvent; +use crate::node::db::events::object_id::{ArtifactId, GenesisId, ObjectId, UnitId}; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum VaultObject { /// SingUp request Unit { - event: KvLogEvent, + event: KvLogEvent, }, Genesis { - event: KvLogEvent, + event: KvLogEvent, }, JoinUpdate { - event: KvLogEvent, + event: KvLogEvent, }, JoinRequest { - event: KvLogEvent, + event: KvLogEvent, }, } -impl VaultObject { - pub fn key(&self) -> &KvKey { +impl ObjIdExtractor for VaultObject { + fn obj_id(&self) -> ObjectId { match self { - VaultObject::Unit { event } => &event.key, - VaultObject::Genesis { event } => &event.key, - VaultObject::JoinUpdate { event } => &event.key, - VaultObject::JoinRequest { event } => &event.key, + VaultObject::Unit { event } => ObjectId::from(event.key.obj_id.clone()), + VaultObject::Genesis { event } => ObjectId::from(event.key.obj_id.clone()), + VaultObject::JoinUpdate { event } => ObjectId::from(event.key.obj_id.clone()), + VaultObject::JoinRequest { event } => ObjectId::from(event.key.obj_id.clone()) } } } diff --git a/core/src/node/db/generic_db.rs b/core/src/node/db/generic_db.rs index 05f22b91..6f897d77 100644 --- a/core/src/node/db/generic_db.rs +++ b/core/src/node/db/generic_db.rs @@ -1,23 +1,11 @@ use async_trait::async_trait; -use tracing::Instrument; -use crate::node::db::events::common::LogEventKeyBasedRecord; use crate::node::db::events::generic_log_event::GenericKvLogEvent; -use crate::node::db::events::kv_log_event::KvKey; use crate::node::db::events::object_id::ObjectId; #[async_trait(? Send)] pub trait SaveCommand { - async fn save(&self, key: ObjectId, value: GenericKvLogEvent) -> anyhow::Result; - - async fn save_event(&self, value: GenericKvLogEvent) -> anyhow::Result { - match &value.key() { - KvKey { obj_id, .. } => { - let _ = self.save(obj_id.clone(), value.clone()).in_current_span().await; - Ok(obj_id.clone()) - } - } - } + async fn save(&self, value: GenericKvLogEvent) -> anyhow::Result; } #[async_trait(? Send)] diff --git a/core/src/node/db/objects/persistent_object.rs b/core/src/node/db/objects/persistent_object.rs index 9c6ce28f..cae7566a 100644 --- a/core/src/node/db/objects/persistent_object.rs +++ b/core/src/node/db/objects/persistent_object.rs @@ -13,7 +13,7 @@ use crate::node::db::events::global_index::GlobalIndexObject; use crate::node::db::events::kv_log_event::{KvKey, KvLogEvent}; use crate::node::db::events::local::DbTailObject; use crate::node::db::events::object_descriptor::ObjectDescriptor; -use crate::node::db::events::object_id::{IdGen, ObjectId}; +use crate::node::db::events::object_id::{IdGen, Next, ObjectId}; use crate::node::db::events::vault_event::VaultObject; use crate::node::db::generic_db::KvLogEventRepo; @@ -95,7 +95,13 @@ impl PersistentObject { match found_event_result { Ok(Some(_curr_tail)) => { existing_id = curr_tail_id.clone(); - curr_tail_id = curr_tail_id.next(); + match existing_id { + ObjectId::Unit(id) => { + curr_tail_id = id.next(); + } + ObjectId::Genesis(_) => {} + ObjectId::Artifact(_) => {} + } } _ => break, } diff --git a/wasm/src/wasm_repo.rs b/wasm/src/wasm_repo.rs index 610db527..65122987 100644 --- a/wasm/src/wasm_repo.rs +++ b/wasm/src/wasm_repo.rs @@ -3,7 +3,7 @@ use async_trait::async_trait; use indexed_db_futures::prelude::*; use indexed_db_futures::IdbDatabase; use js_sys::Object; -use meta_secret_core::node::db::events::generic_log_event::GenericKvLogEvent; +use meta_secret_core::node::db::events::generic_log_event::{GenericKvLogEvent, ObjIdExtractor}; use meta_secret_core::node::db::events::object_id::ObjectId; use meta_secret_core::node::db::generic_db::{ CommitLogDbConfig, DeleteCommand, FindOneQuery, KvLogEventRepo, SaveCommand, @@ -11,6 +11,7 @@ use meta_secret_core::node::db::generic_db::{ use tracing::Instrument; use wasm_bindgen::JsValue; use web_sys::IdbTransactionMode; +use meta_secret_core::node::db::events::kv_log_event::KvKey; pub struct WasmRepo { pub db_name: String, @@ -58,23 +59,26 @@ impl WasmRepo { #[async_trait(? Send)] impl SaveCommand for WasmRepo { - async fn save(&self, key: ObjectId, event: GenericKvLogEvent) -> anyhow::Result { - let event_js: JsValue = - serde_wasm_bindgen::to_value(&event).map_err(|err| anyhow!("Error parsing data to save: {:?}", err))?; + async fn save(&self, event: GenericKvLogEvent) -> anyhow::Result { + let event_js: JsValue = serde_wasm_bindgen::to_value(&event) + .map_err(|err| anyhow!("Error parsing data to save: {:?}", err))?; let db = open_db(self.db_name.as_str()).in_current_span().await; let tx = db .transaction_on_one_with_mode(self.store_name.as_str(), IdbTransactionMode::Readwrite) .unwrap(); + let store = tx.object_store(self.store_name.as_str()).unwrap(); - store.put_key_val_owned(key.id_str().as_str(), &event_js).unwrap(); + + let obj_id = event.obj_id(); + store.put_key_val_owned(obj_id, &event_js).unwrap(); tx.in_current_span().await.into_result().unwrap(); // All of the requests in the transaction have already finished so we can just drop it to // avoid the unused future warning, or assign it to _. //let _ = tx; - Ok(key.clone()) + Ok(obj_id.clone()) } }