From 7b512658b6f95cf4b37a3c4d4a725b83336c10f8 Mon Sep 17 00:00:00 2001 From: Kendall Weihe Date: Mon, 30 Sep 2024 11:43:31 -0400 Subject: [PATCH 1/9] Decorate exact functions w/ async, disregard transitive effect --- crates/web5/src/credentials/credential_schema.rs | 2 +- crates/web5/src/dids/methods/did_dht/mod.rs | 4 ++-- crates/web5/src/dids/methods/did_web/resolver.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/web5/src/credentials/credential_schema.rs b/crates/web5/src/credentials/credential_schema.rs index a6235def..4cee5cb8 100644 --- a/crates/web5/src/credentials/credential_schema.rs +++ b/crates/web5/src/credentials/credential_schema.rs @@ -11,7 +11,7 @@ pub struct CredentialSchema { pub r#type: String, } -pub(crate) fn validate_credential_schema( +pub(crate) async fn validate_credential_schema( verifiable_credential: &VerifiableCredential, ) -> Result<()> { let credential_schema = match &verifiable_credential.credential_schema { diff --git a/crates/web5/src/dids/methods/did_dht/mod.rs b/crates/web5/src/dids/methods/did_dht/mod.rs index 321c8b2f..8acc96ee 100644 --- a/crates/web5/src/dids/methods/did_dht/mod.rs +++ b/crates/web5/src/dids/methods/did_dht/mod.rs @@ -160,7 +160,7 @@ impl DidDht { /// let bearer_did = DidDht::create(None)?; /// DidDht::publish(bearer_did, None)?; /// ``` - pub fn publish(bearer_did: BearerDid, gateway_url: Option) -> Result<()> { + pub async fn publish(bearer_did: BearerDid, gateway_url: Option) -> Result<()> { let packet = bearer_did.document.to_packet().map_err(|e| { Web5Error::Encoding(format!("failed to convert document to packet {}", e)) })?; @@ -241,7 +241,7 @@ impl DidDht { /// # Errors /// /// Returns a `ResolutionMetadataError` if the DID cannot be resolved or verified. - pub fn resolve(uri: &str, gateway_url: Option) -> ResolutionResult { + pub async fn resolve(uri: &str, gateway_url: Option) -> ResolutionResult { let result: std::result::Result = (|| { // check did method and decode id let did = Did::parse(uri).map_err(|_| ResolutionMetadataError::InvalidDid)?; diff --git a/crates/web5/src/dids/methods/did_web/resolver.rs b/crates/web5/src/dids/methods/did_web/resolver.rs index 5a79c189..eca71a40 100644 --- a/crates/web5/src/dids/methods/did_web/resolver.rs +++ b/crates/web5/src/dids/methods/did_web/resolver.rs @@ -42,7 +42,7 @@ impl Resolver { }) } - pub fn resolve(&self) -> Result { + pub async fn resolve(&self) -> Result { let response = http_std::fetch(&self.http_url, None) .map_err(|_| ResolutionMetadataError::InternalError)?; From dd8fd3c6a6c1b4068dc8fb1f4b8586dc649d555a Mon Sep 17 00:00:00 2001 From: Kendall Weihe Date: Mon, 30 Sep 2024 13:41:38 -0400 Subject: [PATCH 2/9] Make all async inside web5 and web5_cli --- crates/web5/src/credentials/create.rs | 222 +++++++++------ crates/web5/src/credentials/decode.rs | 4 +- .../credentials/presentation_definition.rs | 59 ++-- crates/web5/src/credentials/sign.rs | 23 +- .../src/credentials/status_list_credential.rs | 61 ++-- .../credentials/verifiable_credential_1_1.rs | 265 ++++++++++-------- .../verifiable_presentation_1_1.rs | 57 ++-- crates/web5/src/dids/methods/did_dht/mod.rs | 100 ++++--- crates/web5/src/dids/methods/did_web/mod.rs | 16 +- .../src/dids/resolution/resolution_result.rs | 30 +- crates/web5/src/jose.rs | 8 +- crates/web5/src/test_vectors.rs | 17 +- crates/web5_cli/Cargo.toml | 3 +- crates/web5_cli/src/dids/create.rs | 3 +- crates/web5_cli/src/dids/mod.rs | 6 +- crates/web5_cli/src/main.rs | 7 +- crates/web5_cli/src/vcs.rs | 7 +- 17 files changed, 503 insertions(+), 385 deletions(-) diff --git a/crates/web5/src/credentials/create.rs b/crates/web5/src/credentials/create.rs index 9ea8136e..a897c04b 100644 --- a/crates/web5/src/credentials/create.rs +++ b/crates/web5/src/credentials/create.rs @@ -13,7 +13,7 @@ use crate::{ use std::time::SystemTime; use uuid::Uuid; -pub fn create_vc( +pub async fn create_vc( issuer: Issuer, credential_subject: CredentialSubject, options: Option, @@ -42,7 +42,7 @@ pub fn create_vc( evidence: options.evidence, }; - validate_credential_schema(&verifiable_credential)?; + validate_credential_schema(&verifiable_credential).await?; Ok(verifiable_credential) } @@ -106,6 +106,7 @@ mod tests { use super::*; use crate::credentials::credential_schema::{CredentialSchema, CREDENTIAL_SCHEMA_TYPE}; use crate::json::JsonValue; + use crate::{credentials::issuer::ObjectIssuer, json::JsonObject}; use mockito::Server; use regex::Regex; use std::collections::HashMap; @@ -116,9 +117,11 @@ mod tests { fn issuer() -> Issuer { Issuer::from(ISSUER_DID_URI) } + fn credential_subject() -> CredentialSubject { CredentialSubject::from(SUBJECT_DID_URI) } + fn mock_json_schema(url: String, schema_override: Option) -> String { let schema = schema_override .unwrap_or_else(|| "https://json-schema.org/draft/2020-12/schema".to_string()); @@ -148,6 +151,7 @@ mod tests { }}"### ) } + fn mock_credential_schema(url: String) -> Option { Some(CredentialSchema { id: format!("{}/schemas/email.json", url), @@ -155,116 +159,128 @@ mod tests { }) } - use crate::{credentials::issuer::ObjectIssuer, json::JsonObject}; - - #[test] - fn test_default_context_added_if_not_supplied() { + #[tokio::test] + async fn test_default_context_added_if_not_supplied() { let vc = create_vc( issuer(), credential_subject(), Some(VerifiableCredentialCreateOptions::default()), ) + .await .unwrap(); assert_eq!(vc.context, vec![BASE_CONTEXT]); } - #[test] - fn test_default_context_not_duplicated_if_supplied() { + #[tokio::test] + async fn test_default_context_not_duplicated_if_supplied() { let options = VerifiableCredentialCreateOptions { context: Some(vec![BASE_CONTEXT.to_string()]), ..Default::default() }; - let vc = create_vc(issuer(), credential_subject(), Some(options)).unwrap(); + let vc = create_vc(issuer(), credential_subject(), Some(options)) + .await + .unwrap(); assert_eq!(vc.context, vec![BASE_CONTEXT]); } - #[test] - fn test_developer_provided_context_appended_to_default() { + #[tokio::test] + async fn test_developer_provided_context_appended_to_default() { let custom_context = "https://example.com/custom-context"; let options = VerifiableCredentialCreateOptions { context: Some(vec![custom_context.to_string()]), ..Default::default() }; - let vc = create_vc(issuer(), credential_subject(), Some(options)).unwrap(); + let vc = create_vc(issuer(), credential_subject(), Some(options)) + .await + .unwrap(); assert_eq!(vc.context, vec![BASE_CONTEXT, custom_context]); } - #[test] - fn test_default_type_added_if_not_supplied() { + #[tokio::test] + async fn test_default_type_added_if_not_supplied() { let vc = create_vc( issuer(), credential_subject(), Some(VerifiableCredentialCreateOptions::default()), ) + .await .unwrap(); assert_eq!(vc.r#type, vec![BASE_TYPE]); } - #[test] - fn test_default_type_not_duplicated_if_supplied() { + #[tokio::test] + async fn test_default_type_not_duplicated_if_supplied() { let options = VerifiableCredentialCreateOptions { r#type: Some(vec![BASE_TYPE.to_string()]), ..Default::default() }; - let vc = create_vc(issuer(), credential_subject(), Some(options)).unwrap(); + let vc = create_vc(issuer(), credential_subject(), Some(options)) + .await + .unwrap(); assert_eq!(vc.r#type, vec![BASE_TYPE]); } - #[test] - fn test_developer_provided_type_appended_to_default() { + #[tokio::test] + async fn test_developer_provided_type_appended_to_default() { let custom_type = "CustomType"; let options = VerifiableCredentialCreateOptions { r#type: Some(vec![custom_type.to_string()]), ..Default::default() }; - let vc = create_vc(issuer(), credential_subject(), Some(options)).unwrap(); + let vc = create_vc(issuer(), credential_subject(), Some(options)) + .await + .unwrap(); assert_eq!(vc.r#type, vec![BASE_TYPE, custom_type]); } - #[test] - fn test_id_generated_if_not_supplied() { + #[tokio::test] + async fn test_id_generated_if_not_supplied() { let vc = create_vc( issuer(), credential_subject(), Some(VerifiableCredentialCreateOptions::default()), ) + .await .unwrap(); let uuid_regex = Regex::new(r"^urn:uuid:[0-9a-fA-F-]{36}$").unwrap(); assert!(uuid_regex.is_match(&vc.id)); } - #[test] - fn test_id_must_be_set_if_supplied() { + #[tokio::test] + async fn test_id_must_be_set_if_supplied() { let custom_id = "custom-id"; let options = VerifiableCredentialCreateOptions { id: Some(custom_id.to_string()), ..Default::default() }; - let vc = create_vc(issuer(), credential_subject(), Some(options)).unwrap(); + let vc = create_vc(issuer(), credential_subject(), Some(options)) + .await + .unwrap(); assert_eq!(vc.id, custom_id); } - #[test] - fn test_issuer_string_must_not_be_empty() { + #[tokio::test] + async fn test_issuer_string_must_not_be_empty() { let empty_issuer = Issuer::from(""); let result = create_vc( empty_issuer, credential_subject(), Some(VerifiableCredentialCreateOptions::default()), - ); + ) + .await; match result { Err(Web5Error::Parameter(err_msg)) => { @@ -274,25 +290,27 @@ mod tests { }; } - #[test] - fn test_issuer_string_must_be_set() { + #[tokio::test] + async fn test_issuer_string_must_be_set() { let vc = create_vc( issuer(), credential_subject(), Some(VerifiableCredentialCreateOptions::default()), ) + .await .unwrap(); assert_eq!(vc.issuer, issuer()); } - #[test] - fn test_issuer_string_must_be_valid_did() { + #[tokio::test] + async fn test_issuer_string_must_be_valid_did() { let result = create_vc( Issuer::String("did:invalid-123".to_string()), credential_subject(), Some(VerifiableCredentialCreateOptions::default()), - ); + ) + .await; match result { Err(Web5Error::Parameter(err_msg)) => { @@ -302,8 +320,8 @@ mod tests { }; } - #[test] - fn test_issuer_object_id_must_not_be_empty() { + #[tokio::test] + async fn test_issuer_object_id_must_not_be_empty() { let issuer = Issuer::Object(ObjectIssuer { id: "".to_string(), name: "Example Name".to_string(), @@ -314,7 +332,8 @@ mod tests { issuer, credential_subject(), Some(VerifiableCredentialCreateOptions::default()), - ); + ) + .await; match result { Err(Web5Error::Parameter(err_msg)) => { @@ -324,8 +343,8 @@ mod tests { }; } - #[test] - fn test_issuer_object_id_must_be_valid_did() { + #[tokio::test] + async fn test_issuer_object_id_must_be_valid_did() { let result = create_vc( issuer(), CredentialSubject { @@ -333,7 +352,8 @@ mod tests { ..Default::default() }, Some(VerifiableCredentialCreateOptions::default()), - ); + ) + .await; match result { Err(Web5Error::Parameter(err_msg)) => { @@ -346,8 +366,8 @@ mod tests { }; } - #[test] - fn test_issuer_object_name_must_not_be_empty() { + #[tokio::test] + async fn test_issuer_object_name_must_not_be_empty() { let issuer = Issuer::Object(ObjectIssuer { id: ISSUER_DID_URI.to_string(), name: "".to_string(), @@ -358,7 +378,8 @@ mod tests { issuer, credential_subject(), Some(VerifiableCredentialCreateOptions::default()), - ); + ) + .await; match result { Err(Web5Error::Parameter(err_msg)) => { @@ -368,8 +389,8 @@ mod tests { }; } - #[test] - fn test_issuer_object_must_be_set() { + #[tokio::test] + async fn test_issuer_object_must_be_set() { let issuer = Issuer::Object(ObjectIssuer { id: ISSUER_DID_URI.to_string(), name: "Example Name".to_string(), @@ -381,13 +402,14 @@ mod tests { credential_subject(), Some(VerifiableCredentialCreateOptions::default()), ) + .await .unwrap(); assert_eq!(vc.issuer, issuer); } - #[test] - fn test_issuer_object_supports_additional_properties() { + #[tokio::test] + async fn test_issuer_object_supports_additional_properties() { let additional_properties = JsonObject { properties: HashMap::from([( "extra_key".to_string(), @@ -406,6 +428,7 @@ mod tests { credential_subject(), Some(VerifiableCredentialCreateOptions::default()), ) + .await .unwrap(); match vc.issuer { @@ -416,15 +439,16 @@ mod tests { }; } - #[test] - fn test_credential_subject_id_must_not_be_empty() { + #[tokio::test] + async fn test_credential_subject_id_must_not_be_empty() { let credential_subject = CredentialSubject::from(""); let result = create_vc( issuer(), credential_subject, Some(VerifiableCredentialCreateOptions::default()), - ); + ) + .await; match result { Err(Web5Error::Parameter(err_msg)) => { @@ -434,20 +458,21 @@ mod tests { }; } - #[test] - fn test_credential_subject_must_be_set() { + #[tokio::test] + async fn test_credential_subject_must_be_set() { let vc = create_vc( issuer(), credential_subject(), Some(VerifiableCredentialCreateOptions::default()), ) + .await .unwrap(); assert_eq!(vc.credential_subject, credential_subject()); } - #[test] - fn test_credential_subject_supports_additional_properties() { + #[tokio::test] + async fn test_credential_subject_supports_additional_properties() { let additional_properties = JsonObject { properties: HashMap::from([( "extra_key".to_string(), @@ -465,6 +490,7 @@ mod tests { credential_subject.clone(), Some(VerifiableCredentialCreateOptions::default()), ) + .await .unwrap(); assert_eq!( @@ -473,8 +499,8 @@ mod tests { ); } - #[test] - fn test_issuance_date_must_be_set() { + #[tokio::test] + async fn test_issuance_date_must_be_set() { let issuance_date = SystemTime::now(); let options = VerifiableCredentialCreateOptions { @@ -482,18 +508,21 @@ mod tests { ..Default::default() }; - let vc = create_vc(issuer(), credential_subject(), Some(options)).unwrap(); + let vc = create_vc(issuer(), credential_subject(), Some(options)) + .await + .unwrap(); assert_eq!(vc.issuance_date, issuance_date); } - #[test] - fn test_issuance_date_must_be_now_if_not_supplied() { + #[tokio::test] + async fn test_issuance_date_must_be_now_if_not_supplied() { let vc = create_vc( issuer(), credential_subject(), Some(VerifiableCredentialCreateOptions::default()), ) + .await .unwrap(); let now = SystemTime::now(); @@ -502,21 +531,23 @@ mod tests { assert!(vc.issuance_date >= hundred_millis_ago && vc.issuance_date <= now); } - #[test] - fn test_expiration_date_must_be_set_if_supplied() { + #[tokio::test] + async fn test_expiration_date_must_be_set_if_supplied() { let expiration_date = SystemTime::now(); let options = VerifiableCredentialCreateOptions { expiration_date: Some(expiration_date), ..Default::default() }; - let vc = create_vc(issuer(), credential_subject(), Some(options)).unwrap(); + let vc = create_vc(issuer(), credential_subject(), Some(options)) + .await + .unwrap(); assert_eq!(vc.expiration_date, Some(expiration_date)); } - #[test] - fn test_evidence_must_be_set_if_supplied() { + #[tokio::test] + async fn test_evidence_must_be_set_if_supplied() { let mut evidence_item = JsonObject::new(); evidence_item.insert_value("A Key", JsonValue::String("A Value".to_string())); let evidence = vec![evidence_item]; @@ -526,13 +557,15 @@ mod tests { ..Default::default() }; - let vc = create_vc(issuer(), credential_subject(), Some(options)).unwrap(); + let vc = create_vc(issuer(), credential_subject(), Some(options)) + .await + .unwrap(); assert_eq!(Some(evidence), vc.evidence); } - #[test] - fn test_schema_type_must_be_jsonschema() { + #[tokio::test] + async fn test_schema_type_must_be_jsonschema() { let result = create_vc( issuer(), credential_subject(), @@ -543,7 +576,8 @@ mod tests { }), ..Default::default() }), - ); + ) + .await; match result { Err(Web5Error::Parameter(err_msg)) => { @@ -556,8 +590,8 @@ mod tests { } } - #[test] - fn test_schema_resolve_network_issue() { + #[tokio::test] + async fn test_schema_resolve_network_issue() { let url = "http://local".to_string(); // here let result = create_vc( @@ -567,7 +601,8 @@ mod tests { credential_schema: mock_credential_schema(url), ..Default::default() }), - ); + ) + .await; match result { Err(Web5Error::Http(err)) => { @@ -580,8 +615,8 @@ mod tests { }; } - #[test] - fn test_schema_resolve_non_success() { + #[tokio::test] + async fn test_schema_resolve_non_success() { let mut mock_server = Server::new(); let url = mock_server.url(); @@ -597,7 +632,8 @@ mod tests { credential_schema: mock_credential_schema(url), ..Default::default() }), - ); + ) + .await; match result { Err(Web5Error::JsonSchema(err_msg)) => { @@ -610,8 +646,8 @@ mod tests { } } - #[test] - fn test_schema_resolve_invalid_response_body() { + #[tokio::test] + async fn test_schema_resolve_invalid_response_body() { let mut mock_server = Server::new(); let url = mock_server.url(); @@ -629,7 +665,8 @@ mod tests { credential_schema: mock_credential_schema(url), ..Default::default() }), - ); + ) + .await; match result { Err(Web5Error::Json(err_msg)) => { @@ -642,8 +679,8 @@ mod tests { } } - #[test] - fn test_schema_invalid_json_schema() { + #[tokio::test] + async fn test_schema_invalid_json_schema() { let mut mock_server = Server::new(); let url = mock_server.url(); @@ -664,7 +701,8 @@ mod tests { credential_schema: mock_credential_schema(url), ..Default::default() }), - ); + ) + .await; match result { Err(Web5Error::JsonSchema(err_msg)) => { @@ -677,8 +715,8 @@ mod tests { } } - #[test] - fn test_schema_do_not_support_draft04() { + #[tokio::test] + async fn test_schema_do_not_support_draft04() { let mut mock_server = Server::new(); let url = mock_server.url(); @@ -699,7 +737,8 @@ mod tests { credential_schema: mock_credential_schema(url), ..Default::default() }), - ); + ) + .await; match result { Err(Web5Error::JsonSchema(err_msg)) => { @@ -712,8 +751,8 @@ mod tests { } } - #[test] - fn test_schema_do_not_support_draft06() { + #[tokio::test] + async fn test_schema_do_not_support_draft06() { let mut mock_server = Server::new(); let url = mock_server.url(); @@ -734,7 +773,8 @@ mod tests { credential_schema: mock_credential_schema(url), ..Default::default() }), - ); + ) + .await; match result { Err(Web5Error::JsonSchema(err_msg)) => { @@ -747,8 +787,8 @@ mod tests { } } - #[test] - fn test_schema_fails_validation() { + #[tokio::test] + async fn test_schema_fails_validation() { let mut mock_server = Server::new(); let url = mock_server.url(); @@ -766,7 +806,8 @@ mod tests { credential_schema: mock_credential_schema(url), ..Default::default() }), - ); + ) + .await; match result { Err(Web5Error::JsonSchema(err_msg)) => { @@ -779,8 +820,8 @@ mod tests { } } - #[test] - fn test_schema_example_from_spec() { + #[tokio::test] + async fn test_schema_example_from_spec() { // using Example 1 & Example 2 from here https://www.w3.org/TR/vc-json-schema/#jsonschema let mut mock_server = Server::new(); @@ -810,6 +851,7 @@ mod tests { ..Default::default() }), ) + .await .unwrap(); } } diff --git a/crates/web5/src/credentials/decode.rs b/crates/web5/src/credentials/decode.rs index bb2fcb26..0690df13 100644 --- a/crates/web5/src/credentials/decode.rs +++ b/crates/web5/src/credentials/decode.rs @@ -6,8 +6,8 @@ use super::{ use crate::errors::Result; use crate::{jose::Jwt, json::FromJsonValue}; -pub fn decode(vc_jwt: &str, verify_signature: bool) -> Result { - let jwt = Jwt::from_compact_jws(vc_jwt, verify_signature)?; +pub async fn decode(vc_jwt: &str, verify_signature: bool) -> Result { + let jwt = Jwt::from_compact_jws(vc_jwt, verify_signature).await?; let jti = jwt .claims diff --git a/crates/web5/src/credentials/presentation_definition.rs b/crates/web5/src/credentials/presentation_definition.rs index 605cbd81..aabcb879 100644 --- a/crates/web5/src/credentials/presentation_definition.rs +++ b/crates/web5/src/credentials/presentation_definition.rs @@ -178,11 +178,11 @@ impl PresentationDefinition { /// # Returns /// /// A `Result` containing a vector of VCs that fulfill the input descriptors. If no VCs match, returns an empty vector. - pub fn select_credentials(&self, vc_jwts: &Vec) -> Result> { + pub async fn select_credentials(&self, vc_jwts: &Vec) -> Result> { let mut matches: HashSet = HashSet::new(); for input_descriptor in &self.input_descriptors { - let matching_vc_jwts = input_descriptor.select_credentials(vc_jwts)?; + let matching_vc_jwts = input_descriptor.select_credentials(vc_jwts).await?; if matching_vc_jwts.is_empty() { return Ok(vec![]); } @@ -203,7 +203,7 @@ impl PresentationDefinition { /// A `PresentationResult` which holds the `PresentationSubmission` and a `Vec` which has the vc_jwts that were used /// A `PresentationSubmission` object. /// A `Vec` which contains the chosen vc_jwts - pub fn create_presentation_from_credentials( + pub async fn create_presentation_from_credentials( &self, vc_jwts: &Vec, ) -> Result { @@ -215,7 +215,7 @@ impl PresentationDefinition { } // Select the appropriate credentials that match the presentation definition - let selected_credentials = self.select_credentials(vc_jwts)?; + let selected_credentials = self.select_credentials(vc_jwts).await?; if selected_credentials.is_empty() { return Err(PexError::IllegalState( @@ -227,15 +227,17 @@ impl PresentationDefinition { let mut used_vc_jwts = Vec::new(); for input_descriptor in &self.input_descriptors { - let matching_vcs: Vec<&String> = selected_credentials - .iter() - .filter(|vc_jwt| { - input_descriptor - .select_credentials(&vec![vc_jwt.to_string()]) - .map(|result| !result.is_empty()) - .unwrap_or(false) - }) - .collect(); + let mut matching_vcs = Vec::new(); + for vc_jwt in &selected_credentials { + if let Ok(result) = input_descriptor + .select_credentials(&vec![vc_jwt.to_string()]) + .await + { + if !result.is_empty() { + matching_vcs.push(vc_jwt); + } + } + } if matching_vcs.is_empty() { return Err(PexError::IllegalState(format!( @@ -301,7 +303,7 @@ fn get_value_at_json_path(json: &str, path: &str) -> Option { } impl InputDescriptor { - pub fn select_credentials(&self, vc_jwts: &Vec) -> Result> { + pub async fn select_credentials(&self, vc_jwts: &Vec) -> Result> { let mut tokenized_fields: Vec = vec![]; let mut json_schema_builder = JsonSchemaBuilder::new(); @@ -343,7 +345,7 @@ impl InputDescriptor { for vc_jwt in vc_jwts { let mut selection_candidate: Map = Map::new(); - let vc = match VerifiableCredential::from_vc_jwt(vc_jwt, true) { + let vc = match VerifiableCredential::from_vc_jwt(vc_jwt, true).await { Ok(vc) => vc, Err(_) => { continue; @@ -422,8 +424,8 @@ mod tests { use serde_json::json; use std::collections::HashMap; - #[test] - fn test_create_presentation_from_credentials() { + #[tokio::test] + async fn test_create_presentation_from_credentials() { let issuer = DidJwk::create(None).unwrap(); let issuer_uri = issuer.clone().did.uri; @@ -460,13 +462,16 @@ mod tests { CredentialSubject::from(issuer_uri.clone()), Default::default(), ) + .await .unwrap(); let signed_vcjwt_1 = vc_1.sign(&issuer.clone(), None).unwrap(); let vc_jwts = vec![signed_vcjwt_1]; - let result = presentation_definition.create_presentation_from_credentials(&vc_jwts); + let result = presentation_definition + .create_presentation_from_credentials(&vc_jwts) + .await; assert!(result.is_ok(), "Failed to create presentation submission"); @@ -510,8 +515,8 @@ mod tests { /// /// This flow illustrates how a holder can create a VP that satisfies a verifier's requirements, based on input descriptors. - #[test] - fn test_presentation_exchange_full_flow() { + #[tokio::test] + async fn test_presentation_exchange_full_flow() { // Step 1: Create an issuer (typically the entity that issued the credential) let issuer = DidJwk::create(None).unwrap(); let issuer_uri = issuer.clone().did.uri; @@ -552,6 +557,7 @@ mod tests { CredentialSubject::from(issuer_uri.clone()), Default::default(), ) + .await .unwrap(); // Step 4: Sign the VC to generate a VC in JWT format @@ -563,6 +569,7 @@ mod tests { // Step 6: Select the credentials that match the PD's input descriptors let presentation_result = presentation_definition .create_presentation_from_credentials(&vc_jwts) + .await .unwrap(); // Step 7: Create the Verifiable Presentation (VP) with the selected credentials and additional data @@ -588,6 +595,7 @@ mod tests { presentation_result.matched_vc_jwts, // Use the selected credentials from the PD Some(vp_create_options), ) + .await .expect("Failed to create Verifiable Presentation"); // Step 8: Sign the VP to generate a JWT format @@ -595,6 +603,7 @@ mod tests { // Step 9: Decode and verify the signed VP to ensure correctness let decoded_vp = VerifiablePresentation::from_vp_jwt(&vp_jwt, true) + .await .expect("Failed to decode Verifiable Presentation JWT"); // Step 10: Verify the holder matches the expected holder @@ -618,8 +627,8 @@ mod tests { ); } - #[test] - fn test_presentation_exchange_with_multiple_vcs() { + #[tokio::test] + async fn test_presentation_exchange_with_multiple_vcs() { let issuer = DidJwk::create(None).unwrap(); let issuer_uri = issuer.clone().did.uri; @@ -684,6 +693,7 @@ mod tests { }, Default::default(), ) + .await .unwrap(); // For vc_2, we add the "role" property to match the second input descriptor @@ -701,6 +711,7 @@ mod tests { vc_2_credential_subject, Default::default(), ) + .await .unwrap(); // vc_3 won't match either input descriptor @@ -712,6 +723,7 @@ mod tests { }, Default::default(), ) + .await .unwrap(); // Sign all three VCs @@ -728,6 +740,7 @@ mod tests { // Unwrap the result of `create_presentation_from_credentials` let presentation_result = presentation_definition .create_presentation_from_credentials(&vc_jwts) + .await .unwrap(); let holder = DidJwk::create(None).unwrap(); @@ -750,12 +763,14 @@ mod tests { presentation_result.matched_vc_jwts, Some(vp_create_options), ) + .await .expect("Failed to create Verifiable Presentation"); let vp_jwt = vp.sign(&holder.clone(), None).unwrap(); // Decode the Verifiable Presentation JWT let decoded_vp = VerifiablePresentation::from_vp_jwt(&vp_jwt, true) + .await .expect("Failed to decode Verifiable Presentation JWT"); // Check that the holder matches diff --git a/crates/web5/src/credentials/sign.rs b/crates/web5/src/credentials/sign.rs index 2402f8fe..ae29f645 100644 --- a/crates/web5/src/credentials/sign.rs +++ b/crates/web5/src/credentials/sign.rs @@ -68,32 +68,35 @@ mod tests { use super::*; - #[test] - fn test_can_sign_then_verify() { + #[tokio::test] + async fn test_can_sign_then_verify() { let bearer_did = DidJwk::create(None).unwrap(); let vc = VerifiableCredential::create( Issuer::String(bearer_did.did.uri.clone()), credential_subject(), Default::default(), ) + .await .unwrap(); let vc_jwt = sign_with_did(&vc, &bearer_did, None).expect("should be able to sign vc jwt"); let vc_from_vc_jwt = VerifiableCredential::from_vc_jwt(&vc_jwt, true) + .await .expect("should be able to verify the signed vc jwt"); assert_eq!(vc.id, vc_from_vc_jwt.id) } - #[test] - fn test_bearer_did_mismatch_issuer() { + #[tokio::test] + async fn test_bearer_did_mismatch_issuer() { let bearer_did = DidJwk::create(None).unwrap(); let vc = VerifiableCredential::create( Issuer::String(bearer_did.did.uri.clone()), credential_subject(), Default::default(), ) + .await .unwrap(); let different_bearer_did = DidJwk::create(None).unwrap(); @@ -113,32 +116,34 @@ mod tests { }; } - #[test] - fn test_defaults_to_first_vm() { + #[tokio::test] + async fn test_defaults_to_first_vm() { let bearer_did = DidJwk::create(None).unwrap(); let vc = VerifiableCredential::create( Issuer::String(bearer_did.did.uri.clone()), credential_subject(), Default::default(), ) + .await .unwrap(); let vc_jwt = sign_with_did(&vc, &bearer_did, None).expect("should sign with default vm"); - let kid = Jwt::from_compact_jws(&vc_jwt, false).unwrap().kid; + let kid = Jwt::from_compact_jws(&vc_jwt, false).await.unwrap().kid; assert_eq!(bearer_did.document.verification_method[0].id, kid) } - #[test] - fn test_vm_must_be_assertion_method() { + #[tokio::test] + async fn test_vm_must_be_assertion_method() { let mut bearer_did = DidJwk::create(None).unwrap(); let vc = VerifiableCredential::create( Issuer::String(bearer_did.did.uri.clone()), credential_subject(), Default::default(), ) + .await .unwrap(); // remove the assertionMethod diff --git a/crates/web5/src/credentials/status_list_credential.rs b/crates/web5/src/credentials/status_list_credential.rs index 5795aa06..c7b4dafd 100644 --- a/crates/web5/src/credentials/status_list_credential.rs +++ b/crates/web5/src/credentials/status_list_credential.rs @@ -58,7 +58,7 @@ impl StatusListCredential { /// Some(vec![verifiable_credential.clone()]), /// ).unwrap(); /// ``` - pub fn create( + pub async fn create( issuer: Issuer, status_purpose: String, disabled_credentials: Option>, @@ -105,7 +105,7 @@ impl StatusListCredential { }; let verifiable_credential = - VerifiableCredential::create(issuer, credential_subject, Some(vc_options))?; + VerifiableCredential::create(issuer, credential_subject, Some(vc_options)).await?; Ok(Self { base: verifiable_credential, @@ -347,7 +347,7 @@ mod tests { CredentialSubject::from(SUBJECT_DID_URI) } - fn create_test_credential(index: &str, purpose: &str) -> VerifiableCredential { + async fn create_test_credential(index: &str, purpose: &str) -> VerifiableCredential { let credential_status = CredentialStatus { id: format!("https://example.com/status/{}", index), r#type: STATUS_LIST_2021_ENTRY.to_string(), @@ -364,28 +364,30 @@ mod tests { ..Default::default() }), ) + .await .unwrap() } - fn create_test_credential_with_type( + async fn create_test_credential_with_type( index: &str, status_type: &str, purpose: &str, ) -> VerifiableCredential { - let mut credential = create_test_credential(index, purpose); + let mut credential = create_test_credential(index, purpose).await; if let Some(status) = &mut credential.credential_status { status.r#type = status_type.to_string(); } credential } - #[test] - fn test_create_status_list_credential2() { + #[tokio::test] + async fn test_create_status_list_credential2() { let issuer = Issuer::from("did:example:123".to_string()); let status_purpose = "revocation".to_string(); let credentials_to_disable = None; - let result = StatusListCredential::create(issuer, status_purpose, credentials_to_disable); + let result = + StatusListCredential::create(issuer, status_purpose, credentials_to_disable).await; assert!(result.is_ok()); let status_list_credential = result.unwrap(); @@ -449,39 +451,40 @@ mod tests { assert!(result.is_err()); } - #[test] - fn test_is_disabled() -> Result<()> { + #[tokio::test] + async fn test_is_disabled() -> Result<()> { // Create a StatusListCredential with some disabled credentials let issuer = Issuer::from("did:example:issuer"); let status_purpose = "revocation".to_string(); let credentials_to_disable = Some(vec![ - create_test_credential("3", &status_purpose), - create_test_credential("1023", &status_purpose), + create_test_credential("3", &status_purpose).await, + create_test_credential("1023", &status_purpose).await, ]); let status_list_credential = - StatusListCredential::create(issuer, status_purpose.clone(), credentials_to_disable)?; + StatusListCredential::create(issuer, status_purpose.clone(), credentials_to_disable) + .await?; // Test 1: Check a disabled credential (index 3) - let disabled_credential = create_test_credential("3", &status_purpose); + let disabled_credential = create_test_credential("3", &status_purpose).await; assert!(status_list_credential.is_disabled(&disabled_credential)?); // Test 2: Check another disabled credential (index 1023) - let another_disabled_credential = create_test_credential("1023", &status_purpose); + let another_disabled_credential = create_test_credential("1023", &status_purpose).await; assert!(status_list_credential.is_disabled(&another_disabled_credential)?); // Test 3: Check an enabled credential (index 5) - let enabled_credential = create_test_credential("5", &status_purpose); + let enabled_credential = create_test_credential("5", &status_purpose).await; assert!(!status_list_credential.is_disabled(&enabled_credential)?); // Test 4: Check a credential with mismatched status type let mismatched_type_credential = - create_test_credential_with_type("7", "InvalidType", &status_purpose); + create_test_credential_with_type("7", "InvalidType", &status_purpose).await; assert!(status_list_credential .is_disabled(&mismatched_type_credential) .is_err()); // Test 5: Check a credential with mismatched status purpose - let mismatched_purpose_credential = create_test_credential("9", "suspension"); + let mismatched_purpose_credential = create_test_credential("9", "suspension").await; assert!(status_list_credential .is_disabled(&mismatched_purpose_credential) .is_err()); @@ -491,7 +494,8 @@ mod tests { Issuer::from("did:example:issuer"), CredentialSubject::from("did:example:subject"), None, - )?; + ) + .await?; assert!(status_list_credential .is_disabled(&no_status_credential) .is_err()); @@ -499,12 +503,14 @@ mod tests { Ok(()) } - #[test] - fn test_full_flow() { + #[tokio::test] + async fn test_full_flow() { let status_purpose = "revocation".to_string(); let credentials_to_disable = None; let status_list_credential = - StatusListCredential::create(issuer(), status_purpose, credentials_to_disable).unwrap(); + StatusListCredential::create(issuer(), status_purpose, credentials_to_disable) + .await + .unwrap(); let encoded_list = StatusListCredential::get_additional_property( &status_list_credential @@ -540,8 +546,9 @@ mod tests { ..Default::default() }); - let vc1 = - VerifiableCredential::create(issuer(), credential_subject(), vc1_options).unwrap(); + let vc1 = VerifiableCredential::create(issuer(), credential_subject(), vc1_options) + .await + .unwrap(); let vc2_options = Some(VerifiableCredentialCreateOptions { credential_status: Some(CredentialStatus { @@ -554,8 +561,9 @@ mod tests { ..Default::default() }); - let vc2 = - VerifiableCredential::create(issuer(), credential_subject(), vc2_options).unwrap(); + let vc2 = VerifiableCredential::create(issuer(), credential_subject(), vc2_options) + .await + .unwrap(); let credentials_to_disable = Some(vec![vc1, vc2]); @@ -564,6 +572,7 @@ mod tests { "revocation".to_string(), credentials_to_disable, ) + .await .unwrap(); let updated_encoded_list = StatusListCredential::get_additional_property( diff --git a/crates/web5/src/credentials/verifiable_credential_1_1.rs b/crates/web5/src/credentials/verifiable_credential_1_1.rs index 6b973541..9fd01e5e 100644 --- a/crates/web5/src/credentials/verifiable_credential_1_1.rs +++ b/crates/web5/src/credentials/verifiable_credential_1_1.rs @@ -158,12 +158,12 @@ impl VerifiableCredential { /// None, /// ).unwrap(); /// ``` - pub fn create( + pub async fn create( issuer: Issuer, credential_subject: CredentialSubject, options: Option, ) -> Result { - super::create::create_vc(issuer, credential_subject, options) + super::create::create_vc(issuer, credential_subject, options).await } /// Constructs a Verifiable Credential from a VC JWT (JSON Web Token). @@ -179,12 +179,12 @@ impl VerifiableCredential { /// let verifiable_credential = /// VerifiableCredential::from_vc_jwt(vc_jwt, true).unwrap(); /// ``` - pub fn from_vc_jwt(vc_jwt: &str, verify: bool) -> Result { - let verifiable_credential = decode(vc_jwt, verify)?; + pub async fn from_vc_jwt(vc_jwt: &str, verify: bool) -> Result { + let verifiable_credential = decode(vc_jwt, verify).await?; if verify { validate_vc_data_model(&verifiable_credential)?; - validate_credential_schema(&verifiable_credential)?; + validate_credential_schema(&verifiable_credential).await?; } Ok(verifiable_credential) @@ -281,20 +281,20 @@ mod tests { ) } - #[test] - fn test_missing_kid_jose_header() { + #[tokio::test] + async fn test_missing_kid_jose_header() { let vc_jwt_without_kid = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmEzYzY3NGI5LTliNGUtNGE2OS1hYzUwLWM3N2JhYzY0OTg2MCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKclZ6YzNjbnA2VTNGUExYSkxUekpIY1hwd04zRk9TRGhEYWtORmJFMHpabmhMUmtWcVdFTmtaRWxWSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yN1QyMDo0NzoyNS4xMTk2MjQrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnJWemMzY25wNlUzRlBMWEpMVHpKSGNYcHdOM0ZPU0RoRGFrTkZiRTB6Wm5oTFJrVnFXRU5rWkVsVkluMCIsImp0aSI6InVybjp1dWlkOmEzYzY3NGI5LTliNGUtNGE2OS1hYzUwLWM3N2JhYzY0OTg2MCIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDc5MTY0NSwiaWF0IjoxNzI0NzkxNjQ1fQ.ocOyYhqFwz4Jvkdwpa69oFDXCOr2n-_IXSHg5elFebOM0T_lx3Cs6DgQJ7YLLk--mAOvPqrH05bh92BSaLB_DQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_without_kid, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_without_kid, true).await; assert_credential_error(result, VerificationError::MissingKid); } - #[test] - fn test_empty_kid_jose_header() { + #[tokio::test] + async fn test_empty_kid_jose_header() { let vc_jwt_with_empty_kid = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6IiJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmE5MzcwYTZjLWFmNDAtNDU3Zi1iNDNiLWM0YmYzMzcwZTg1OSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKNE5XODFYM3BHTTE5a1QzaDBlbFZzTUVjNGREQnZkVlUyZFRsVFFVdEpiVkZXZFRaa1lsSlpiMUJqSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yN1QyMDozODo0Ni45MjcxMzYrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSjROVzgxWDNwR00xOWtUM2gwZWxWc01FYzRkREJ2ZFZVMmRUbFRRVXRKYlZGV2RUWmtZbEpaYjFCakluMCIsImp0aSI6InVybjp1dWlkOmE5MzcwYTZjLWFmNDAtNDU3Zi1iNDNiLWM0YmYzMzcwZTg1OSIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDc5MTEyNiwiaWF0IjoxNzI0NzkxMTI2fQ.0LzNrPzFY4CsEWRqYdo8pogGDonZqjRqfx9k30NEoWASw8pas6YC-mlDSAQ-4qQaE-otQ6p7zoMeopfw9M1CCQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_kid, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_kid, true).await; match result { Err(Web5Error::CredentialError(err)) => { @@ -304,11 +304,11 @@ mod tests { }; } - #[test] - fn test_kid_invalid_did_uri() { + #[tokio::test] + async fn test_kid_invalid_did_uri() { let vc_jwt_with_invalid_did_uri = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImludmFsaWQgZGlkIHVyaSJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmFhYzFmN2M5LTIzOWQtNGE4OC05NDBiLTEwOTk3NmViNWYyNCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaW52YWxpZCBkaWQgdXJpIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMjozMDowOC41OTAxOTcrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImludmFsaWQgZGlkIHVyaSIsImp0aSI6InVybjp1dWlkOmFhYzFmN2M5LTIzOWQtNGE4OC05NDBiLTEwOTk3NmViNWYyNCIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg0ODIwOCwiaWF0IjoxNzI0ODQ4MjA4fQ.YdmnfP0wIK5HDu8Lft52UFdZCzfdFO0rclAOF-mWt6Y1vqAgoyuOn7AnX1Lx782-iWaekKApCGqCTaXepzj4CQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_did_uri, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_did_uri, true).await; match result { Err(Web5Error::Resolution(err)) => { @@ -318,12 +318,12 @@ mod tests { }; } - #[test] - fn test_kid_fail_to_resolve_did() { + #[tokio::test] + async fn test_kid_fail_to_resolve_did() { let vc_jwt_with_invalid_did_resolution = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6c29tZXRoaW5nLWludmFsaWQifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjhiNGM1NmI5LTM1ODgtNGM0Mi1iOTg3LWEwZTAxNDFmNzA2YSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmRodDpzb21ldGhpbmctaW52YWxpZCIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDgtMjhUMTI6MzQ6NDguMzMzMjg5KzAwOjAwIiwiZXhwaXJhdGlvbkRhdGUiOm51bGwsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5In19LCJpc3MiOiJkaWQ6ZGh0OnNvbWV0aGluZy1pbnZhbGlkIiwianRpIjoidXJuOnV1aWQ6OGI0YzU2YjktMzU4OC00YzQyLWI5ODctYTBlMDE0MWY3MDZhIiwic3ViIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5IiwibmJmIjoxNzI0ODQ4NDg4LCJpYXQiOjE3MjQ4NDg0ODh9.hXbWLVU8ef38O5SY-HshVhXPM1RadFEAGRj0ds5Yjw1_lweWxe1-CNJxLmo0D4BiRCo4T4hCWP_bkwRoteImBA"#; let result = - VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_did_resolution, true); + VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_did_resolution, true).await; match result { Err(Web5Error::Resolution(err)) => { @@ -333,11 +333,11 @@ mod tests { }; } - #[test] - fn test_kid_missing_verification_method() { + #[tokio::test] + async fn test_kid_missing_verification_method() { let vc_jwt_with_missing_vm = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSmZNblZ0WDJFM2EwMU1OM1p0TXpGdlRWbGhjVE5WWWpGTWRWbzBhazFUTjNaT2NsTndlbWxvVWpkWkluMCMwLWludmFsaWQifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmM5ZjUzNTY0LTdkMjYtNGE1NS1iN2E4LTk2MTU4ZTBhNWVhNSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKZk1uVnRYMkUzYTAxTU4zWnRNekZ2VFZsaGNUTlZZakZNZFZvMGFrMVROM1pPY2xOd2VtbG9VamRaSW4wIzAtaW52YWxpZCIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDgtMjhUMTI6NDA6NDIuMjk2Njc4KzAwOjAwIiwiZXhwaXJhdGlvbkRhdGUiOm51bGwsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5In19LCJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUpmTW5WdFgyRTNhMDFNTjNadE16RnZUVmxoY1ROVllqRk1kVm8wYWsxVE4zWk9jbE53ZW1sb1VqZFpJbjAjMC1pbnZhbGlkIiwianRpIjoidXJuOnV1aWQ6YzlmNTM1NjQtN2QyNi00YTU1LWI3YTgtOTYxNThlMGE1ZWE1Iiwic3ViIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5IiwibmJmIjoxNzI0ODQ4ODQyLCJpYXQiOjE3MjQ4NDg4NDJ9.g-KcBy9jJ87PvIZkBUDPkBVF-dlnSTsLUVxOxB4az5q64aIDFJNTffVETD3Cq0fjXKX3tZq3QpfzmNoiTo4xBQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_vm, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_vm, true).await; match result { Err(Web5Error::NotFound(err_msg)) => { @@ -347,11 +347,12 @@ mod tests { }; } - #[test] - fn test_fails_cryptographic_verification() { + #[tokio::test] + async fn test_fails_cryptographic_verification() { let vc_jwt_with_invalid_signature = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZDI1NTE5Iiwia2lkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKMmJGOUNOVTB6UzFwclNXdDNTMDg1VGpKRlVFTTFjVE5IVGxoamQwWktObFl0VlU5RkxTMUlVa3MwSW4wIzAifQ.eyJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUoyYkY5Q05VMHpTMXByU1d0M1MwODVUakpGVUVNMWNUTkhUbGhqZDBaS05sWXRWVTlGTFMxSVVrczBJbjAiLCJqdGkiOiJ1cm46dXVpZDoyMWUxNWRjYi0xM2MzLTQwYTYtYWJiNS01NTA3Nzg5Zjk4YmEiLCJzdWIiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJuYmYiOjE3MjU4OTU2NTYsImlhdCI6MTcyNTg5NTY1NiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiXSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUoyYkY5Q05VMHpTMXByU1d0M1MwODVUakpGVUVNMWNUTkhUbGhqZDBaS05sWXRWVTlGTFMxSVVrczBJbjAiLCJpZCI6InVybjp1dWlkOjIxZTE1ZGNiLTEzYzMtNDBhNi1hYmI1LTU1MDc3ODlmOThiYSIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDktMDlUMTU6Mjc6MzZaIn19.6AR3aNzlMDgRpniSMhOGfXN3wUS0IkIoWa_KpZprOWwVbSyVjcI_Ndo3SGCutUSiBboYH9sFomdGb7_0AeVDCg"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_signature, true); + let result = + VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_signature, true).await; match result { Err(Web5Error::Crypto(err_msg)) => { @@ -361,11 +362,12 @@ mod tests { }; } - #[test] - fn test_passes_cryptographic_verification() { + #[tokio::test] + async fn test_passes_cryptographic_verification() { let vc_jwt_valid = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSkhWelpGVERsSVRUbHRkSGx5Y0dsWWRGRlVNR3B4Wms1MmFXTm5RVGxCVkRnME1IWTFZMDh5YjFSckluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjZmYTQ2MDVjLWFlZGItNGQ2NC05NzdiLTFmY2NmYTU1ZTM1ZiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKSFZ6WkZURGxJVFRsdGRIbHljR2xZZEZGVU1HcHhaazUyYVdOblFUbEJWRGcwTUhZMVkwOHliMVJySW4wIzAiLCJpc3N1YW5jZURhdGUiOiIyMDI0LTA4LTI4VDEyOjQyOjI3Ljc3Mjg4OSswMDowMCIsImV4cGlyYXRpb25EYXRlIjpudWxsLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSJ9fSwiaXNzIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKSFZ6WkZURGxJVFRsdGRIbHljR2xZZEZGVU1HcHhaazUyYVdOblFUbEJWRGcwTUhZMVkwOHliMVJySW4wIzAiLCJqdGkiOiJ1cm46dXVpZDo2ZmE0NjA1Yy1hZWRiLTRkNjQtOTc3Yi0xZmNjZmE1NWUzNWYiLCJzdWIiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJuYmYiOjE3MjQ4NDg5NDcsImlhdCI6MTcyNDg0ODk0N30.-JwIGYZ9HlJASYxdRBWY5KlwP0iJUxWUOU6BsOR74VeC-zKgZb9WWZR08OVD-wv0X8KD5--0K5Dr9r5fL3B0Aw"#; let vc = VerifiableCredential::from_vc_jwt(vc_jwt_valid, true) + .await .expect("vc_jwt should be valid"); assert_eq!( "did:jwk:eyJhbGciOiJFZDI1NTE5Iiwia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJHVzZFTDlITTltdHlycGlYdFFUMGpxZk52aWNnQTlBVDg0MHY1Y08yb1RrIn0#0", @@ -373,40 +375,44 @@ mod tests { ); } - #[test] - fn test_can_skip_cryptographic_verification() { + #[tokio::test] + async fn test_can_skip_cryptographic_verification() { let vc_jwt_with_invalid_signature = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSkhWelpGVERsSVRUbHRkSGx5Y0dsWWRGRlVNR3B4Wms1MmFXTm5RVGxCVkRnME1IWTFZMDh5YjFSckluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjZmYTQ2MDVjLWFlZGItNGQ2NC05NzdiLTFmY2NmYTU1ZTM1ZiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKSFZ6WkZURGxJVFRsdGRIbHljR2xZZEZGVU1HcHhaazUyYVdOblFUbEJWRGcwTUhZMVkwOHliMVJySW4wIzAiLCJpc3N1YW5jZURhdGUiOiIyMDI0LTA4LTI4VDEyOjQyOjI3Ljc3Mjg4OSswMDowMCIsImV4cGlyYXRpb25EYXRlIjpudWxsLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSJ9fSwiaXNzIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKSFZ6WkZURGxJVFRsdGRIbHljR2xZZEZGVU1HcHhaazUyYVdOblFUbEJWRGcwTUhZMVkwOHliMVJySW4wIzAiLCJqdGkiOiJ1cm46dXVpZDo2ZmE0NjA1Yy1hZWRiLTRkNjQtOTc3Yi0xZmNjZmE1NWUzNWYiLCJzdWIiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJuYmYiOjE3MjQ4NDg5NDcsImlhdCI6MTcyNDg0ODk0N30.-JwIGYZ9HlJASYxdRBWY5KlwP0iJUxWUOU6BsOR74VeC-zKgZb9WWZR08OVD-wv0X8KD5--0K5Dr9r5fL3B0Aw-invalid-signature"#; let vc = VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_signature, false) + .await .expect("vc_jwt should be valid"); assert_eq!("urn:uuid:6fa4605c-aedb-4d64-977b-1fccfa55e35f", vc.id) } - #[test] - fn test_can_skip_data_model_validation() { + #[tokio::test] + async fn test_can_skip_data_model_validation() { // expired would throw an error, but since verify=false it doesn't let vc_jwt_with_expired = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnpjV3hxVTJaZlgzbE9TVVpKTVVwaWNYQkVSVEJuVUZGT2FVazBiVkZqV2pONmRtZFVVbmg2WTAxbkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmFkNzBmN2Y2LWExNTctNGYxZi1hZjI5LTdjYmJkNDRmODlmMCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKemNXeHFVMlpmWDNsT1NVWkpNVXBpY1hCRVJUQm5VRkZPYVVrMGJWRmpXak42ZG1kVVVuaDZZMDFuSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzo0NDoyNy45MTUwMjUrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMTktMDktMDRUMTM6NDQ6MjcuOTE0ODY0KzAwOjAwIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnpjV3hxVTJaZlgzbE9TVVpKTVVwaWNYQkVSVEJuVUZGT2FVazBiVkZqV2pONmRtZFVVbmg2WTAxbkluMCIsImp0aSI6InVybjp1dWlkOmFkNzBmN2Y2LWExNTctNGYxZi1hZjI5LTdjYmJkNDRmODlmMCIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg1MjY2NywiaWF0IjoxNzI0ODUyNjY3LCJleHAiOjE1Njc2MDQ2Njd9.pP_8QVzTqxuhUlIWpXDWQ3Py_VlDA4uX82xdD9GOdmRT2UK-K5Gn7A5qdUxBPhXifiRVnH_Q8NbWZCUQ8jZUBg"#; let vc = VerifiableCredential::from_vc_jwt(vc_jwt_with_expired, false) + .await .expect("vc_jwt should be valid"); assert_eq!("urn:uuid:ad70f7f6-a157-4f1f-af29-7cbbd44f89f0", vc.id) } - #[test] - fn test_can_skip_credential_schema_validation() { + #[tokio::test] + async fn test_can_skip_credential_schema_validation() { // expired would throw an error, but since verify=false it doesn't let vc_jwt_with_invalid_schema = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSXlkMjFXVjFwblMySk1iM0JPVEhWTmRYUlNSV2gwTWtWMmJEbExkVkpFTFY5MlVrRnpWMlZwUm01TkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjE1OTY4MDA4LTI1OTEtNGY0MS1hOWI1LWU2YmUxNDU5ZDcxNiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJeWQyMVdWMXBuUzJKTWIzQk9USFZOZFhSU1JXaDBNa1YyYkRsTGRWSkVMVjkyVWtGelYyVnBSbTVOSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0zMFQxNDo1NTozNS41MTc5NjUrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6ImludmFsaWQgdXJsL3NjaGVtYXMvZW1haWwuanNvbiIsInR5cGUiOiJKc29uU2NoZW1hIn19LCJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUl5ZDIxV1YxcG5TMkpNYjNCT1RIVk5kWFJTUldoME1rVjJiRGxMZFZKRUxWOTJVa0Z6VjJWcFJtNU5JbjAiLCJqdGkiOiJ1cm46dXVpZDoxNTk2ODAwOC0yNTkxLTRmNDEtYTliNS1lNmJlMTQ1OWQ3MTYiLCJzdWIiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJuYmYiOjE3MjUwMjk3MzUsImlhdCI6MTcyNTAyOTczNX0.8zNS9RWIpvTlMvAzaI9dNSjKKM1drFig7bKhQeQ6Mv9hWXwazvDhxthy3D25EmITWAPiJfGcMPDqoDobETf8DA"#; let vc = VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_schema, false) + .await .expect("vc_jwt should be valid"); assert_eq!("urn:uuid:15968008-2591-4f41-a9b5-e6be1459d716", vc.id) } - #[test] - fn test_decode_issuer_string() { + #[tokio::test] + async fn test_decode_issuer_string() { let vc_jwt_with_issuer_as_string = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnlkMmhYU1VOWWNsSjNiMFphUm1SMU0wbHNOaTFCTkdVdGRqazNRbE14UmtaUmFWRTRhV05tV2t0ckluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjc0NTY5ZmIzLWMyZTktNGZiMy1hOThkLWY3NGFjNzVjYTg5NSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKeWQyaFhTVU5ZY2xKM2IwWmFSbVIxTTBsc05pMUJOR1V0ZGprM1FsTXhSa1pSYVZFNGFXTm1Xa3RySW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxNjozNjoyOS4zNDc4ODArMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnlkMmhYU1VOWWNsSjNiMFphUm1SMU0wbHNOaTFCTkdVdGRqazNRbE14UmtaUmFWRTRhV05tV2t0ckluMCIsImp0aSI6InVybjp1dWlkOjc0NTY5ZmIzLWMyZTktNGZiMy1hOThkLWY3NGFjNzVjYTg5NSIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg2Mjk4OSwiaWF0IjoxNzI0ODYyOTg5fQ.0DSZ2XbPtjtrtxNKo3tImoByb1-jlQxZQN11lsngaFSe4lhy4mYmaxGAby4wIl-c_cLEkgBULfF3Qa_dlNSTCw"#; let vc = VerifiableCredential::from_vc_jwt(&vc_jwt_with_issuer_as_string, false) + .await .expect("should be valid vc jwt"); match vc.issuer { Issuer::String(issuer) => { @@ -419,11 +425,12 @@ mod tests { } } - #[test] - fn test_decode_issuer_object() { + #[tokio::test] + async fn test_decode_issuer_object() { let vc_jwt_with_issuer_object = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSTFVazF5YVVNMVZsaHVielpTVkRoTVdWVnJibnBKWm5OamFUUXlZbXhCYVdsTFdrcENaR2huVm5WQkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjcwNWM0MTZiLTU1ODYtNDUzMS1hMmRmLWI3YzdhNTMxMGY5NiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjp7ImlkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJMVVrMXlhVU0xVmxodWJ6WlNWRGhNV1ZWcmJucEpabk5qYVRReVlteEJhV2xMV2twQ1pHaG5WblZCSW4wIiwibmFtZSI6InNvbWUgbmFtZSJ9LCJpc3N1YW5jZURhdGUiOiIyMDI0LTA4LTI4VDE2OjQwOjExLjUwNDIyMCswMDowMCIsImV4cGlyYXRpb25EYXRlIjpudWxsLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSJ9fSwiaXNzIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJMVVrMXlhVU0xVmxodWJ6WlNWRGhNV1ZWcmJucEpabk5qYVRReVlteEJhV2xMV2twQ1pHaG5WblZCSW4wIiwianRpIjoidXJuOnV1aWQ6NzA1YzQxNmItNTU4Ni00NTMxLWEyZGYtYjdjN2E1MzEwZjk2Iiwic3ViIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5IiwibmJmIjoxNzI0ODYzMjExLCJpYXQiOjE3MjQ4NjMyMTF9.Mv-wlUcnj0w-OWuoMBCciaQXrAogXL3qqgZnthTRI9f55S5PidYiSapWFxFqc4SzxTVSpe64H2vF7kfGU-QpBw"#; let vc = VerifiableCredential::from_vc_jwt(&vc_jwt_with_issuer_object, false) + .await .expect("should be valid vc jwt"); match vc.issuer { Issuer::String(_) => panic!("issuer should be object"), @@ -437,10 +444,11 @@ mod tests { } } - #[test] - fn test_decode_evidence() { + #[tokio::test] + async fn test_decode_evidence() { let vc_jwt_with_evidence = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSmljbll0T1VKSGRUVlhNVFV4VkVKVk9GY3hVVkozU1dwSWRXVmlVVGc1TlRCQ2VuRTFjR1ZxV25wSkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjkxYWM1NzBmLTRjMDMtNDIxZi1iZGY4LWQ3Y2YyNzQ1YzVmNSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKaWNuWXRPVUpIZFRWWE1UVXhWRUpWT0ZjeFVWSjNTV3BJZFdWaVVUZzVOVEJDZW5FMWNHVnFXbnBKSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0zMFQxMDowMToyNC4yNTgzNjYrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiZXZpZGVuY2UiOlt7IkEgS2V5IjoiQSBWYWx1ZSJ9XX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSmljbll0T1VKSGRUVlhNVFV4VkVKVk9GY3hVVkozU1dwSWRXVmlVVGc1TlRCQ2VuRTFjR1ZxV25wSkluMCIsImp0aSI6InVybjp1dWlkOjkxYWM1NzBmLTRjMDMtNDIxZi1iZGY4LWQ3Y2YyNzQ1YzVmNSIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNTAxMjA4NCwiaWF0IjoxNzI1MDEyMDg0fQ.M7t4Ox08v-rC-naPSfIqlE1KKhZ1nrx_QA2HbuW38AkgxnSZOYEpXEG1UTAzh6mdwKZin9jwoGrj29u24K1ABA"#; let vc = VerifiableCredential::from_vc_jwt(&vc_jwt_with_evidence, false) + .await .expect("should be valid vc jwt"); let mut evidence_item = JsonObject::new(); @@ -449,10 +457,11 @@ mod tests { assert_eq!(Some(expected_evidence), vc.evidence); } - #[test] - fn test_decode_credential_schema() { + #[tokio::test] + async fn test_decode_credential_schema() { let vc_jwt_with_credential_schema = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSTFUMXB2TVd4bU9VcHlOeTFZTkdGWU4yRmxka2N5WVU5MGEwWmxlSFZuYzBwcVZVbEtWVU5UYVVkUkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjNhMDU2NjE1LWNlZDMtNGQ4Zi05ODRhLTUwMzQ2Y2FlNDQ2ZiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJMVQxcHZNV3htT1VweU55MVlOR0ZZTjJGbGRrY3lZVTkwYTBabGVIVm5jMHBxVlVsS1ZVTlRhVWRSSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0zMFQxNDo1OToyMi4xMDMzODUrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5jb20vc2NoZW1hcy9lbWFpbC5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSTFUMXB2TVd4bU9VcHlOeTFZTkdGWU4yRmxka2N5WVU5MGEwWmxlSFZuYzBwcVZVbEtWVU5UYVVkUkluMCIsImp0aSI6InVybjp1dWlkOjNhMDU2NjE1LWNlZDMtNGQ4Zi05ODRhLTUwMzQ2Y2FlNDQ2ZiIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNTAyOTk2MiwiaWF0IjoxNzI1MDI5OTYyfQ.ZQkusfYLJSpfLVF9OuWrrhw8NdcBnjlalMFZbsfAxJp8i74KH47RkMsVVPadLPuKwbozgcDRCKPsokrl33TuCw"#; let vc = VerifiableCredential::from_vc_jwt(&vc_jwt_with_credential_schema, false) + .await .expect("should be valid vc jwt"); let credential_schema = CredentialSchema { @@ -463,25 +472,28 @@ mod tests { assert_eq!(Some(credential_schema), vc.credential_schema) } - #[test] - fn test_decode_missing_vc_claim() { + #[tokio::test] + async fn test_decode_missing_vc_claim() { let vc_jwt_with_missing_vc_claim = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSlNSbkZSVlVWS1RFOVhlbXh3T1ZaRk1rdEtSalp6UjBwT00yVnpaWHBsY0hSSE0ySTFlbTh4YjAwNEluMCMwIn0.eyJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUpTUm5GUlZVVktURTlYZW14d09WWkZNa3RLUmpaelIwcE9NMlZ6WlhwbGNIUkhNMkkxZW04eGIwMDRJbjAiLCJqdGkiOiJ1cm46dXVpZDozNmU0ZjllNi0yYzdjLTQ0NGMtOTI4OS0zNDhmY2IxNDZlYjYiLCJzdWIiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJuYmYiOjE3MjQ4NTA1MjIsImlhdCI6MTcyNDg1MDUyMn0.SqwZC0q9RuHp9hAtFmE6sBYeJ1uHuuq1hyijF0NmW9nksSBqtDpfNroNlitK_Tl-CLWtwbTpK3b3JduTfzGEAw"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_vc_claim, true); + let result = + VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_vc_claim, true).await; assert_credential_error(result, VerificationError::MissingClaim("vc".to_string())); } - #[test] - fn test_decode_missing_jti_claim() { + #[tokio::test] + async fn test_decode_missing_jti_claim() { let vc_jwt_with_missing_jti_claim = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSm5jMjlTZGsxUFlXMHliMlJQTlY4NWVqbExlV2xzV1VzM1Yzb3RZa1owWW5wdlVrWm1iVTlUTVRJNEluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjEwODM2MzgwLWI2MmMtNGVmZC04YmU0LTZhNzJiMDZjYWI4NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKbmMyOVNkazFQWVcweWIyUlBOVjg1ZWpsTGVXbHNXVXMzVjNvdFlrWjBZbnB2VWtabWJVOVRNVEk0SW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzoxMDo1NS4yMDYwOTIrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSm5jMjlTZGsxUFlXMHliMlJQTlY4NWVqbExlV2xzV1VzM1Yzb3RZa1owWW5wdlVrWm1iVTlUTVRJNEluMCIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg1MDY1NSwiaWF0IjoxNzI0ODUwNjU1fQ.1XDmdvB1GDsCHw9Qwp0HA5r8W-JnZB4lz9Yqo0C2V_EEe-uk88bQSl8P9HV8ViNyBC_YaYatLiPTD4jBZY77DA"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_jti_claim, true); + let result = + VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_jti_claim, true).await; assert_credential_error(result, VerificationError::MissingClaim("jti".to_string())); } - #[test] - fn test_decode_missing_issuer_claim() { + #[tokio::test] + async fn test_decode_missing_issuer_claim() { let vc_jwt_with_missing_iss_claim = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnpjamREVWtVek1HbzNjVVU0Y2taVVJYQXdSbFJzYnpKVVVXVmlZa1ZHTVVvelJHaHRTVWhaVTNFd0luMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjRjYzU0NWU0LWI5ZDgtNDdkNS04Zjk0LTA4MmM0ZGViNzAyZCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKemNqZERVa1V6TUdvM2NVVTRja1pVUlhBd1JsUnNiekpVVVdWaVlrVkdNVW96UkdodFNVaFpVM0V3SW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzoxMTo1Mi4zMjg4MTMrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImp0aSI6InVybjp1dWlkOjRjYzU0NWU0LWI5ZDgtNDdkNS04Zjk0LTA4MmM0ZGViNzAyZCIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg1MDcxMiwiaWF0IjoxNzI0ODUwNzEyfQ.hwR6edt6ItlN0HHkDcxzhE3N5hLk-5-VYDLrqkalUoTKB41vsfaPvGnt_UQK3EAuekQgrTQ0SuCq-6ut0EdlBw"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_iss_claim, true); + let result = + VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_iss_claim, true).await; match result { Err(Web5Error::CredentialError(err)) => { @@ -491,11 +503,12 @@ mod tests { }; } - #[test] - fn test_decode_missing_subject_claim() { + #[tokio::test] + async fn test_decode_missing_subject_claim() { let vc_jwt_with_missing_sub_claim = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSldiRFprTjFFMWRXOTNSMVk1TWxsRlVWSkxOMnROWkdRM1lYcFJiMGxsU0hac1FXaFNSMVJmTlRJMEluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjBmYTE0MTgxLTllMWYtNDk0ZC05ZmVmLWMwYjgxZDE1ZGJiYiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKV2JEWmtOMUUxZFc5M1IxWTVNbGxGVVZKTE4ydE5aR1EzWVhwUmIwbGxTSFpzUVdoU1IxUmZOVEkwSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzoxMjo0NS40NTg4MjYrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSldiRFprTjFFMWRXOTNSMVk1TWxsRlVWSkxOMnROWkdRM1lYcFJiMGxsU0hac1FXaFNSMVJmTlRJMEluMCIsImp0aSI6InVybjp1dWlkOjBmYTE0MTgxLTllMWYtNDk0ZC05ZmVmLWMwYjgxZDE1ZGJiYiIsIm5iZiI6MTcyNDg1MDc2NSwiaWF0IjoxNzI0ODUwNzY1fQ.61IFQhdASbbcYKUzMfhO7WPmikBd8AoE468FTlqRysxXck7kNa3bAAow3jK2uhYrIWLyRu3kuBp7JyYhLavjBw"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_sub_claim, true); + let result = + VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_sub_claim, true).await; match result { Err(Web5Error::CredentialError(err)) => { @@ -505,11 +518,12 @@ mod tests { }; } - #[test] - fn test_decode_missing_nbf_claim() { + #[tokio::test] + async fn test_decode_missing_nbf_claim() { let vc_jwt_with_missing_nbf_claim = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSXdOR1ZzZGxGdlJWbDBZbEJIT0RsWlVtaGpTR2RJT1cwMlMzSjZiRVkyUWpGUldrZGxOR2RGUjJKakluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjk3OGZhZTIxLTVmMDYtNDBmNy1iZTJmLTM4MzRmZGMwZDY0NSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJd05HVnNkbEZ2UlZsMFlsQkhPRGxaVW1oalNHZElPVzAyUzNKNmJFWTJRakZSV2tkbE5HZEZSMkpqSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzoxMzoyNi4zMzQzNjYrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSXdOR1ZzZGxGdlJWbDBZbEJIT0RsWlVtaGpTR2RJT1cwMlMzSjZiRVkyUWpGUldrZGxOR2RGUjJKakluMCIsImp0aSI6InVybjp1dWlkOjk3OGZhZTIxLTVmMDYtNDBmNy1iZTJmLTM4MzRmZGMwZDY0NSIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsImlhdCI6MTcyNDg1MDgwNn0.ZXfuZmvddH1nvmub8WDpQ2UEOhuiLaN6WL2q3XDhn0eouM_bNVa7vmCUCUZc3sfJ1YCtnAGCJOlJxSGnD3tOCw"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_nbf_claim, true); + let result = + VerifiableCredential::from_vc_jwt(vc_jwt_with_missing_nbf_claim, true).await; match result { Err(Web5Error::CredentialError(err)) => { @@ -522,11 +536,11 @@ mod tests { }; } - #[test] - fn test_decode_claim_mismatch_id() { + #[tokio::test] + async fn test_decode_claim_mismatch_id() { let vc_jwt_with_mismatch_id = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnZTWHBSUjJkTmNGTlNPSEpRWTNkd1IxZEJTRnBaV0hwUFdYRlRiMFkyTWtoM09HTlJRamRJUzIxM0luMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InNvbWV0aGluZyBpbnZhbGlkIiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUp2U1hwUlIyZE5jRk5TT0hKUVkzZHdSMWRCU0ZwWldIcFBXWEZUYjBZMk1raDNPR05SUWpkSVMyMTNJbjAiLCJpc3N1YW5jZURhdGUiOiIyMDI0LTA4LTI4VDEzOjE2OjAwLjcyMjgxOSswMDowMCIsImV4cGlyYXRpb25EYXRlIjpudWxsLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSJ9fSwiaXNzIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKdlNYcFJSMmROY0ZOU09ISlFZM2R3UjFkQlNGcFpXSHBQV1hGVGIwWTJNa2gzT0dOUlFqZElTMjEzSW4wIiwianRpIjoidXJuOnV1aWQ6ZGFkM2Y2MjktMzFiMS00NDcxLWFhYTMtMWE4MGZjN2I1YmU2Iiwic3ViIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5IiwibmJmIjoxNzI0ODUwOTYwLCJpYXQiOjE3MjQ4NTA5NjB9.P8-Z3KsMxIk7-Dz9a5odVhbGJZtWsWp4mDVYLlVxuZTNJl-Km-j2S1KusTjRTDkg1DqQoiVvp2Is0kr5WoAFBA"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_mismatch_id, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_mismatch_id, true).await; match result { Err(Web5Error::CredentialError(err)) => { @@ -536,11 +550,11 @@ mod tests { }; } - #[test] - fn test_decode_claim_mismatch_issuer() { + #[tokio::test] + async fn test_decode_claim_mismatch_issuer() { let vc_jwt_with_mismatch_issuer = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSXpWRVZsYWs0emIzSXpUbXR4WkZWVllYQjZaMVZ5TFcxblZFTkNkWEZRWVZkT1JWcE9lRXcwWkhRd0luMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjJiNzQzNWY0LWU0YjctNGQyZC1iN2M2LTVkOTE5ODRlNDlhOCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoic29tZXRoaW5nIGludmFsaWQiLCJpc3N1YW5jZURhdGUiOiIyMDI0LTA4LTI4VDEzOjE3OjQ1LjI4ODk2NiswMDowMCIsImV4cGlyYXRpb25EYXRlIjpudWxsLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSJ9fSwiaXNzIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJelZFVmxhazR6YjNJelRtdHhaRlZWWVhCNloxVnlMVzFuVkVOQ2RYRlFZVmRPUlZwT2VFdzBaSFF3SW4wIiwianRpIjoidXJuOnV1aWQ6MmI3NDM1ZjQtZTRiNy00ZDJkLWI3YzYtNWQ5MTk4NGU0OWE4Iiwic3ViIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5IiwibmJmIjoxNzI0ODUxMDY1LCJpYXQiOjE3MjQ4NTEwNjV9.x0UY38J4lEwmrXR4qrzhnk58btjZfMf8DVhdgBoj9M0JOgJqCDFCzwcS5weVCpNAv3gN72Qo32RH9Tx0eYyoDA"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_mismatch_issuer, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_mismatch_issuer, true).await; match result { Err(Web5Error::CredentialError(err)) => { @@ -550,11 +564,12 @@ mod tests { }; } - #[test] - fn test_decode_claim_mismatch_subject() { + #[tokio::test] + async fn test_decode_claim_mismatch_subject() { let vc_jwt_with_mismatch_subject = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSXdVRmh0UkVNMlNIWnVia1E0Vmw5QkxWbDVSelZ1TWtSa2IxQkdTVFkxY2tkb2MwVTVZWFZsWW5CckluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjAwNDJiYTQ4LWU0ZGYtNGVhMS04ZmJjLWJjYmI4ODY3ZjFhMCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJd1VGaHRSRU0yU0hadWJrUTRWbDlCTFZsNVJ6VnVNa1JrYjFCR1NUWTFja2RvYzBVNVlYVmxZbkJySW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzoxOToxMC4xNjM0ODkrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJzb21ldGhpbmcgaW52YWxpZCJ9fSwiaXNzIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJd1VGaHRSRU0yU0hadWJrUTRWbDlCTFZsNVJ6VnVNa1JrYjFCR1NUWTFja2RvYzBVNVlYVmxZbkJySW4wIiwianRpIjoidXJuOnV1aWQ6MDA0MmJhNDgtZTRkZi00ZWExLThmYmMtYmNiYjg4NjdmMWEwIiwic3ViIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5IiwibmJmIjoxNzI0ODUxMTUwLCJpYXQiOjE3MjQ4NTExNTB9.bAm9kKJX2-Rcw679VS7cUPbqg9awuq5Lwu9wiZoGcE0TCSc59rQTIP4nvxlP22o3V-VVs_DbfpJU-qB4duDSCA"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_mismatch_subject, true); + let result = + VerifiableCredential::from_vc_jwt(vc_jwt_with_mismatch_subject, true).await; match result { Err(Web5Error::CredentialError(err)) => { @@ -564,11 +579,12 @@ mod tests { }; } - #[test] - fn test_decode_claim_misconfigured_exp() { + #[tokio::test] + async fn test_decode_claim_misconfigured_exp() { let vc_jwt_with_misconfigured_exp = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnJkWFI2V21WM01EVTBMVlUwUVRBM2FsYzJZbkkxUlV4NU1UQlpOSGxPVTFCaVkyOTNXakJ3TjJWakluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjYxZjgwM2I4LWUxMDQtNDdhOC04YWE1LTk4YzQ1ZTFiOGUzMSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKcmRYUjZXbVYzTURVMExWVTBRVEEzYWxjMlluSTFSVXg1TVRCWk5IbE9VMUJpWTI5M1dqQndOMlZqSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzoyMzo0My45NDg4MzQrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjktMDgtMjJUMTM6MjM6NDMuOTQ4NzYwKzAwOjAwIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnJkWFI2V21WM01EVTBMVlUwUVRBM2FsYzJZbkkxUlV4NU1UQlpOSGxPVTFCaVkyOTNXakJ3TjJWakluMCIsImp0aSI6InVybjp1dWlkOjYxZjgwM2I4LWUxMDQtNDdhOC04YWE1LTk4YzQ1ZTFiOGUzMSIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg1MTQyMywiaWF0IjoxNzI0ODUxNDIzfQ.AWYyvLRISXwLH5gAXb5CcwBXNwaRKwacGqstXjnk-xIHx9gmm5xj8zGONvcKE2Xx0t9j3pNHicrhkp5wcOkABQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_misconfigured_exp, true); + let result = + VerifiableCredential::from_vc_jwt(vc_jwt_with_misconfigured_exp, true).await; match result { Err(Web5Error::CredentialError(err)) => { @@ -583,11 +599,11 @@ mod tests { }; } - #[test] - fn test_decode_claim_mismatch_exp() { + #[tokio::test] + async fn test_decode_claim_mismatch_exp() { let vc_jwt_with_mismatch_exp = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSk1lWEJmUjJVelVEZGtjbVZhYTJSV1VsTnJZbmROVldkcVkxUTRhMHd6VUVVMk1Hc3pZMGgzVTJ0ckluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjRhMjA2YmMzLWZmOTYtNDMwNS1iMzM4LTJiZGQ1ODRiYzkyOSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKTWVYQmZSMlV6VURka2NtVmFhMlJXVWxOclluZE5WV2RxWTFRNGEwd3pVRVUyTUdzelkwaDNVMnRySW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzoyNzozMy40Mjg1NjMrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjktMDgtMjJUMTM6Mjc6MzMuNDI4NDgyKzAwOjAwIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSk1lWEJmUjJVelVEZGtjbVZhYTJSV1VsTnJZbmROVldkcVkxUTRhMHd6VUVVMk1Hc3pZMGgzVTJ0ckluMCIsImp0aSI6InVybjp1dWlkOjRhMjA2YmMzLWZmOTYtNDMwNS1iMzM4LTJiZGQ1ODRiYzkyOSIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg1MTY1MywiaWF0IjoxNzI0ODUxNjUzLCJleHAiOjE4ODUxMjM2NTN9.lAaTG8RhL2D92iNI6psZrv1uhtHYAO0m0AacGIQrW0XIThg-Livef36_CN9t4Lz2Ta5US2Be2VP6D3lCA-z1DQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_mismatch_exp, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_mismatch_exp, true).await; match result { Err(Web5Error::CredentialError(err)) => { @@ -602,11 +618,11 @@ mod tests { // --- Data Model Validation Tests --- - #[test] - fn test_validate_dm_empty_id() { + #[tokio::test] + async fn test_validate_dm_empty_id() { let vc_jwt_with_empty_id = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSmxja0pYTmpoTVpXWlVZbGhEU0Zwck5VeG5OVVl5U3pSalJrVmlNVmhNYlVWa1VVNWxTbVJKV2pkTkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6IiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKbGNrSlhOamhNWldaVVlsaERTRnByTlV4bk5VWXlTelJqUmtWaU1WaE1iVVZrVVU1bFNtUkpXamROSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzozMDo1My44NDQ2ODMrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjktMDgtMjJUMTM6MzA6NTMuODQ0NjMwKzAwOjAwIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSmxja0pYTmpoTVpXWlVZbGhEU0Zwck5VeG5OVVl5U3pSalJrVmlNVmhNYlVWa1VVNWxTbVJKV2pkTkluMCIsImp0aSI6IiIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg1MTg1MywiaWF0IjoxNzI0ODUxODUzLCJleHAiOjE4ODIwOTk4NTN9.X_jkleLbhdAo0vm7KtN0qr6nR6hvWrXxk08UslfZAhZCkDN2kqLvWhoHps3GNznmGAuhJxwhZ0SN60OV7pp1DQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_id, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_id, true).await; match result { Err(Web5Error::CredentialError(VerificationError::DataModelValidationError( @@ -621,11 +637,11 @@ mod tests { }; } - #[test] - fn test_validate_dm_empty_context() { + #[tokio::test] + async fn test_validate_dm_empty_context() { let vc_jwt_with_empty_context = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSjFSbXRGTVdkblNGcENaME4yY1doa1VqRkJZelZqUkd0Q2IybDFRMnhOYm5CTVVFNDRYM1ZOVjBRd0luMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6W10sImlkIjoidXJuOnV1aWQ6ODVmM2MzNWUtYTI5Yi00YmQ2LTk1MmMtNzhlYWJiOTIzNzI4IiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUoxUm10Rk1XZG5TRnBDWjBOMmNXaGtVakZCWXpWalJHdENiMmwxUTJ4TmJuQk1VRTQ0WDNWTlYwUXdJbjAiLCJpc3N1YW5jZURhdGUiOiIyMDI0LTA4LTI4VDEzOjMyOjM1LjI2MzM1NiswMDowMCIsImV4cGlyYXRpb25EYXRlIjpudWxsLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSJ9fSwiaXNzIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKMVJtdEZNV2RuU0ZwQ1owTjJjV2hrVWpGQll6VmpSR3RDYjJsMVEyeE5ibkJNVUU0NFgzVk5WMFF3SW4wIiwianRpIjoidXJuOnV1aWQ6ODVmM2MzNWUtYTI5Yi00YmQ2LTk1MmMtNzhlYWJiOTIzNzI4Iiwic3ViIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5IiwibmJmIjoxNzI0ODUxOTU1LCJpYXQiOjE3MjQ4NTE5NTV9.2GaazffucPj-LfdnO9OtMwij0PQK9crDC7rMMcwV9nt50Q3ACc1UtYCruMWsfYMc_CKfl5g7m6-zwDW8SpDzAw"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_context, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_context, true).await; match result { Err(Web5Error::CredentialError(VerificationError::DataModelValidationError( @@ -640,10 +656,10 @@ mod tests { }; } - #[test] - fn test_validate_dm_context_base_mismatch() { + #[tokio::test] + async fn test_validate_dm_context_base_mismatch() { let vc_jwt_without_base_context = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnFSVWRmU1V4TlZDMVVUMGgyTjIxeFJ6UlJWVmRMTWs1dU9FcGlUVU5OWldKQ1pXVjRkVGxIYlhWWkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJhIGNvbnRleHQiXSwiaWQiOiJ1cm46dXVpZDo4N2VmMDI1MC0yYWE2LTQyNTctYjIxMi0xYzAyMWFhZDY2Y2YiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIl0sImlzc3VlciI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnFSVWRmU1V4TlZDMVVUMGgyTjIxeFJ6UlJWVmRMTWs1dU9FcGlUVU5OWldKQ1pXVjRkVGxIYlhWWkluMCIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDgtMjhUMTM6MzQ6MjcuODk4MDkwKzAwOjAwIiwiZXhwaXJhdGlvbkRhdGUiOm51bGwsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5In19LCJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUpxUlVkZlNVeE5WQzFVVDBoMk4yMXhSelJSVlZkTE1rNXVPRXBpVFVOTlpXSkNaV1Y0ZFRsSGJYVlpJbjAiLCJqdGkiOiJ1cm46dXVpZDo4N2VmMDI1MC0yYWE2LTQyNTctYjIxMi0xYzAyMWFhZDY2Y2YiLCJzdWIiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJuYmYiOjE3MjQ4NTIwNjcsImlhdCI6MTcyNDg1MjA2N30.cgkGQF5CXqHw_C1KNaKLFeIzPzmBuWRzRk-7KgvEYc1jJzwoXoOWB6cn-8I3MjWAgd_NeM1Yt656lJ60gy0RAQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_without_base_context, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_without_base_context, true).await; match result { Err(Web5Error::CredentialError(VerificationError::DataModelValidationError( @@ -658,11 +674,11 @@ mod tests { }; } - #[test] - fn test_validate_dm_empty_type() { + #[tokio::test] + async fn test_validate_dm_empty_type() { let vc_jwt_with_empty_type = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSTJSV2Q2T0RZeGExRjNVMTh3U25SWVVqQlJha3BtWldOemQyVkJiRWN3UzBadGMwZGxUa0ZoZVdwQkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmNmNjQ1MTNiLTIwODQtNDliNC1iNWMzLTgxZTk1ODNjOTcyOCIsInR5cGUiOltdLCJpc3N1ZXIiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUkyUldkNk9EWXhhMUYzVTE4d1NuUllVakJSYWtwbVpXTnpkMlZCYkVjd1MwWnRjMGRsVGtGaGVXcEJJbjAiLCJpc3N1YW5jZURhdGUiOiIyMDI0LTA4LTI4VDEzOjM1OjM2LjkxMzQyNyswMDowMCIsImV4cGlyYXRpb25EYXRlIjpudWxsLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSJ9fSwiaXNzIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJMlJXZDZPRFl4YTFGM1UxOHdTblJZVWpCUmFrcG1aV056ZDJWQmJFY3dTMFp0YzBkbFRrRmhlV3BCSW4wIiwianRpIjoidXJuOnV1aWQ6Y2Y2NDUxM2ItMjA4NC00OWI0LWI1YzMtODFlOTU4M2M5NzI4Iiwic3ViIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5IiwibmJmIjoxNzI0ODUyMTM2LCJpYXQiOjE3MjQ4NTIxMzZ9.EY1q2nZHnPk-hnzdScvf6QYA0ko_sshHWOnPxU9tkU-RhxdklRoO9JQgmoHZC1FdDgEfgs4nDFNUKyX-FlJPBw"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_type, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_type, true).await; match result { Err(Web5Error::CredentialError(VerificationError::DataModelValidationError( @@ -677,11 +693,11 @@ mod tests { }; } - #[test] - fn test_validate_dm_type_base_mismatch() { + #[tokio::test] + async fn test_validate_dm_type_base_mismatch() { let vc_jwt_without_base_type = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSlJTMjVyVDNvd2RETkpRWGRqVWtGamQyTjFkVWxKUkZsT2NHWlhkWFJvY21SVE5EVktiemRFU1dsckluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmQ1NTdkODY3LWRlNTgtNDE3Ny1iZjE4LTM1ZjQ3NDA5NDlmMSIsInR5cGUiOlsiYSB0eXBlIl0sImlzc3VlciI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSlJTMjVyVDNvd2RETkpRWGRqVWtGamQyTjFkVWxKUkZsT2NHWlhkWFJvY21SVE5EVktiemRFU1dsckluMCIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDgtMjhUMTM6MzY6MzUuNDgwMTkwKzAwOjAwIiwiZXhwaXJhdGlvbkRhdGUiOm51bGwsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmRodDpxZ21tcHlqdzVod25xZmd6bjd3bXJtMzNhZHk4Z2I4ejlpZGVpYjZtOWdqNHlzNndueTh5In19LCJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUpSUzI1clQzb3dkRE5KUVhkalVrRmpkMk4xZFVsSlJGbE9jR1pYZFhSb2NtUlRORFZLYnpkRVNXbHJJbjAiLCJqdGkiOiJ1cm46dXVpZDpkNTU3ZDg2Ny1kZTU4LTQxNzctYmYxOC0zNWY0NzQwOTQ5ZjEiLCJzdWIiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJuYmYiOjE3MjQ4NTIxOTUsImlhdCI6MTcyNDg1MjE5NX0.S3vchUrNfdgXTQFeu7HcI5F0ZdkQdYkd4IqAXF8_uhcOe_sX9joDWspBSxwP3BY6ESCPIpJoms_dPIp01RWABA"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_without_base_type, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_without_base_type, true).await; match result { Err(Web5Error::CredentialError(VerificationError::DataModelValidationError( @@ -696,11 +712,11 @@ mod tests { }; } - #[test] - fn test_validate_dm_empty_issuer() { + #[tokio::test] + async fn test_validate_dm_empty_issuer() { let vc_jwt_with_empty_issuer = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnRPSEZRTVhoR1p6RndZMlpqZUY5UWVrUnJOMjFPYVhoak9YQTFWamN4WlVZelYwRTViSGwzTWpsckluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmFhMmNjNWNkLTg4N2QtNDFkMi1iZTM3LTIzMjMxMGVkODdjMiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzozOToxNS42MjMzOTMrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6IiIsImp0aSI6InVybjp1dWlkOmFhMmNjNWNkLTg4N2QtNDFkMi1iZTM3LTIzMjMxMGVkODdjMiIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg1MjM1NSwiaWF0IjoxNzI0ODUyMzU1fQ.mRYZKF3qNz_Vyg8xpemuBOipGLOliYy9xJ6b9ZqcMNjZbb8GtEyiaBv8rgF2jqmHreRT71wHaT3P6mV9GsQOCA"#; - let vc = decode(vc_jwt_with_empty_issuer, true).unwrap(); + let vc = decode(vc_jwt_with_empty_issuer, true).await.unwrap(); let result = validate_vc_data_model(&vc); match result { @@ -714,11 +730,11 @@ mod tests { }; } - #[test] - fn test_validate_dm_empty_subject() { + #[tokio::test] + async fn test_validate_dm_empty_subject() { let vc_jwt_with_empty_subject = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnpOakV6U1hobGFWWk9WMW81YzBaM1NrdE1OSEI2WkdaRlRsWXRWVEZxYkMweVNIcFpXV2hCUWxWM0luMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjNkNGMzMjQxLWU0NDUtNGE2Ny1hYmE0LTIxYjBmM2NkMmMxYyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKek5qRXpTWGhsYVZaT1YxbzVjMFozU2t0TU5IQjZaR1pGVGxZdFZURnFiQzB5U0hwWldXaEJRbFYzSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzo0MToxMC4xNzM2NzIrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiIifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnpOakV6U1hobGFWWk9WMW81YzBaM1NrdE1OSEI2WkdaRlRsWXRWVEZxYkMweVNIcFpXV2hCUWxWM0luMCIsImp0aSI6InVybjp1dWlkOjNkNGMzMjQxLWU0NDUtNGE2Ny1hYmE0LTIxYjBmM2NkMmMxYyIsInN1YiI6IiIsIm5iZiI6MTcyNDg1MjQ3MCwiaWF0IjoxNzI0ODUyNDcwfQ.Ek9NMfHyb8BzJ7GnV0JRQPVl-UQyMOCMZ2_ABMx9Cvh8d8T81wMjrYUPp6v57-veqKntYFO_WZciL2FC_VZWAw"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_subject, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_empty_subject, true).await; match result { Err(Web5Error::CredentialError(VerificationError::DataModelValidationError( @@ -733,12 +749,12 @@ mod tests { }; } - #[test] - fn test_validate_dm_issuance_in_future() { + #[tokio::test] + async fn test_validate_dm_issuance_in_future() { let vc_jwt_with_issuance_date_in_future = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSmhhazFPTms1Zk1rOVRWbVl5TFdGd1VsOW1VbWRwVG1OMVNVMXphVWMzTVhaM2FYVnBVSGd4YTFOTkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjJiODhmMDhmLTVkOGItNDJiYS1iYmY0LTg4MjU1MjlmOGE2NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKaGFrMU9OazVmTWs5VFZtWXlMV0Z3VWw5bVVtZHBUbU4xU1UxemFVYzNNWFozYVhWcFVIZ3hhMU5OSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyOS0wOC0yMlQxMzo0Mjo1Ni43OTA2OTcrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSmhhazFPTms1Zk1rOVRWbVl5TFdGd1VsOW1VbWRwVG1OMVNVMXphVWMzTVhaM2FYVnBVSGd4YTFOTkluMCIsImp0aSI6InVybjp1dWlkOjJiODhmMDhmLTVkOGItNDJiYS1iYmY0LTg4MjU1MjlmOGE2NyIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTg4MjEwMDU3NiwiaWF0IjoxNzI0ODUyNTc2fQ.QM4LHyJ8wW1_A0PcuhpsorI3FOA9NLX9-u7a6MkAMXrQoxwNFIfHZeHuwLGVBshmco2emUievVAfKWUQFpOvBQ"#; let result = - VerifiableCredential::from_vc_jwt(vc_jwt_with_issuance_date_in_future, true); + VerifiableCredential::from_vc_jwt(vc_jwt_with_issuance_date_in_future, true).await; match result { Err(Web5Error::CredentialError(VerificationError::DataModelValidationError( @@ -753,11 +769,11 @@ mod tests { }; } - #[test] - fn test_validate_dm_credential_expired() { + #[tokio::test] + async fn test_validate_dm_credential_expired() { let vc_jwt_with_expired = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnpjV3hxVTJaZlgzbE9TVVpKTVVwaWNYQkVSVEJuVUZGT2FVazBiVkZqV2pONmRtZFVVbmg2WTAxbkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmFkNzBmN2Y2LWExNTctNGYxZi1hZjI5LTdjYmJkNDRmODlmMCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKemNXeHFVMlpmWDNsT1NVWkpNVXBpY1hCRVJUQm5VRkZPYVVrMGJWRmpXak42ZG1kVVVuaDZZMDFuSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0yOFQxMzo0NDoyNy45MTUwMjUrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMTktMDktMDRUMTM6NDQ6MjcuOTE0ODY0KzAwOjAwIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnpjV3hxVTJaZlgzbE9TVVpKTVVwaWNYQkVSVEJuVUZGT2FVazBiVkZqV2pONmRtZFVVbmg2WTAxbkluMCIsImp0aSI6InVybjp1dWlkOmFkNzBmN2Y2LWExNTctNGYxZi1hZjI5LTdjYmJkNDRmODlmMCIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNDg1MjY2NywiaWF0IjoxNzI0ODUyNjY3LCJleHAiOjE1Njc2MDQ2Njd9.pP_8QVzTqxuhUlIWpXDWQ3Py_VlDA4uX82xdD9GOdmRT2UK-K5Gn7A5qdUxBPhXifiRVnH_Q8NbWZCUQ8jZUBg"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_expired, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_expired, true).await; match result { Err(Web5Error::CredentialError(VerificationError::DataModelValidationError( @@ -772,11 +788,12 @@ mod tests { }; } - #[test] - fn test_schema_type_must_be_jsonschema() { + #[tokio::test] + async fn test_schema_type_must_be_jsonschema() { let vc_jwt_with_wrong_schema_type = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSXhlbTlYY0VWTWN6TnhiV0p5VW5GblRFbzBjbDlCZUhCYVNFSmpjMUZJVGtSaVRGYzBOM1JmVGpkSkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjQ1NGY1NWJmLWYzMjAtNDQyOS1iNmViLTRkMzdlNTMzNDkwYyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJeGVtOVhjRVZNY3pOeGJXSnlVbkZuVEVvMGNsOUJlSEJhU0VKamMxRklUa1JpVEZjME4zUmZUamRKSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOC0zMFQxNTowMjo1NC4zNjg1NjMrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHBzOi8vZXhhbXBsZS5jb20iLCJ0eXBlIjoic29tZXRoaW5nIGludmFsaWFkIn19LCJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUl4ZW05WGNFVk1jek54YldKeVVuRm5URW8wY2w5QmVIQmFTRUpqYzFGSVRrUmlURmMwTjNSZlRqZEpJbjAiLCJqdGkiOiJ1cm46dXVpZDo0NTRmNTViZi1mMzIwLTQ0MjktYjZlYi00ZDM3ZTUzMzQ5MGMiLCJzdWIiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJuYmYiOjE3MjUwMzAxNzQsImlhdCI6MTcyNTAzMDE3NH0.8gxVx3_Qd1Lvao-y5PZ56XS3lMQvrFtBVMgfNDIdW9eoQkBQMNv79YKIxFCig0LHanzg_vyzX7tBviW6xJUuDw"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_wrong_schema_type, true); + let result = + VerifiableCredential::from_vc_jwt(vc_jwt_with_wrong_schema_type, true).await; match result { Err(Web5Error::Parameter(err_msg)) => { @@ -789,11 +806,11 @@ mod tests { }; } - #[test] - fn test_schema_resolve_network_issue() { + #[tokio::test] + async fn test_schema_resolve_network_issue() { let vc_jwt_with_invalid_url = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZDI1NTE5Iiwia2lkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKTmEycDVaRlo1ZFhaU1psaExRMDVWYm0wNVVWRnJVbkUwY0doWVdYRTBObUpFVjJGemFHOW5kbXhWSW4wIzAifQ.eyJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUpOYTJwNVpGWjVkWFpTWmxoTFEwNVZibTA1VVZGclVuRTBjR2hZV1hFME5tSkVWMkZ6YUc5bmRteFZJbjAiLCJqdGkiOiJ1cm46dXVpZDo2YzM2YzU0Zi02M2VhLTRiY2MtOTgxOS0zYmNmMGIyYmUxMDgiLCJzdWIiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJuYmYiOjE3MjYwODk0NDIsImlhdCI6MTcyNjA4OTQ0MiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiXSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHA6Ly9sb2NhbC9zY2hlbWFzL2VtYWlsLmpzb24iLCJ0eXBlIjoiSnNvblNjaGVtYSJ9LCJpZCI6InVybjp1dWlkOjZjMzZjNTRmLTYzZWEtNGJjYy05ODE5LTNiY2YwYjJiZTEwOCIsImlzc3VlciI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSk5hMnA1WkZaNWRYWlNabGhMUTA1VmJtMDVVVkZyVW5FMGNHaFlXWEUwTm1KRVYyRnphRzluZG14VkluMCIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDktMTFUMjE6MTc6MjJaIiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSJ9fX0.eZfQZdkDB2D2QMs6BPaxjU-FCJLIGMlCz0sF5FjhHkaizItfv3zGXqWVEjc8f-SRiLSmujlEKgwfw22cCvnDAQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_url, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_with_invalid_url, true).await; match result { Err(Web5Error::Http(err)) => { @@ -806,8 +823,8 @@ mod tests { }; } - #[test] - fn test_schema_resolve_non_success() { + #[tokio::test] + async fn test_schema_resolve_non_success() { let mut mock_server = Server::new_with_opts(ServerOpts { port: 40001, ..Default::default() @@ -820,7 +837,7 @@ mod tests { let vc_jwt_at_port = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSm9jMmhVZEU4M2F5MVNjVE5oVWtWR1lUVTRhUzFoWlZVdGRWaHNUVXB4UkdkallteEhhMTlpTW5OM0luMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmE5Nzk1YTdmLTRmNzktNDU3OC1hYTkxLTcwYmYxM2YxZWVkNiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKb2MyaFVkRTgzYXkxU2NUTmhVa1ZHWVRVNGFTMWhaVlV0ZFZoc1RVcHhSR2RqWW14SGExOWlNbk4zSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOS0wM1QxNTo0MDowMS4wNDg1MzIrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMDEvc2NoZW1hcy9lbWFpbC5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSm9jMmhVZEU4M2F5MVNjVE5oVWtWR1lUVTRhUzFoWlZVdGRWaHNUVXB4UkdkallteEhhMTlpTW5OM0luMCIsImp0aSI6InVybjp1dWlkOmE5Nzk1YTdmLTRmNzktNDU3OC1hYTkxLTcwYmYxM2YxZWVkNiIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNTM3ODAwMSwiaWF0IjoxNzI1Mzc4MDAxfQ.9739UnhTfGXr2tsbsjun7FQfFuXNtqmzfxhP_okbywVDoh6nsBGk8smLUU_D0VYwtiMBTo1ujDs1QtKPbCZDDA"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true).await; match result { Err(Web5Error::JsonSchema(err_msg)) => { assert_eq!("failed to resolve status code 500", err_msg) @@ -832,8 +849,8 @@ mod tests { } } - #[test] - fn test_schema_resolve_invalid_response_body() { + #[tokio::test] + async fn test_schema_resolve_invalid_response_body() { let mut mock_server = Server::new_with_opts(ServerOpts { port: 40002, ..Default::default() @@ -848,7 +865,7 @@ mod tests { let vc_jwt_at_port = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSXhkek4zU25CUlZIVkNhRUZuV2tSd2JtbHZWME51ZW5kalp6bDBkMFZ4WVZGWldFUTVOblJXUTA1QkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmQ1NmYxMzRjLThjN2QtNDkyOC04OWYwLWQ5NWEzYjllZmU3YiIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lJeGR6TjNTbkJSVkhWQ2FFRm5Xa1J3Ym1sdlYwTnVlbmRqWnpsMGQwVnhZVkZaV0VRNU5uUldRMDVCSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOS0wM1QxNTo0Mzo1OC40MTE0NTcrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMDIvc2NoZW1hcy9lbWFpbC5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSXhkek4zU25CUlZIVkNhRUZuV2tSd2JtbHZWME51ZW5kalp6bDBkMFZ4WVZGWldFUTVOblJXUTA1QkluMCIsImp0aSI6InVybjp1dWlkOmQ1NmYxMzRjLThjN2QtNDkyOC04OWYwLWQ5NWEzYjllZmU3YiIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNTM3ODIzOCwiaWF0IjoxNzI1Mzc4MjM4fQ.vYZ5YeXa4ZXaomhVp2obgJwlgjwScFctNAJBqTf2hJOUr1v-jN1C5huK4JL_e16_dRCJd_ysmiOpgFOJD2MOCQ"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true).await; match result { Err(Web5Error::Json(err_msg)) => { assert!(err_msg.contains("expected value at line")) @@ -860,8 +877,8 @@ mod tests { } } - #[test] - fn test_schema_invalid_json_schema() { + #[tokio::test] + async fn test_schema_invalid_json_schema() { let mut mock_server = Server::new_with_opts(ServerOpts { port: 40003, ..Default::default() @@ -879,7 +896,7 @@ mod tests { let vc_jwt_at_port = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSlRNemRDWVdaR01FTnRla2xmVTJ4WlEyTXlNSHBKZGt4eVprTnFjM1ptTUVWUWFtbDVkV2N5Wmt0WkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjJjZWFmODUxLTBiYzktNDFkYy04NzNmLThhMGMyN2Y0ZDZkOCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKVE16ZENZV1pHTUVOdGVrbGZVMnhaUTJNeU1IcEpka3h5WmtOcWMzWm1NRVZRYW1sNWRXY3laa3RaSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOS0wM1QxNTo0NTozMC4zMDY4MDYrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMDMvc2NoZW1hcy9lbWFpbC5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSlRNemRDWVdaR01FTnRla2xmVTJ4WlEyTXlNSHBKZGt4eVprTnFjM1ptTUVWUWFtbDVkV2N5Wmt0WkluMCIsImp0aSI6InVybjp1dWlkOjJjZWFmODUxLTBiYzktNDFkYy04NzNmLThhMGMyN2Y0ZDZkOCIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNTM3ODMzMCwiaWF0IjoxNzI1Mzc4MzMwfQ.Drh8iEOdWWeL6l9KdmKMv9qfbBxWln-TW0KNwOJN3lZatyaSkwlBO_1o2FIWj0WIDiD_TP2EestMFazf4XFQDA"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true).await; match result { Err(Web5Error::JsonSchema(err_msg)) => { assert!(err_msg.contains("unable to compile json schema")) @@ -891,8 +908,8 @@ mod tests { } } - #[test] - fn test_schema_do_not_support_draft04() { + #[tokio::test] + async fn test_schema_do_not_support_draft04() { let mut mock_server = Server::new_with_opts(ServerOpts { port: 40004, ..Default::default() @@ -910,7 +927,7 @@ mod tests { let vc_jwt_at_port = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnBNemMwTFVkc1lVSmZiMmxQZG1aR1ZteGtiVWhhVXpNNVpEZEtlalUxUm0xU2R6WkVjbmswVkRjd0luMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmYzNDc3ZDdkLWJiOWUtNGI5Ny1iYjhkLTk4NDMwNjgzN2RmMyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKcE16YzBMVWRzWVVKZmIybFBkbVpHVm14a2JVaGFVek01WkRkS2VqVTFSbTFTZHpaRWNuazBWRGN3SW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOS0wM1QxNTo0Nzo0MS4wNjgxNjIrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMDQvc2NoZW1hcy9lbWFpbC5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnBNemMwTFVkc1lVSmZiMmxQZG1aR1ZteGtiVWhhVXpNNVpEZEtlalUxUm0xU2R6WkVjbmswVkRjd0luMCIsImp0aSI6InVybjp1dWlkOmYzNDc3ZDdkLWJiOWUtNGI5Ny1iYjhkLTk4NDMwNjgzN2RmMyIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNTM3ODQ2MSwiaWF0IjoxNzI1Mzc4NDYxfQ.X7pZBMqPeBO0oTq1QNtMcSrYcIpDxCavPEoPDiB1A9GOqCohx7KCgOerXaJGSyklAkmNJod7ssmL4DMM-l3uDA"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true).await; match result { Err(Web5Error::JsonSchema(err_msg)) => { assert_eq!("draft unsupported Draft4", err_msg) @@ -922,8 +939,8 @@ mod tests { } } - #[test] - fn test_schema_do_not_support_draft06() { + #[tokio::test] + async fn test_schema_do_not_support_draft06() { let mut mock_server = Server::new_with_opts(ServerOpts { port: 40005, ..Default::default() @@ -941,7 +958,7 @@ mod tests { let vc_jwt_at_port = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSkhSemxDUVU1QlpXUkplR2RpYzJkVlprOWZRWFpPWVZsWmFHMWxZbmhXYWpOZlVuQnBWREp4ZG5WVkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjQ4MGM0ZjQ5LTAyMmEtNDIwMi1hYjFiLTc1ZThjZjQ1NDEyMyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKSFJ6bENRVTVCWldSSmVHZGljMmRWWms5ZlFYWk9ZVmxaYUcxbFluaFdhak5mVW5CcFZESnhkblZWSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOS0wM1QxNTo0ODo1MC4wNjM4NjIrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMDUvc2NoZW1hcy9lbWFpbC5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSkhSemxDUVU1QlpXUkplR2RpYzJkVlprOWZRWFpPWVZsWmFHMWxZbmhXYWpOZlVuQnBWREp4ZG5WVkluMCIsImp0aSI6InVybjp1dWlkOjQ4MGM0ZjQ5LTAyMmEtNDIwMi1hYjFiLTc1ZThjZjQ1NDEyMyIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNTM3ODUzMCwiaWF0IjoxNzI1Mzc4NTMwfQ.Id6rsvMkqjocv6x5g_s8fnfR74HdXIpIdL3bMR33f1FYPFQ9CZRArMc1ZTh3xL3QfUggY8AUkRraQSAJh_onBA"#; - let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true); + let result = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true).await; match result { Err(Web5Error::JsonSchema(err_msg)) => { assert_eq!("draft unsupported Draft6", err_msg) @@ -953,8 +970,8 @@ mod tests { } } - #[test] - fn test_schema_fails_validation() { + #[tokio::test] + async fn test_schema_fails_validation() { let mut mock_server = Server::new_with_opts(ServerOpts { port: 40006, ..Default::default() @@ -973,7 +990,7 @@ mod tests { let vc_jwt_at_port_with_invalid_schema = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnBlRkpyUVhodk5GTmtVMXAwTW1VMGFWQm5WRTV0T1dnelFYWnJYMU42Wm1WUlNVeFNkbFJHU0RSSkluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOmY4NThhZGM2LTZhMDQtNDY5ZC04MGJiLWM2MmI1N2MyNWI5NSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKcGVGSnJRWGh2TkZOa1UxcDBNbVUwYVZCblZFNXRPV2d6UVhaclgxTjZabVZSU1V4U2RsUkdTRFJKSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOS0wM1QxNTo1MDozOS4yMTM3NzIrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMDYvc2NoZW1hcy9lbWFpbC5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSnBlRkpyUVhodk5GTmtVMXAwTW1VMGFWQm5WRTV0T1dnelFYWnJYMU42Wm1WUlNVeFNkbFJHU0RSSkluMCIsImp0aSI6InVybjp1dWlkOmY4NThhZGM2LTZhMDQtNDY5ZC04MGJiLWM2MmI1N2MyNWI5NSIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNTM3ODYzOSwiaWF0IjoxNzI1Mzc4NjM5fQ.zxz0OZO1umdlxgRyrwyMJis4t4esE_7Zo6nma4Q8T4josAkw6vnQJFI_cPoZV4usQ1vve5bB5OOiMcf_tca6Cw"#; let result = - VerifiableCredential::from_vc_jwt(vc_jwt_at_port_with_invalid_schema, true); + VerifiableCredential::from_vc_jwt(vc_jwt_at_port_with_invalid_schema, true).await; match result { Err(Web5Error::JsonSchema(err_msg)) => { assert!(err_msg.contains("validation errors")) @@ -985,8 +1002,8 @@ mod tests { } } - #[test] - fn test_schema_example_from_spec() { + #[tokio::test] + async fn test_schema_example_from_spec() { let mut mock_server = Server::new_with_opts(ServerOpts { port: 40007, ..Default::default() @@ -1004,7 +1021,9 @@ mod tests { let vc_jwt_at_port = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSkZjVm96YVdGVldqWnpUMlZ5VEVGMWEzcEpRbkV6Ym1sNVEzZHVVWEF0WWtkNk1EQlZMVk15YURGakluMCMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJpZCI6InVybjp1dWlkOjM4OWE2OWYyLWEwOTYtNDc0Ni1hNzU0LTRlNmE0ZThiZDEzYyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKRmNWb3phV0ZWV2paelQyVnlURUYxYTNwSlFuRXpibWw1UTNkdVVYQXRZa2Q2TURCVkxWTXlhREZqSW4wIiwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOS0wM1QxNTo1MzoxNy43NjgzNzQrMDA6MDAiLCJleHBpcmF0aW9uRGF0ZSI6bnVsbCwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnFnbW1weWp3NWh3bnFmZ3puN3dtcm0zM2FkeThnYjh6OWlkZWliNm05Z2o0eXM2d255OHkiLCJlbWFpbEFkZHJlc3MiOiJhbGljZUB0YmQuZW1haWwifSwiY3JlZGVudGlhbFNjaGVtYSI6eyJpZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDAwMDcvc2NoZW1hcy9lbWFpbC5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifX0sImlzcyI6ImRpZDpqd2s6ZXlKaGJHY2lPaUpGWkRJMU5URTVJaXdpYTNSNUlqb2lUMHRRSWl3aVkzSjJJam9pUldReU5UVXhPU0lzSW5naU9pSkZjVm96YVdGVldqWnpUMlZ5VEVGMWEzcEpRbkV6Ym1sNVEzZHVVWEF0WWtkNk1EQlZMVk15YURGakluMCIsImp0aSI6InVybjp1dWlkOjM4OWE2OWYyLWEwOTYtNDc0Ni1hNzU0LTRlNmE0ZThiZDEzYyIsInN1YiI6ImRpZDpkaHQ6cWdtbXB5anc1aHducWZnem43d21ybTMzYWR5OGdiOHo5aWRlaWI2bTlnajR5czZ3bnk4eSIsIm5iZiI6MTcyNTM3ODc5NywiaWF0IjoxNzI1Mzc4Nzk3fQ.AC1OGOJ-MxfRsyNJZEQM4PW_t1eNCiSdTNtEtiPPOnIDGYnDl7JGtVIki9tHdWduQHoanrV0dWDeB5dnTTmZAw"#; - let _ = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true).unwrap(); + let _ = VerifiableCredential::from_vc_jwt(vc_jwt_at_port, true) + .await + .unwrap(); } } } diff --git a/crates/web5/src/credentials/verifiable_presentation_1_1.rs b/crates/web5/src/credentials/verifiable_presentation_1_1.rs index 3e83c301..d35b6305 100644 --- a/crates/web5/src/credentials/verifiable_presentation_1_1.rs +++ b/crates/web5/src/credentials/verifiable_presentation_1_1.rs @@ -172,7 +172,7 @@ impl VerifiablePresentation { /// None, /// ).unwrap(); /// ``` - pub fn create( + pub async fn create( holder: String, vc_jwts: Vec, options: Option, @@ -187,7 +187,7 @@ impl VerifiablePresentation { // Verify vcjwts for vc_jwt in vc_jwts.clone() { - VerifiableCredential::from_vc_jwt(&vc_jwt, true)?; + VerifiableCredential::from_vc_jwt(&vc_jwt, true).await?; } let context = build_vp_context(options.context); @@ -225,11 +225,11 @@ impl VerifiablePresentation { /// let vp_jwt = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZDI1NTE5Iiwia2lkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKYWNUaFJaR05XYlRrMlluZGpRa3R3WVhwV2RGQmlkekJ6U1c4NE0wbG9XRXAyVGtoV1VIUnpWWFYzSW4wIzAifQ.eyJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUphY1RoUlpHTldiVGsyWW5kalFrdHdZWHBXZEZCaWR6QnpTVzg0TTBsb1dFcDJUa2hXVUhSelZYVjNJbjAiLCJqdGkiOiJ1cm46dXVpZDowZDg5YTcxMS0zNTdjLTQzNTQtOWYzMS02OWQ0NDE1NWQ1ZTMiLCJuYmYiOjE3MjYyMzQwODEsImlhdCI6MTcyNjIzNDA4MSwidnAiOnsiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOS0xM1QxMzoyODowMVoiLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVQcmVzZW50YXRpb24iXSwidmVyaWZpYWJsZUNyZWRlbnRpYWwiOlsiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKRlpESTFOVEU1SWl3aWEybGtJam9pWkdsa09tcDNhenBsZVVwb1lrZGphVTlwU2taYVJFa3hUbFJGTlVscGQybGhNMUkxU1dwdmFWUXdkRkZKYVhkcFdUTktNa2xxYjJsU1YxRjVUbFJWZUU5VFNYTkpibWRwVDJsS1VWRnNiRTVTYlRreFdUQnpOVk16WkZCVFNGSjZUbXBvVTA1RlZuZGpiVmw1VFhwT1RFNVVVazFOVmxaSlRqRlNTV05VVW1aaE1HaE9TVzR3SXpBaWZRLmV5SnBjM01pT2lKa2FXUTZhbmRyT21WNVNtaGlSMk5wVDJsS1JscEVTVEZPVkVVMVNXbDNhV0V6VWpWSmFtOXBWREIwVVVscGQybFpNMG95U1dwdmFWSlhVWGxPVkZWNFQxTkpjMGx1WjJsUGFVcFJVV3hzVGxKdE9URlpNSE0xVXpOa1VGTklVbnBPYW1oVFRrVldkMk50V1hsTmVrNU1UbFJTVFUxV1ZrbE9NVkpKWTFSU1ptRXdhRTVKYmpBaUxDSnFkR2tpT2lKMWNtNDZkWFZwWkRwaE1UaGlOREppWVMwMk1UVTVMVFExWVRrdFlXTXpZaTB5TnpaaVlqQmtORGRpWmpZaUxDSnpkV0lpT2lKa2FXUTZaR2gwT201bk5HaHRjWFJ5WjNWcWIzZzBZV2R3WmpodmEzaHBhRzU1ZVRGNmNXNXhPVGR4Wm1WeE1UVjRPRzloY2pkNVpYQjZhSGtpTENKdVltWWlPakUzTWpZeU16RTVOeklzSW1saGRDSTZNVGN5TmpJek1UazNNaXdpZG1NaU9uc2lRR052Ym5SbGVIUWlPbHNpYUhSMGNITTZMeTkzZDNjdWR6TXViM0puTHpJd01UZ3ZZM0psWkdWdWRHbGhiSE12ZGpFaVhTd2lZM0psWkdWdWRHbGhiRk4xWW1wbFkzUWlPbnNpYVdRaU9pSmthV1E2WkdoME9tNW5OR2h0Y1hSeVozVnFiM2cwWVdkd1pqaHZhM2hwYUc1NWVURjZjVzV4T1RkeFptVnhNVFY0T0c5aGNqZDVaWEI2YUhraWZTd2lhWE56ZFdWeUlqb2laR2xrT21wM2F6cGxlVXBvWWtkamFVOXBTa1phUkVreFRsUkZOVWxwZDJsaE0xSTFTV3B2YVZRd2RGRkphWGRwV1ROS01rbHFiMmxTVjFGNVRsUlZlRTlUU1hOSmJtZHBUMmxLVVZGc2JFNVNiVGt4V1RCek5WTXpaRkJUU0ZKNlRtcG9VMDVGVm5kamJWbDVUWHBPVEU1VVVrMU5WbFpKVGpGU1NXTlVVbVpoTUdoT1NXNHdJaXdpYVhOemRXRnVZMlZFWVhSbElqb2lNakF5TkMwd09TMHhNMVF4TWpvMU1qbzFNbG9pTENKMGVYQmxJanBiSWxabGNtbG1hV0ZpYkdWRGNtVmtaVzUwYVdGc0lsMHNJbWxrSWpvaWRYSnVPblYxYVdRNllURTRZalF5WW1FdE5qRTFPUzAwTldFNUxXRmpNMkl0TWpjMlltSXdaRFEzWW1ZMkluMTkuaUNkN1FsQWlCTkxDZnZ0VWJCdGstOVBUcUZmdWNxWjQ0S3hoRnZqR2NSU2prR0pyNjEwLTBqTFZzTlNBX0NQOGdibFljZncxZTVqeDNwR2VFckMtQnciXSwiaG9sZGVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKYWNUaFJaR05XYlRrMlluZGpRa3R3WVhwV2RGQmlkekJ6U1c4NE0wbG9XRXAyVGtoV1VIUnpWWFYzSW4wIiwiaWQiOiJ1cm46dXVpZDowZDg5YTcxMS0zNTdjLTQzNTQtOWYzMS02OWQ0NDE1NWQ1ZTMifX0.f-kdfbIIms3Gg2dMKUMayeU1rQnaO_o0io33kLzy-uPqI6vsdsJZvSmDIilx7scRqlia7Pmnnj6bnF2x8F2fAw"#; /// let verifiable_presentation = VerifiablePresentation::from_vp_jwt(vp_jwt, true).unwrap(); /// ``` - pub fn from_vp_jwt(vp_jwt: &str, verify: bool) -> Result { - let verifiable_presentation = decode_vp_jwt(vp_jwt, verify)?; + pub async fn from_vp_jwt(vp_jwt: &str, verify: bool) -> Result { + let verifiable_presentation = decode_vp_jwt(vp_jwt, verify).await?; if verify { - validate_vp_data_model(&verifiable_presentation)?; + validate_vp_data_model(&verifiable_presentation).await?; } Ok(verifiable_presentation) @@ -328,8 +328,8 @@ fn build_vp_type(r#type: Option>) -> Vec { types } -pub fn decode_vp_jwt(vp_jwt: &str, verify_signature: bool) -> Result { - let jwt = Jwt::from_compact_jws(vp_jwt, verify_signature)?; +pub async fn decode_vp_jwt(vp_jwt: &str, verify_signature: bool) -> Result { + let jwt = Jwt::from_compact_jws(vp_jwt, verify_signature).await?; let jti = jwt .claims @@ -380,7 +380,7 @@ pub fn decode_vp_jwt(vp_jwt: &str, verify_signature: bool) -> Result std::result::Result<(), VerificationError> { // Required fields ["@context", "id", "type", "holder", "verifiableCredential"] @@ -426,9 +426,11 @@ pub fn validate_vp_data_model( // Verify vc_jwts for vc_jwt in vp.verifiable_credential.clone() { - VerifiableCredential::from_vc_jwt(&vc_jwt, true).map_err(|e| { - VerificationError::DataModelValidationError(format!("invalid vc_jwt: {}", e)) - })?; + VerifiableCredential::from_vc_jwt(&vc_jwt, true) + .await + .map_err(|e| { + VerificationError::DataModelValidationError(format!("invalid vc_jwt: {}", e)) + })?; } Ok(()) @@ -439,6 +441,7 @@ mod tests { use super::*; use crate::credentials::{CredentialSubject, Issuer}; use crate::dids::methods::did_jwk::DidJwk; + fn setup_vc_issuer_and_holder() -> (BearerDid, String, BearerDid, String) { let vc_issuer_did = DidJwk::create(None).expect("Failed to create VC issuer DID"); let vc_issuer_uri = vc_issuer_did.did.uri.clone(); @@ -449,7 +452,7 @@ mod tests { (vc_issuer_did, vc_issuer_uri, holder, holder_uri) } - fn create_verifiable_credential(vc_issuer_uri: &str) -> VerifiableCredential { + async fn create_verifiable_credential(vc_issuer_uri: &str) -> VerifiableCredential { let credential_subject = CredentialSubject { id: vc_issuer_uri.to_string(), ..Default::default() @@ -460,6 +463,7 @@ mod tests { credential_subject, None, ) + .await .expect("Failed to create Verifiable Credential") } @@ -468,15 +472,16 @@ mod tests { .expect("Failed to sign Verifiable Credential") } - #[test] - fn test_create_verifiable_presentation() { + #[tokio::test] + async fn test_create_verifiable_presentation() { let (vc_issuer_did, vc_issuer_uri, _holder, holder_uri) = setup_vc_issuer_and_holder(); - let vc = create_verifiable_credential(&vc_issuer_uri); + let vc = create_verifiable_credential(&vc_issuer_uri).await; let vc_jwt = sign_verifiable_credential(&vc, &vc_issuer_did); let vp = VerifiablePresentation::create(holder_uri.clone(), vec![vc_jwt.clone()], None) + .await .expect("Failed to create Verifiable Presentation"); assert_eq!(vp.holder, holder_uri); @@ -488,14 +493,16 @@ mod tests { assert!(vp.issuance_date <= SystemTime::now()); assert!(vp.expiration_date.is_none() || vp.expiration_date.unwrap() > SystemTime::now()); - validate_vp_data_model(&vp).expect("Verifiable Presentation data model validation failed"); + validate_vp_data_model(&vp) + .await + .expect("Verifiable Presentation data model validation failed"); } - #[test] - fn test_verifiable_presentation_expiration() { + #[tokio::test] + async fn test_verifiable_presentation_expiration() { let (vc_issuer_did, vc_issuer_uri, _holder, holder_uri) = setup_vc_issuer_and_holder(); - let vc = create_verifiable_credential(&vc_issuer_uri); + let vc = create_verifiable_credential(&vc_issuer_uri).await; let vc_jwt = sign_verifiable_credential(&vc, &vc_issuer_did); @@ -508,9 +515,10 @@ mod tests { ..Default::default() }), ) + .await .expect("Failed to create Verifiable Presentation"); - let validation_result = validate_vp_data_model(&vp); + let validation_result = validate_vp_data_model(&vp).await; match validation_result { Err(VerificationError::DataModelValidationError(msg)) => { @@ -522,15 +530,16 @@ mod tests { } } - #[test] - fn test_verifiable_presentation_sign() { + #[tokio::test] + async fn test_verifiable_presentation_sign() { let (vc_issuer_did, vc_issuer_uri, holder, holder_uri) = setup_vc_issuer_and_holder(); - let vc = create_verifiable_credential(&vc_issuer_uri); + let vc = create_verifiable_credential(&vc_issuer_uri).await; let vc_jwt = sign_verifiable_credential(&vc, &vc_issuer_did); let vp = VerifiablePresentation::create(holder_uri.clone(), vec![vc_jwt.clone()], None) + .await .expect("Failed to create Verifiable Presentation"); // Sign the Verifiable Presentation @@ -540,6 +549,7 @@ mod tests { // Decode the signed Verifiable Presentation JWT let decoded_vp = VerifiablePresentation::from_vp_jwt(&vp_jwt, true) + .await .expect("Failed to decode signed Verifiable Presentation JWT"); // Verify that the decoded Verifiable Presentation matches the original @@ -550,6 +560,7 @@ mod tests { // Validate the signed Verifiable Presentation data model validate_vp_data_model(&decoded_vp) + .await .expect("Signed Verifiable Presentation data model validation failed"); } } diff --git a/crates/web5/src/dids/methods/did_dht/mod.rs b/crates/web5/src/dids/methods/did_dht/mod.rs index 8acc96ee..af93222d 100644 --- a/crates/web5/src/dids/methods/did_dht/mod.rs +++ b/crates/web5/src/dids/methods/did_dht/mod.rs @@ -89,7 +89,7 @@ impl DidDht { /// let did_dht = DidDht::create(None)?; /// println!("Created DID DHT: {:?}", did_dht); /// ``` - pub fn create(options: Option) -> Result { + pub async fn create(options: Option) -> Result { let options = options.unwrap_or_default(); let key_manager = options @@ -134,7 +134,7 @@ impl DidDht { }; if options.publish.unwrap_or(true) { - DidDht::publish(bearer_did.clone(), options.gateway_url)?; + DidDht::publish(bearer_did.clone(), options.gateway_url).await?; } Ok(bearer_did) @@ -307,14 +307,15 @@ mod tests { mod create { use super::*; - #[test] - fn test_can_specify_key_manager() { + #[tokio::test] + async fn test_can_specify_key_manager() { let key_manager = Arc::new(InMemoryKeyManager::new()); let result = DidDht::create(Some(DidDhtCreateOptions { publish: Some(false), key_manager: Some(key_manager.clone()), ..Default::default() - })); + })) + .await; assert!(result.is_ok()); @@ -326,8 +327,8 @@ mod tests { assert!(result.is_ok()) } - #[test] - fn test_can_specify_publish_and_gateway_url() { + #[tokio::test] + async fn test_can_specify_publish_and_gateway_url() { let mut mock_server = mockito::Server::new(); let gateway_url = mock_server.url(); @@ -342,15 +343,16 @@ mod tests { publish: Some(true), gateway_url: Some(gateway_url.clone()), // Use the mock server's URL ..Default::default() - })); + })) + .await; assert!(result.is_ok()); mock.assert(); } - #[test] - fn test_should_add_optional_verification_methods() { + #[tokio::test] + async fn test_should_add_optional_verification_methods() { let additional_verification_method = VerificationMethod { id: "did:web:example.com#key-1".to_string(), r#type: "JsonWebKey".to_string(), @@ -362,7 +364,8 @@ mod tests { publish: Some(false), verification_method: Some(vec![additional_verification_method.clone()]), ..Default::default() - })); + })) + .await; assert!(result.is_ok()); @@ -374,8 +377,8 @@ mod tests { ); } - #[test] - fn test_should_add_optional_services() { + #[tokio::test] + async fn test_should_add_optional_services() { let service = Service { id: "did:web:example.com#service-0".to_string(), r#type: "SomeService".to_string(), @@ -386,7 +389,8 @@ mod tests { publish: Some(false), service: Some(vec![service.clone()]), ..Default::default() - })); + })) + .await; assert!(result.is_ok()); @@ -394,15 +398,16 @@ mod tests { assert_eq!(did_web.document.service.unwrap()[0], service); } - #[test] - fn test_should_add_optional_also_known_as() { + #[tokio::test] + async fn test_should_add_optional_also_known_as() { let also_known_as = vec!["https://alias.example.com".to_string()]; let result = DidDht::create(Some(DidDhtCreateOptions { publish: Some(false), also_known_as: Some(also_known_as.clone()), ..Default::default() - })); + })) + .await; assert!(result.is_ok()); @@ -410,15 +415,16 @@ mod tests { assert_eq!(did_web.document.also_known_as.unwrap(), also_known_as); } - #[test] - fn test_should_add_optional_controllers() { + #[tokio::test] + async fn test_should_add_optional_controllers() { let controllers = vec!["did:web:controller.example.com".to_string()]; let result = DidDht::create(Some(DidDhtCreateOptions { publish: Some(false), controller: Some(controllers.clone()), ..Default::default() - })); + })) + .await; assert!(result.is_ok()); @@ -430,8 +436,8 @@ mod tests { mod publish { use super::*; - #[test] - fn test_can_specify_gateway_url() { + #[tokio::test] + async fn test_can_specify_gateway_url() { let mut mock_server = mockito::Server::new(); let gateway_url = mock_server.url(); @@ -446,20 +452,22 @@ mod tests { publish: Some(false), ..Default::default() })) + .await .unwrap(); let result = DidDht::publish( bearer_did, Some(gateway_url.clone()), // Use the mock server's URL - ); + ) + .await; assert!(result.is_ok()); mock.assert(); } - #[test] - fn test_can_handle_network_error() { + #[tokio::test] + async fn test_can_handle_network_error() { let mut mock_server = mockito::Server::new(); let gateway_url = mock_server.url(); @@ -474,9 +482,10 @@ mod tests { publish: Some(false), ..Default::default() })) + .await .unwrap(); - let result = DidDht::publish(bearer_did, Some(gateway_url)); + let result = DidDht::publish(bearer_did, Some(gateway_url)).await; assert!(result.is_err()); if let Err(Web5Error::Network(msg)) = result { @@ -490,34 +499,34 @@ mod tests { } mod resolve { - use std::sync::Mutex; - use super::*; + use std::sync::Mutex; - #[test] - fn test_invalid_did() { - let resolution_result = DidDht::resolve("something invalid", None); + #[tokio::test] + async fn test_invalid_did() { + let resolution_result = DidDht::resolve("something invalid", None).await; assert_eq!( resolution_result.resolution_metadata.error, Some(ResolutionMetadataError::InvalidDid) ) } - #[test] - fn test_method_not_supported() { - let resolution_result = DidDht::resolve("did:web:example", None); + #[tokio::test] + async fn test_method_not_supported() { + let resolution_result = DidDht::resolve("did:web:example", None).await; assert_eq!( resolution_result.resolution_metadata.error, Some(ResolutionMetadataError::MethodNotSupported) ) } - #[test] - fn test_not_found() { + #[tokio::test] + async fn test_not_found() { let bearer_did = DidDht::create(Some(DidDhtCreateOptions { publish: Some(false), ..Default::default() })) + .await .unwrap(); let mut mock_server = mockito::Server::new(); @@ -530,7 +539,7 @@ mod tests { .with_header("content-type", "application/octet-stream") .create(); - let resolution_result = DidDht::resolve(&bearer_did.did.uri, Some(gateway_url)); + let resolution_result = DidDht::resolve(&bearer_did.did.uri, Some(gateway_url)).await; assert_eq!( resolution_result.resolution_metadata.error, Some(ResolutionMetadataError::NotFound) @@ -539,12 +548,13 @@ mod tests { mock.assert(); } - #[test] - fn test_internal_error() { + #[tokio::test] + async fn test_internal_error() { let bearer_did = DidDht::create(Some(DidDhtCreateOptions { publish: Some(false), ..Default::default() })) + .await .unwrap(); let mut mock_server = mockito::Server::new(); @@ -557,7 +567,7 @@ mod tests { .with_header("content-type", "application/octet-stream") .create(); - let resolution_result = DidDht::resolve(&bearer_did.did.uri, Some(gateway_url)); + let resolution_result = DidDht::resolve(&bearer_did.did.uri, Some(gateway_url)).await; assert_eq!( resolution_result.resolution_metadata.error, Some(ResolutionMetadataError::InternalError) @@ -566,8 +576,8 @@ mod tests { mock.assert(); } - #[test] - fn test_can_create_then_resolve() { + #[tokio::test] + async fn test_can_create_then_resolve() { let mut mock_server = mockito::Server::new(); let gateway_url = mock_server.url(); @@ -590,7 +600,8 @@ mod tests { publish: Some(true), gateway_url: Some(gateway_url), ..Default::default() - })); + })) + .await; assert!(create_result.is_ok()); let bearer_did = create_result.unwrap(); @@ -605,7 +616,8 @@ mod tests { .with_body(stored_body.clone()) // Use the captured body as the response .create(); - let resolution_result = DidDht::resolve(&bearer_did.did.uri, Some(mock_server.url())); + let resolution_result = + DidDht::resolve(&bearer_did.did.uri, Some(mock_server.url())).await; assert_eq!(resolution_result.resolution_metadata.error, None); assert!(resolution_result.document.is_some()); diff --git a/crates/web5/src/dids/methods/did_web/mod.rs b/crates/web5/src/dids/methods/did_web/mod.rs index cd2e6856..7115de55 100644 --- a/crates/web5/src/dids/methods/did_web/mod.rs +++ b/crates/web5/src/dids/methods/did_web/mod.rs @@ -189,14 +189,14 @@ impl DidWeb { /// # Errors /// /// Returns a `ResolutionMetadataError` if the DID is invalid or cannot be resolved. - pub fn resolve(uri: &str) -> ResolutionResult { + pub async fn resolve(uri: &str) -> ResolutionResult { let did = match Did::parse(uri) { Ok(did) => did, Err(_) => return ResolutionResult::from(ResolutionMetadataError::InvalidDid), }; let resolution_result = match Resolver::new(did) { - Ok(resolver) => resolver.resolve(), + Ok(resolver) => resolver.resolve().await, Err(e) => return ResolutionResult::from(e), }; @@ -450,17 +450,17 @@ mod tests { use super::*; use mockito::Server; - #[test] - fn test_invalid_did() { - let resolution_result = DidWeb::resolve("something invalid"); + #[tokio::test] + async fn test_invalid_did() { + let resolution_result = DidWeb::resolve("something invalid").await; assert_eq!( resolution_result.resolution_metadata.error, Some(ResolutionMetadataError::InvalidDid) ) } - #[test] - fn test_create_then_resolve() { + #[tokio::test] + async fn test_create_then_resolve() { let mut mock_server = Server::new(); let url = mock_server.url(); @@ -475,7 +475,7 @@ mod tests { .with_body(serde_json::to_string(&bearer_did.document).unwrap()) .create(); - let resolution_result = DidWeb::resolve(&bearer_did.did.uri); + let resolution_result = DidWeb::resolve(&bearer_did.did.uri).await; assert_eq!(resolution_result.resolution_metadata.error, None); assert!(resolution_result.document.is_some()); diff --git a/crates/web5/src/dids/resolution/resolution_result.rs b/crates/web5/src/dids/resolution/resolution_result.rs index ae057eef..0cc45624 100644 --- a/crates/web5/src/dids/resolution/resolution_result.rs +++ b/crates/web5/src/dids/resolution/resolution_result.rs @@ -50,7 +50,7 @@ impl ResolutionResult { /// println!("Resolution failed with error: {:?}", result.resolution_metadata.error); /// } /// ``` - pub fn resolve(uri: &str) -> Self { + pub async fn resolve(uri: &str) -> Self { let did = match Did::parse(uri) { Ok(did) => did, Err(_) => return ResolutionResult::from(ResolutionMetadataError::InvalidDid), @@ -58,8 +58,8 @@ impl ResolutionResult { match did.method.as_str() { "jwk" => DidJwk::resolve(uri), - "dht" => DidDht::resolve(uri, None), - "web" => DidWeb::resolve(uri), + "dht" => DidDht::resolve(uri, None).await, + "web" => DidWeb::resolve(uri).await, _ => ResolutionResult::from(ResolutionMetadataError::MethodNotSupported), } } @@ -98,26 +98,26 @@ mod tests { mod resolve { use super::*; - #[test] - fn test_invalid_did() { - let resolution_result = ResolutionResult::resolve("something invalid"); + #[tokio::test] + async fn test_invalid_did() { + let resolution_result = ResolutionResult::resolve("something invalid").await; assert_eq!( resolution_result.resolution_metadata.error, Some(ResolutionMetadataError::InvalidDid) ) } - #[test] - fn test_did_jwk() { + #[tokio::test] + async fn test_did_jwk() { let bearer_did = DidJwk::create(None).unwrap(); - let resolution_result = ResolutionResult::resolve(&bearer_did.did.uri); + let resolution_result = ResolutionResult::resolve(&bearer_did.did.uri).await; assert_eq!(resolution_result.resolution_metadata.error, None); assert_eq!(resolution_result.document.unwrap(), bearer_did.document); } - #[test] - fn test_did_web() { + #[tokio::test] + async fn test_did_web() { let mut mock_server = Server::new(); let url = mock_server.url(); @@ -130,16 +130,16 @@ mod tests { .with_body(serde_json::to_string(&bearer_did.document).unwrap()) .create(); - let resolution_result = ResolutionResult::resolve(&bearer_did.did.uri); + let resolution_result = ResolutionResult::resolve(&bearer_did.did.uri).await; assert_eq!(resolution_result.resolution_metadata.error, None); assert!(resolution_result.document.is_some()); assert_eq!(resolution_result.document.unwrap(), bearer_did.document); } - #[test] - fn test_method_not_supported() { - let resolution_result = ResolutionResult::resolve("did:example:123"); + #[tokio::test] + async fn test_method_not_supported() { + let resolution_result = ResolutionResult::resolve("did:example:123").await; assert!(resolution_result.resolution_metadata.error.is_some()); assert_eq!( resolution_result.resolution_metadata.error.unwrap(), diff --git a/crates/web5/src/jose.rs b/crates/web5/src/jose.rs index 4e57af8c..895ce760 100644 --- a/crates/web5/src/jose.rs +++ b/crates/web5/src/jose.rs @@ -105,7 +105,7 @@ impl Jws { }) } - pub fn from_compact_jws(compact_jws: &str, verify: bool) -> Result { + pub async fn from_compact_jws(compact_jws: &str, verify: bool) -> Result { let parts = compact_jws .split('.') .map(String::from) @@ -141,7 +141,7 @@ impl Jws { } if verify { - let resolution_result = ResolutionResult::resolve(&kid); + let resolution_result = ResolutionResult::resolve(&kid).await; let document = match resolution_result.resolution_metadata.error { Some(e) => return Err(e.into()), None => match resolution_result.document { @@ -250,8 +250,8 @@ impl Jwt { }) } - pub fn from_compact_jws(compact_jws: &str, verify: bool) -> Result { - let jws = Jws::from_compact_jws(compact_jws, verify)?; + pub async fn from_compact_jws(compact_jws: &str, verify: bool) -> Result { + let jws = Jws::from_compact_jws(compact_jws, verify).await?; let claims = JwtClaims::from_json_byte_array(&jws.payload)?; Ok(Self { diff --git a/crates/web5/src/test_vectors.rs b/crates/web5/src/test_vectors.rs index 977f29bc..fda69d75 100644 --- a/crates/web5/src/test_vectors.rs +++ b/crates/web5/src/test_vectors.rs @@ -117,8 +117,8 @@ mod test_vectors { did_resolution_metadata: ResolutionMetadata, } - #[test] - fn resolve() { + #[tokio::test] + async fn resolve() { let path = "did_dht/resolve.json"; let vectors: TestVectorFile = TestVectorFile::load_from_path(path); @@ -146,7 +146,7 @@ mod test_vectors { // }; } - let resolution_result = DidDht::resolve(&vector_input.did_uri, None); + let resolution_result = DidDht::resolve(&vector_input.did_uri, None).await; let metadata_error = resolution_result.resolution_metadata.error.as_ref(); let expected_error = vector_output.did_resolution_metadata.error.as_ref(); @@ -179,9 +179,9 @@ mod test_vectors { pub selected_credentials: Vec, } - #[test] + #[tokio::test] #[ignore] // TODO temporarily ignoring, because web5-spec test vectors use did:key which isn't supported - fn select_credentials() { + async fn select_credentials() { let path = "presentation_exchange/select_credentials.json"; let vectors: TestVectorFile = TestVectorFile::load_from_path(path); @@ -196,6 +196,7 @@ mod test_vectors { let selected_credentials = presentation_definition .select_credentials(&vc_jwts) + .await .expect(&error_msg); let set1: HashSet<_> = selected_credentials.iter().collect(); @@ -335,8 +336,8 @@ mod test_vectors { pub vc_jwt: String, } - #[test] - fn verify() { + #[tokio::test] + async fn verify() { let path = "credentials/verify.json"; let vectors: TestVectorFile> = TestVectorFile::load_from_path(path); @@ -347,7 +348,7 @@ mod test_vectors { } let vc_jwt = vector.input.vc_jwt; - let result = VerifiableCredential::from_vc_jwt(&vc_jwt, true); + let result = VerifiableCredential::from_vc_jwt(&vc_jwt, true).await; if matches!(vector.errors, Some(true)) { assert!( diff --git a/crates/web5_cli/Cargo.toml b/crates/web5_cli/Cargo.toml index 36d5f023..bbc2514f 100644 --- a/crates/web5_cli/Cargo.toml +++ b/crates/web5_cli/Cargo.toml @@ -10,6 +10,7 @@ license-file.workspace = true chrono = { workspace = true } clap = { version = "4.5.7", features = ["derive"] } serde_json = { workspace = true } +tokio = { version = "1.38.0", features = ["full"] } web5 = { path = "../web5" } url = "2.5.2" -uuid = { workspace = true } \ No newline at end of file +uuid = { workspace = true } diff --git a/crates/web5_cli/src/dids/create.rs b/crates/web5_cli/src/dids/create.rs index ffba7e10..a42cdb29 100644 --- a/crates/web5_cli/src/dids/create.rs +++ b/crates/web5_cli/src/dids/create.rs @@ -51,7 +51,7 @@ fn print_portable_did(portable_did: PortableDid, no_indent: &bool, json_escape: } impl Commands { - pub fn command(&self) { + pub async fn command(&self) { match self { Commands::Jwk { no_indent, @@ -101,6 +101,7 @@ impl Commands { key_manager: Some(key_manager.clone()), ..Default::default() })) + .await .unwrap(); let portable_did = bearer_did.to_portable_did(key_manager).unwrap(); diff --git a/crates/web5_cli/src/dids/mod.rs b/crates/web5_cli/src/dids/mod.rs index e39eebaf..47dae9e5 100644 --- a/crates/web5_cli/src/dids/mod.rs +++ b/crates/web5_cli/src/dids/mod.rs @@ -17,10 +17,10 @@ pub enum Commands { } impl Commands { - pub fn command(&self) { + pub async fn command(&self) { match self { Commands::Resolve { uri } => { - let resolution_result = ResolutionResult::resolve(uri); + let resolution_result = ResolutionResult::resolve(uri).await; match &resolution_result.resolution_metadata.error { Some(e) => println!("{:?} {}", e, e), None => match &resolution_result.document { @@ -40,7 +40,7 @@ impl Commands { }, } } - Commands::Create { did_create_command } => did_create_command.command(), + Commands::Create { did_create_command } => did_create_command.command().await, } } } diff --git a/crates/web5_cli/src/main.rs b/crates/web5_cli/src/main.rs index 46aee3d6..86e94a11 100644 --- a/crates/web5_cli/src/main.rs +++ b/crates/web5_cli/src/main.rs @@ -25,11 +25,12 @@ enum Commands { }, } -fn main() { +#[tokio::main] +async fn main() { let cli = Cli::parse(); match cli.command { - Commands::Did { did_command } => did_command.command(), - Commands::Vc { vc_command } => vc_command.command(), + Commands::Did { did_command } => did_command.command().await, + Commands::Vc { vc_command } => vc_command.command().await, } } diff --git a/crates/web5_cli/src/vcs.rs b/crates/web5_cli/src/vcs.rs index b71f326a..dae5a837 100644 --- a/crates/web5_cli/src/vcs.rs +++ b/crates/web5_cli/src/vcs.rs @@ -3,7 +3,7 @@ use clap::Subcommand; use std::time::SystemTime; use web5::{ credentials::{ - CredentialSubject, Issuer, {VerifiableCredential, VerifiableCredentialCreateOptions}, + CredentialSubject, Issuer, VerifiableCredential, VerifiableCredentialCreateOptions, }, dids::{bearer_did::BearerDid, portable_did::PortableDid}, json::{FromJson, ToJson}, @@ -34,7 +34,7 @@ pub enum Commands { } impl Commands { - pub fn command(&self) { + pub async fn command(&self) { match self { Commands::Create { credential_subject_id, @@ -75,6 +75,7 @@ impl Commands { ..Default::default() }), ) + .await .unwrap(); let mut output_str = match no_indent { @@ -98,7 +99,7 @@ impl Commands { vc_jwt, no_indent, json_escape, - } => match VerifiableCredential::from_vc_jwt(vc_jwt, true) { + } => match VerifiableCredential::from_vc_jwt(vc_jwt, true).await { Err(e) => { println!("\n❌ Verfication failed\n"); println!("{:?} {}", e, e); From 590a49254756d545ab3a6aea399c01d208e96614 Mon Sep 17 00:00:00 2001 From: Kendall Weihe Date: Mon, 30 Sep 2024 13:48:49 -0400 Subject: [PATCH 3/9] Add async to uniffi crates --- bindings/web5_uniffi/src/web5.udl | 22 ++++++++++--------- .../credentials/presentation_definition.rs | 11 ++++++---- .../src/credentials/status_list_credential.rs | 10 ++++----- .../credentials/verifiable_credential_1_1.rs | 9 ++++---- .../verifiable_presentation_1_1.rs | 9 ++++---- .../src/dids/methods/did_dht.rs | 15 ++++++++----- .../src/dids/methods/did_web.rs | 4 ++-- .../src/dids/resolution/resolution_result.rs | 4 ++-- 8 files changed, 46 insertions(+), 38 deletions(-) diff --git a/bindings/web5_uniffi/src/web5.udl b/bindings/web5_uniffi/src/web5.udl index 33a835b9..74d5749b 100644 --- a/bindings/web5_uniffi/src/web5.udl +++ b/bindings/web5_uniffi/src/web5.udl @@ -8,12 +8,14 @@ namespace web5 { [Throws=Web5Error] BearerDid did_web_create(string domain, DidWebCreateOptions? options); + [Async] ResolutionResult did_web_resolve([ByRef] string uri); - [Throws=Web5Error] + [Throws=Web5Error, Async] BearerDid did_dht_create(DidDhtCreateOptions? options); - [Throws=Web5Error] + [Throws=Web5Error, Async] void did_dht_publish(BearerDid bearer_did, string? gateway_url); + [Async] ResolutionResult did_dht_resolve([ByRef] string uri, string? gateway_url); }; @@ -190,7 +192,7 @@ dictionary ResolutionResultData { }; interface ResolutionResult { - [Name=resolve] + [Name=resolve, Async] constructor([ByRef] string uri); ResolutionResultData get_data(); }; @@ -256,9 +258,9 @@ interface PresentationDefinition { constructor(string json_serialized_presentation_definition); [Throws=Web5Error] string get_json_serialized_presentation_definition(); - [Throws=Web5Error] + [Throws=Web5Error, Async] sequence select_credentials([ByRef] sequence vc_jwts); - [Throws=Web5Error] + [Throws=Web5Error, Async] string create_presentation_from_credentials([ByRef] sequence vc_jwts); }; @@ -274,7 +276,7 @@ dictionary VerifiableCredentialCreateOptionsData { }; interface VerifiableCredential { - [Throws=Web5Error, Name=create] + [Throws=Web5Error, Name=create, Async] constructor( string json_serialized_issuer, string json_serialized_credential_subject, @@ -282,7 +284,7 @@ interface VerifiableCredential { ); [Throws=Web5Error] VerifiableCredentialData get_data(); - [Throws=Web5Error, Name=from_vc_jwt] + [Throws=Web5Error, Name=from_vc_jwt, Async] constructor(string vc_jwt, boolean verify); [Throws=Web5Error] string sign(BearerDid bearer_did, string? verification_method_id); @@ -315,7 +317,7 @@ dictionary CredentialStatusData { }; interface StatusListCredential { - [Throws=Web5Error, Name=create] + [Throws=Web5Error, Name=create, Async] constructor( string json_serialized_issuer, string status_purpose, @@ -338,7 +340,7 @@ dictionary VerifiablePresentationCreateOptionsData { }; interface VerifiablePresentation { - [Throws=Web5Error, Name=create] + [Throws=Web5Error, Name=create, Async] constructor( string holder, sequence vc_jwts, @@ -348,7 +350,7 @@ interface VerifiablePresentation { [Throws=Web5Error] VerifiablePresentationData get_data(); - [Throws=Web5Error, Name=from_vp_jwt] + [Throws=Web5Error, Name=from_vp_jwt, Async] constructor(string vp_jwt, boolean verify); [Throws=Web5Error] diff --git a/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs b/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs index 8bd037c2..7975bda0 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs @@ -12,12 +12,15 @@ impl PresentationDefinition { Ok(Self(inner_presentation_definition)) } - pub fn select_credentials(&self, vc_jwts: &Vec) -> Result> { - Ok(self.0.select_credentials(vc_jwts)?) + pub async fn select_credentials(&self, vc_jwts: &Vec) -> Result> { + Ok(self.0.select_credentials(vc_jwts).await?) } - pub fn create_presentation_from_credentials(&self, vc_jwts: &Vec) -> Result { - let presentation_result = self.0.create_presentation_from_credentials(vc_jwts)?; + pub async fn create_presentation_from_credentials( + &self, + vc_jwts: &Vec, + ) -> Result { + let presentation_result = self.0.create_presentation_from_credentials(vc_jwts).await?; let json_serialized_presentation_result = serde_json::to_string(&presentation_result)?; Ok(json_serialized_presentation_result) diff --git a/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs b/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs index 26c6ee25..b75659f1 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs @@ -10,7 +10,7 @@ use web5::{ pub struct StatusListCredential(pub InnerStatusListCredential); impl StatusListCredential { - pub fn create( + pub async fn create( json_serialized_issuer: String, status_purpose: String, credentials_to_disable: Option>>, @@ -25,11 +25,9 @@ impl StatusListCredential { .collect() }); - Ok(Self(InnerStatusListCredential::create( - issuer, - status_purpose, - inner_vcs, - )?)) + Ok(Self( + InnerStatusListCredential::create(issuer, status_purpose, inner_vcs).await?, + )) } pub fn get_base(&self) -> Result> { diff --git a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs index bb6d69cd..df04427e 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs @@ -33,7 +33,7 @@ pub struct VerifiableCredential { } impl VerifiableCredential { - pub fn create( + pub async fn create( json_serialized_issuer: String, json_serialized_credential_subject: String, options: Option, @@ -61,7 +61,8 @@ impl VerifiableCredential { }; let inner_vc = - InnerVerifiableCredential::create(issuer, credential_subject, Some(inner_options))?; + InnerVerifiableCredential::create(issuer, credential_subject, Some(inner_options)) + .await?; Ok(Self { inner_vc, @@ -90,8 +91,8 @@ impl VerifiableCredential { }) } - pub fn from_vc_jwt(vc_jwt: String, verify: bool) -> Result { - let inner_vc = InnerVerifiableCredential::from_vc_jwt(&vc_jwt, verify)?; + pub async fn from_vc_jwt(vc_jwt: String, verify: bool) -> Result { + let inner_vc = InnerVerifiableCredential::from_vc_jwt(&vc_jwt, verify).await?; let json_serialized_issuer = serde_json::to_string(&inner_vc.issuer)?; let json_serialized_credential_subject = serde_json::to_string(&inner_vc.credential_subject)?; diff --git a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs index a8e8f3e3..c56627a4 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs @@ -21,7 +21,7 @@ pub struct VerifiablePresentation { } impl VerifiablePresentation { - pub fn create( + pub async fn create( holder: String, vc_jwts: Vec, options: Option, @@ -44,7 +44,8 @@ impl VerifiablePresentation { additional_data, }; - let inner_vp = InnerVerifiablePresentation::create(holder, vc_jwts, Some(inner_options))?; + let inner_vp = + InnerVerifiablePresentation::create(holder, vc_jwts, Some(inner_options)).await?; Ok(Self { inner_vp }) } @@ -67,8 +68,8 @@ impl VerifiablePresentation { }) } - pub fn from_vp_jwt(vp_jwt: String, verify: bool) -> Result { - let inner_vp = InnerVerifiablePresentation::from_vp_jwt(&vp_jwt, verify)?; + pub async fn from_vp_jwt(vp_jwt: String, verify: bool) -> Result { + let inner_vp = InnerVerifiablePresentation::from_vp_jwt(&vp_jwt, verify).await?; Ok(Self { inner_vp }) } diff --git a/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs b/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs index e6fa6334..bf92614b 100644 --- a/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs +++ b/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs @@ -9,8 +9,8 @@ use web5::dids::{ methods::did_dht::{DidDht as InnerDidDht, DidDhtCreateOptions as InnerDidDhtCreateOptions}, }; -pub fn did_dht_resolve(uri: &str, gateway_url: Option) -> Arc { - let resolution_result = InnerDidDht::resolve(uri, gateway_url); +pub async fn did_dht_resolve(uri: &str, gateway_url: Option) -> Arc { + let resolution_result = InnerDidDht::resolve(uri, gateway_url).await; Arc::new(ResolutionResult(resolution_result)) } @@ -25,7 +25,7 @@ pub struct DidDhtCreateOptions { pub verification_method: Option>, } -pub fn did_dht_create(options: Option) -> Result> { +pub async fn did_dht_create(options: Option) -> Result> { let inner_options = options.map(|o| InnerDidDhtCreateOptions { publish: o.publish, gateway_url: o.gateway_url, @@ -39,10 +39,13 @@ pub fn did_dht_create(options: Option) -> Result, gateway_url: Option) -> Result<()> { - Ok(InnerDidDht::publish(bearer_did.0.clone(), gateway_url)?) +pub async fn did_dht_publish( + bearer_did: Arc, + gateway_url: Option, +) -> Result<()> { + Ok(InnerDidDht::publish(bearer_did.0.clone(), gateway_url).await?) } diff --git a/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs b/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs index 6b1363af..d72320d3 100644 --- a/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs +++ b/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs @@ -14,8 +14,8 @@ use web5::{ }, }; -pub fn did_web_resolve(uri: &str) -> Arc { - let resolution_result = InnerDidWeb::resolve(uri); +pub async fn did_web_resolve(uri: &str) -> Arc { + let resolution_result = InnerDidWeb::resolve(uri).await; Arc::new(ResolutionResult(resolution_result)) } diff --git a/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs b/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs index 4eb0184d..fc3c9a5c 100644 --- a/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs +++ b/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs @@ -3,8 +3,8 @@ use web5::dids::resolution::resolution_result::ResolutionResult as InnerResoluti pub struct ResolutionResult(pub InnerResolutionResult); impl ResolutionResult { - pub fn resolve(uri: &str) -> Self { - Self(InnerResolutionResult::resolve(uri)) + pub async fn resolve(uri: &str) -> Self { + Self(InnerResolutionResult::resolve(uri).await) } pub fn get_data(&self) -> InnerResolutionResult { From 979128331488556ce3b0318d3778468fb4e4270b Mon Sep 17 00:00:00 2001 From: Kendall Weihe Date: Mon, 30 Sep 2024 14:07:14 -0400 Subject: [PATCH 4/9] Add async to http-std --- crates/http-std/Cargo.toml | 1 + crates/http-std/src/client.rs | 4 +++- crates/http-std/src/default_client.rs | 4 +++- crates/http-std/src/lib.rs | 9 ++++++--- crates/http-std/src/reqwest_client.rs | 13 +++++++------ crates/web5/src/credentials/credential_schema.rs | 2 +- crates/web5/src/dids/methods/did_dht/mod.rs | 13 ++++++++----- crates/web5/src/dids/methods/did_web/resolver.rs | 1 + 8 files changed, 30 insertions(+), 17 deletions(-) diff --git a/crates/http-std/Cargo.toml b/crates/http-std/Cargo.toml index b9dd2e2a..05efdeba 100644 --- a/crates/http-std/Cargo.toml +++ b/crates/http-std/Cargo.toml @@ -7,6 +7,7 @@ repository.workspace = true license-file.workspace = true [dependencies] +async-trait = "0.1.83" lazy_static = { workspace = true } thiserror = { workspace = true } url = "2.5.0" diff --git a/crates/http-std/src/client.rs b/crates/http-std/src/client.rs index a92bdb52..8444d6c4 100644 --- a/crates/http-std/src/client.rs +++ b/crates/http-std/src/client.rs @@ -1,8 +1,10 @@ use crate::Result; +use async_trait::async_trait; use std::collections::HashMap; +#[async_trait] pub trait Client: Send + Sync { - fn fetch(&self, url: &str, options: Option) -> Result; + async fn fetch(&self, url: &str, options: Option) -> Result; } #[derive(Default)] diff --git a/crates/http-std/src/default_client.rs b/crates/http-std/src/default_client.rs index ea5424a1..f0c2289f 100644 --- a/crates/http-std/src/default_client.rs +++ b/crates/http-std/src/default_client.rs @@ -1,4 +1,5 @@ use crate::{Client, Error, FetchOptions, Method, Response, Result}; +use async_trait::async_trait; use rustls::pki_types::ServerName; use rustls::{ClientConfig, ClientConnection, RootCertStore, StreamOwned}; use rustls_native_certs::load_native_certs; @@ -158,8 +159,9 @@ fn parse_response(response_bytes: &[u8]) -> Result { pub struct DefaultClient; +#[async_trait] impl Client for DefaultClient { - fn fetch(&self, url: &str, options: Option) -> Result { + async fn fetch(&self, url: &str, options: Option) -> Result { let options = options.unwrap_or_default(); let destination = parse_destination(url)?; let method = options.method.unwrap_or(Method::Get); diff --git a/crates/http-std/src/lib.rs b/crates/http-std/src/lib.rs index 53b820b6..7c23bab3 100644 --- a/crates/http-std/src/lib.rs +++ b/crates/http-std/src/lib.rs @@ -5,6 +5,8 @@ mod error; #[cfg(not(target_arch = "wasm32"))] mod reqwest_client; +#[cfg(target_arch = "wasm32")] +use async_trait::async_trait; use lazy_static::lazy_static; use std::sync::{Arc, Mutex}; @@ -32,17 +34,18 @@ pub fn get_client() -> Arc { client.clone() } -pub fn fetch(url: &str, options: Option) -> Result { +pub async fn fetch(url: &str, options: Option) -> Result { let client = get_client(); - client.fetch(url, options) + client.fetch(url, options).await } #[cfg(target_arch = "wasm32")] pub struct ForeignEmptyClient; #[cfg(target_arch = "wasm32")] +#[async_trait] impl Client for ForeignEmptyClient { - fn fetch(&self, _url: &str, _options: Option) -> Result { + async fn fetch(&self, _url: &str, _options: Option) -> Result { return Err(Error::Unknown("global client not set".to_string())); } } diff --git a/crates/http-std/src/reqwest_client.rs b/crates/http-std/src/reqwest_client.rs index e9391c10..b45551b8 100644 --- a/crates/http-std/src/reqwest_client.rs +++ b/crates/http-std/src/reqwest_client.rs @@ -1,23 +1,24 @@ use crate::{Client, FetchOptions, Method, Response, Result}; -use reqwest::blocking::Client as ReqwestBlockingClient; +use async_trait::async_trait; use reqwest::header::HeaderMap; use std::collections::HashMap; use std::convert::TryFrom; pub struct ReqwestClient { - client: ReqwestBlockingClient, + client: reqwest::Client, } impl ReqwestClient { pub fn new() -> Self { ReqwestClient { - client: ReqwestBlockingClient::new(), + client: reqwest::Client::new(), } } } +#[async_trait] impl Client for ReqwestClient { - fn fetch(&self, url: &str, options: Option) -> Result { + async fn fetch(&self, url: &str, options: Option) -> Result { let options = options.unwrap_or_default(); let method = options.method.unwrap_or(Method::Get).to_string(); @@ -43,7 +44,7 @@ impl Client for ReqwestClient { req = req.body(body); } - let res = req.send().map_err(crate::Error::from)?; + let res = req.send().await.map_err(crate::Error::from)?; let status_code = res.status().as_u16(); let mut headers = HashMap::new(); @@ -51,7 +52,7 @@ impl Client for ReqwestClient { headers.insert(key.to_string(), value.to_str().unwrap().to_string()); } - let body = res.bytes().map_err(crate::Error::from)?.to_vec(); + let body = res.bytes().await.map_err(crate::Error::from)?.to_vec(); Ok(Response { status_code, diff --git a/crates/web5/src/credentials/credential_schema.rs b/crates/web5/src/credentials/credential_schema.rs index 4cee5cb8..7af3159c 100644 --- a/crates/web5/src/credentials/credential_schema.rs +++ b/crates/web5/src/credentials/credential_schema.rs @@ -28,7 +28,7 @@ pub(crate) async fn validate_credential_schema( let url = &credential_schema.id; - let response = http_std::fetch(url, None)?; + let response = http_std::fetch(url, None).await?; if !(200..300).contains(&response.status_code) { return Err(Web5Error::JsonSchema(format!( diff --git a/crates/web5/src/dids/methods/did_dht/mod.rs b/crates/web5/src/dids/methods/did_dht/mod.rs index af93222d..3be608a2 100644 --- a/crates/web5/src/dids/methods/did_dht/mod.rs +++ b/crates/web5/src/dids/methods/did_dht/mod.rs @@ -207,7 +207,8 @@ impl DidDht { ), body: Some(body), }), - )?; + ) + .await?; if response.status_code != 200 { return Err(Web5Error::Network( "failed to PUT DID to mainline".to_string(), @@ -242,7 +243,7 @@ impl DidDht { /// /// Returns a `ResolutionMetadataError` if the DID cannot be resolved or verified. pub async fn resolve(uri: &str, gateway_url: Option) -> ResolutionResult { - let result: std::result::Result = (|| { + let result: std::result::Result = async { // check did method and decode id let did = Did::parse(uri).map_err(|_| ResolutionMetadataError::InvalidDid)?; if did.method != "dht" { @@ -264,8 +265,9 @@ impl DidDht { did.id.trim_start_matches('/') ); - let response = - http_std::fetch(&url, None).map_err(|_| ResolutionMetadataError::InternalError)?; + let response = http_std::fetch(&url, None) + .await // todo here + .map_err(|_| ResolutionMetadataError::InternalError)?; if response.status_code == 404 { return Err(ResolutionMetadataError::NotFound); @@ -291,7 +293,8 @@ impl DidDht { document: Some(document), ..Default::default() }) - })(); + } + .await; match result { Ok(resolution_result) => resolution_result, diff --git a/crates/web5/src/dids/methods/did_web/resolver.rs b/crates/web5/src/dids/methods/did_web/resolver.rs index eca71a40..76dc1bee 100644 --- a/crates/web5/src/dids/methods/did_web/resolver.rs +++ b/crates/web5/src/dids/methods/did_web/resolver.rs @@ -44,6 +44,7 @@ impl Resolver { pub async fn resolve(&self) -> Result { let response = http_std::fetch(&self.http_url, None) + .await .map_err(|_| ResolutionMetadataError::InternalError)?; if response.status_code == 404 { From fe565b41f9c6343d4533448bbc85e98f8be6125e Mon Sep 17 00:00:00 2001 From: Kendall Weihe Date: Mon, 30 Sep 2024 14:14:37 -0400 Subject: [PATCH 5/9] Make all tests pass --- crates/web5/src/credentials/create.rs | 14 +++++++------- .../src/credentials/verifiable_presentation_1_1.rs | 8 ++++---- crates/web5/src/dids/methods/did_dht/mod.rs | 12 ++++++------ crates/web5/src/dids/methods/did_web/mod.rs | 2 +- .../web5/src/dids/resolution/resolution_result.rs | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/crates/web5/src/credentials/create.rs b/crates/web5/src/credentials/create.rs index a897c04b..5c824466 100644 --- a/crates/web5/src/credentials/create.rs +++ b/crates/web5/src/credentials/create.rs @@ -617,7 +617,7 @@ mod tests { #[tokio::test] async fn test_schema_resolve_non_success() { - let mut mock_server = Server::new(); + let mut mock_server = Server::new_async().await; let url = mock_server.url(); let _ = mock_server @@ -648,7 +648,7 @@ mod tests { #[tokio::test] async fn test_schema_resolve_invalid_response_body() { - let mut mock_server = Server::new(); + let mut mock_server = Server::new_async().await; let url = mock_server.url(); let _ = mock_server @@ -681,7 +681,7 @@ mod tests { #[tokio::test] async fn test_schema_invalid_json_schema() { - let mut mock_server = Server::new(); + let mut mock_server = Server::new_async().await; let url = mock_server.url(); let _ = mock_server @@ -717,7 +717,7 @@ mod tests { #[tokio::test] async fn test_schema_do_not_support_draft04() { - let mut mock_server = Server::new(); + let mut mock_server = Server::new_async().await; let url = mock_server.url(); let _ = mock_server @@ -753,7 +753,7 @@ mod tests { #[tokio::test] async fn test_schema_do_not_support_draft06() { - let mut mock_server = Server::new(); + let mut mock_server = Server::new_async().await; let url = mock_server.url(); let _ = mock_server @@ -789,7 +789,7 @@ mod tests { #[tokio::test] async fn test_schema_fails_validation() { - let mut mock_server = Server::new(); + let mut mock_server = Server::new_async().await; let url = mock_server.url(); let _ = mock_server @@ -824,7 +824,7 @@ mod tests { async fn test_schema_example_from_spec() { // using Example 1 & Example 2 from here https://www.w3.org/TR/vc-json-schema/#jsonschema - let mut mock_server = Server::new(); + let mut mock_server = Server::new_async().await; let url = mock_server.url(); let _ = mock_server diff --git a/crates/web5/src/credentials/verifiable_presentation_1_1.rs b/crates/web5/src/credentials/verifiable_presentation_1_1.rs index d35b6305..9cea372e 100644 --- a/crates/web5/src/credentials/verifiable_presentation_1_1.rs +++ b/crates/web5/src/credentials/verifiable_presentation_1_1.rs @@ -158,7 +158,7 @@ impl VerifiablePresentation { /// * `options` - Optional parameters for creating the presentation, such as context or expiration. /// /// # Example - /// ```rust + /// ```ignore /// use web5::credentials::VerifiablePresentation; /// use web5::dids::methods::did_jwk::DidJwk; /// @@ -170,7 +170,7 @@ impl VerifiablePresentation { /// holder_bearer_did.did.uri.clone(), /// vc_jwts, /// None, - /// ).unwrap(); + /// ).await.unwrap(); /// ``` pub async fn create( holder: String, @@ -219,11 +219,11 @@ impl VerifiablePresentation { /// against the signature and validating the Data Model. /// /// # Example - /// ```rust + /// ```ignore /// use web5::credentials::VerifiablePresentation; /// /// let vp_jwt = r#"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZDI1NTE5Iiwia2lkIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKYWNUaFJaR05XYlRrMlluZGpRa3R3WVhwV2RGQmlkekJ6U1c4NE0wbG9XRXAyVGtoV1VIUnpWWFYzSW4wIzAifQ.eyJpc3MiOiJkaWQ6andrOmV5SmhiR2NpT2lKRlpESTFOVEU1SWl3aWEzUjVJam9pVDB0UUlpd2lZM0oySWpvaVJXUXlOVFV4T1NJc0luZ2lPaUphY1RoUlpHTldiVGsyWW5kalFrdHdZWHBXZEZCaWR6QnpTVzg0TTBsb1dFcDJUa2hXVUhSelZYVjNJbjAiLCJqdGkiOiJ1cm46dXVpZDowZDg5YTcxMS0zNTdjLTQzNTQtOWYzMS02OWQ0NDE1NWQ1ZTMiLCJuYmYiOjE3MjYyMzQwODEsImlhdCI6MTcyNjIzNDA4MSwidnAiOnsiaXNzdWFuY2VEYXRlIjoiMjAyNC0wOS0xM1QxMzoyODowMVoiLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVQcmVzZW50YXRpb24iXSwidmVyaWZpYWJsZUNyZWRlbnRpYWwiOlsiZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKRlpESTFOVEU1SWl3aWEybGtJam9pWkdsa09tcDNhenBsZVVwb1lrZGphVTlwU2taYVJFa3hUbFJGTlVscGQybGhNMUkxU1dwdmFWUXdkRkZKYVhkcFdUTktNa2xxYjJsU1YxRjVUbFJWZUU5VFNYTkpibWRwVDJsS1VWRnNiRTVTYlRreFdUQnpOVk16WkZCVFNGSjZUbXBvVTA1RlZuZGpiVmw1VFhwT1RFNVVVazFOVmxaSlRqRlNTV05VVW1aaE1HaE9TVzR3SXpBaWZRLmV5SnBjM01pT2lKa2FXUTZhbmRyT21WNVNtaGlSMk5wVDJsS1JscEVTVEZPVkVVMVNXbDNhV0V6VWpWSmFtOXBWREIwVVVscGQybFpNMG95U1dwdmFWSlhVWGxPVkZWNFQxTkpjMGx1WjJsUGFVcFJVV3hzVGxKdE9URlpNSE0xVXpOa1VGTklVbnBPYW1oVFRrVldkMk50V1hsTmVrNU1UbFJTVFUxV1ZrbE9NVkpKWTFSU1ptRXdhRTVKYmpBaUxDSnFkR2tpT2lKMWNtNDZkWFZwWkRwaE1UaGlOREppWVMwMk1UVTVMVFExWVRrdFlXTXpZaTB5TnpaaVlqQmtORGRpWmpZaUxDSnpkV0lpT2lKa2FXUTZaR2gwT201bk5HaHRjWFJ5WjNWcWIzZzBZV2R3WmpodmEzaHBhRzU1ZVRGNmNXNXhPVGR4Wm1WeE1UVjRPRzloY2pkNVpYQjZhSGtpTENKdVltWWlPakUzTWpZeU16RTVOeklzSW1saGRDSTZNVGN5TmpJek1UazNNaXdpZG1NaU9uc2lRR052Ym5SbGVIUWlPbHNpYUhSMGNITTZMeTkzZDNjdWR6TXViM0puTHpJd01UZ3ZZM0psWkdWdWRHbGhiSE12ZGpFaVhTd2lZM0psWkdWdWRHbGhiRk4xWW1wbFkzUWlPbnNpYVdRaU9pSmthV1E2WkdoME9tNW5OR2h0Y1hSeVozVnFiM2cwWVdkd1pqaHZhM2hwYUc1NWVURjZjVzV4T1RkeFptVnhNVFY0T0c5aGNqZDVaWEI2YUhraWZTd2lhWE56ZFdWeUlqb2laR2xrT21wM2F6cGxlVXBvWWtkamFVOXBTa1phUkVreFRsUkZOVWxwZDJsaE0xSTFTV3B2YVZRd2RGRkphWGRwV1ROS01rbHFiMmxTVjFGNVRsUlZlRTlUU1hOSmJtZHBUMmxLVVZGc2JFNVNiVGt4V1RCek5WTXpaRkJUU0ZKNlRtcG9VMDVGVm5kamJWbDVUWHBPVEU1VVVrMU5WbFpKVGpGU1NXTlVVbVpoTUdoT1NXNHdJaXdpYVhOemRXRnVZMlZFWVhSbElqb2lNakF5TkMwd09TMHhNMVF4TWpvMU1qbzFNbG9pTENKMGVYQmxJanBiSWxabGNtbG1hV0ZpYkdWRGNtVmtaVzUwYVdGc0lsMHNJbWxrSWpvaWRYSnVPblYxYVdRNllURTRZalF5WW1FdE5qRTFPUzAwTldFNUxXRmpNMkl0TWpjMlltSXdaRFEzWW1ZMkluMTkuaUNkN1FsQWlCTkxDZnZ0VWJCdGstOVBUcUZmdWNxWjQ0S3hoRnZqR2NSU2prR0pyNjEwLTBqTFZzTlNBX0NQOGdibFljZncxZTVqeDNwR2VFckMtQnciXSwiaG9sZGVyIjoiZGlkOmp3azpleUpoYkdjaU9pSkZaREkxTlRFNUlpd2lhM1I1SWpvaVQwdFFJaXdpWTNKMklqb2lSV1F5TlRVeE9TSXNJbmdpT2lKYWNUaFJaR05XYlRrMlluZGpRa3R3WVhwV2RGQmlkekJ6U1c4NE0wbG9XRXAyVGtoV1VIUnpWWFYzSW4wIiwiaWQiOiJ1cm46dXVpZDowZDg5YTcxMS0zNTdjLTQzNTQtOWYzMS02OWQ0NDE1NWQ1ZTMifX0.f-kdfbIIms3Gg2dMKUMayeU1rQnaO_o0io33kLzy-uPqI6vsdsJZvSmDIilx7scRqlia7Pmnnj6bnF2x8F2fAw"#; - /// let verifiable_presentation = VerifiablePresentation::from_vp_jwt(vp_jwt, true).unwrap(); + /// let verifiable_presentation = VerifiablePresentation::from_vp_jwt(vp_jwt, true).await.unwrap(); /// ``` pub async fn from_vp_jwt(vp_jwt: &str, verify: bool) -> Result { let verifiable_presentation = decode_vp_jwt(vp_jwt, verify).await?; diff --git a/crates/web5/src/dids/methods/did_dht/mod.rs b/crates/web5/src/dids/methods/did_dht/mod.rs index 3be608a2..773e8c44 100644 --- a/crates/web5/src/dids/methods/did_dht/mod.rs +++ b/crates/web5/src/dids/methods/did_dht/mod.rs @@ -332,7 +332,7 @@ mod tests { #[tokio::test] async fn test_can_specify_publish_and_gateway_url() { - let mut mock_server = mockito::Server::new(); + let mut mock_server = mockito::Server::new_async().await; let gateway_url = mock_server.url(); let mock = mock_server @@ -441,7 +441,7 @@ mod tests { #[tokio::test] async fn test_can_specify_gateway_url() { - let mut mock_server = mockito::Server::new(); + let mut mock_server = mockito::Server::new_async().await; let gateway_url = mock_server.url(); let mock = mock_server @@ -471,7 +471,7 @@ mod tests { #[tokio::test] async fn test_can_handle_network_error() { - let mut mock_server = mockito::Server::new(); + let mut mock_server = mockito::Server::new_async().await; let gateway_url = mock_server.url(); let mock = mock_server @@ -532,7 +532,7 @@ mod tests { .await .unwrap(); - let mut mock_server = mockito::Server::new(); + let mut mock_server = mockito::Server::new_async().await; let gateway_url = mock_server.url(); let mock = mock_server @@ -560,7 +560,7 @@ mod tests { .await .unwrap(); - let mut mock_server = mockito::Server::new(); + let mut mock_server = mockito::Server::new_async().await; let gateway_url = mock_server.url(); let mock = mock_server @@ -581,7 +581,7 @@ mod tests { #[tokio::test] async fn test_can_create_then_resolve() { - let mut mock_server = mockito::Server::new(); + let mut mock_server = mockito::Server::new_async().await; let gateway_url = mock_server.url(); let published_body = Arc::new(Mutex::new(Vec::new())); diff --git a/crates/web5/src/dids/methods/did_web/mod.rs b/crates/web5/src/dids/methods/did_web/mod.rs index 7115de55..931e0f3a 100644 --- a/crates/web5/src/dids/methods/did_web/mod.rs +++ b/crates/web5/src/dids/methods/did_web/mod.rs @@ -461,7 +461,7 @@ mod tests { #[tokio::test] async fn test_create_then_resolve() { - let mut mock_server = Server::new(); + let mut mock_server = Server::new_async().await; let url = mock_server.url(); let result = DidWeb::create(&url, None); diff --git a/crates/web5/src/dids/resolution/resolution_result.rs b/crates/web5/src/dids/resolution/resolution_result.rs index 0cc45624..bd154980 100644 --- a/crates/web5/src/dids/resolution/resolution_result.rs +++ b/crates/web5/src/dids/resolution/resolution_result.rs @@ -118,7 +118,7 @@ mod tests { #[tokio::test] async fn test_did_web() { - let mut mock_server = Server::new(); + let mut mock_server = Server::new_async().await; let url = mock_server.url(); let bearer_did = DidWeb::create(&url, None).unwrap(); From 6e71fb862a9d510cba563a2281bfc9e87365b887 Mon Sep 17 00:00:00 2001 From: Kendall Weihe Date: Mon, 30 Sep 2024 15:23:36 -0400 Subject: [PATCH 6/9] Use futures block_on at uniffi layer --- bindings/web5_uniffi/src/web5.udl | 22 +++++++++---------- bindings/web5_uniffi_wrapper/Cargo.toml | 1 + .../credentials/presentation_definition.rs | 12 +++++----- .../src/credentials/status_list_credential.rs | 11 ++++++---- .../credentials/verifiable_credential_1_1.rs | 15 ++++++++----- .../verifiable_presentation_1_1.rs | 14 +++++++----- .../src/dids/methods/did_dht.rs | 19 ++++++++-------- .../src/dids/methods/did_web.rs | 5 +++-- .../src/dids/resolution/resolution_result.rs | 5 +++-- 9 files changed, 57 insertions(+), 47 deletions(-) diff --git a/bindings/web5_uniffi/src/web5.udl b/bindings/web5_uniffi/src/web5.udl index 74d5749b..33a835b9 100644 --- a/bindings/web5_uniffi/src/web5.udl +++ b/bindings/web5_uniffi/src/web5.udl @@ -8,14 +8,12 @@ namespace web5 { [Throws=Web5Error] BearerDid did_web_create(string domain, DidWebCreateOptions? options); - [Async] ResolutionResult did_web_resolve([ByRef] string uri); - [Throws=Web5Error, Async] + [Throws=Web5Error] BearerDid did_dht_create(DidDhtCreateOptions? options); - [Throws=Web5Error, Async] + [Throws=Web5Error] void did_dht_publish(BearerDid bearer_did, string? gateway_url); - [Async] ResolutionResult did_dht_resolve([ByRef] string uri, string? gateway_url); }; @@ -192,7 +190,7 @@ dictionary ResolutionResultData { }; interface ResolutionResult { - [Name=resolve, Async] + [Name=resolve] constructor([ByRef] string uri); ResolutionResultData get_data(); }; @@ -258,9 +256,9 @@ interface PresentationDefinition { constructor(string json_serialized_presentation_definition); [Throws=Web5Error] string get_json_serialized_presentation_definition(); - [Throws=Web5Error, Async] + [Throws=Web5Error] sequence select_credentials([ByRef] sequence vc_jwts); - [Throws=Web5Error, Async] + [Throws=Web5Error] string create_presentation_from_credentials([ByRef] sequence vc_jwts); }; @@ -276,7 +274,7 @@ dictionary VerifiableCredentialCreateOptionsData { }; interface VerifiableCredential { - [Throws=Web5Error, Name=create, Async] + [Throws=Web5Error, Name=create] constructor( string json_serialized_issuer, string json_serialized_credential_subject, @@ -284,7 +282,7 @@ interface VerifiableCredential { ); [Throws=Web5Error] VerifiableCredentialData get_data(); - [Throws=Web5Error, Name=from_vc_jwt, Async] + [Throws=Web5Error, Name=from_vc_jwt] constructor(string vc_jwt, boolean verify); [Throws=Web5Error] string sign(BearerDid bearer_did, string? verification_method_id); @@ -317,7 +315,7 @@ dictionary CredentialStatusData { }; interface StatusListCredential { - [Throws=Web5Error, Name=create, Async] + [Throws=Web5Error, Name=create] constructor( string json_serialized_issuer, string status_purpose, @@ -340,7 +338,7 @@ dictionary VerifiablePresentationCreateOptionsData { }; interface VerifiablePresentation { - [Throws=Web5Error, Name=create, Async] + [Throws=Web5Error, Name=create] constructor( string holder, sequence vc_jwts, @@ -350,7 +348,7 @@ interface VerifiablePresentation { [Throws=Web5Error] VerifiablePresentationData get_data(); - [Throws=Web5Error, Name=from_vp_jwt, Async] + [Throws=Web5Error, Name=from_vp_jwt] constructor(string vp_jwt, boolean verify); [Throws=Web5Error] diff --git a/bindings/web5_uniffi_wrapper/Cargo.toml b/bindings/web5_uniffi_wrapper/Cargo.toml index b7f6f61c..956c43e4 100644 --- a/bindings/web5_uniffi_wrapper/Cargo.toml +++ b/bindings/web5_uniffi_wrapper/Cargo.toml @@ -7,6 +7,7 @@ repository.workspace = true license-file.workspace = true [dependencies] +futures = "0.3.30" serde_json = { workspace = true } thiserror = { workspace = true } web5 = { path = "../../crates/web5" } \ No newline at end of file diff --git a/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs b/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs index 7975bda0..3e8c50d3 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs @@ -1,4 +1,5 @@ use crate::errors::Result; +use futures::executor::block_on; use web5::credentials::presentation_definition::PresentationDefinition as InnerPresentationDefinition; pub struct PresentationDefinition(pub InnerPresentationDefinition); @@ -12,15 +13,12 @@ impl PresentationDefinition { Ok(Self(inner_presentation_definition)) } - pub async fn select_credentials(&self, vc_jwts: &Vec) -> Result> { - Ok(self.0.select_credentials(vc_jwts).await?) + pub fn select_credentials(&self, vc_jwts: &Vec) -> Result> { + Ok(block_on(self.0.select_credentials(vc_jwts))?) } - pub async fn create_presentation_from_credentials( - &self, - vc_jwts: &Vec, - ) -> Result { - let presentation_result = self.0.create_presentation_from_credentials(vc_jwts).await?; + pub fn create_presentation_from_credentials(&self, vc_jwts: &Vec) -> Result { + let presentation_result = block_on(self.0.create_presentation_from_credentials(vc_jwts))?; let json_serialized_presentation_result = serde_json::to_string(&presentation_result)?; Ok(json_serialized_presentation_result) diff --git a/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs b/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs index b75659f1..f88265bb 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs @@ -1,5 +1,6 @@ use crate::credentials::verifiable_credential_1_1::VerifiableCredential; use crate::errors::Result; +use futures::executor::block_on; use std::sync::Arc; use web5::credentials::Issuer; use web5::{ @@ -10,7 +11,7 @@ use web5::{ pub struct StatusListCredential(pub InnerStatusListCredential); impl StatusListCredential { - pub async fn create( + pub fn create( json_serialized_issuer: String, status_purpose: String, credentials_to_disable: Option>>, @@ -25,9 +26,11 @@ impl StatusListCredential { .collect() }); - Ok(Self( - InnerStatusListCredential::create(issuer, status_purpose, inner_vcs).await?, - )) + Ok(Self(block_on(InnerStatusListCredential::create( + issuer, + status_purpose, + inner_vcs, + ))?)) } pub fn get_base(&self) -> Result> { diff --git a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs index df04427e..1f08acc1 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs @@ -1,4 +1,5 @@ use crate::{dids::bearer_did::BearerDid, errors::Result}; +use futures::executor::block_on; use std::{sync::Arc, time::SystemTime}; use web5::credentials::CredentialStatus; use web5::credentials::Issuer; @@ -33,7 +34,7 @@ pub struct VerifiableCredential { } impl VerifiableCredential { - pub async fn create( + pub fn create( json_serialized_issuer: String, json_serialized_credential_subject: String, options: Option, @@ -60,9 +61,11 @@ impl VerifiableCredential { evidence, }; - let inner_vc = - InnerVerifiableCredential::create(issuer, credential_subject, Some(inner_options)) - .await?; + let inner_vc = block_on(InnerVerifiableCredential::create( + issuer, + credential_subject, + Some(inner_options), + ))?; Ok(Self { inner_vc, @@ -91,8 +94,8 @@ impl VerifiableCredential { }) } - pub async fn from_vc_jwt(vc_jwt: String, verify: bool) -> Result { - let inner_vc = InnerVerifiableCredential::from_vc_jwt(&vc_jwt, verify).await?; + pub fn from_vc_jwt(vc_jwt: String, verify: bool) -> Result { + let inner_vc = block_on(InnerVerifiableCredential::from_vc_jwt(&vc_jwt, verify))?; let json_serialized_issuer = serde_json::to_string(&inner_vc.issuer)?; let json_serialized_credential_subject = serde_json::to_string(&inner_vc.credential_subject)?; diff --git a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs index c56627a4..c9831dfb 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs @@ -1,4 +1,5 @@ use crate::{dids::bearer_did::BearerDid, errors::Result}; +use futures::executor::block_on; use serde_json::Value; use std::collections::HashMap; use std::sync::Arc; @@ -21,7 +22,7 @@ pub struct VerifiablePresentation { } impl VerifiablePresentation { - pub async fn create( + pub fn create( holder: String, vc_jwts: Vec, options: Option, @@ -44,8 +45,11 @@ impl VerifiablePresentation { additional_data, }; - let inner_vp = - InnerVerifiablePresentation::create(holder, vc_jwts, Some(inner_options)).await?; + let inner_vp = block_on(InnerVerifiablePresentation::create( + holder, + vc_jwts, + Some(inner_options), + ))?; Ok(Self { inner_vp }) } @@ -68,8 +72,8 @@ impl VerifiablePresentation { }) } - pub async fn from_vp_jwt(vp_jwt: String, verify: bool) -> Result { - let inner_vp = InnerVerifiablePresentation::from_vp_jwt(&vp_jwt, verify).await?; + pub fn from_vp_jwt(vp_jwt: String, verify: bool) -> Result { + let inner_vp = block_on(InnerVerifiablePresentation::from_vp_jwt(&vp_jwt, verify))?; Ok(Self { inner_vp }) } diff --git a/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs b/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs index bf92614b..4973c861 100644 --- a/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs +++ b/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs @@ -3,14 +3,15 @@ use crate::{ dids::{bearer_did::BearerDid, resolution::resolution_result::ResolutionResult}, errors::Result, }; +use futures::executor::block_on; use std::sync::Arc; use web5::dids::{ data_model::{service::Service, verification_method::VerificationMethod}, methods::did_dht::{DidDht as InnerDidDht, DidDhtCreateOptions as InnerDidDhtCreateOptions}, }; -pub async fn did_dht_resolve(uri: &str, gateway_url: Option) -> Arc { - let resolution_result = InnerDidDht::resolve(uri, gateway_url).await; +pub fn did_dht_resolve(uri: &str, gateway_url: Option) -> Arc { + let resolution_result = block_on(InnerDidDht::resolve(uri, gateway_url)); Arc::new(ResolutionResult(resolution_result)) } @@ -25,7 +26,7 @@ pub struct DidDhtCreateOptions { pub verification_method: Option>, } -pub async fn did_dht_create(options: Option) -> Result> { +pub fn did_dht_create(options: Option) -> Result> { let inner_options = options.map(|o| InnerDidDhtCreateOptions { publish: o.publish, gateway_url: o.gateway_url, @@ -39,13 +40,13 @@ pub async fn did_dht_create(options: Option) -> Result, - gateway_url: Option, -) -> Result<()> { - Ok(InnerDidDht::publish(bearer_did.0.clone(), gateway_url).await?) +pub fn did_dht_publish(bearer_did: Arc, gateway_url: Option) -> Result<()> { + Ok(block_on(InnerDidDht::publish( + bearer_did.0.clone(), + gateway_url, + ))?) } diff --git a/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs b/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs index d72320d3..42c6c66e 100644 --- a/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs +++ b/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs @@ -3,6 +3,7 @@ use crate::{ dids::{bearer_did::BearerDid, resolution::resolution_result::ResolutionResult}, errors::Result, }; +use futures::executor::block_on; use std::sync::Arc; use web5::{ crypto::dsa::Dsa, @@ -14,8 +15,8 @@ use web5::{ }, }; -pub async fn did_web_resolve(uri: &str) -> Arc { - let resolution_result = InnerDidWeb::resolve(uri).await; +pub fn did_web_resolve(uri: &str) -> Arc { + let resolution_result = block_on(InnerDidWeb::resolve(uri)); Arc::new(ResolutionResult(resolution_result)) } diff --git a/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs b/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs index fc3c9a5c..19a3a65d 100644 --- a/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs +++ b/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs @@ -1,10 +1,11 @@ +use futures::executor::block_on; use web5::dids::resolution::resolution_result::ResolutionResult as InnerResolutionResult; pub struct ResolutionResult(pub InnerResolutionResult); impl ResolutionResult { - pub async fn resolve(uri: &str) -> Self { - Self(InnerResolutionResult::resolve(uri).await) + pub fn resolve(uri: &str) -> Self { + Self(block_on(InnerResolutionResult::resolve(uri))) } pub fn get_data(&self) -> InnerResolutionResult { From 79989c1630fdc82fd9d10e1c1e0734e0aa7480bc Mon Sep 17 00:00:00 2001 From: Kendall Weihe Date: Mon, 30 Sep 2024 15:50:54 -0400 Subject: [PATCH 7/9] Add serde serialization to http types --- crates/http-std/Cargo.toml | 1 + crates/http-std/src/client.rs | 35 ++++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/crates/http-std/Cargo.toml b/crates/http-std/Cargo.toml index 05efdeba..4b85f61d 100644 --- a/crates/http-std/Cargo.toml +++ b/crates/http-std/Cargo.toml @@ -8,6 +8,7 @@ license-file.workspace = true [dependencies] async-trait = "0.1.83" +serde = { workspace = true } lazy_static = { workspace = true } thiserror = { workspace = true } url = "2.5.0" diff --git a/crates/http-std/src/client.rs b/crates/http-std/src/client.rs index 8444d6c4..5273e237 100644 --- a/crates/http-std/src/client.rs +++ b/crates/http-std/src/client.rs @@ -1,37 +1,54 @@ -use crate::Result; +use crate::{Error, Result}; use async_trait::async_trait; -use std::collections::HashMap; +use serde::{Deserialize, Serialize}; +use std::{collections::HashMap, fmt, str::FromStr}; #[async_trait] pub trait Client: Send + Sync { async fn fetch(&self, url: &str, options: Option) -> Result; } -#[derive(Default)] +#[derive(Default, Serialize, Deserialize)] pub struct FetchOptions { pub method: Option, pub headers: Option>, pub body: Option>, } +#[derive(Serialize, Deserialize)] pub struct Response { pub status_code: u16, pub headers: HashMap, pub body: Vec, } +#[derive(Serialize, Deserialize)] pub enum Method { Get, Post, Put, } -impl ToString for Method { - fn to_string(&self) -> String { - match self { - Method::Get => "GET".to_string(), - Method::Post => "POST".to_string(), - Method::Put => "PUT".to_string(), +impl fmt::Display for Method { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let method_str = match self { + Method::Get => "GET", + Method::Post => "POST", + Method::Put => "PUT", + }; + write!(f, "{}", method_str) + } +} + +impl FromStr for Method { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s.to_ascii_uppercase().as_ref() { + "GET" => Ok(Method::Get), + "POST" => Ok(Method::Post), + "PUT" => Ok(Method::Put), + _ => return Err(Error::Parameter(format!("unknown method {}", s))), } } } From 0e6bcda023f6791962b8de7cb1afad491f90465e Mon Sep 17 00:00:00 2001 From: Kendall Weihe Date: Mon, 30 Sep 2024 16:14:58 -0400 Subject: [PATCH 8/9] Fix linting --- crates/http-std/src/client.rs | 2 +- crates/http-std/src/default_client.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/http-std/src/client.rs b/crates/http-std/src/client.rs index 5273e237..e5673d7a 100644 --- a/crates/http-std/src/client.rs +++ b/crates/http-std/src/client.rs @@ -48,7 +48,7 @@ impl FromStr for Method { "GET" => Ok(Method::Get), "POST" => Ok(Method::Post), "PUT" => Ok(Method::Put), - _ => return Err(Error::Parameter(format!("unknown method {}", s))), + _ => Err(Error::Parameter(format!("unknown method {}", s))), } } } diff --git a/crates/http-std/src/default_client.rs b/crates/http-std/src/default_client.rs index f0c2289f..e7c2d56f 100644 --- a/crates/http-std/src/default_client.rs +++ b/crates/http-std/src/default_client.rs @@ -170,9 +170,7 @@ impl Client for DefaultClient { "{} {} HTTP/1.1\r\n\ Host: {}\r\n\ Connection: close\r\n", - method.to_string(), - destination.path, - destination.host, + method, destination.path, destination.host, ); if let Some(headers) = &options.headers { if !headers.is_empty() { From fbad4fa2a784f75e13701f2d2f75d8127fc13b29 Mon Sep 17 00:00:00 2001 From: Kendall Weihe Date: Mon, 30 Sep 2024 16:51:07 -0400 Subject: [PATCH 9/9] Fix kt tests --- bindings/web5_uniffi/src/web5.udl | 4 +++- bindings/web5_uniffi_wrapper/Cargo.toml | 2 +- .../credentials/presentation_definition.rs | 10 +++++---- .../src/credentials/status_list_credential.rs | 5 +++-- .../credentials/verifiable_credential_1_1.rs | 8 ++++--- .../verifiable_presentation_1_1.rs | 9 ++++---- .../src/dids/methods/did_dht.rs | 18 ++++++++-------- .../src/dids/methods/did_web.rs | 10 ++++----- .../src/dids/resolution/resolution_result.rs | 7 ++++--- bindings/web5_uniffi_wrapper/src/lib.rs | 10 +++++++++ .../src/main/kotlin/web5/sdk/rust/UniFFI.kt | 21 +++++++++++-------- 11 files changed, 63 insertions(+), 41 deletions(-) diff --git a/bindings/web5_uniffi/src/web5.udl b/bindings/web5_uniffi/src/web5.udl index 33a835b9..70128d7d 100644 --- a/bindings/web5_uniffi/src/web5.udl +++ b/bindings/web5_uniffi/src/web5.udl @@ -8,12 +8,14 @@ namespace web5 { [Throws=Web5Error] BearerDid did_web_create(string domain, DidWebCreateOptions? options); + [Throws=Web5Error] ResolutionResult did_web_resolve([ByRef] string uri); [Throws=Web5Error] BearerDid did_dht_create(DidDhtCreateOptions? options); [Throws=Web5Error] void did_dht_publish(BearerDid bearer_did, string? gateway_url); + [Throws=Web5Error] ResolutionResult did_dht_resolve([ByRef] string uri, string? gateway_url); }; @@ -190,7 +192,7 @@ dictionary ResolutionResultData { }; interface ResolutionResult { - [Name=resolve] + [Name=resolve, Throws=Web5Error] constructor([ByRef] string uri); ResolutionResultData get_data(); }; diff --git a/bindings/web5_uniffi_wrapper/Cargo.toml b/bindings/web5_uniffi_wrapper/Cargo.toml index 956c43e4..d8621950 100644 --- a/bindings/web5_uniffi_wrapper/Cargo.toml +++ b/bindings/web5_uniffi_wrapper/Cargo.toml @@ -7,7 +7,7 @@ repository.workspace = true license-file.workspace = true [dependencies] -futures = "0.3.30" serde_json = { workspace = true } thiserror = { workspace = true } +tokio = { version = "1.38.0", features = ["full"] } web5 = { path = "../../crates/web5" } \ No newline at end of file diff --git a/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs b/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs index 3e8c50d3..863d97be 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/presentation_definition.rs @@ -1,5 +1,4 @@ -use crate::errors::Result; -use futures::executor::block_on; +use crate::{errors::Result, get_rt}; use web5::credentials::presentation_definition::PresentationDefinition as InnerPresentationDefinition; pub struct PresentationDefinition(pub InnerPresentationDefinition); @@ -14,11 +13,14 @@ impl PresentationDefinition { } pub fn select_credentials(&self, vc_jwts: &Vec) -> Result> { - Ok(block_on(self.0.select_credentials(vc_jwts))?) + let rt = get_rt()?; + Ok(rt.block_on(self.0.select_credentials(vc_jwts))?) } pub fn create_presentation_from_credentials(&self, vc_jwts: &Vec) -> Result { - let presentation_result = block_on(self.0.create_presentation_from_credentials(vc_jwts))?; + let rt = get_rt()?; + let presentation_result = + rt.block_on(self.0.create_presentation_from_credentials(vc_jwts))?; let json_serialized_presentation_result = serde_json::to_string(&presentation_result)?; Ok(json_serialized_presentation_result) diff --git a/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs b/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs index f88265bb..70d3345f 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/status_list_credential.rs @@ -1,6 +1,6 @@ use crate::credentials::verifiable_credential_1_1::VerifiableCredential; use crate::errors::Result; -use futures::executor::block_on; +use crate::get_rt; use std::sync::Arc; use web5::credentials::Issuer; use web5::{ @@ -26,7 +26,8 @@ impl StatusListCredential { .collect() }); - Ok(Self(block_on(InnerStatusListCredential::create( + let rt = get_rt()?; + Ok(Self(rt.block_on(InnerStatusListCredential::create( issuer, status_purpose, inner_vcs, diff --git a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs index 1f08acc1..0cfa0306 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_credential_1_1.rs @@ -1,5 +1,5 @@ +use crate::get_rt; use crate::{dids::bearer_did::BearerDid, errors::Result}; -use futures::executor::block_on; use std::{sync::Arc, time::SystemTime}; use web5::credentials::CredentialStatus; use web5::credentials::Issuer; @@ -61,7 +61,8 @@ impl VerifiableCredential { evidence, }; - let inner_vc = block_on(InnerVerifiableCredential::create( + let rt = get_rt()?; + let inner_vc = rt.block_on(InnerVerifiableCredential::create( issuer, credential_subject, Some(inner_options), @@ -95,7 +96,8 @@ impl VerifiableCredential { } pub fn from_vc_jwt(vc_jwt: String, verify: bool) -> Result { - let inner_vc = block_on(InnerVerifiableCredential::from_vc_jwt(&vc_jwt, verify))?; + let rt = get_rt()?; + let inner_vc = rt.block_on(InnerVerifiableCredential::from_vc_jwt(&vc_jwt, verify))?; let json_serialized_issuer = serde_json::to_string(&inner_vc.issuer)?; let json_serialized_credential_subject = serde_json::to_string(&inner_vc.credential_subject)?; diff --git a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs index c9831dfb..be81aee4 100644 --- a/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs +++ b/bindings/web5_uniffi_wrapper/src/credentials/verifiable_presentation_1_1.rs @@ -1,5 +1,5 @@ +use crate::get_rt; use crate::{dids::bearer_did::BearerDid, errors::Result}; -use futures::executor::block_on; use serde_json::Value; use std::collections::HashMap; use std::sync::Arc; @@ -45,7 +45,8 @@ impl VerifiablePresentation { additional_data, }; - let inner_vp = block_on(InnerVerifiablePresentation::create( + let rt = get_rt()?; + let inner_vp = rt.block_on(InnerVerifiablePresentation::create( holder, vc_jwts, Some(inner_options), @@ -73,8 +74,8 @@ impl VerifiablePresentation { } pub fn from_vp_jwt(vp_jwt: String, verify: bool) -> Result { - let inner_vp = block_on(InnerVerifiablePresentation::from_vp_jwt(&vp_jwt, verify))?; - + let rt = get_rt()?; + let inner_vp = rt.block_on(InnerVerifiablePresentation::from_vp_jwt(&vp_jwt, verify))?; Ok(Self { inner_vp }) } diff --git a/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs b/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs index 4973c861..9c692f0b 100644 --- a/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs +++ b/bindings/web5_uniffi_wrapper/src/dids/methods/did_dht.rs @@ -2,17 +2,18 @@ use crate::{ crypto::key_manager::{KeyManager, ToInnerKeyManager}, dids::{bearer_did::BearerDid, resolution::resolution_result::ResolutionResult}, errors::Result, + get_rt, }; -use futures::executor::block_on; use std::sync::Arc; use web5::dids::{ data_model::{service::Service, verification_method::VerificationMethod}, methods::did_dht::{DidDht as InnerDidDht, DidDhtCreateOptions as InnerDidDhtCreateOptions}, }; -pub fn did_dht_resolve(uri: &str, gateway_url: Option) -> Arc { - let resolution_result = block_on(InnerDidDht::resolve(uri, gateway_url)); - Arc::new(ResolutionResult(resolution_result)) +pub fn did_dht_resolve(uri: &str, gateway_url: Option) -> Result> { + let rt = get_rt()?; + let resolution_result = rt.block_on(InnerDidDht::resolve(uri, gateway_url)); + Ok(Arc::new(ResolutionResult(resolution_result))) } #[derive(Default)] @@ -40,13 +41,12 @@ pub fn did_dht_create(options: Option) -> Result, gateway_url: Option) -> Result<()> { - Ok(block_on(InnerDidDht::publish( - bearer_did.0.clone(), - gateway_url, - ))?) + let rt = get_rt()?; + Ok(rt.block_on(InnerDidDht::publish(bearer_did.0.clone(), gateway_url))?) } diff --git a/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs b/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs index 42c6c66e..49d218cd 100644 --- a/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs +++ b/bindings/web5_uniffi_wrapper/src/dids/methods/did_web.rs @@ -1,9 +1,8 @@ use crate::{ crypto::key_manager::{KeyManager, ToInnerKeyManager}, dids::{bearer_did::BearerDid, resolution::resolution_result::ResolutionResult}, - errors::Result, + errors::Result, get_rt, }; -use futures::executor::block_on; use std::sync::Arc; use web5::{ crypto::dsa::Dsa, @@ -15,9 +14,10 @@ use web5::{ }, }; -pub fn did_web_resolve(uri: &str) -> Arc { - let resolution_result = block_on(InnerDidWeb::resolve(uri)); - Arc::new(ResolutionResult(resolution_result)) +pub fn did_web_resolve(uri: &str) -> Result> { + let rt = get_rt()?; + let resolution_result = rt.block_on(InnerDidWeb::resolve(uri)); + Ok(Arc::new(ResolutionResult(resolution_result))) } #[derive(Default)] diff --git a/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs b/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs index 19a3a65d..dcd4c7c1 100644 --- a/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs +++ b/bindings/web5_uniffi_wrapper/src/dids/resolution/resolution_result.rs @@ -1,11 +1,12 @@ -use futures::executor::block_on; +use crate::{errors::Result, get_rt}; use web5::dids::resolution::resolution_result::ResolutionResult as InnerResolutionResult; pub struct ResolutionResult(pub InnerResolutionResult); impl ResolutionResult { - pub fn resolve(uri: &str) -> Self { - Self(block_on(InnerResolutionResult::resolve(uri))) + pub fn resolve(uri: &str) -> Result { + let rt = get_rt()?; + Ok(Self(rt.block_on(InnerResolutionResult::resolve(uri)))) } pub fn get_data(&self) -> InnerResolutionResult { diff --git a/bindings/web5_uniffi_wrapper/src/lib.rs b/bindings/web5_uniffi_wrapper/src/lib.rs index e4dde532..9d5e36d4 100644 --- a/bindings/web5_uniffi_wrapper/src/lib.rs +++ b/bindings/web5_uniffi_wrapper/src/lib.rs @@ -1,5 +1,15 @@ +use errors::Result; +use tokio::runtime::Runtime; +use web5::errors::Web5Error; + pub mod credentials; pub mod crypto; pub mod dids; pub mod errors; + +pub fn get_rt() -> Result { + let rt = Runtime::new() + .map_err(|e| Web5Error::Unknown(format!("unable to instantiate tokio runtime {}", e)))?; + Ok(rt) +} diff --git a/bound/kt/src/main/kotlin/web5/sdk/rust/UniFFI.kt b/bound/kt/src/main/kotlin/web5/sdk/rust/UniFFI.kt index 5dc9078b..010858cb 100644 --- a/bound/kt/src/main/kotlin/web5/sdk/rust/UniFFI.kt +++ b/bound/kt/src/main/kotlin/web5/sdk/rust/UniFFI.kt @@ -1429,7 +1429,7 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_web5_uniffi_checksum_func_did_dht_publish() != 17158.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_web5_uniffi_checksum_func_did_dht_resolve() != 56140.toShort()) { + if (lib.uniffi_web5_uniffi_checksum_func_did_dht_resolve() != 25411.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } if (lib.uniffi_web5_uniffi_checksum_func_did_jwk_create() != 64914.toShort()) { @@ -1441,7 +1441,7 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_web5_uniffi_checksum_func_did_web_create() != 8722.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_web5_uniffi_checksum_func_did_web_resolve() != 15538.toShort()) { + if (lib.uniffi_web5_uniffi_checksum_func_did_web_resolve() != 6380.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } if (lib.uniffi_web5_uniffi_checksum_func_ed25519_generator_generate() != 57849.toShort()) { @@ -1585,7 +1585,7 @@ private fun uniffiCheckApiChecksums(lib: UniffiLib) { if (lib.uniffi_web5_uniffi_checksum_constructor_presentationdefinition_new() != 13282.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } - if (lib.uniffi_web5_uniffi_checksum_constructor_resolutionresult_resolve() != 11404.toShort()) { + if (lib.uniffi_web5_uniffi_checksum_constructor_resolutionresult_resolve() != 14670.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } if (lib.uniffi_web5_uniffi_checksum_constructor_secp256k1signer_new() != 58975.toShort()) { @@ -4986,9 +4986,10 @@ open class ResolutionResult: Disposable, AutoCloseable, ResolutionResultInterfac companion object { - fun `resolve`(`uri`: kotlin.String): ResolutionResult { + + @Throws(Web5Exception::class) fun `resolve`(`uri`: kotlin.String): ResolutionResult { return FfiConverterTypeResolutionResult.lift( - uniffiRustCall() { _status -> + uniffiRustCallWithError(Web5Exception) { _status -> UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_constructor_resolutionresult_resolve( FfiConverterString.lower(`uri`),_status) } @@ -8588,9 +8589,10 @@ public object FfiConverterMapStringString: FfiConverterRustBuffer + uniffiRustCallWithError(Web5Exception) { _status -> UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_func_did_dht_resolve( FfiConverterString.lower(`uri`),FfiConverterOptionalString.lower(`gatewayUrl`),_status) } @@ -8626,9 +8628,10 @@ public object FfiConverterMapStringString: FfiConverterRustBuffer + uniffiRustCallWithError(Web5Exception) { _status -> UniffiLib.INSTANCE.uniffi_web5_uniffi_fn_func_did_web_resolve( FfiConverterString.lower(`uri`),_status) }