Skip to content

Commit

Permalink
Keep ManifestDefinition as part of Builder.
Browse files Browse the repository at this point in the history
  • Loading branch information
gpeacock committed Aug 29, 2024
1 parent 0509f9d commit ede9e9d
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 343 deletions.
5 changes: 4 additions & 1 deletion export_schema/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{fs, path::Path};

use anyhow::Result;
use c2pa::{settings::Settings, ManifestDefinition, ManifestStore};
use c2pa::{settings::Settings, Builder, ManifestDefinition, ManifestStore};
use schemars::{schema::RootSchema, schema_for};

fn write_schema(schema: &RootSchema, name: &str) {
Expand All @@ -15,6 +15,9 @@ fn write_schema(schema: &RootSchema, name: &str) {
}

fn main() -> Result<()> {
let builder = schema_for!(Builder);
write_schema(&builder, "Builder");

let manifest_definition = schema_for!(ManifestDefinition);
write_schema(&manifest_definition, "ManifestDefinition");

Expand Down
241 changes: 122 additions & 119 deletions sdk/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,137 +19,139 @@ use std::{
};

use async_generic::async_generic;
#[cfg(feature = "json_schema")]
use schemars::JsonSchema;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_with::skip_serializing_none;
use uuid::Uuid;
use zip::{write::FileOptions, ZipArchive, ZipWriter};

use crate::{
assertion::AssertionBase,
assertion::{AssertionBase, AssertionDecodeError},
assertions::{
labels, Actions, CreativeWork, DataHash, Exif, SoftwareAgent, Thumbnail, User, UserCbor,
labels, Actions, CreativeWork, DataHash, Exif, Metadata, SoftwareAgent, Thumbnail, User,
UserCbor,
},
claim::Claim,
error::{Error, Result},
ingredient::Ingredient,
manifest_definition::{AssertionData, AssertionDefinition, ManifestDefinition},
// manifest_definition::{AssertionData, AssertionDefinition, ManifestDefinition},
resource_store::{ResourceRef, ResourceResolver, ResourceStore},
salt::DefaultSalt,
store::Store,
utils::mime::format_to_mime,
AsyncSigner, ClaimGeneratorInfo, HashRange, Signer,
AsyncSigner,
ClaimGeneratorInfo,
HashRange,
Ingredient,
Signer,
};

/// Version of the Builder Archive file
const ARCHIVE_VERSION: &str = "1";

// /// A Manifest Definition
// /// This is used to define a manifest and is used to build a ManifestStore
// /// A Manifest is a collection of ingredients and assertions
// /// It is used to define a claim that can be signed and embedded into a file
// #[skip_serializing_none]
// #[derive(Debug, Default, Deserialize, Serialize)]
// #[cfg_attr(feature = "json_schema", derive(JsonSchema))]
// #[non_exhaustive]
// pub struct ManifestDefinition {
// /// Optional prefix added to the generated Manifest Label
// /// This is typically Internet domain name for the vendor (i.e. `adobe`)
// pub vendor: Option<String>,

// /// Clam Generator Info is always required with at least one entry
// #[serde(default = "default_claim_generator_info")]
// pub claim_generator_info: Vec<ClaimGeneratorInfo>,

// /// Optional manifest metadata
// pub metadata: Option<Vec<Metadata>>,

// /// A human-readable title, generally source filename.
// pub title: Option<String>,

// /// The format of the source file as a MIME type.
// #[serde(default = "default_format")]
// pub format: String,

// /// Instance ID from `xmpMM:InstanceID` in XMP metadata.
// #[serde(default = "default_instance_id")]
// pub instance_id: String,

// pub thumbnail: Option<ResourceRef>,

// /// A List of ingredients
// #[serde(default = "default_vec::<Ingredient>")]
// pub ingredients: Vec<Ingredient>,

// /// A list of assertions
// #[serde(default = "default_vec::<AssertionDefinition>")]
// pub assertions: Vec<AssertionDefinition>,

// /// A list of redactions - URIs to a redacted assertions
// pub redactions: Option<Vec<String>>,

// pub label: Option<String>,
// }

// fn default_instance_id() -> String {
// format!("xmp:iid:{}", Uuid::new_v4())
// }

// fn default_claim_generator_info() -> Vec<ClaimGeneratorInfo> {
// [ClaimGeneratorInfo::default()].to_vec()
// }

// fn default_format() -> String {
// "application/octet-stream".to_owned()
// }

// fn default_vec<T>() -> Vec<T> {
// Vec::new()
// }

// #[derive(Debug, Deserialize, Serialize, Clone)]
// #[cfg_attr(feature = "json_schema", derive(JsonSchema))]
// #[serde(untagged)]
// pub enum AssertionData {
// #[cfg_attr(feature = "json_schema", schemars(skip))]
// Cbor(serde_cbor::Value),
// Json(serde_json::Value),
// }

// #[derive(Debug, Deserialize, Serialize, Clone)]
// #[cfg_attr(feature = "json_schema", derive(JsonSchema))]
// #[non_exhaustive]
// pub struct AssertionDefinition {
// pub label: String,
// pub data: AssertionData,
// }

// use serde::de::DeserializeOwned;

// use crate::assertion::AssertionDecodeError;
// impl AssertionDefinition {
// pub(crate) fn to_assertion<T: DeserializeOwned>(&self) -> Result<T> {
// match &self.data {
// AssertionData::Json(value) => serde_json::from_value(value.clone()).map_err(|e| {
// Error::AssertionDecoding(AssertionDecodeError::from_err(
// self.label.to_owned(),
// None,
// "application/json".to_owned(),
// e,
// ))
// }),
// AssertionData::Cbor(value) => {
// serde_cbor::value::from_value(value.clone()).map_err(|e| {
// Error::AssertionDecoding(AssertionDecodeError::from_err(
// self.label.to_owned(),
// None,
// "application/cbor".to_owned(),
// e,
// ))
// })
// }
// }
// }
// }
/// A Manifest Definition
/// This is used to define a manifest and is used to build a ManifestStore
/// A Manifest is a collection of ingredients and assertions
/// It is used to define a claim that can be signed and embedded into a file
#[skip_serializing_none]
#[derive(Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "json_schema", derive(JsonSchema))]
#[non_exhaustive]
pub struct ManifestDefinition {
/// Optional prefix added to the generated Manifest Label
/// This is typically Internet domain name for the vendor (i.e. `adobe`)
pub vendor: Option<String>,

/// Clam Generator Info is always required with at least one entry
#[serde(default = "default_claim_generator_info")]
pub claim_generator_info: Vec<ClaimGeneratorInfo>,

/// Optional manifest metadata
pub metadata: Option<Vec<Metadata>>,

/// A human-readable title, generally source filename.
pub title: Option<String>,

/// The format of the source file as a MIME type.
#[serde(default = "default_format")]
pub format: String,

/// Instance ID from `xmpMM:InstanceID` in XMP metadata.
#[serde(default = "default_instance_id")]
pub instance_id: String,

pub thumbnail: Option<ResourceRef>,

/// A List of ingredients
#[serde(default = "default_vec::<Ingredient>")]
pub ingredients: Vec<Ingredient>,

/// A list of assertions
#[serde(default = "default_vec::<AssertionDefinition>")]
pub assertions: Vec<AssertionDefinition>,

/// A list of redactions - URIs to a redacted assertions
pub redactions: Option<Vec<String>>,

pub label: Option<String>,
}

fn default_instance_id() -> String {
format!("xmp:iid:{}", Uuid::new_v4())
}

fn default_claim_generator_info() -> Vec<ClaimGeneratorInfo> {
[ClaimGeneratorInfo::default()].to_vec()
}

fn default_format() -> String {
"application/octet-stream".to_owned()
}

fn default_vec<T>() -> Vec<T> {
Vec::new()
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[cfg_attr(feature = "json_schema", derive(JsonSchema))]
#[serde(untagged)]
pub enum AssertionData {
#[cfg_attr(feature = "json_schema", schemars(skip))]
Cbor(serde_cbor::Value),
Json(serde_json::Value),
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[cfg_attr(feature = "json_schema", derive(JsonSchema))]
#[non_exhaustive]
pub struct AssertionDefinition {
pub label: String,
pub data: AssertionData,
}
impl AssertionDefinition {
pub(crate) fn to_assertion<T: DeserializeOwned>(&self) -> Result<T> {
match &self.data {
AssertionData::Json(value) => serde_json::from_value(value.clone()).map_err(|e| {
Error::AssertionDecoding(AssertionDecodeError::from_err(
self.label.to_owned(),
None,
"application/json".to_owned(),
e,
))
}),
AssertionData::Cbor(value) => {
serde_cbor::value::from_value(value.clone()).map_err(|e| {
Error::AssertionDecoding(AssertionDecodeError::from_err(
self.label.to_owned(),
None,
"application/cbor".to_owned(),
e,
))
})
}
}
}
}

/// A Builder is used to add a signed manifest to an asset.
///
Expand Down Expand Up @@ -204,6 +206,7 @@ const ARCHIVE_VERSION: &str = "1";
/// ```
#[skip_serializing_none]
#[derive(Debug, Default, Deserialize, Serialize)]
#[cfg_attr(feature = "json_schema", derive(JsonSchema))]
pub struct Builder {
#[serde(flatten)]
pub definition: ManifestDefinition,
Expand Down Expand Up @@ -1047,6 +1050,12 @@ mod tests {
"version": "1.0.0"
}
],
"metadata": [
{
"dateTime": "1985-04-12T23:20:50.52Z",
"my_custom_metadata": "my custom metatdata value"
}
],
"title": "Test_Manifest",
"format": "image/tiff",
"instance_id": "1234",
Expand All @@ -1067,13 +1076,7 @@ mod tests {
"label": "org.test.assertion",
"data": "assertion"
}
],
"metadata": [
{
"dateTime": "1985-04-12T23:20:50.52Z",
"my_custom_metadata": "my custom metatdata value"
}
],
]
})
.to_string()
}
Expand Down
6 changes: 1 addition & 5 deletions sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub use assertions::Relationship;
#[cfg(feature = "v1_api")]
pub use asset_io::{CAIRead, CAIReadWrite};
#[cfg(feature = "unstable_api")]
pub use builder::Builder;
pub use builder::{Builder, ManifestDefinition};
pub use callback_signer::{CallbackFunc, CallbackSigner};
pub use claim_generator_info::ClaimGeneratorInfo;
pub use error::{Error, Result};
Expand All @@ -128,8 +128,6 @@ pub use ingredient::Ingredient;
pub use ingredient::{DefaultOptions, IngredientOptions};
pub use manifest::{Manifest, SignatureInfo};
pub use manifest_assertion::{ManifestAssertion, ManifestAssertionKind};
#[cfg(feature = "unstable_api")]
pub use manifest_definition::ManifestDefinition;
#[cfg(feature = "v1_api")]
pub use manifest_store::ManifestStore;
#[cfg(feature = "v1_api")]
Expand Down Expand Up @@ -161,8 +159,6 @@ pub(crate) mod ingredient;
pub(crate) mod jumbf;
pub(crate) mod manifest;
pub(crate) mod manifest_assertion;
#[cfg(feature = "unstable_api")]
pub(crate) mod manifest_definition;
pub(crate) mod manifest_store;
pub(crate) mod manifest_store_report;
pub(crate) mod ocsp_utils;
Expand Down
Loading

0 comments on commit ede9e9d

Please sign in to comment.