Skip to content

Commit ba322ff

Browse files
committed
Hmmm … maybe this doesn't need to be so complicated
1 parent 0f90e21 commit ba322ff

File tree

7 files changed

+152
-64
lines changed

7 files changed

+152
-64
lines changed

c2pa_c_ffi/src/c_api.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -463,11 +463,6 @@ pub unsafe extern "C" fn c2pa_free_string_array(ptr: *const *const c_char, count
463463

464464
// Run CAWG post-validation - this is async and requires a runtime.
465465
fn post_validate(result: Result<C2paReader, c2pa::Error>) -> Result<C2paReader, c2pa::Error> {
466-
if false {
467-
// CONSIDER BEFORE MERGING ...
468-
todo!("Remove me?");
469-
}
470-
471466
match result {
472467
Ok(mut reader) => {
473468
let runtime = match Runtime::new() {

c2pa_c_ffi/src/json_api.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ use crate::{Error, Result, SignerInfo};
2424
pub fn read_file(path: &str, data_dir: Option<String>) -> Result<String> {
2525
let mut reader = Reader::from_file(path).map_err(Error::from_c2pa_error)?;
2626
let runtime = Runtime::new().map_err(|e| Error::Other(e.to_string()))?;
27-
if false {
28-
// CONSIDER BEFORE MERGING ...
29-
todo!("Remove post_validate_async here?");
30-
}
3127
runtime
3228
.block_on(reader.post_validate_async(&CawgValidator {}))
3329
.map_err(Error::from_c2pa_error)?;

cli/src/main.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -574,10 +574,6 @@ fn verify_fragmented(init_pattern: &Path, frag_pattern: &Path) -> Result<Vec<Rea
574574

575575
// run cawg validation if supported
576576
fn validate_cawg(reader: &mut Reader) -> Result<()> {
577-
if false {
578-
// CONSIDER BEFORE MERGING ...
579-
todo!("Remove me?");
580-
}
581577
#[cfg(not(target_os = "wasi"))]
582578
{
583579
Runtime::new()?

sdk/examples/cawg_identity.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,7 @@ mod cawg {
124124

125125
builder.sign_file_async(&signer, source, &dest).await?;
126126

127-
let reader = Reader::from_file_async(dest).await?;
128-
127+
let reader = Reader::from_file_with_cawg_async(dest).await?;
129128
println!("{reader}");
130129
Ok(())
131130
}

sdk/src/identity/validator.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,13 @@ mod tests {
7777
crate::settings::set_settings_value("verify.verify_trust", false).unwrap();
7878

7979
let mut stream = Cursor::new(CONNECTED_IDENTITIES_VALID);
80-
let reader = Reader::from_stream_async("image/jpeg", &mut stream)
80+
81+
let reader = Reader::from_stream_with_cawg_async("image/jpeg", &mut stream)
8182
.await
8283
.unwrap();
84+
8385
//println!("validation results: {}", reader);
86+
8487
assert_eq!(
8588
reader
8689
.validation_results()
@@ -100,10 +103,13 @@ mod tests {
100103
crate::settings::set_settings_value("verify.verify_trust", false).unwrap();
101104

102105
let mut stream = Cursor::new(MULTIPLE_IDENTITIES_VALID);
103-
let reader = Reader::from_stream_async("image/jpeg", &mut stream)
106+
107+
let reader = Reader::from_stream_with_cawg_async("image/jpeg", &mut stream)
104108
.await
105109
.unwrap();
110+
106111
println!("validation results: {reader}");
112+
107113
assert_eq!(
108114
reader
109115
.validation_results()
@@ -119,9 +125,11 @@ mod tests {
119125
#[c2pa_test_async]
120126
async fn test_cawg_validate_with_hard_binding_missing() {
121127
let mut stream = Cursor::new(NO_HARD_BINDING);
122-
let reader = Reader::from_stream_async("image/jpeg", &mut stream)
128+
129+
let reader = Reader::from_stream_with_cawg_async("image/jpeg", &mut stream)
123130
.await
124131
.unwrap();
132+
125133
assert_eq!(
126134
reader
127135
.validation_results()

sdk/src/identity/x509/x509_credential_holder.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,16 @@ mod tests {
134134
// Read back the Manifest that was generated.
135135
dest.rewind().unwrap();
136136

137-
let manifest_store = Reader::from_stream_async(format, &mut dest).await.unwrap();
137+
let manifest_store = Reader::from_stream_with_cawg_async(format, &mut dest)
138+
.await
139+
.unwrap();
140+
138141
assert_eq!(manifest_store.validation_status(), None);
139142

140143
let validation_results = manifest_store.validation_results().unwrap();
141144
let active_manifest_results = validation_results.active_manifest().unwrap();
142145
let active_manifest_success_codes = active_manifest_results.success();
143146

144-
dbg!(&active_manifest_success_codes);
145-
146147
let mut ia_success_codes = active_manifest_success_codes.iter().filter(|s| {
147148
s.url()
148149
.map(|url| url.ends_with("cawg.identity"))
@@ -151,8 +152,6 @@ mod tests {
151152
});
152153

153154
let ia_success = ia_success_codes.next().unwrap();
154-
dbg!(&ia_success);
155-
156155
assert_eq!(ia_success.code(), "signingCredential.trusted");
157156
assert!(ia_success.url().unwrap().ends_with("cawg.identity"));
158157
assert_eq!(ia_success.kind(), &LogKind::Success);

sdk/src/reader.rs

Lines changed: 136 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use crate::{
3535
crypto::base64,
3636
dynamic_assertion::PartialClaim,
3737
error::{Error, Result},
38+
identity::validator::CawgValidator,
3839
jumbf::labels::{manifest_label_from_uri, to_absolute_uri, to_relative_uri},
3940
jumbf_io,
4041
manifest::StoreOptions,
@@ -108,13 +109,17 @@ type ValidationFn =
108109

109110
impl Reader {
110111
/// Create a manifest store [`Reader`] from a stream. A Reader is used to validate C2PA data from an asset.
112+
///
111113
/// # Arguments
112114
/// * `format` - The format of the stream. MIME type or extension that maps to a MIME type.
113115
/// * `stream` - The stream to read from. Must implement the Read and Seek traits. (NOTE: Explain Send trait, required for both sync & async?).
116+
///
114117
/// # Returns
115118
/// A [`Reader`] for the manifest store.
119+
///
116120
/// # Errors
117121
/// Returns an [`Error`] when the manifest data cannot be read. If there's no error upon reading, you must still check validation status to ensure that the manifest data is validated. That is, even if there are no errors, the data still might not be valid.
122+
///
118123
/// # Example
119124
/// This example reads from a memory buffer and prints out the JSON manifest data.
120125
/// ```no_run
@@ -125,51 +130,163 @@ impl Reader {
125130
/// let reader = Reader::from_stream("image/jpeg", stream).unwrap();
126131
/// println!("{}", reader.json());
127132
/// ```
128-
#[async_generic()]
133+
///
134+
/// # Note
135+
/// This function does not validate [CAWG identity] assertions that may be
136+
/// contained within any C2PA Manifests. If an async call is feasible, use
137+
/// [from_stream_with_cawg_async()]; if not, you can construct an async runtime
138+
/// on your own and perform the CAWG validation separately as shown in the
139+
/// following example:
140+
///
141+
/// ```no_run
142+
/// use std::io::Cursor;
143+
///
144+
/// use c2pa::Reader;
145+
/// let mut stream = Cursor::new(include_bytes!("../tests/fixtures/CA.jpg"));
146+
/// let mut reader = Reader::from_stream("image/jpeg", stream).unwrap();
147+
/// let runtime = tokio::runtime::Runtime::new().unwrap();
148+
/// runtime
149+
/// .block_on(reader.post_validate_async(&CawgValidator {}))
150+
/// .unwrap();
151+
/// println!("{}", reader.json());
152+
/// ```
153+
///
154+
/// [CAWG identity]: https://cawg.io/identity
155+
/// [from_stream_with_cawg_async()]: Self::from_stream_with_cawg_async
156+
#[async_generic]
129157
#[cfg(not(target_arch = "wasm32"))]
130158
pub fn from_stream(format: &str, mut stream: impl Read + Seek + Send) -> Result<Reader> {
131159
let verify = get_settings_value::<bool>("verify.verify_after_reading")?; // defaults to true
132160
let mut validation_log = StatusTracker::default();
161+
133162
let store = if _sync {
134163
Store::from_stream(format, &mut stream, verify, &mut validation_log)
135164
} else {
136165
Store::from_stream_async(format, &mut stream, verify, &mut validation_log).await
137166
}?;
138167

139-
#[allow(unused_mut)] // TEMPORARY until I figure out the synchronous path.
140-
let mut result = Self::from_store(store, &validation_log)?;
141-
if _sync {
142-
// TO DO: Figure out how to handle synchronous validation with
143-
// identity assertions? Just report an error (needs async)?
144-
if false {
145-
todo!("Add identity assertion validation here");
146-
}
168+
Self::from_store(store, &validation_log)
169+
}
170+
171+
#[async_generic]
172+
#[cfg(target_arch = "wasm32")]
173+
pub fn from_stream(format: &str, mut stream: impl Read + Seek) -> Result<Reader> {
174+
let verify = get_settings_value::<bool>("verify.verify_after_reading")?; // defaults to true
175+
let mut validation_log = StatusTracker::default();
176+
177+
let store = if _sync {
178+
Store::from_stream(format, &mut stream, verify, &mut validation_log)
147179
} else {
148-
use crate::identity::validator::CawgValidator;
149-
result
150-
.post_validate_internal_async(&CawgValidator {})
151-
.await?;
180+
Store::from_stream_async(format, &mut stream, verify, &mut validation_log).await
181+
}?;
182+
183+
Self::from_store(store, &validation_log)
184+
}
185+
186+
/// Create a manifest store [`Reader`] from a stream. A `Reader` is used to
187+
/// validate C2PA data from an asset. This variation also validates
188+
/// [CAWG identity] assertions within the C2PA data.
189+
///
190+
/// # Arguments
191+
/// * `format` - The format of the stream. MIME type or extension that maps to a MIME type.
192+
/// * `stream` - The stream to read from. Must implement the Read and Seek traits. (NOTE: Explain Send trait, required for both sync & async?).
193+
///
194+
/// # Returns
195+
/// A [`Reader`] for the manifest store.
196+
///
197+
/// # Errors
198+
/// Returns an [`Error`] when the manifest data cannot be read. If there's no error upon reading, you must still check validation status to ensure that the manifest data is validated. That is, even if there are no errors, the data still might not be valid.
199+
///
200+
/// # Example
201+
/// This example reads from a memory buffer and prints out the JSON manifest data.
202+
/// ```no_run
203+
/// use std::io::Cursor;
204+
///
205+
/// use c2pa::Reader;
206+
/// let mut stream = Cursor::new(include_bytes!("../tests/fixtures/CA.jpg"));
207+
/// let reader = Reader::from_stream_with_cawg_async("image/jpeg", stream)
208+
/// .await
209+
/// .unwrap();
210+
/// println!("{}", reader.json());
211+
/// ```
212+
///
213+
/// [CAWG identity]: https://cawg.io/identity
214+
/// [from_stream_with_cawg_async()]: Self::from_stream_with_cawg_async
215+
#[cfg(not(target_arch = "wasm32"))]
216+
pub async fn from_stream_with_cawg_async(
217+
format: &str,
218+
stream: impl Read + Seek + Send,
219+
) -> Result<Reader> {
220+
let mut reader = Self::from_stream_async(format, stream).await?;
221+
222+
if get_settings_value::<bool>("verify.verify_after_reading")? {
223+
reader.post_validate_async(&CawgValidator {}).await?;
152224
}
153225

154-
Ok(result)
226+
Ok(reader)
155227
}
156228

157-
#[async_generic()]
158229
#[cfg(target_arch = "wasm32")]
159-
pub fn from_stream(format: &str, mut stream: impl Read + Seek) -> Result<Reader> {
230+
pub async fn from_stream_with_cawg_async(
231+
format: &str,
232+
stream: impl Read + Seek,
233+
) -> Result<Reader> {
234+
let mut reader = Self::from_stream_async(format, stream).await?;
235+
236+
if get_settings_value::<bool>("verify.verify_after_reading")? {
237+
reader.post_validate_async(&CawgValidator {}).await?;
238+
}
239+
240+
Ok(reader)
241+
}
242+
243+
/// Create a manifest store [`Reader`] from a stream. A Reader is used to validate C2PA data from an asset.
244+
/// # Arguments
245+
/// * `format` - The format of the stream. MIME type or extension that maps to a MIME type.
246+
/// * `stream` - The stream to read from. Must implement the Read and Seek traits. (NOTE: Explain Send trait, required for both sync & async?).
247+
/// # Returns
248+
/// A [`Reader`] for the manifest store.
249+
/// # Errors
250+
/// Returns an [`Error`] when the manifest data cannot be read. If there's no error upon reading, you must still check validation status to ensure that the manifest data is validated. That is, even if there are no errors, the data still might not be valid.
251+
/// # Example
252+
/// This example reads from a memory buffer and prints out the JSON manifest data.
253+
/// ```no_run
254+
/// use std::io::Cursor;
255+
///
256+
/// use c2pa::Reader;
257+
/// let mut stream = Cursor::new(include_bytes!("../tests/fixtures/CA.jpg"));
258+
/// let reader = Reader::from_stream("image/jpeg", stream).unwrap();
259+
/// println!("{}", reader.json());
260+
/// ```
261+
#[cfg(not(target_arch = "wasm32"))]
262+
pub fn from_stream_with_cawg_async(
263+
format: &str,
264+
mut stream: impl Read + Seek + Send,
265+
) -> Result<Reader> {
266+
use crate::identity::validator::CawgValidator;
267+
160268
let verify = get_settings_value::<bool>("verify.verify_after_reading")?; // defaults to true
161269
let mut validation_log = StatusTracker::default();
162-
163270
let store = if _sync {
164271
Store::from_stream(format, &mut stream, verify, &mut validation_log)
165272
} else {
166273
Store::from_stream_async(format, &mut stream, verify, &mut validation_log).await
167274
}?;
168275

276+
#[allow(unused_mut)] // TEMPORARY until I figure out the synchronous path.
169277
let mut result = Self::from_store(store, &validation_log)?;
170-
if false {
171-
todo!("Add identity assertion validation here");
278+
279+
#[allow(unused)] // TEMPORARY until I figure the synchronous path.
280+
let cawg_validator = CawgValidator {};
281+
282+
if _sync {
283+
if false {
284+
panic!("Need sync implementation of CawgValidator");
285+
}
286+
} else {
287+
result.post_validate_async(&cawg_validator).await?;
172288
}
289+
173290
Ok(result)
174291
}
175292

@@ -754,24 +871,6 @@ impl Reader {
754871
validator: &impl AsyncPostValidator
755872
))]
756873
pub fn post_validate(&mut self, validator: &impl PostValidator) -> Result<()> {
757-
if false {
758-
// CONSIDER BEFORE MERGING ...
759-
todo!("Remove me?");
760-
}
761-
762-
if _sync {
763-
self.post_validate_internal(validator)
764-
} else {
765-
self.post_validate_internal_async(validator).await
766-
}
767-
}
768-
769-
#[async_generic(async_signature(
770-
&mut self,
771-
validator: &impl AsyncPostValidator
772-
))]
773-
fn post_validate_internal(&mut self, validator: &impl PostValidator) -> Result<()> {
774-
// TEMPORARY: Make this available while I sort out new code path.
775874
let mut validation_log = StatusTracker::default();
776875
let mut validation_results = self.validation_results.take().unwrap_or_default();
777876
let mut assertion_values = HashMap::new();
@@ -1034,10 +1133,6 @@ pub mod tests {
10341133

10351134
#[test]
10361135
fn test_reader_post_validate() -> Result<()> {
1037-
if false {
1038-
// CONSIDER BEFORE MERGING ...
1039-
todo!("Remove me?");
1040-
}
10411136
use crate::{log_item, status_tracker::StatusTracker};
10421137

10431138
let mut reader =

0 commit comments

Comments
 (0)