Skip to content

Commit

Permalink
Make VCDM credential subject a non-empty vec
Browse files Browse the repository at this point in the history
  • Loading branch information
sbihel committed Oct 25, 2024
1 parent d031802 commit ea10de5
Show file tree
Hide file tree
Showing 17 changed files with 66 additions and 54 deletions.
12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ssi"
version = "0.9.0"
version = "0.10.0"
authors = ["Spruce Systems, Inc."]
edition = "2021"
license = "Apache-2.0"
Expand Down Expand Up @@ -37,9 +37,9 @@ ssi-json-ld = { path = "./crates/json-ld", version = "0.3", default-features = f
ssi-security = { path = "./crates/security", version = "0.1", default-features = false }
ssi-caips = { path = "./crates/caips", version = "0.2.1", default-features = false }
ssi-ucan = { path = "./crates/ucan", version = "0.2.1", default-features = false }
ssi-zcap-ld = { path = "./crates/zcap-ld", version = "0.2.1", default-features = false }
ssi-zcap-ld = { path = "./crates/zcap-ld", version = "0.3.0", default-features = false }
ssi-ssh = { path = "./crates/ssh", version = "0.2.1", default-features = false }
ssi-status = { path = "./crates/status", version = "0.2", default-features = false }
ssi-status = { path = "./crates/status", version = "0.3.0", default-features = false }
ssi-bbs = { path = "./crates/bbs", version = "0.1.1", default-features = false }

# Verifiable Claims
Expand All @@ -48,13 +48,13 @@ ssi-jws = { path = "./crates/claims/crates/jws", version = "0.3", default-featur
ssi-jwt = { path = "./crates/claims/crates/jwt", version = "0.3", default-features = false }
ssi-sd-jwt = { path = "./crates/claims/crates/sd-jwt", version = "0.3", default-features = false }
ssi-cose = { path = "./crates/claims/crates/cose", version = "0.1", default-features = false }
ssi-vc = { path = "./crates/claims/crates/vc", version = "0.3.1", default-features = false }
ssi-vc-jose-cose = { path = "./crates/claims/crates/vc-jose-cose", version = "0.1.1", default-features = false }
ssi-vc = { path = "./crates/claims/crates/vc", version = "0.4.0", default-features = false }
ssi-vc-jose-cose = { path = "./crates/claims/crates/vc-jose-cose", version = "0.2.0", default-features = false }
ssi-data-integrity-core = { path = "./crates/claims/crates/data-integrity/core", version = "0.2", default-features = false }
ssi-di-sd-primitives = { path = "./crates/claims/crates/data-integrity/sd-primitives", version = "0.2", default-features = false }
ssi-data-integrity-suites = { path = "./crates/claims/crates/data-integrity/suites", version = "0.1.1", default-features = false }
ssi-data-integrity = { path = "./crates/claims/crates/data-integrity", version = "0.1.1", default-features = false }
ssi-claims = { path = "./crates/claims", version = "0.1.1", default-features = false }
ssi-claims = { path = "./crates/claims", version = "0.2.0", default-features = false }

# DID methods
ssi-dids-core = { path = "./crates/dids/core", version = "0.1.1", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion crates/claims/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ssi-claims"
version = "0.1.1"
version = "0.2.0"
edition = "2021"
authors = ["Spruce Systems, Inc."]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion crates/claims/crates/vc-jose-cose/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ssi-vc-jose-cose"
version = "0.1.1"
version = "0.2.0"
edition = "2021"
authors = ["Spruce Systems, Inc."]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion crates/claims/crates/vc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ssi-vc"
version = "0.3.1"
version = "0.4.0"
edition = "2021"
authors = ["Spruce Systems, Inc."]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion crates/claims/crates/vc/src/v1/revocation/v2020.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ impl CredentialStatus for RevocationList2020Status {
)));
}

let revocation_list = match revocation_list_credential.credential_subjects.as_slice() {
let revocation_list = match revocation_list_credential.credential_subjects.as_ref() {
[RevocationList2020Subject::RevocationList2020(l)] => l,
[] => return Ok(StatusCheck::Invalid(Reason::MissingCredentialSubject)),
_ => return Ok(StatusCheck::Invalid(Reason::TooManyCredentialSubjects)),
Expand Down
2 changes: 1 addition & 1 deletion crates/claims/crates/vc/src/v1/revocation/v2021.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ impl CredentialStatus for StatusList2021Entry {
)));
}

let revocation_list = match status_list_credential.credential_subjects.as_slice() {
let revocation_list = match status_list_credential.credential_subjects.as_ref() {
[StatusList2021Subject::StatusList2021(l)] => l,
[] => return Ok(StatusCheck::Invalid(Reason::MissingCredentialSubject)),
_ => return Ok(StatusCheck::Invalid(Reason::TooManyCredentialSubjects)),
Expand Down
16 changes: 6 additions & 10 deletions crates/claims/crates/vc/src/v1/syntax/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use xsd_types::DateTime;

use crate::{
syntax::{
not_null, value_or_array, IdOr, IdentifiedObject, IdentifiedTypedObject,
MaybeIdentifiedTypedObject, RequiredContextList, RequiredType, RequiredTypeSet,
TypeSerializationPolicy, Types,
non_empty_value_or_array, not_null, value_or_array, IdOr, IdentifiedObject,
IdentifiedTypedObject, MaybeIdentifiedTypedObject, NonEmptyVec, RequiredContextList,
RequiredType, RequiredTypeSet, TypeSerializationPolicy, Types,
},
Identified, MaybeIdentified, Typed,
};
Expand Down Expand Up @@ -79,12 +79,8 @@ pub struct SpecializedJsonCredential<

/// Credential subjects.
#[serde(rename = "credentialSubject")]
#[serde(
with = "value_or_array",
default,
skip_serializing_if = "Vec::is_empty"
)]
pub credential_subjects: Vec<Subject>,
#[serde(with = "non_empty_value_or_array")]
pub credential_subjects: NonEmptyVec<Subject>,

/// Issuer.
pub issuer: Issuer,
Expand Down Expand Up @@ -180,7 +176,7 @@ where
id: Option<UriBuf>,
issuer: Issuer,
issuance_date: xsd_types::DateTime,
credential_subjects: Vec<Subject>,
credential_subjects: NonEmptyVec<Subject>,
) -> Self {
Self {
context: Context::default(),
Expand Down
9 changes: 6 additions & 3 deletions crates/dids/methods/ethr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,10 @@ mod tests {
signing::AlterSignature, AnyInputSuiteOptions, AnySuite, CryptographicSuite,
ProofOptions,
},
vc::v1::{JsonCredential, JsonPresentation},
vc::{
syntax::NonEmptyVec,
v1::{JsonCredential, JsonPresentation},
},
VerificationParameters,
};
use ssi_dids_core::{did, DIDResolver};
Expand Down Expand Up @@ -492,9 +495,9 @@ mod tests {
None,
did.clone().into_uri().into(),
"2021-02-18T20:23:13Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:example:foo"
})],
})),
);

let verification_method = if eip712 {
Expand Down
14 changes: 7 additions & 7 deletions crates/dids/methods/key/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ mod tests {
use resolution::Parameters;
use ssi_claims::{
data_integrity::{AnyInputSuiteOptions, AnySuite},
vc::v1::JsonCredential,
vc::{syntax::NonEmptyVec, v1::JsonCredential},
VerificationParameters,
};
use ssi_data_integrity::{CryptographicSuite, ProofOptions as SuiteOptions};
Expand Down Expand Up @@ -576,9 +576,9 @@ mod tests {
Some(uri!("http://example.org/credentials/3731").to_owned()),
did.clone().into_uri().into(),
"2020-08-19T21:41:50Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:example:d23dd687a7dc6787646f2eb98d0"
})],
})),
);

let verification_method = DIDKey
Expand Down Expand Up @@ -630,9 +630,9 @@ mod tests {
None,
did.clone().into_uri().into(),
"2021-02-18T20:17:46Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:example:d23dd687a7dc6787646f2eb98d0"
})],
})),
);

let verification_method = DIDKey
Expand Down Expand Up @@ -684,9 +684,9 @@ mod tests {
None,
did.clone().into_uri().into(),
"2021-02-18T20:17:46Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:example:d23dd687a7dc6787646f2eb98d0"
})],
})),
);

let verification_method = DIDKey
Expand Down
18 changes: 12 additions & 6 deletions crates/dids/methods/pkh/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,10 @@ mod tests {
data_integrity::{
signing::AlterSignature, AnyInputSuiteOptions, CryptographicSuite, ProofOptions,
},
vc::v1::{JsonCredential, JsonPresentation},
vc::{
syntax::NonEmptyVec,
v1::{JsonCredential, JsonPresentation},
},
VerificationParameters,
};
use ssi_verification_methods_core::{ProofPurpose, SingleSecretSigner};
Expand All @@ -974,9 +977,9 @@ mod tests {
None,
did.clone().into_uri().into(),
"2021-03-18T16:38:25Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:example:foo"
})],
})),
);

let issuance_date = cred.issuance_date.clone().unwrap();
Expand Down Expand Up @@ -1090,7 +1093,10 @@ mod tests {
data_integrity::{
signing::AlterSignature, AnyInputSuiteOptions, CryptographicSuite, ProofOptions,
},
vc::v1::{JsonCredential, JsonPresentation},
vc::{
syntax::NonEmptyVec,
v1::{JsonCredential, JsonPresentation},
},
VerificationParameters,
};
use ssi_verification_methods_core::{ProofPurpose, SingleSecretSigner};
Expand All @@ -1105,9 +1111,9 @@ mod tests {
None,
did.clone().into_uri().into(),
"2021-03-18T16:38:25Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:example:foo"
})],
})),
);
let issuance_date = cred.issuance_date.clone().unwrap();
let created_date =
Expand Down
17 changes: 10 additions & 7 deletions crates/dids/methods/tz/tests/did.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use ssi_claims::{
signing::AlterSignature, AnyInputSuiteOptions, AnySuite, CryptographicSuite, DataIntegrity,
ProofOptions as SuiteOptions,
},
vc::v1::{JsonCredential, JsonPresentation},
vc::{
syntax::NonEmptyVec,
v1::{JsonCredential, JsonPresentation},
},
VerificationParameters,
};
use ssi_dids_core::{did, resolution::Options, DIDResolver, VerificationMethodDIDResolver};
Expand Down Expand Up @@ -223,9 +226,9 @@ async fn credential_prove_verify_did_tz1() {
None,
did.clone().into_uri().into(),
"2021-01-27T16:39:07Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:example:foo"
})]
}))
),
vec![ssi_claims::data_integrity::Proof::new(
ssi_claims::data_integrity::suites::Ed25519BLAKE2BDigestSize20Base58CheckEncodedSignature2021,
Expand Down Expand Up @@ -327,9 +330,9 @@ async fn credential_prove_verify_did_tz2() {
None,
did.clone().into_uri().into(),
"2021-02-18T20:23:13Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:example:foo"
})],
})),
);

let didtz = VerificationMethodDIDResolver::new(DIDTZ);
Expand Down Expand Up @@ -425,9 +428,9 @@ async fn credential_prove_verify_did_tz3() {
None,
did.clone().into_uri().into(),
"2021-03-04T14:18:21Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:example:foo"
})],
})),
);

let didtz = VerificationMethodDIDResolver::new(DIDTZ);
Expand Down
6 changes: 3 additions & 3 deletions crates/dids/methods/web/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl DIDMethodResolver for DIDWeb {
mod tests {
use ssi_claims::{
data_integrity::{AnySuite, CryptographicSuite, ProofOptions},
vc::v1::JsonCredential,
vc::{syntax::NonEmptyVec, v1::JsonCredential},
VerificationParameters,
};
use ssi_dids_core::{did, DIDResolver, Document, VerificationMethodDIDResolver};
Expand Down Expand Up @@ -254,9 +254,9 @@ mod tests {
None,
did!("did:web:localhost").to_owned().into_uri().into(),
"2021-01-26T16:57:27Z".parse().unwrap(),
vec![json_syntax::json!({
NonEmptyVec::new(json_syntax::json!({
"id": "did:web:localhost"
})],
})),
);

let key: JWK = include_str!("../../../../../tests/ed25519-2020-10-18.json")
Expand Down
2 changes: 1 addition & 1 deletion crates/status/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ssi-status"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
authors = ["Spruce Systems, Inc."]
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion crates/zcap-ld/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ssi-zcap-ld"
version = "0.2.1"
version = "0.3.0"
edition = "2021"
authors = ["Spruce Systems, Inc."]
license = "Apache-2.0"
Expand Down
4 changes: 2 additions & 2 deletions examples/issue-revocation-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use ssi::{
jwk::JWK,
verification_methods::SingleSecretSigner,
};
use ssi_claims::VerificationParameters;
use ssi_claims::{vc::syntax::NonEmptyVec, VerificationParameters};
use ssi_dids::DIDResolver;
use static_iref::{iri, uri};

Expand All @@ -30,7 +30,7 @@ async fn main() {
Some(uri!("https://example.test/revocationList.json").to_owned()),
uri!("did:example:foo").to_owned().into(),
xsd_types::DateTime::now_ms(),
vec![RevocationList2020Subject::RevocationList2020(rl)],
NonEmptyVec::new(RevocationList2020Subject::RevocationList2020(rl)),
);

let verification_method = iri!("did:example:foo#key1").into();
Expand Down
4 changes: 2 additions & 2 deletions examples/issue-status-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use ssi::{
jwk::JWK,
verification_methods::SingleSecretSigner,
};
use ssi_claims::VerificationParameters;
use ssi_claims::{vc::syntax::NonEmptyVec, VerificationParameters};
use ssi_dids::DIDResolver;
use static_iref::{iri, uri};

Expand All @@ -28,7 +28,7 @@ async fn main() {
Some(uri!("https://example.com/credentials/status/3").to_owned()),
uri!("did:example:12345").to_owned().into(),
xsd_types::DateTime::now_ms(),
vec![StatusList2021Subject::StatusList2021(rl)],
NonEmptyVec::new(StatusList2021Subject::StatusList2021(rl)),
);

let verification_method = iri!("did:example:12345#key1").into();
Expand Down
6 changes: 5 additions & 1 deletion tests/send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use ssi::{
verification_methods::SingleSecretSigner,
JWK,
};
use ssi_claims::vc::syntax::NonEmptyVec;
use static_iref::uri;
use std::future::Future;

Expand All @@ -30,7 +31,10 @@ fn data_integrity_sign_is_send() {
Some(uri!("https://example.org/#CredentialId").to_owned()), // id
uri!("https://example.org/#Issuer").to_owned().into(), // issuer
xsd_types::DateTime::now(), // issuance date
vec![],
NonEmptyVec::new(Claims {
name: "name".into(),
email: "email@example.com".into(),
}),
);

let key = JWK::generate_p256(); // requires the `p256` feature.
Expand Down

0 comments on commit ea10de5

Please sign in to comment.