Skip to content

Commit b2f6d43

Browse files
committed
feat(dataverse): garantee claim storage format
1 parent f74aa3b commit b2f6d43

File tree

2 files changed

+47
-37
lines changed

2 files changed

+47
-37
lines changed

contracts/okp4-dataverse/src/registrar/credential.rs

+41-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::credential::rdf_marker::IRI_VC_TYPE;
22
use crate::credential::vc::VerifiableCredential;
3+
use crate::registrar::rdf::VC_CLAIM;
34
use crate::ContractError;
45
use cosmwasm_std::Addr;
56
use itertools::Itertools;
6-
use okp4_rdf::dataset::Dataset;
7+
use rio_api::model::{BlankNode, NamedNode, Subject, Term, Triple};
78

89
#[derive(Debug, PartialEq)]
910
pub struct DataverseCredential<'a> {
@@ -14,7 +15,7 @@ pub struct DataverseCredential<'a> {
1415
pub valid_from: &'a str,
1516
pub valid_until: Option<&'a str>,
1617
pub subject: &'a str,
17-
pub claim: &'a Dataset<'a>,
18+
pub claim: Vec<Triple<'a>>,
1819
}
1920

2021
impl<'a> DataverseCredential<'a> {
@@ -33,16 +34,46 @@ impl<'a> DataverseCredential<'a> {
3334

3435
fn extract_vc_claim(
3536
vc: &'a VerifiableCredential<'a>,
36-
) -> Result<(&'a str, &'a Dataset<'a>), ContractError> {
37-
vc.claims
37+
) -> Result<(&'a str, Vec<Triple<'a>>), ContractError> {
38+
//todo: use the canon identifier issuer instead and rename all blank nodes
39+
let claim_node = BlankNode { id: "c0" };
40+
41+
let claim = vc.claims.iter().exactly_one().map_err(|_| {
42+
ContractError::UnsupportedCredential(
43+
"credential is expected to contain exactly one claim".to_string(),
44+
)
45+
})?;
46+
47+
let mut triples = claim
48+
.content
3849
.iter()
39-
.exactly_one()
40-
.map(|claim| (claim.id, &(claim.content)))
41-
.map_err(|_| {
42-
ContractError::UnsupportedCredential(
43-
"credential is expected to contain exactly one claim".to_string(),
44-
)
50+
.map(|q| {
51+
let subject = match q.subject {
52+
Subject::NamedNode(n) => {
53+
if n.iri != claim.id {
54+
Err(ContractError::UnsupportedCredential(
55+
"claim hierarchy can be forge only through blank nodes".to_string(),
56+
))?;
57+
}
58+
Subject::BlankNode(claim_node)
59+
}
60+
_ => q.subject,
61+
};
62+
Ok(Triple {
63+
subject,
64+
predicate: q.predicate,
65+
object: q.object,
66+
})
4567
})
68+
.collect::<Result<Vec<Triple<'a>>, ContractError>>()?;
69+
70+
triples.push(Triple {
71+
subject: Subject::NamedNode(NamedNode { iri: vc.id }),
72+
predicate: VC_CLAIM,
73+
object: Term::BlankNode(BlankNode { id: "c0" }),
74+
});
75+
76+
Ok((claim.id, triples))
4677
}
4778
}
4879

contracts/okp4-dataverse/src/registrar/rdf.rs

+6-27
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::registrar::credential::DataverseCredential;
33
use crate::ContractError;
44
use cosmwasm_std::{Binary, StdError};
55
use okp4_rdf::serde::{DataFormat, TripleWriter};
6-
use rio_api::model::{BlankNode, Literal, NamedNode, Subject, Term, Triple};
6+
use rio_api::model::{Literal, NamedNode, Subject, Term, Triple};
77

88
pub const VC_SUBMITTER_ADDRESS: NamedNode<'_> = NamedNode {
99
iri: "dataverse:credential#submitterAddress",
@@ -27,13 +27,9 @@ pub const VC_CLAIM: NamedNode<'_> = NamedNode {
2727
iri: "dataverse:credential#claim",
2828
};
2929

30-
impl<'a> TryFrom<&'a DataverseCredential<'a>> for Vec<Triple<'a>> {
31-
type Error = ContractError;
32-
33-
fn try_from(credential: &'a DataverseCredential<'a>) -> Result<Self, Self::Error> {
30+
impl<'a> From<&'a DataverseCredential<'a>> for Vec<Triple<'a>> {
31+
fn from(credential: &'a DataverseCredential<'a>) -> Self {
3432
let c_subject = Subject::NamedNode(NamedNode { iri: credential.id });
35-
//todo: use the canon identifier issuer instead and rename all blank nodes
36-
let claim_node = BlankNode { id: "c0" };
3733

3834
let mut triples = vec![
3935
Triple {
@@ -72,26 +68,9 @@ impl<'a> TryFrom<&'a DataverseCredential<'a>> for Vec<Triple<'a>> {
7268
iri: credential.subject,
7369
}),
7470
},
75-
Triple {
76-
subject: c_subject,
77-
predicate: VC_CLAIM,
78-
object: Term::BlankNode(claim_node),
79-
},
8071
];
8172

82-
triples.extend(credential.claim.iter().map(|q| {
83-
let subject = match q.subject {
84-
Subject::NamedNode(n) if n.iri == credential.subject => {
85-
Subject::BlankNode(claim_node)
86-
}
87-
_ => q.subject,
88-
};
89-
Triple {
90-
subject,
91-
predicate: q.predicate,
92-
object: q.object,
93-
}
94-
}));
73+
triples.extend(credential.claim.as_slice());
9574

9675
if let Some(valid_until) = credential.valid_until {
9776
triples.push(Triple {
@@ -104,15 +83,15 @@ impl<'a> TryFrom<&'a DataverseCredential<'a>> for Vec<Triple<'a>> {
10483
});
10584
}
10685

107-
Ok(triples)
86+
triples
10887
}
10988
}
11089

11190
pub fn serialize(
11291
credential: &DataverseCredential<'_>,
11392
format: DataFormat,
11493
) -> Result<Binary, ContractError> {
115-
let triples: Vec<Triple<'_>> = credential.try_into()?;
94+
let triples: Vec<Triple<'_>> = credential.into();
11695
let out: Vec<u8> = Vec::default();
11796
let mut writer = TripleWriter::new(&format, out);
11897
for triple in triples {

0 commit comments

Comments
 (0)