Skip to content

Commit

Permalink
Fix W3C Bitstring status list statusMessage.status property de/seri…
Browse files Browse the repository at this point in the history
…alization.

Fixes #594
  • Loading branch information
timothee-haudebourg committed Aug 23, 2024
1 parent 0a939b1 commit 605bb18
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 124 deletions.
3 changes: 0 additions & 3 deletions crates/claims/crates/jws/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ pub use signature::*;
mod verification;
pub use verification::*;

#[cfg(feature = "linked-data")]
mod linked_data;

/// Decoded JWS.
#[derive(Clone, PartialEq, Eq)]
pub struct JWS<T = Vec<u8>> {
Expand Down
118 changes: 0 additions & 118 deletions crates/claims/crates/jws/src/linked_data.rs

This file was deleted.

4 changes: 2 additions & 2 deletions crates/claims/crates/vc/examples/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use ssi_verification_methods::{
};
use static_iref::{iri, uri};
use std::{borrow::Cow, collections::HashMap, sync::Arc};
use xsd_types::DateTime;
use xsd_types::{DateTime, DateTimeStamp};

#[derive(Clone, linked_data::Serialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -159,7 +159,7 @@ async fn main() {
// Signature options, defining the crypto suite, signature date,
// signing key and proof purpose.
let proof_options = ProofOptions::new(
DateTime::now(),
DateTimeStamp::now(),
iri!("https://example.com/controller#key").to_owned().into(),
ProofPurpose::Assertion,
(),
Expand Down
31 changes: 30 additions & 1 deletion crates/status/src/impl/bitstring_status_list/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! W3C Bitstring Status List v1.0
//! W3C Bitstring Status List v1.0 (Working Draft 06 April 2024)
//!
//! A privacy-preserving, space-efficient, and high-performance mechanism for
//! publishing status information such as suspension or revocation of Verifiable
Expand All @@ -17,10 +17,17 @@ pub use syntax::*;

#[derive(Debug, Serialize, Deserialize)]
pub struct StatusMessage {
#[serde(with = "prefixed_hexadecimal")]
pub status: u8,
pub message: String,
}

impl StatusMessage {
pub fn new(status: u8, message: String) -> Self {
Self { status, message }
}
}

#[derive(Debug, thiserror::Error)]
#[error("invalid status size `{0}`")]
pub struct InvalidStatusSize(u8);
Expand Down Expand Up @@ -545,6 +552,28 @@ impl StatusMap for StatusList {
}
}

mod prefixed_hexadecimal {
use serde::{Deserialize, Deserializer, Serialize, Serializer};

pub fn serialize<S>(value: &u8, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
format!("{value:#x}").serialize(serializer)
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<u8, D::Error>
where
D: Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;
let number = string
.strip_prefix("0x")
.ok_or_else(|| serde::de::Error::custom("missing `0x` prefix"))?;
u8::from_str_radix(&number, 16).map_err(serde::de::Error::custom)
}
}

#[cfg(test)]
mod tests {
use rand::{rngs::StdRng, RngCore, SeedableRng};
Expand Down
4 changes: 4 additions & 0 deletions crates/status/src/impl/bitstring_status_list/syntax/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ impl EncodedList {
/// 16MB.
pub const DEFAULT_LIMIT: u64 = 16 * 1024 * 1024;

pub fn new(value: String) -> Self {
Self(value)
}

pub fn encode(bytes: &[u8]) -> Self {
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
encoder.write_all(bytes).unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,53 @@ impl BitstringStatusList {
Ok(StatusList::from_bytes(self.status_size, bytes, self.ttl))
}
}

#[cfg(test)]
mod tests {
use super::BitstringStatusList;
use crate::bitstring_status_list::{EncodedList, StatusMessage, StatusPurpose, TimeToLive};

const STATUS_LIST: &str = r#"{
"id": "https://example.com/status/3#list",
"type": "BitstringStatusList",
"ttl": 500,
"statusPurpose": "message",
"statusReference": "https://example.org/status-dictionary/",
"statusSize": 2,
"statusMessage": [
{"status":"0x0", "message":"valid"},
{"status":"0x1", "message":"invalid"},
{"status":"0x2", "message":"pending_review"}
],
"encodedList": "uH4sIAAAAAAAAA-3BMQEAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA"
}"#;

#[test]
fn deserialize() {
serde_json::from_str::<BitstringStatusList>(STATUS_LIST).unwrap();
}

#[test]
fn serialize() {
let expected: serde_json::Value = serde_json::from_str(STATUS_LIST).unwrap();

let status_list = BitstringStatusList {
id: Some("https://example.com/status/3#list".parse().unwrap()),
ttl: TimeToLive(500),
status_purpose: StatusPurpose::Message,
status_reference: Some("https://example.org/status-dictionary/".parse().unwrap()),
status_size: 2.try_into().unwrap(),
status_message: vec![
StatusMessage::new(0, "valid".to_owned()),
StatusMessage::new(1, "invalid".to_owned()),
StatusMessage::new(2, "pending_review".to_owned()),
],
encoded_list: EncodedList::new(
"uH4sIAAAAAAAAA-3BMQEAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA".to_owned(),
),
};

let value = serde_json::to_value(status_list).unwrap();
assert_eq!(value, expected);
}
}

0 comments on commit 605bb18

Please sign in to comment.