use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum AccessTier {
Public = 0,
Professional = 1,
Confidential = 2,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PassportCredential {
#[serde(rename = "@context")]
pub context: Vec<String>,
#[serde(rename = "type")]
pub credential_type: Vec<String>,
pub id: String,
pub issuer: String,
pub valid_from: DateTime<Utc>,
pub credential_subject: PassportCredentialSubject,
}
impl PassportCredential {
pub const VC_BASE_CONTEXT: &'static str = "https://www.w3.org/ns/credentials/v2";
pub const PASSPORT_CONTEXT: &'static str =
"https://schema.odal-node.io/credentials/dpp-passport/v1";
#[must_use]
pub fn new(issuer: String, credential_subject: PassportCredentialSubject) -> Self {
Self {
context: vec![Self::VC_BASE_CONTEXT.into(), Self::PASSPORT_CONTEXT.into()],
credential_type: vec![
"VerifiableCredential".into(),
"DppPassportCredential".into(),
],
id: format!("urn:uuid:{}", uuid::Uuid::now_v7()),
issuer,
valid_from: Utc::now(),
credential_subject,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PassportCredentialSubject {
pub id: String,
pub payload_hash: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignedCredential {
pub credential: PassportCredential,
pub jws: String,
pub issuer_did: String,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_passport_credential_guarantees_vc_base_context_and_type() {
let vc = PassportCredential::new(
"did:web:issuer.example.com".into(),
PassportCredentialSubject {
id: "urn:uuid:00000000-0000-0000-0000-000000000000".into(),
payload_hash: "deadbeef".into(),
},
);
assert_eq!(
vc.context.first().map(String::as_str),
Some(PassportCredential::VC_BASE_CONTEXT)
);
assert!(
vc.credential_type
.contains(&"VerifiableCredential".to_string())
);
assert!(vc.id.starts_with("urn:uuid:"));
}
}