Skip to content

Commit

Permalink
add credential_type method to constraint field
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Tate <[email protected]>
  • Loading branch information
Ryanmtate committed Sep 19, 2024
1 parent eeffa6c commit 12e5442
Showing 1 changed file with 66 additions and 12 deletions.
78 changes: 66 additions & 12 deletions src/core/input_descriptor.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashSet;

use super::{credential_format::*, presentation_submission::*};
use crate::utils::NonEmptyVec;

Expand Down Expand Up @@ -135,6 +137,23 @@ impl InputDescriptor {
self
}

/// Return the format of the input descriptor.
///
/// The Input Descriptor Object MAY contain a format property. If present,
/// its value MUST be an object with one or more properties matching the registered
/// Claim Format Designations (e.g., jwt, jwt_vc, jwt_vp, etc.).
///
/// 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) -> &ClaimFormatMap {
&self.format
}

/// Return the format designations of the input descriptor as a hash set.
pub fn format_designations(&self) -> HashSet<&ClaimFormatDesignation> {
self.format.keys().collect()
}

/// Set the group of the constraints field.
pub fn set_group(mut self, group: Vec<GroupId>) -> Self {
self.group = group;
Expand Down Expand Up @@ -253,18 +272,6 @@ impl InputDescriptor {

Ok(())
}

/// Return the format of the input descriptor.
///
/// The Input Descriptor Object MAY contain a format property. If present,
/// its value MUST be an object with one or more properties matching the registered
/// Claim Format Designations (e.g., jwt, jwt_vc, jwt_vp, etc.).
///
/// 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) -> &ClaimFormatMap {
&self.format
}
}

/// Constraints are objects used to describe the constraints that a [Holder](https://identity.foundation/presentation-exchange/spec/v2.0.0/#term:holder) must satisfy to fulfill an Input Descriptor.
Expand Down Expand Up @@ -588,6 +595,53 @@ impl ConstraintsField {
})
.collect()
}

/// Return the Credential Type of the constraints field
pub fn credential_type(&self) -> Option<CredentialType> {
// NOTE: There may be other ways to search for a valid the credential type
// that meets the input descriptor constraints.
//
// A more exhaustive search may require parsing each credential to
// check if it contains a certain field, e.g. `firstName`, `familyName`, etc.,
// and see if it will satisfy the constraints.
//
// For now, we explicity check the type of the credential if it is present
// in the credential `type` field.

if self
.path
.as_ref()
.iter()
// Check if any of the paths contain a reference to type.
// NOTE: I am not sure if this is normative to add a `type` field to the path
// for a verifiable credential.
.any(|path| path.contains(&"type".to_string()))
{
// Check the filter field to determine the `const`
// value for the credential type, e.g. `iso.org.18013.5.1.mDL`, etc.
if let Some(credential) = self.filter.as_ref().and_then(|filter| {
filter
.get("const")
.and_then(serde_json::Value::as_str)
.map(CredentialType::from)
}) {
return Some(credential);
}

// The `type` field may be an array with a nested const value.
if let Some(credential) = self.filter.as_ref().and_then(|filter| {
filter
.get("contains")
.and_then(|value| value.get("const"))
.and_then(serde_json::Value::as_str)
.map(CredentialType::from)
}) {
return Some(credential);
}
}

None
}
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
Expand Down

0 comments on commit 12e5442

Please sign in to comment.