use std::sync::Arc;
use holochain_keystore::MetaLairClient;
use holochain_types::prelude::*;
use crate::CellRunner;
#[async_trait::async_trait]
#[mockall::automock]
#[allow(clippy::needless_lifetimes)]
pub trait DpkiService: Send + Sync {
async fn is_key_valid(&self, key: AgentPubKey, timestamp: Timestamp)
-> DpkiServiceResult<bool>;
async fn key_mutation(
&self,
old_key: Option<AgentPubKey>,
new_key: Option<AgentPubKey>,
) -> DpkiServiceResult<()>;
fn cell_ids<'a>(&'a self) -> std::collections::HashSet<&'a CellId>;
}
#[derive(thiserror::Error, Debug)]
#[allow(missing_docs)]
pub enum DpkiServiceError {
#[error("DPKI DNA could not be called: {0}")]
ZomeCallFailed(anyhow::Error),
}
pub type DpkiServiceResult<T> = Result<T, DpkiServiceError>;
#[async_trait::async_trait]
pub trait DpkiServiceExt: DpkiService {
async fn register_key(&self, key: AgentPubKey) -> DpkiServiceResult<()> {
self.key_mutation(None, Some(key)).await
}
async fn update_key(
&self,
old_key: AgentPubKey,
new_key: AgentPubKey,
) -> DpkiServiceResult<()> {
self.key_mutation(Some(old_key), Some(new_key)).await
}
async fn remove_key(&self, key: AgentPubKey) -> DpkiServiceResult<()> {
self.key_mutation(Some(key), None).await
}
}
#[derive(derive_more::Constructor)]
pub struct DeepkeyBuiltin {
runner: Arc<dyn CellRunner>,
keystore: MetaLairClient,
cell_id: CellId,
}
#[allow(unreachable_code)]
#[allow(unused_variables)]
#[allow(clippy::needless_lifetimes)]
#[async_trait::async_trait]
impl DpkiService for DeepkeyBuiltin {
async fn is_key_valid(
&self,
key: AgentPubKey,
timestamp: Timestamp,
) -> DpkiServiceResult<bool> {
let keystore = self.keystore.clone();
let cell_id = self.cell_id.clone();
let zome_name: ZomeName = "TODO: depends on dna implementation".into();
let fn_name: FunctionName = "TODO: depends on dna implementation".into();
let payload = todo!("TODO: depends on dna implementation");
let cap_secret = None;
let provenance = cell_id.agent_pubkey().clone();
let response = self
.runner
.call_zome(
&provenance,
cap_secret,
cell_id,
zome_name,
fn_name,
payload,
)
.await
.map_err(DpkiServiceError::ZomeCallFailed)?;
let is_valid = todo!("deserialize response");
Ok(is_valid)
}
async fn key_mutation(
&self,
old_key: Option<AgentPubKey>,
new_key: Option<AgentPubKey>,
) -> DpkiServiceResult<()> {
todo!()
}
fn cell_ids<'a>(&'a self) -> std::collections::HashSet<&'a CellId> {
[&self.cell_id].into_iter().collect()
}
}
pub fn mock_dpki() -> MockDpkiService {
use futures::FutureExt;
let mut dpki = MockDpkiService::new();
dpki.expect_is_key_valid()
.returning(|_, _| async move { Ok(true) }.boxed());
dpki.expect_cell_ids()
.return_const(std::collections::HashSet::new());
dpki
}