From ecd5af9cea283ef7576eee33c409a81d57022ffd Mon Sep 17 00:00:00 2001 From: "Charles E. Lehner" Date: Fri, 7 Jan 2022 11:45:32 -0500 Subject: [PATCH 1/3] Refactor HTTPDIDResolver::resolve Reduce indentation --- src/did_resolve.rs | 93 +++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/src/did_resolve.rs b/src/did_resolve.rs index 10d355feb..b57779073 100644 --- a/src/did_resolve.rs +++ b/src/did_resolve.rs @@ -790,59 +790,50 @@ impl DIDResolver for HTTPDIDResolver { })), } .unwrap_or_else(|| "".to_string()); - let mut res_meta = ResolutionMetadata::default(); - let doc_opt; - let doc_meta_opt; - match &content_type[..] { - TYPE_DID_RESOLUTION => { - let result: ResolutionResult = - match serde_json::from_slice(&res_result_representation) { - Ok(result) => result, - Err(err) => { - return ( - ResolutionMetadata::from_error(&format!( - "Error parsing resolution result: {}", - err - )), - None, - None, - ) - } - }; - if let Some(meta) = result.did_resolution_metadata { - res_meta = meta; - // https://www.w3.org/TR/did-core/#did-resolution-metadata - // contentType - "MUST NOT be present if the resolve function was called" - res_meta.content_type = None; - }; - doc_opt = result.did_document; - doc_meta_opt = result.did_document_metadata; - } - _ => { - if resp.status() == StatusCode::NOT_FOUND { - res_meta.error = Some(ERROR_NOT_FOUND.to_string()); - doc_opt = None; - } else { - // Assume the response is a JSON-LD DID Document by default. - let doc: Document = match serde_json::from_slice(&res_result_representation) { - Ok(doc) => doc, - Err(err) => { - return ( - ResolutionMetadata::from_error(&format!( - "Error parsing DID document: {}", - err - )), - None, - None, - ) - } - }; - doc_opt = Some(doc); + + if content_type == TYPE_DID_RESOLUTION { + // Handle result using DID Resolution Result media type (JSON-LD) + let result: ResolutionResult = match serde_json::from_slice(&res_result_representation) + { + Ok(result) => result, + Err(err) => { + return ( + ResolutionMetadata::from_error(&format!( + "Error parsing resolution result: {}", + err + )), + None, + None, + ) } - doc_meta_opt = None; - } + }; + let res_meta = if let Some(mut meta) = result.did_resolution_metadata { + // https://www.w3.org/TR/did-core/#did-resolution-metadata + // contentType - "MUST NOT be present if the resolve function was called" + meta.content_type = None; + meta + } else { + ResolutionMetadata::default() + }; + return (res_meta, result.did_document, result.did_document_metadata); } - (res_meta, doc_opt, doc_meta_opt) + + if resp.status() == StatusCode::NOT_FOUND { + return (ResolutionMetadata::from_error(ERROR_NOT_FOUND), None, None); + } + + // Assume the response is a JSON(-LD) DID Document by default. + let doc: Document = match serde_json::from_slice(&res_result_representation) { + Ok(doc) => doc, + Err(err) => { + return ( + ResolutionMetadata::from_error(&format!("Error parsing DID document: {}", err)), + None, + None, + ) + } + }; + return (ResolutionMetadata::default(), Some(doc), None); } // Use default resolveRepresentation implementation in terms of resolve, From c97028d1515dae102b35d2271c180966b849fffd Mon Sep 17 00:00:00 2001 From: "Charles E. Lehner" Date: Fri, 7 Jan 2022 11:41:28 -0500 Subject: [PATCH 2/3] Detect DID Resolution Result without media type --- src/did_resolve.rs | 53 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/did_resolve.rs b/src/did_resolve.rs index b57779073..c3a93b2de 100644 --- a/src/did_resolve.rs +++ b/src/did_resolve.rs @@ -125,6 +125,15 @@ pub enum Content { Null, } +#[cfg(feature = "http")] +fn get_first_context_uri(value: &Value) -> Option<&str> { + match value.get("@context")? { + Value::Array(ref vec) => vec.get(0)?.as_str(), + Value::String(ref string) => Some(string.as_str()), + _ => None, + } +} + impl Content { pub fn into_vec(self) -> Result, Error> { if let Content::Data(data) = self { @@ -822,8 +831,50 @@ impl DIDResolver for HTTPDIDResolver { return (ResolutionMetadata::from_error(ERROR_NOT_FOUND), None, None); } + // Assume the response is JSON(-LD) (DID Document or DID Resolution result) + let value: Value = match serde_json::from_slice(&res_result_representation) { + Ok(result) => result, + Err(err) => { + return ( + ResolutionMetadata::from_error(&format!( + "Error parsing resolution response: {}", + err + )), + None, + None, + ) + } + }; + + let first_context_uri = get_first_context_uri(&value); + if first_context_uri == Some(crate::jsonld::DID_RESOLUTION_V1_CONTEXT) { + // Detect DID Resolution Result that didn't have specific media type. + let result: ResolutionResult = match serde_json::from_value(value) { + Ok(result) => result, + Err(err) => { + return ( + ResolutionMetadata::from_error(&format!( + "Error parsing resolution result: {}", + err + )), + None, + None, + ) + } + }; + let res_meta = if let Some(mut meta) = result.did_resolution_metadata { + // https://www.w3.org/TR/did-core/#did-resolution-metadata + // contentType - "MUST NOT be present if the resolve function was called" + meta.content_type = None; + meta + } else { + ResolutionMetadata::default() + }; + return (res_meta, result.did_document, result.did_document_metadata); + } + // Assume the response is a JSON(-LD) DID Document by default. - let doc: Document = match serde_json::from_slice(&res_result_representation) { + let doc: Document = match serde_json::from_value(value) { Ok(doc) => doc, Err(err) => { return ( From 0d50fc86b23f2f0a0c38e43fed756d7b07dd540b Mon Sep 17 00:00:00 2001 From: "Charles E. Lehner" Date: Thu, 13 Jan 2022 16:18:12 -0500 Subject: [PATCH 3/3] Factor out transforming Resolution Result --- src/did_resolve.rs | 78 ++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 45 deletions(-) diff --git a/src/did_resolve.rs b/src/did_resolve.rs index c3a93b2de..975017670 100644 --- a/src/did_resolve.rs +++ b/src/did_resolve.rs @@ -682,6 +682,37 @@ impl HTTPDIDResolver { } } +fn transform_resolution_result( + result: Result, +) -> ( + ResolutionMetadata, + Option, + Option, +) { + let result: ResolutionResult = match result { + Ok(result) => result, + Err(err) => { + return ( + ResolutionMetadata::from_error(&format!( + "Error parsing resolution result: {}", + err + )), + None, + None, + ) + } + }; + let res_meta = if let Some(mut meta) = result.did_resolution_metadata { + // https://www.w3.org/TR/did-core/#did-resolution-metadata + // contentType - "MUST NOT be present if the resolve function was called" + meta.content_type = None; + meta + } else { + ResolutionMetadata::default() + }; + return (res_meta, result.did_document, result.did_document_metadata); +} + #[cfg(feature = "http")] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] @@ -802,29 +833,7 @@ impl DIDResolver for HTTPDIDResolver { if content_type == TYPE_DID_RESOLUTION { // Handle result using DID Resolution Result media type (JSON-LD) - let result: ResolutionResult = match serde_json::from_slice(&res_result_representation) - { - Ok(result) => result, - Err(err) => { - return ( - ResolutionMetadata::from_error(&format!( - "Error parsing resolution result: {}", - err - )), - None, - None, - ) - } - }; - let res_meta = if let Some(mut meta) = result.did_resolution_metadata { - // https://www.w3.org/TR/did-core/#did-resolution-metadata - // contentType - "MUST NOT be present if the resolve function was called" - meta.content_type = None; - meta - } else { - ResolutionMetadata::default() - }; - return (res_meta, result.did_document, result.did_document_metadata); + return transform_resolution_result(serde_json::from_slice(&res_result_representation)); } if resp.status() == StatusCode::NOT_FOUND { @@ -849,28 +858,7 @@ impl DIDResolver for HTTPDIDResolver { let first_context_uri = get_first_context_uri(&value); if first_context_uri == Some(crate::jsonld::DID_RESOLUTION_V1_CONTEXT) { // Detect DID Resolution Result that didn't have specific media type. - let result: ResolutionResult = match serde_json::from_value(value) { - Ok(result) => result, - Err(err) => { - return ( - ResolutionMetadata::from_error(&format!( - "Error parsing resolution result: {}", - err - )), - None, - None, - ) - } - }; - let res_meta = if let Some(mut meta) = result.did_resolution_metadata { - // https://www.w3.org/TR/did-core/#did-resolution-metadata - // contentType - "MUST NOT be present if the resolve function was called" - meta.content_type = None; - meta - } else { - ResolutionMetadata::default() - }; - return (res_meta, result.did_document, result.did_document_metadata); + return transform_resolution_result(serde_json::from_value(value)); } // Assume the response is a JSON(-LD) DID Document by default.