From 6a4a7ccf5cc082d510025b8dc15f327a7af74c10 Mon Sep 17 00:00:00 2001 From: Eric Scouten Date: Tue, 25 Feb 2025 11:10:52 -0800 Subject: [PATCH] Add StatusTracker to the IdentityAssertion entry points --- .../src/identity_assertion/assertion.rs | 37 ++++++++++++++----- .../src/tests/builder/simple_case.rs | 17 +++++---- .../src/tests/claim_aggregation/interop.rs | 16 +++++--- cawg_identity/src/tests/x509.rs | 10 ++++- 4 files changed, 55 insertions(+), 25 deletions(-) diff --git a/cawg_identity/src/identity_assertion/assertion.rs b/cawg_identity/src/identity_assertion/assertion.rs index ae9302eec..bb7e3ac8b 100644 --- a/cawg_identity/src/identity_assertion/assertion.rs +++ b/cawg_identity/src/identity_assertion/assertion.rs @@ -17,6 +17,7 @@ use std::{ }; use c2pa::{Manifest, Reader}; +use c2pa_status_tracker::StatusTracker; use serde::{Deserialize, Serialize}; use serde_bytes::ByteBuf; @@ -63,9 +64,10 @@ impl IdentityAssertion { /// Iterator returns a [`Result`] because each assertion may fail to parse. /// /// Aside from CBOR parsing, no further validation is performed. - pub fn from_manifest( - manifest: &Manifest, - ) -> impl Iterator> + use<'_> { + pub fn from_manifest<'a>( + manifest: &'a Manifest, + _status_tracker: &'a mut StatusTracker, + ) -> impl Iterator> + use<'a> { manifest .assertions() .iter() @@ -83,17 +85,20 @@ impl IdentityAssertion { pub async fn to_summary( &self, manifest: &Manifest, + status_tracker: &mut StatusTracker, verifier: &SV, ) -> impl Serialize where ::Output: 'static, { - self.to_summary_impl(manifest, verifier).await + self.to_summary_impl(manifest, status_tracker, verifier) + .await } pub(crate) async fn to_summary_impl( &self, manifest: &Manifest, + status_tracker: &mut StatusTracker, verifier: &SV, ) -> IdentityAssertionReport< <::Output as ToCredentialSummary>::CredentialSummary, @@ -101,7 +106,7 @@ impl IdentityAssertion { where ::Output: 'static, { - match self.validate(manifest, verifier).await { + match self.validate(manifest, status_tracker, verifier).await { Ok(named_actor) => { let summary = named_actor.to_summary(); @@ -120,13 +125,15 @@ impl IdentityAssertion { /// Summarize all of the identity assertions found for a [`Manifest`]. pub async fn summarize_all( manifest: &Manifest, + status_tracker: &mut StatusTracker, verifier: &SV, ) -> impl Serialize { - Self::summarize_all_impl(manifest, verifier).await + Self::summarize_all_impl(manifest, status_tracker, verifier).await } pub(crate) async fn summarize_all_impl( manifest: &Manifest, + status_tracker: &mut StatusTracker, verifier: &SV, ) -> IdentityAssertionsForManifest< <::Output as ToCredentialSummary>::CredentialSummary, @@ -139,9 +146,16 @@ impl IdentityAssertion { >, > = vec![]; - for assertion in Self::from_manifest(manifest) { + let assertion_results: Vec> = + Self::from_manifest(manifest, status_tracker).collect(); + + for assertion in assertion_results { let report = match assertion { - Ok(assertion) => assertion.to_summary_impl(manifest, verifier).await, + Ok(assertion) => { + assertion + .to_summary_impl(manifest, status_tracker, verifier) + .await + } Err(_) => { todo!("Handle assertion failed to parse case"); } @@ -163,6 +177,7 @@ impl IdentityAssertion { #[cfg(feature = "v1_api")] pub async fn summarize_manifest_store( store: &c2pa::ManifestStore, + status_tracker: &mut StatusTracker, verifier: &SV, ) -> impl Serialize { // NOTE: We can't write this using .map(...).collect() because there are async @@ -175,7 +190,7 @@ impl IdentityAssertion { > = BTreeMap::new(); for (id, manifest) in store.manifests() { - let report = Self::summarize_all_impl(manifest, verifier).await; + let report = Self::summarize_all_impl(manifest, status_tracker, verifier).await; reports.insert(id.clone(), report); } @@ -189,6 +204,7 @@ impl IdentityAssertion { /// Summarize all of the identity assertions found for a [`Reader`]. pub async fn summarize_from_reader( reader: &Reader, + status_tracker: &mut StatusTracker, verifier: &SV, ) -> impl Serialize { // NOTE: We can't write this using .map(...).collect() because there are async @@ -201,7 +217,7 @@ impl IdentityAssertion { > = BTreeMap::new(); for (id, manifest) in reader.manifests() { - let report = Self::summarize_all_impl(manifest, verifier).await; + let report = Self::summarize_all_impl(manifest, status_tracker, verifier).await; reports.insert(id.clone(), report); } @@ -222,6 +238,7 @@ impl IdentityAssertion { pub async fn validate( &self, manifest: &Manifest, + _status_tracker: &mut StatusTracker, verifier: &SV, ) -> Result> { self.check_padding()?; diff --git a/cawg_identity/src/tests/builder/simple_case.rs b/cawg_identity/src/tests/builder/simple_case.rs index 98c2df92c..52bf526ce 100644 --- a/cawg_identity/src/tests/builder/simple_case.rs +++ b/cawg_identity/src/tests/builder/simple_case.rs @@ -14,6 +14,7 @@ use std::io::{Cursor, Seek}; use c2pa::{Builder, Reader, SigningAlg}; +use c2pa_status_tracker::StatusTracker; use serde_json::json; #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; @@ -70,17 +71,17 @@ async fn simple_case() { assert_eq!(manifest_store.validation_status(), None); let manifest = manifest_store.active_manifest().unwrap(); - let mut ia_iter = IdentityAssertion::from_manifest(manifest); + let mut st = StatusTracker::default(); + let mut ia_iter = IdentityAssertion::from_manifest(manifest, &mut st); // Should find exactly one identity assertion. let ia = ia_iter.next().unwrap().unwrap(); - dbg!(&ia); - assert!(ia_iter.next().is_none()); + drop(ia_iter); // And that identity assertion should be valid for this manifest. let nsv = NaiveSignatureVerifier {}; - let naive_credential = ia.validate(manifest, &nsv).await.unwrap(); + let naive_credential = ia.validate(manifest, &mut st, &nsv).await.unwrap(); let nc_summary = naive_credential.to_summary(); let nc_json = serde_json::to_string(&nc_summary).unwrap(); @@ -125,17 +126,17 @@ async fn simple_case_async() { assert_eq!(manifest_store.validation_status(), None); let manifest = manifest_store.active_manifest().unwrap(); - let mut ia_iter = IdentityAssertion::from_manifest(manifest); + let mut st = StatusTracker::default(); + let mut ia_iter = IdentityAssertion::from_manifest(manifest, &mut st); // Should find exactly one identity assertion. let ia = ia_iter.next().unwrap().unwrap(); - dbg!(&ia); - assert!(ia_iter.next().is_none()); + drop(ia_iter); // And that identity assertion should be valid for this manifest. let nsv = NaiveSignatureVerifier {}; - let naive_credential = ia.validate(manifest, &nsv).await.unwrap(); + let naive_credential = ia.validate(manifest, &mut st, &nsv).await.unwrap(); let nc_summary = naive_credential.to_summary(); let nc_json = serde_json::to_string(&nc_summary).unwrap(); diff --git a/cawg_identity/src/tests/claim_aggregation/interop.rs b/cawg_identity/src/tests/claim_aggregation/interop.rs index 171b0d526..c4a6516c1 100644 --- a/cawg_identity/src/tests/claim_aggregation/interop.rs +++ b/cawg_identity/src/tests/claim_aggregation/interop.rs @@ -14,6 +14,7 @@ use std::{io::Cursor, str::FromStr}; use c2pa::{HashedUri, Reader}; +use c2pa_status_tracker::StatusTracker; use chrono::{DateTime, FixedOffset}; use iref::UriBuf; use non_empty_string::NonEmptyString; @@ -41,15 +42,17 @@ async fn adobe_connected_identities() { assert_eq!(reader.validation_status(), None); let manifest = reader.active_manifest().unwrap(); - let mut ia_iter = IdentityAssertion::from_manifest(manifest); + let mut st = StatusTracker::default(); + let mut ia_iter = IdentityAssertion::from_manifest(manifest, &mut st); // Should find exactly one identity assertion. let ia = ia_iter.next().unwrap().unwrap(); assert!(ia_iter.next().is_none()); + drop(ia_iter); // And that identity assertion should be valid for this manifest. let isv = IcaSignatureVerifier {}; - let ica = ia.validate(manifest, &isv).await.unwrap(); + let ica = ia.validate(manifest, &mut st, &isv).await.unwrap(); // There should be exactly one verified identity. let ica_vc = ica.credential_subjects.first(); @@ -87,7 +90,8 @@ async fn adobe_connected_identities() { ); // Check the summary report for the entire manifest store. - let ia_summary = IdentityAssertion::summarize_from_reader(&reader, &isv).await; + let mut st = StatusTracker::default(); + let ia_summary = IdentityAssertion::summarize_from_reader(&reader, &mut st, &isv).await; let ia_json = serde_json::to_string(&ia_summary).unwrap(); assert_eq!( @@ -96,7 +100,8 @@ async fn adobe_connected_identities() { ); // Check the summary report for this manifest. - let ia_summary = IdentityAssertion::summarize_all(manifest, &isv).await; + let mut st = StatusTracker::default(); + let ia_summary = IdentityAssertion::summarize_all(manifest, &mut st, &isv).await; let ia_json = serde_json::to_string(&ia_summary).unwrap(); assert_eq!( @@ -121,8 +126,9 @@ async fn ims_multiple_manifests() { assert_eq!(reader.validation_status(), None); // Check the summary report for the entire manifest store. + let mut st = StatusTracker::default(); let isv = IcaSignatureVerifier {}; - let ia_summary = IdentityAssertion::summarize_from_reader(&reader, &isv).await; + let ia_summary = IdentityAssertion::summarize_from_reader(&reader, &mut st, &isv).await; let ia_json = serde_json::to_string(&ia_summary).unwrap(); assert_eq!( diff --git a/cawg_identity/src/tests/x509.rs b/cawg_identity/src/tests/x509.rs index 4ea4076e1..328493db6 100644 --- a/cawg_identity/src/tests/x509.rs +++ b/cawg_identity/src/tests/x509.rs @@ -15,6 +15,7 @@ use std::io::{Cursor, Seek}; use c2pa::{Builder, Reader, SigningAlg}; use c2pa_crypto::raw_signature; +use c2pa_status_tracker::StatusTracker; use serde_json::json; #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] use wasm_bindgen_test::wasm_bindgen_test; @@ -78,15 +79,20 @@ async fn simple_case() { assert_eq!(manifest_store.validation_status(), None); let manifest = manifest_store.active_manifest().unwrap(); - let mut ia_iter = IdentityAssertion::from_manifest(manifest); + let mut st = StatusTracker::default(); + let mut ia_iter = IdentityAssertion::from_manifest(manifest, &mut st); // Should find exactly one identity assertion. let ia = ia_iter.next().unwrap().unwrap(); assert!(ia_iter.next().is_none()); + drop(ia_iter); // And that identity assertion should be valid for this manifest. let x509_verifier = X509SignatureVerifier {}; - let sig_info = ia.validate(manifest, &x509_verifier).await.unwrap(); + let sig_info = ia + .validate(manifest, &mut st, &x509_verifier) + .await + .unwrap(); let cert_info = &sig_info.cert_info; assert_eq!(cert_info.alg.unwrap(), SigningAlg::Ed25519);