diff --git a/Cargo.lock b/Cargo.lock index fe54db0..b995b77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2651,6 +2651,7 @@ dependencies = [ "async-trait", "ed25519-dalek", "event-emitter-rs", + "fixt", "holo_hash", "holochain", "holochain_conductor_api", diff --git a/Cargo.toml b/Cargo.toml index 9c932e6..825fac2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,14 +36,15 @@ holochain_nonce = "0.4.0-dev.6" holochain_zome_types = { workspace = true } lair_keystore_api = { version = "0.4.5", optional = true } +kitsune_p2p_types = "0.4.0-dev.12" tokio = { version = "1.36", features = ["rt"] } [dev-dependencies] arbitrary = "1.2" +fixt = "0.4.0-dev.3" holochain = { version = "0.4.0-dev.20", features = ["test_utils"] } rand = "0.8" -kitsune_p2p_types = "0.4.0-dev.12" [features] default = ["lair_signing"] diff --git a/src/admin_websocket.rs b/src/admin_websocket.rs index fec320e..342ab5a 100644 --- a/src/admin_websocket.rs +++ b/src/admin_websocket.rs @@ -16,6 +16,7 @@ use holochain_zome_types::{ capability::GrantedFunctions, prelude::{DnaDef, GrantZomeCallCapabilityPayload, Record}, }; +use kitsune_p2p_types::agent_info::AgentInfoSigned; use serde::{Deserialize, Serialize}; use std::{net::ToSocketAddrs, sync::Arc}; use tokio::task::JoinHandle; @@ -319,6 +320,30 @@ impl AdminWebsocket { } } + pub async fn agent_info( + &self, + cell_id: Option, + ) -> ConductorApiResult> { + let msg = AdminRequest::AgentInfo { cell_id }; + let response = self.send(msg).await?; + match response { + AdminResponse::AgentInfo(agent_info) => Ok(agent_info), + _ => unreachable!("Unexpected response {:?}", response), + } + } + + pub async fn add_agent_info( + &self, + agent_infos: Vec, + ) -> ConductorApiResult<()> { + let msg = AdminRequest::AddAgentInfo { agent_infos }; + let response = self.send(msg).await?; + match response { + AdminResponse::AgentInfoAdded => Ok(()), + _ => unreachable!("Unexpected response {:?}", response), + } + } + pub async fn authorize_signing_credentials( &self, request: AuthorizeSigningCredentialsPayload, diff --git a/tests/admin.rs b/tests/admin.rs index 0f35c09..adba6c7 100644 --- a/tests/admin.rs +++ b/tests/admin.rs @@ -7,6 +7,7 @@ use holochain_client::{ use holochain_conductor_api::{CellInfo, StorageBlob}; use holochain_types::websocket::AllowedOrigins; use holochain_zome_types::prelude::ExternIO; +use kitsune_p2p_types::fixt::AgentInfoSignedFixturator; use std::collections::BTreeSet; use std::net::Ipv4Addr; use std::{collections::HashMap, path::PathBuf}; @@ -257,3 +258,41 @@ async fn revoke_agent_key() { }; assert!(matches!(&response[0], (cell, error) if *cell == cell_id && error.contains("invalid"))); } + +#[tokio::test(flavor = "multi_thread")] +async fn agent_info() { + let conductor = SweetConductor::from_standard_config().await; + let admin_port = conductor.get_arbitrary_admin_websocket_port().unwrap(); + let admin_ws = AdminWebsocket::connect(format!("127.0.0.1:{}", admin_port)) + .await + .unwrap(); + let app_id: InstalledAppId = "test-app".into(); + let agent_key = admin_ws.generate_agent_pub_key().await.unwrap(); + admin_ws + .install_app(InstallAppPayload { + agent_key: Some(agent_key.clone()), + installed_app_id: Some(app_id.clone()), + existing_cells: HashMap::new(), + membrane_proofs: Some(HashMap::new()), + network_seed: None, + source: AppBundleSource::Path(PathBuf::from("./fixture/test.happ")), + ignore_genesis_failure: false, + }) + .await + .unwrap(); + admin_ws.enable_app(app_id.clone()).await.unwrap(); + + let agent_infos = admin_ws.agent_info(None).await.unwrap(); + // 2 agent infos expected, 1 app agent and 1 DPKI agent. + assert_eq!(agent_infos.len(), 2); + + let other_agent = fixt::fixt!(AgentInfoSigned); + admin_ws + .add_agent_info(vec![other_agent.clone()]) + .await + .unwrap(); + + let agent_infos = admin_ws.agent_info(None).await.unwrap(); + assert_eq!(agent_infos.len(), 3); + assert!(agent_infos.contains(&other_agent)); +}