Skip to content

Commit

Permalink
feat(dataverse): garantee claim storage format
Browse files Browse the repository at this point in the history
  • Loading branch information
amimart committed Feb 16, 2024
1 parent f74aa3b commit b2f6d43
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 37 deletions.
51 changes: 41 additions & 10 deletions contracts/okp4-dataverse/src/registrar/credential.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::credential::rdf_marker::IRI_VC_TYPE;
use crate::credential::vc::VerifiableCredential;
use crate::registrar::rdf::VC_CLAIM;
use crate::ContractError;
use cosmwasm_std::Addr;
use itertools::Itertools;
use okp4_rdf::dataset::Dataset;
use rio_api::model::{BlankNode, NamedNode, Subject, Term, Triple};

#[derive(Debug, PartialEq)]
pub struct DataverseCredential<'a> {
Expand All @@ -14,7 +15,7 @@ pub struct DataverseCredential<'a> {
pub valid_from: &'a str,
pub valid_until: Option<&'a str>,
pub subject: &'a str,
pub claim: &'a Dataset<'a>,
pub claim: Vec<Triple<'a>>,
}

impl<'a> DataverseCredential<'a> {
Expand All @@ -33,16 +34,46 @@ impl<'a> DataverseCredential<'a> {

fn extract_vc_claim(
vc: &'a VerifiableCredential<'a>,
) -> Result<(&'a str, &'a Dataset<'a>), ContractError> {
vc.claims
) -> Result<(&'a str, Vec<Triple<'a>>), ContractError> {
//todo: use the canon identifier issuer instead and rename all blank nodes
let claim_node = BlankNode { id: "c0" };

let claim = vc.claims.iter().exactly_one().map_err(|_| {
ContractError::UnsupportedCredential(
"credential is expected to contain exactly one claim".to_string(),
)
})?;

let mut triples = claim
.content
.iter()
.exactly_one()
.map(|claim| (claim.id, &(claim.content)))
.map_err(|_| {
ContractError::UnsupportedCredential(
"credential is expected to contain exactly one claim".to_string(),
)
.map(|q| {
let subject = match q.subject {
Subject::NamedNode(n) => {
if n.iri != claim.id {
Err(ContractError::UnsupportedCredential(
"claim hierarchy can be forge only through blank nodes".to_string(),
))?;
}
Subject::BlankNode(claim_node)
}
_ => q.subject,
};
Ok(Triple {
subject,
predicate: q.predicate,
object: q.object,
})
})
.collect::<Result<Vec<Triple<'a>>, ContractError>>()?;

triples.push(Triple {
subject: Subject::NamedNode(NamedNode { iri: vc.id }),
predicate: VC_CLAIM,
object: Term::BlankNode(BlankNode { id: "c0" }),
});

Ok((claim.id, triples))
}
}

Expand Down
33 changes: 6 additions & 27 deletions contracts/okp4-dataverse/src/registrar/rdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::registrar::credential::DataverseCredential;
use crate::ContractError;
use cosmwasm_std::{Binary, StdError};
use okp4_rdf::serde::{DataFormat, TripleWriter};
use rio_api::model::{BlankNode, Literal, NamedNode, Subject, Term, Triple};
use rio_api::model::{Literal, NamedNode, Subject, Term, Triple};

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

impl<'a> TryFrom<&'a DataverseCredential<'a>> for Vec<Triple<'a>> {
type Error = ContractError;

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

let mut triples = vec![
Triple {
Expand Down Expand Up @@ -72,26 +68,9 @@ impl<'a> TryFrom<&'a DataverseCredential<'a>> for Vec<Triple<'a>> {
iri: credential.subject,
}),
},
Triple {
subject: c_subject,
predicate: VC_CLAIM,
object: Term::BlankNode(claim_node),
},
];

triples.extend(credential.claim.iter().map(|q| {
let subject = match q.subject {
Subject::NamedNode(n) if n.iri == credential.subject => {
Subject::BlankNode(claim_node)
}
_ => q.subject,
};
Triple {
subject,
predicate: q.predicate,
object: q.object,
}
}));
triples.extend(credential.claim.as_slice());

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

Ok(triples)
triples
}
}

pub fn serialize(
credential: &DataverseCredential<'_>,
format: DataFormat,
) -> Result<Binary, ContractError> {
let triples: Vec<Triple<'_>> = credential.try_into()?;
let triples: Vec<Triple<'_>> = credential.into();
let out: Vec<u8> = Vec::default();
let mut writer = TripleWriter::new(&format, out);
for triple in triples {
Expand Down

0 comments on commit b2f6d43

Please sign in to comment.