mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-06-28 03:59:27 +00:00
Move Ephemeral registry to submodule (#136)
This commit is contained in:
parent
960d0bc119
commit
e163980715
@ -1,114 +1,2 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::Debug,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crypto::Ed25519VerifyingKey;
|
||||
use libchat::{
|
||||
AccountDirectory, DeviceSet, IdentityProvider, RegistrationService, SignedDeviceBundle,
|
||||
verify_bundle,
|
||||
};
|
||||
|
||||
pub mod ephemeral;
|
||||
pub mod http;
|
||||
|
||||
/// A Contact Registry used for Tests.
|
||||
/// This implementation stores bundle bytes and then returns them when
|
||||
/// retrieved.
|
||||
///
|
||||
/// Like the real `keypackage-registry`, one object serves both roles: a
|
||||
/// keypackage store ([`RegistrationService`]) keyed by `device_id`, and an
|
||||
/// account → device directory ([`AccountDirectory`]) keyed by the hex account key.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct EphemeralRegistry {
|
||||
key_packages: Arc<Mutex<HashMap<String, Vec<u8>>>>,
|
||||
installations: Arc<Mutex<HashMap<String, SignedDeviceBundle>>>,
|
||||
}
|
||||
|
||||
impl EphemeralRegistry {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for EphemeralRegistry {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let registry = self.key_packages.lock().unwrap();
|
||||
let truncated: Vec<(&String, String)> = registry
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let hex = if v.len() <= 8 {
|
||||
hex::encode(v)
|
||||
} else {
|
||||
format!(
|
||||
"{}..{}",
|
||||
hex::encode(&v[..4]),
|
||||
hex::encode(&v[v.len() - 4..])
|
||||
)
|
||||
};
|
||||
(k, hex)
|
||||
})
|
||||
.collect();
|
||||
f.debug_struct("EphemeralRegistry")
|
||||
.field("registry", &truncated)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl RegistrationService for EphemeralRegistry {
|
||||
type Error = String;
|
||||
|
||||
fn register(
|
||||
&mut self,
|
||||
identity: &dyn IdentityProvider,
|
||||
key_bundle: Vec<u8>,
|
||||
) -> Result<(), <Self as RegistrationService>::Error> {
|
||||
self.key_packages
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(identity.id().to_string(), key_bundle);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn retrieve(
|
||||
&self,
|
||||
device_id: &str,
|
||||
) -> Result<Option<Vec<u8>>, <Self as RegistrationService>::Error> {
|
||||
Ok(self.key_packages.lock().unwrap().get(device_id).cloned())
|
||||
}
|
||||
}
|
||||
|
||||
/// Account → device directory, verifying each bundle on `fetch` exactly as the
|
||||
/// HTTP client does so callers exercise the same trust path without a server.
|
||||
impl AccountDirectory for EphemeralRegistry {
|
||||
type Error = String;
|
||||
|
||||
fn publish(
|
||||
&mut self,
|
||||
bundle: &SignedDeviceBundle,
|
||||
) -> Result<(), <Self as AccountDirectory>::Error> {
|
||||
self.installations
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(hex::encode(bundle.account_pub.as_ref()), bundle.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fetch(
|
||||
&self,
|
||||
account: &Ed25519VerifyingKey,
|
||||
) -> Result<Option<DeviceSet>, <Self as AccountDirectory>::Error> {
|
||||
let Some(bundle) = self
|
||||
.installations
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get(&hex::encode(account.as_ref()))
|
||||
.cloned()
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
verify_bundle(account, &bundle)
|
||||
.map(Some)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
112
extensions/components/src/contact_registry/ephemeral.rs
Normal file
112
extensions/components/src/contact_registry/ephemeral.rs
Normal file
@ -0,0 +1,112 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::Debug,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crypto::Ed25519VerifyingKey;
|
||||
use libchat::{
|
||||
AccountDirectory, DeviceSet, IdentityProvider, RegistrationService, SignedDeviceBundle,
|
||||
verify_bundle,
|
||||
};
|
||||
|
||||
/// A Contact Registry used for Tests.
|
||||
/// This implementation stores bundle bytes and then returns them when
|
||||
/// retrieved.
|
||||
///
|
||||
/// Like the real `keypackage-registry`, one object serves both roles: a
|
||||
/// keypackage store ([`RegistrationService`]) keyed by `device_id`, and an
|
||||
/// account → device directory ([`AccountDirectory`]) keyed by the hex account key.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct EphemeralRegistry {
|
||||
key_packages: Arc<Mutex<HashMap<String, Vec<u8>>>>,
|
||||
installations: Arc<Mutex<HashMap<String, SignedDeviceBundle>>>,
|
||||
}
|
||||
|
||||
impl EphemeralRegistry {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for EphemeralRegistry {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let registry = self.key_packages.lock().unwrap();
|
||||
let truncated: Vec<(&String, String)> = registry
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let hex = if v.len() <= 8 {
|
||||
hex::encode(v)
|
||||
} else {
|
||||
format!(
|
||||
"{}..{}",
|
||||
hex::encode(&v[..4]),
|
||||
hex::encode(&v[v.len() - 4..])
|
||||
)
|
||||
};
|
||||
(k, hex)
|
||||
})
|
||||
.collect();
|
||||
f.debug_struct("EphemeralRegistry")
|
||||
.field("registry", &truncated)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl RegistrationService for EphemeralRegistry {
|
||||
type Error = String;
|
||||
|
||||
fn register(
|
||||
&mut self,
|
||||
identity: &dyn IdentityProvider,
|
||||
key_bundle: Vec<u8>,
|
||||
) -> Result<(), <Self as RegistrationService>::Error> {
|
||||
self.key_packages
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(identity.id().to_string(), key_bundle);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn retrieve(
|
||||
&self,
|
||||
device_id: &str,
|
||||
) -> Result<Option<Vec<u8>>, <Self as RegistrationService>::Error> {
|
||||
Ok(self.key_packages.lock().unwrap().get(device_id).cloned())
|
||||
}
|
||||
}
|
||||
|
||||
/// Account → device directory, verifying each bundle on `fetch` exactly as the
|
||||
/// HTTP client does so callers exercise the same trust path without a server.
|
||||
impl AccountDirectory for EphemeralRegistry {
|
||||
type Error = String;
|
||||
|
||||
fn publish(
|
||||
&mut self,
|
||||
bundle: &SignedDeviceBundle,
|
||||
) -> Result<(), <Self as AccountDirectory>::Error> {
|
||||
self.installations
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(hex::encode(bundle.account_pub.as_ref()), bundle.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fetch(
|
||||
&self,
|
||||
account: &Ed25519VerifyingKey,
|
||||
) -> Result<Option<DeviceSet>, <Self as AccountDirectory>::Error> {
|
||||
let Some(bundle) = self
|
||||
.installations
|
||||
.lock()
|
||||
.unwrap()
|
||||
.get(&hex::encode(account.as_ref()))
|
||||
.cloned()
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
verify_bundle(account, &bundle)
|
||||
.map(Some)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@ mod delivery;
|
||||
mod storage;
|
||||
mod wakeup;
|
||||
|
||||
pub use contact_registry::EphemeralRegistry;
|
||||
pub use contact_registry::ephemeral::EphemeralRegistry;
|
||||
pub use contact_registry::http::{HttpRegistry, HttpRegistryError};
|
||||
pub use delivery::*;
|
||||
pub use storage::*;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user