Skip to content

Commit

Permalink
display metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
UMR1352 committed Sep 20, 2024
1 parent 130af00 commit d278060
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 35 deletions.
2 changes: 1 addition & 1 deletion identity_core/src/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ mod one_or_many;
mod one_or_set;
mod ordered_set;
mod single_struct_error;
mod string_or_url;
mod timestamp;
mod url;
mod string_or_url;
6 changes: 4 additions & 2 deletions identity_core/src/common/string_or_url.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Copyright 2020-2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use std::{fmt::Display, str::FromStr};
use std::fmt::Display;
use std::str::FromStr;

use serde::{Deserialize, Serialize};
use serde::Deserialize;
use serde::Serialize;

use super::Url;

Expand Down
21 changes: 21 additions & 0 deletions identity_credential/src/sd_jwt_vc/metadata/display.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use serde::Deserialize;
use serde::Serialize;
use serde_json::Value;

/// Credential type's display information of a given languange.
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct DisplayMetadata {
/// Language tag as defined in [RFC5646](https://www.rfc-editor.org/rfc/rfc5646.txt).
pub lang: String,
/// VC type's human-readable name.
pub name: String,
/// VC type's human-readable description.
pub description: Option<String>,
/// Optional rendering information.
pub rendering: Option<serde_json::Map<String, Value>>,
}

/// Information on how to render a given credential type.
// TODO: model the actual object properties.
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct RenderingMetadata(serde_json::Map<String, Value>);
42 changes: 30 additions & 12 deletions identity_credential/src/sd_jwt_vc/metadata/integrity.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use std::{fmt::Display, str::FromStr};
use std::fmt::Display;
use std::str::FromStr;

use anyhow::anyhow;
use identity_core::convert::{Base, BaseEncoding};
use serde::{Deserialize, Serialize};
use identity_core::convert::Base;
use identity_core::convert::BaseEncoding;
use serde::Deserialize;
use serde::Serialize;

/// An integrity metadata string as defined in [W3C SRI](https://www.w3.org/TR/SRI/#integrity-metadata).
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
Expand All @@ -14,8 +17,11 @@ impl IntegrityMetadata {
/// ## Example
/// ```rust
/// use identity_credential::sd_jwt_vc::metadata::IntegrityMetadata;
///
/// let integrity_data = IntegrityMetadata::parse("sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd").unwrap();
///
/// let integrity_data = IntegrityMetadata::parse(
/// "sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd",
/// )
/// .unwrap();
/// ```
pub fn parse(s: &str) -> Result<Self, anyhow::Error> {
s.parse()
Expand All @@ -25,8 +31,11 @@ impl IntegrityMetadata {
/// ## Example
/// ```rust
/// use identity_credential::sd_jwt_vc::metadata::IntegrityMetadata;
///
/// let integrity_data: IntegrityMetadata = "sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd".parse().unwrap();
///
/// let integrity_data: IntegrityMetadata =
/// "sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd"
/// .parse()
/// .unwrap();
/// assert_eq!(integrity_data.alg(), "sha384");
/// ```
pub fn alg(&self) -> &str {
Expand All @@ -37,9 +46,15 @@ impl IntegrityMetadata {
/// ## Example
/// ```rust
/// use identity_credential::sd_jwt_vc::metadata::IntegrityMetadata;
///
/// let integrity_data: IntegrityMetadata = "sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd".parse().unwrap();
/// assert_eq!(integrity_data.digest(), "dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd");
///
/// let integrity_data: IntegrityMetadata =
/// "sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd"
/// .parse()
/// .unwrap();
/// assert_eq!(
/// integrity_data.digest(),
/// "dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd"
/// );
/// ```
pub fn digest(&self) -> &str {
self.0.split('-').nth(1).unwrap()
Expand All @@ -54,8 +69,11 @@ impl IntegrityMetadata {
/// ## Example
/// ```rust
/// use identity_credential::sd_jwt_vc::metadata::IntegrityMetadata;
///
/// let integrity_data: IntegrityMetadata = "sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd".parse().unwrap();
///
/// let integrity_data: IntegrityMetadata =
/// "sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb1A1cv+Lyv4Hk8vHd"
/// .parse()
/// .unwrap();
/// assert!(integrity_data.options().is_none());
/// ```
pub fn options(&self) -> Option<&str> {
Expand Down
6 changes: 4 additions & 2 deletions identity_credential/src/sd_jwt_vc/metadata/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// Copyright 2020-2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

mod display;
mod integrity;
mod issuer;
mod vc_type;
mod integrity;

pub use display::*;
pub use integrity::*;
pub use issuer::*;
pub use vc_type::*;
pub use integrity::*;
36 changes: 22 additions & 14 deletions identity_credential/src/sd_jwt_vc/metadata/vc_type.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use futures::future::BoxFuture;
use futures::future::FutureExt;
use identity_core::common::StringOrUrl;
use identity_core::common::Url;
use itertools::Itertools as _;
use serde::Deserialize;
Expand All @@ -11,21 +10,29 @@ use crate::sd_jwt_vc::Error;
use crate::sd_jwt_vc::Resolver;
use crate::sd_jwt_vc::Result;

use super::DisplayMetadata;
use super::IntegrityMetadata;

/// Path used to retrieve VC Type Metadata.
pub const WELL_KNOWN_VCT: &str = "/.well-known/vct";

/// SD-JWT VC's credential type.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TypeMetadata {
name: Option<String>,
description: Option<String>,
extends: Option<StringOrUrl>,
/// A human-readable name for the type, intended for developers reading the JSON document.
pub name: Option<String>,
/// A human-readable description for the type, intended for developers reading the JSON document.
pub description: Option<String>,
/// A URI of another type that this type extends.
pub extends: Option<Url>,
/// Integrity metadata for the extended type.
#[serde(rename = "extends#integrity")]
extends_integrity: Option<IntegrityMetadata>,
pub extends_integrity: Option<IntegrityMetadata>,
/// Either an embedded schema or a reference to one.
#[serde(flatten)]
schema: Option<TypeSchema>,
pub schema: Option<TypeSchema>,
/// An object containing display information for the type.
pub display: Option<DisplayMetadata>,
}

impl TypeMetadata {
Expand All @@ -38,7 +45,7 @@ impl TypeMetadata {
self.description.as_deref()
}
/// Returns the URI or string of the type this VC type extends, if any.
pub fn extends(&self) -> Option<&StringOrUrl> {
pub fn extends(&self) -> Option<&Url> {
self.extends.as_ref()
}
/// Returns the integrity string of the extended type object, if any.
Expand All @@ -65,7 +72,7 @@ impl TypeMetadata {
/// another type or JSON schema.
pub async fn validate_credential_with_resolver<R>(&self, credential: &Value, resolver: &R) -> Result<()>
where
R: Resolver<StringOrUrl, Target = Value> + Sync,
R: Resolver<Url, Target = Value> + Sync,
{
validate_credential_impl(self.clone(), credential, resolver, vec![]).await
}
Expand All @@ -79,7 +86,7 @@ fn validate_credential_impl<'c, 'r, R>(
mut passed_types: Vec<TypeMetadata>,
) -> BoxFuture<'c, Result<()>>
where
R: Resolver<StringOrUrl, Target = Value> + Sync,
R: Resolver<Url, Target = Value> + Sync,
'r: 'c,
{
async move {
Expand Down Expand Up @@ -107,8 +114,7 @@ where
let TypeSchema::Uri { schema_uri, .. } = current_type.schema.as_ref().unwrap() else {
unreachable!("schema is provided through `schema_uri` as checked by `validate_credential`");
};
let schema_uri = StringOrUrl::Url(schema_uri.clone());
let schema = resolver.resolve(&schema_uri).await.map_err(|e| Error::Resolution {
let schema = resolver.resolve(schema_uri).await.map_err(|e| Error::Resolution {
input: schema_uri.to_string(),
source: e,
})?;
Expand Down Expand Up @@ -180,6 +186,7 @@ mod tests {
description: None,
extends: None,
extends_integrity: None,
display: None,
schema: Some(TypeSchema::Object {
schema: json!({
"$schema": "https://json-schema.org/draft/2020-12/schema",
Expand All @@ -202,6 +209,7 @@ mod tests {
description: None,
extends: None,
extends_integrity: None,
display: None,
schema: Some(TypeSchema::Uri {
schema_uri: Url::parse("https://example.com/vc_types/1").unwrap(),
schema_uri_integrity: None,
Expand All @@ -210,9 +218,9 @@ mod tests {

struct SchemaResolver;
#[async_trait]
impl Resolver<StringOrUrl> for SchemaResolver {
impl Resolver<Url> for SchemaResolver {
type Target = Value;
async fn resolve(&self, _input: &StringOrUrl) -> resolver::Result<Self::Target> {
async fn resolve(&self, _input: &Url) -> resolver::Result<Self::Target> {
Ok(serde_json::to_value(IMMEDIATE_TYPE_METADATA.clone().schema).unwrap())
}
}
Expand Down
1 change: 0 additions & 1 deletion identity_resolver/src/legacy/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,3 @@ impl<DOC: 'static> SingleThreadedCommand<DOC> {
Self { fun }
}
}

1 change: 0 additions & 1 deletion identity_resolver/src/legacy/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,3 @@ pub enum ErrorCause {
#[error("none of the attached clients support the network {0}")]
UnsupportedNetwork(String),
}

2 changes: 1 addition & 1 deletion identity_resolver/src/legacy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// SPDX-License-Identifier: Apache-2.0

mod commands;
mod resolver;
mod error;
mod resolver;

use self::commands::SingleThreadedCommand;
use identity_document::document::CoreDocument;
Expand Down
2 changes: 1 addition & 1 deletion identity_resolver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#[cfg(feature = "v2")]
#[path = ""]
mod v2 {
mod error;
mod error;
mod resolver;

pub use error::Error;
Expand Down

0 comments on commit d278060

Please sign in to comment.