From b1d593c8316a95de1ed01dd4f8e9bf780346d9dd Mon Sep 17 00:00:00 2001 From: Nander Stabel Date: Thu, 5 Dec 2024 21:01:13 +0100 Subject: [PATCH] fix: persist Linked Verifiable Presentations for `did:web` (#149) --- agent_identity/src/service/aggregate.rs | 16 +++++++++++-- agent_identity/src/service/event.rs | 1 + agent_identity/src/service/views/mod.rs | 7 +++++- agent_identity/src/state.rs | 31 ++++++++++++++++++------- 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/agent_identity/src/service/aggregate.rs b/agent_identity/src/service/aggregate.rs index d5a92384..1d855b62 100644 --- a/agent_identity/src/service/aggregate.rs +++ b/agent_identity/src/service/aggregate.rs @@ -34,6 +34,7 @@ pub enum ServiceResource { pub struct Service { #[serde(rename = "id")] pub service_id: String, + pub presentation_ids: Vec, pub service: Option, pub resource: Option, } @@ -189,6 +190,7 @@ impl Aggregate for Service { .type_("LinkedVerifiablePresentation") .service_endpoint(ServiceEndpoint::from(OrderedSet::from_iter( presentation_ids + .clone() .into_iter() .map(|presentation_id| { // TODO: Find a better way to construct the URL @@ -201,7 +203,11 @@ impl Aggregate for Service { .build() .expect("Failed to create Linked Verifiable Presentation Resource"); - Ok(vec![LinkedVerifiablePresentationServiceCreated { service_id, service }]) + Ok(vec![LinkedVerifiablePresentationServiceCreated { + service_id, + presentation_ids, + service, + }]) } } } @@ -221,8 +227,13 @@ impl Aggregate for Service { self.service.replace(service); self.resource.replace(resource); } - LinkedVerifiablePresentationServiceCreated { service_id, service } => { + LinkedVerifiablePresentationServiceCreated { + service_id, + service, + presentation_ids, + } => { self.service_id = service_id; + self.presentation_ids = presentation_ids; self.service.replace(service); } } @@ -278,6 +289,7 @@ pub mod service_tests { }) .then_expect_events(vec![ServiceEvent::LinkedVerifiablePresentationServiceCreated { service_id: linked_verifiable_presentation_service_id, + presentation_ids: vec!["presentation-1".to_string()], service: linked_verifiable_presentation_service, }]) } diff --git a/agent_identity/src/service/event.rs b/agent_identity/src/service/event.rs index 685c1cc1..d399c189 100644 --- a/agent_identity/src/service/event.rs +++ b/agent_identity/src/service/event.rs @@ -16,6 +16,7 @@ pub enum ServiceEvent { }, LinkedVerifiablePresentationServiceCreated { service_id: String, + presentation_ids: Vec, service: DocumentService, }, } diff --git a/agent_identity/src/service/views/mod.rs b/agent_identity/src/service/views/mod.rs index 89820a70..bda80711 100644 --- a/agent_identity/src/service/views/mod.rs +++ b/agent_identity/src/service/views/mod.rs @@ -18,8 +18,13 @@ impl View for Service { self.service.replace(service.clone()); self.resource.replace(resource.clone()); } - LinkedVerifiablePresentationServiceCreated { service_id, service } => { + LinkedVerifiablePresentationServiceCreated { + service_id, + presentation_ids, + service, + } => { self.service_id.clone_from(service_id); + self.presentation_ids.clone_from(presentation_ids); self.service.replace(service.clone()); } } diff --git a/agent_identity/src/state.rs b/agent_identity/src/state.rs index ec3c2f22..75081669 100644 --- a/agent_identity/src/state.rs +++ b/agent_identity/src/state.rs @@ -87,15 +87,28 @@ pub async fn initialize(state: &IdentityState) { // If the did:web method is enabled, create a document if enable_did_web { let did_method = DidMethod::Web; - let command = DocumentCommand::CreateDocument { - did_method: did_method.clone(), - }; - - if command_handler(&did_method.to_string(), &state.command.document, command) - .await - .is_err() - { - warn!("Failed to create document"); + + match query_handler(&did_method.to_string(), &state.query.document).await { + Ok(Some(Document { + document: Some(document), + .. + })) => { + info!("DID Document for `did:web` already exists: {:?}", document); + } + _document_does_not_exist => { + info!("Creating new DID Document for `did:web`"); + + let command = DocumentCommand::CreateDocument { + did_method: did_method.clone(), + }; + + if command_handler(&did_method.to_string(), &state.command.document, command) + .await + .is_err() + { + warn!("Failed to create DID Document for `did:web`"); + } + } } // If domain linkage is enabled, create the domain linkage service and add it to the document.