Skip to content

Commit

Permalink
replace schema validator for filter type with Value type; fix claim f…
Browse files Browse the repository at this point in the history
…ormat failing test cases

Signed-off-by: Ryan Tate <[email protected]>
  • Loading branch information
Ryanmtate committed Aug 15, 2024
1 parent 91311a2 commit d18f56d
Showing 1 changed file with 44 additions and 26 deletions.
70 changes: 44 additions & 26 deletions src/presentation_exchange.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::json_schema_validation::SchemaValidator;
use std::collections::HashMap;

pub use crate::utils::NonEmptyVec;

use anyhow::{bail, Result};
Expand All @@ -10,6 +11,9 @@ use serde_json::Map;
/// For syntax details, see [https://identity.foundation/presentation-exchange/spec/v2.0.0/#jsonpath-syntax-definition](https://identity.foundation/presentation-exchange/spec/v2.0.0/#jsonpath-syntax-definition)
pub type JsonPath = String;

/// A Json object of claim formats.
pub type ClaimFormatMap = HashMap<ClaimFormatDesignation, ClaimFormatPayload>;

/// The Presentation Definition MAY include a format property. The value MUST be an object with one or
/// more properties matching the registered [ClaimFormatDesignation] (e.g., jwt, jwt_vc, jwt_vp, etc.).
/// The properties inform the Holder of the Claim format configurations the Verifier can process.
Expand All @@ -22,7 +26,6 @@ pub type JsonPath = String;
/// See [https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-definition](https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-definition)
/// for an example schema.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum ClaimFormat {
#[serde(rename = "jwt")]
Jwt {
Expand Down Expand Up @@ -67,11 +70,7 @@ pub enum ClaimFormat {
},
#[serde(rename = "mso_mdoc")]
MsoMDoc(serde_json::Value),
#[serde(untagged)]
Other {
name: String,
value: serde_json::Value,
},
Other(serde_json::Value),
}

impl ClaimFormat {
Expand All @@ -89,17 +88,26 @@ impl ClaimFormat {
ClaimFormat::AcVc { .. } => ClaimFormatDesignation::AcVc,
ClaimFormat::AcVp { .. } => ClaimFormatDesignation::AcVp,
ClaimFormat::MsoMDoc(_) => ClaimFormatDesignation::MsoMDoc,
ClaimFormat::Other { name, .. } => ClaimFormatDesignation::Other(name.to_owned()),
ClaimFormat::Other(_) => ClaimFormatDesignation::Other,
}
}
}

/// Claim format payload
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ClaimFormatPayload {
#[serde(rename = "alg")]
Alg(Vec<String>),
#[serde(rename = "proof_type")]
ProofType(Vec<String>),
}

/// The claim format designation type is used in the input description object to specify the format of the claim.
///
/// Registry of claim format type: https://identity.foundation/claim-format-registry/#registry
///
/// Documentation based on the [DIF Presentation Exchange Specification v2.0](https://identity.foundation/presentation-exchange/spec/v2.0.0/#claim-format-designations)
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum ClaimFormatDesignation {
/// The format is a JSON Web Token (JWT) as defined by [RFC7519](https://identity.foundation/claim-format-registry/#ref:RFC7519)
/// that will be submitted in the form of a JWT encoded string. Expression of
Expand All @@ -119,6 +127,10 @@ pub enum ClaimFormatDesignation {
/// See [JwtVc](JwtVc) for more information.
#[serde(rename = "jwt_vp")]
JwtVp,
#[serde(rename = "jwt_vc_json")]
JwtVcJson,
#[serde(rename = "jwt_vp_json")]
JwtVpJson,
/// The format is a Linked-Data Proof that will be submitted as an object.
/// Expression of supported algorithms in relation to these formats MUST be
/// conveyed using a proof_type property with values that are identifiers from
Expand Down Expand Up @@ -156,8 +168,7 @@ pub enum ClaimFormatDesignation {
/// Other claim format designations not covered by the above.
///
/// The value of this variant is the name of the claim format designation.
#[serde(untagged)]
Other(String),
Other,
}

/// A presentation definition is a JSON object that describes the information a [Verifier](https://identity.foundation/presentation-exchange/spec/v2.0.0/#term:verifier) requires of a [Holder](https://identity.foundation/presentation-exchange/spec/v2.0.0/#term:holder).
Expand All @@ -179,7 +190,7 @@ pub struct PresentationDefinition {
#[serde(skip_serializing_if = "Option::is_none")]
purpose: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
format: Option<ClaimFormat>,
format: Option<ClaimFormatMap>,
}

impl PresentationDefinition {
Expand Down Expand Up @@ -261,13 +272,21 @@ impl PresentationDefinition {
/// as noted in the Claim Format Designations section.
///
/// See: [https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-definition](https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-definition)
pub fn set_format(mut self, format: ClaimFormat) -> Self {
pub fn set_format(mut self, format: ClaimFormatMap) -> Self {
self.format = Some(format);
self
}

/// Add a new format to the presentation definition.
pub fn add_format(mut self, format: ClaimFormatDesignation, value: ClaimFormatPayload) -> Self {
self.format
.get_or_insert_with(HashMap::new)
.insert(format, value);
self
}

/// Return the format of the presentation definition.
pub fn format(&self) -> Option<&ClaimFormat> {
pub fn format(&self) -> Option<&ClaimFormatMap> {
self.format.as_ref()
}
}
Expand All @@ -290,7 +309,7 @@ pub struct InputDescriptor {
#[serde(skip_serializing_if = "Option::is_none")]
purpose: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
format: Option<ClaimFormat>,
format: Option<ClaimFormatMap>,
}

impl InputDescriptor {
Expand Down Expand Up @@ -362,7 +381,7 @@ impl InputDescriptor {
///
/// This format property is identical in value signature to the top-level format object,
/// but can be used to specifically constrain submission of a single input to a subset of formats or algorithms.
pub fn set_format(mut self, format: ClaimFormat) -> Self {
pub fn set_format(mut self, format: ClaimFormatMap) -> Self {
self.format = Some(format);
self
}
Expand All @@ -375,7 +394,7 @@ impl InputDescriptor {
///
/// This format property is identical in value signature to the top-level format object,
/// but can be used to specifically constrain submission of a single input to a subset of formats or algorithms.
pub fn format(&self) -> Option<&ClaimFormat> {
pub fn format(&self) -> Option<&ClaimFormatMap> {
self.format.as_ref()
}
}
Expand Down Expand Up @@ -447,9 +466,8 @@ pub struct ConstraintsField {
purpose: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
name: Option<String>,
// TODO: JSONSchema validation at deserialization time
#[serde(skip_serializing_if = "Option::is_none")]
filter: Option<SchemaValidator>,
filter: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
optional: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -552,13 +570,13 @@ impl ConstraintsField {
///
/// If present its value MUST be a JSON Schema descriptor used to filter against
/// the values returned from evaluation of the JSONPath string expressions in the path array.
pub fn set_filter(mut self, filter: SchemaValidator) -> Self {
pub fn set_filter(mut self, filter: serde_json::Value) -> Self {
self.filter = Some(filter);
self
}

/// Return the filter of the constraints field.
pub fn filter(&self) -> Option<&SchemaValidator> {
pub fn filter(&self) -> Option<&serde_json::Value> {
self.filter.as_ref()
}

Expand Down Expand Up @@ -648,7 +666,7 @@ impl PresentationSubmission {
/// For more information, see: [https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-submission](https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-submission)
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct DescriptorMap {
id: uuid::Uuid,
id: String,
format: ClaimFormatDesignation,
path: JsonPath,
path_nested: Option<Box<DescriptorMap>>,
Expand All @@ -662,7 +680,7 @@ impl DescriptorMap {
/// The descriptor map object MUST include a `path` property. The value of this property MUST be a [JSONPath](https://goessner.net/articles/JsonPath/) string expression. The path property indicates the [Claim](https://identity.foundation/presentation-exchange/spec/v2.0.0/#term:claim) submitted in relation to the identified [InputDescriptor], when executed against the top-level of the object the [PresentationSubmission] is embedded within.
///
/// For more information, see: [https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-submission](https://identity.foundation/presentation-exchange/spec/v2.0.0/#presentation-submission)
pub fn new(id: uuid::Uuid, format: ClaimFormatDesignation, path: JsonPath) -> Self {
pub fn new(id: String, format: ClaimFormatDesignation, path: JsonPath) -> Self {
Self {
id,
format,
Expand All @@ -672,7 +690,7 @@ impl DescriptorMap {
}

/// Return the id of the descriptor map.
pub fn id(&self) -> &uuid::Uuid {
pub fn id(&self) -> &String {
&self.id
}

Expand Down Expand Up @@ -812,7 +830,7 @@ pub(crate) mod tests {
continue;
}
}
print!("{} -> ", path.file_name().unwrap().to_str().unwrap());
println!("{} -> ", path.file_name().unwrap().to_str().unwrap());
let file = File::open(path).unwrap();
let jd = &mut serde_json::Deserializer::from_reader(file.try_clone().unwrap());
let _: PresentationDefinitionTest = serde_path_to_error::deserialize(jd)
Expand Down Expand Up @@ -845,7 +863,7 @@ pub(crate) mod tests {
continue;
}
}
print!("{} -> ", path.file_name().unwrap().to_str().unwrap());
println!("{} -> ", path.file_name().unwrap().to_str().unwrap());
let file = File::open(path).unwrap();
let jd = &mut serde_json::Deserializer::from_reader(file.try_clone().unwrap());
let _: PresentationSubmissionTest = serde_path_to_error::deserialize(jd)
Expand Down

0 comments on commit d18f56d

Please sign in to comment.