Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sovrin-specific DDO facade #871

Merged
merged 14 commits into from
Jun 20, 2023
42 changes: 38 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ members = [
"aries_vcx_core",
"uniffi_aries_vcx/core",
"did_doc",
"did_doc_sov",
"did_parser",
"did_resolver",
"did_resolver_registry",
Expand Down
4 changes: 4 additions & 0 deletions did_doc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ version = "0.1.0"
edition = "2021"

[dependencies]
base64 = "0.21.2"
bs58 = "0.5.0"
did_parser = { path = "../did_parser" }
hex = "0.4.3"
multibase = "0.9.1"
pem = "2.0.1"
serde = { version = "1.0.159", default-features = false, features = ["derive"] }
serde_json = "1.0.95"
uniresid = { version = "0.1.4", default-features = false, features = ["serde"] }
Expand Down
51 changes: 49 additions & 2 deletions did_doc/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ use url::ParseError;
pub enum DidDocumentBuilderError {
InvalidInput(String),
MissingField(&'static str),
UnsupportedPublicKeyField(&'static str),
JsonError(serde_json::Error),
PemError(pem::PemError),
Base58DecodeError(bs58::decode::Error),
Base64DecodeError(base64::DecodeError),
HexDecodeError(hex::FromHexError),
}

impl std::fmt::Display for DidDocumentBuilderError {
Expand All @@ -16,19 +21,37 @@ impl std::fmt::Display for DidDocumentBuilderError {
DidDocumentBuilderError::MissingField(field) => {
write!(f, "Missing field: {}", field)
}
DidDocumentBuilderError::UnsupportedPublicKeyField(field) => {
write!(f, "Unsupported public key field: {}", field)
}
DidDocumentBuilderError::JsonError(error) => {
write!(f, "(De)serialization error: {}", error)
}
DidDocumentBuilderError::PemError(error) => {
write!(f, "PEM error: {}", error)
}
DidDocumentBuilderError::Base58DecodeError(error) => {
write!(f, "Base58 decode error: {}", error)
}
DidDocumentBuilderError::Base64DecodeError(error) => {
write!(f, "Base64 decode error: {}", error)
}
DidDocumentBuilderError::HexDecodeError(error) => {
write!(f, "Hex decode error: {}", error)
}
}
}
}

impl std::error::Error for DidDocumentBuilderError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
DidDocumentBuilderError::InvalidInput(_) => None,
DidDocumentBuilderError::MissingField(_) => None,
DidDocumentBuilderError::JsonError(error) => Some(error),
DidDocumentBuilderError::PemError(error) => Some(error),
DidDocumentBuilderError::Base58DecodeError(error) => Some(error),
DidDocumentBuilderError::Base64DecodeError(error) => Some(error),
DidDocumentBuilderError::HexDecodeError(error) => Some(error),
_ => None,
}
}
}
Expand All @@ -39,6 +62,30 @@ impl From<serde_json::Error> for DidDocumentBuilderError {
}
}

impl From<pem::PemError> for DidDocumentBuilderError {
fn from(error: pem::PemError) -> Self {
DidDocumentBuilderError::PemError(error)
}
}

impl From<bs58::decode::Error> for DidDocumentBuilderError {
fn from(error: bs58::decode::Error) -> Self {
DidDocumentBuilderError::Base58DecodeError(error)
}
}

impl From<base64::DecodeError> for DidDocumentBuilderError {
fn from(error: base64::DecodeError) -> Self {
DidDocumentBuilderError::Base64DecodeError(error)
}
}

impl From<hex::FromHexError> for DidDocumentBuilderError {
fn from(error: hex::FromHexError) -> Self {
DidDocumentBuilderError::HexDecodeError(error)
}
}

impl From<ParseError> for DidDocumentBuilderError {
fn from(error: ParseError) -> Self {
DidDocumentBuilderError::InvalidInput(error.to_string())
Expand Down
37 changes: 27 additions & 10 deletions did_doc/src/schema/did_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::{
verification_method::{VerificationMethod, VerificationMethodKind},
};

type ControllerAlias = OneOrList<Did>;
pub type ControllerAlias = OneOrList<Did>;

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
#[serde(default)]
Expand Down Expand Up @@ -92,6 +92,13 @@ impl<E> DidDocument<E> {
self.extra.get(key)
}

pub fn dereference_key(&self, reference: &DidUrl) -> Option<&VerificationMethod> {
// TODO: Should check controller (if present)
self.verification_method
.iter()
.find(|vm| vm.id().fragment() == reference.fragment())
}

pub fn validate(&self) -> Result<(), DidDocumentBuilderError> {
Ok(())
}
Expand Down Expand Up @@ -183,7 +190,7 @@ impl<E> DidDocumentBuilder<E> {
self
}

pub fn add_key_agreement_refrence(mut self, reference: DidUrl) -> Self {
pub fn add_key_agreement_reference(mut self, reference: DidUrl) -> Self {
self.key_agreement
.push(VerificationMethodKind::Resolvable(reference));
self
Expand All @@ -195,7 +202,7 @@ impl<E> DidDocumentBuilder<E> {
self
}

pub fn add_capability_invocation_refrence(mut self, reference: DidUrl) -> Self {
pub fn add_capability_invocation_reference(mut self, reference: DidUrl) -> Self {
self.capability_invocation
.push(VerificationMethodKind::Resolvable(reference));
self
Expand Down Expand Up @@ -248,26 +255,29 @@ impl<E> DidDocumentBuilder<E> {
#[cfg(test)]
mod tests {
use super::*;
use crate::schema::service::ServiceBuilder;
use crate::schema::{service::ServiceBuilder, verification_method::VerificationMethodType};

#[test]
fn test_did_document_builder() {
let id = Did::parse("did:example:123456789abcdefghi".to_string()).unwrap();
let also_known_as = Uri::new("https://example.com").unwrap();
let controller = Did::parse("did:example:controller".to_string()).unwrap();

let vm1_id = DidUrl::parse("did:example:vm1#vm1".to_string()).unwrap();
let verification_method = VerificationMethod::builder(
DidUrl::parse("did:example:vm1".to_string()).unwrap(),
Did::parse("did:example:vm2".to_string()).unwrap(),
"typevm".to_string(),
vm1_id.clone(),
Did::parse("did:example:vm1".to_string()).unwrap(),
VerificationMethodType::Ed25519VerificationKey2018,
)
.add_public_key_base58("H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV".to_string())
.build();
let authentication_reference = DidUrl::parse("did:example:authref".to_string()).unwrap();
let assertion_method = VerificationMethod::builder(
DidUrl::parse("did:example:am1".to_string()).unwrap(),
Did::parse("did:example:am2".to_string()).unwrap(),
"typeam".to_string(),
VerificationMethodType::Ed25519VerificationKey2018,
)
.add_public_key_base58("H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV".to_string())
.build();

let service_id = Uri::new("did:example:123456789abcdefghi;service-1").unwrap();
Expand All @@ -291,9 +301,9 @@ mod tests {
.add_assertion_method(assertion_method.clone())
.add_assertion_method_reference(authentication_reference.clone())
.add_key_agreement(verification_method.clone())
.add_key_agreement_refrence(authentication_reference.clone())
.add_key_agreement_reference(authentication_reference.clone())
.add_capability_invocation(verification_method.clone())
.add_capability_invocation_refrence(authentication_reference.clone())
.add_capability_invocation_reference(authentication_reference.clone())
.add_capability_delegation(verification_method.clone())
.add_capability_delegation_refrence(authentication_reference.clone())
.add_service(service.clone())
Expand Down Expand Up @@ -345,5 +355,12 @@ mod tests {
]
);
assert_eq!(document.service(), &[service]);

let vm = document.dereference_key(&vm1_id);
if let Some(vm) = vm {
assert_eq!(vm.id(), &vm1_id);
} else {
panic!("Verification method not found")
};
}
}
2 changes: 1 addition & 1 deletion did_doc/src/schema/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub mod did_doc;
pub mod service;
pub mod types;
pub(crate) mod utils;
pub mod utils;
pub mod verification_method;
2 changes: 1 addition & 1 deletion did_doc/src/schema/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::{
utils::OneOrList,
};

type ServiceTypeAlias = OneOrList<String>;
pub type ServiceTypeAlias = OneOrList<String>;

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
Expand Down
4 changes: 4 additions & 0 deletions did_doc/src/schema/types/jsonwebkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ impl JsonWebKey {
pub fn new(jwk: &str) -> Result<Self, DidDocumentBuilderError> {
Ok(serde_json::from_str(jwk)?)
}

pub fn to_vec(&self) -> Result<Vec<u8>, DidDocumentBuilderError> {
serde_json::to_vec(self).map_err(|e| e.into())
}
}

impl FromStr for JsonWebKey {
Expand Down
Loading