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

test(FTL-17138): add unit tests for affinidi-did-resolver-methods #33

Merged
merged 2 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ regex = "1"
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = "1.0"
blake2 = "0.10"
ssi = "0.9"
ssi = { version = "0.9", features = ["secp384r1"] }
anton-iskryzhytskyi marked this conversation as resolved.
Show resolved Hide resolved
thiserror = "1.0"
tokio = { version = "1.40", features = ["full"] }
tracing = "0.1"
Expand Down
333 changes: 333 additions & 0 deletions affinidi-did-resolver-methods/did-peer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,339 @@ impl DIDPeer {
}
}

#[cfg(test)]
mod test {
use crate::{
DIDPeer, DIDPeerCreateKeys, DIDPeerKeyType, DIDPeerKeys, DIDPeerService,
PeerServiceEndPoint, PeerServiceEndPointLong,
};

use ssi::{
dids::{document::DIDVerificationMethod, DIDBuf, DIDResolver, DID},
JWK,
};

const DID_PEER: &str = "did:peer:2.Vz6MkiToqovww7vYtxm1xNM15u9JzqzUFZ1k7s7MazYJUyAxv.EzQ3shQLqRUza6AMJFbPuMdvFRFWm1wKviQRnQSC1fScovJN4s.SeyJ0IjoiRElEQ29tbU1lc3NhZ2luZyIsInMiOnsidXJpIjoiaHR0cHM6Ly8xMjcuMC4wLjE6NzAzNyIsImEiOlsiZGlkY29tbS92MiJdLCJyIjpbXX19";

#[should_panic(
expected = "Failed to convert verification_method. Reason: Missing publicKeyBase58"
)]
#[tokio::test]
async fn expand_keys_throws_key_parsing_missing_pbk58_error() {
let peer = DIDPeer;
let output = peer
.resolve(DID::new::<String>(&DID_PEER.to_string()).unwrap())
.await
.unwrap();

let mut document = output.document.document().clone();
let mut new_vms: Vec<DIDVerificationMethod> = vec![];
for mut vm in document.verification_method {
vm.properties.remove("publicKeyMultibase");
new_vms.push(vm);
}

document.verification_method = new_vms;
let _expanded_doc = DIDPeer::expand_keys(&document).await.unwrap();
}

#[tokio::test]
async fn expand_keys_works() {
let peer = DIDPeer;
let document = peer
.resolve(DID::new::<String>(&DID_PEER.to_string()).unwrap())
.await
.unwrap();

let vm_before_expansion = document.clone().document.verification_method.clone();
let expanded_doc = DIDPeer::expand_keys(&document.document).await.unwrap();
let vms_after_expansion = expanded_doc.verification_method;

for vm in vms_after_expansion.clone() {
assert!(vm.id.starts_with("did:key"));
}
assert_eq!(vm_before_expansion.len(), vms_after_expansion.len())
}

#[tokio::test]
async fn create_peer_did_without_keys_and_services() {
let keys: Vec<DIDPeerCreateKeys> = vec![];
let services: Vec<DIDPeerService> = vec![];

let (did, _) = DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();
let parts: Vec<&str> = did.split(":").collect();

assert_eq!(parts.len(), 3);
assert_eq!(parts[1], "peer");
assert!(parts[2].len() == 1);
}

#[tokio::test]
async fn create_peer_did_without_keys() {
let keys: Vec<DIDPeerCreateKeys> = vec![];
let services = vec![DIDPeerService {
_type: "dm".into(),
service_end_point: PeerServiceEndPoint::Long(PeerServiceEndPointLong {
uri: "https://localhost:7037".into(),
accept: vec!["didcomm/v2".into()],
routing_keys: vec![],
}),
id: None,
}];

let (did, _) = DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();
let parts: Vec<&str> = did.split(":").collect();
let method_ids: Vec<&str> = parts[2].split(".").collect();

assert_eq!(parts.len(), 3);
assert_eq!(parts[1], "peer");
assert!(method_ids.len() > 1);
assert!(method_ids[1].len() > 1);
}

#[tokio::test]
async fn create_peer_did_without_services() {
let (e_did_key, v_did_key, keys) = _get_keys(Some(DIDPeerKeyType::Ed25519), true);
let services: Vec<DIDPeerService> = vec![];

let (did, _) = DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();
let parts: Vec<&str> = did.split(":").collect();
let mut method_ids: Vec<&str> = parts[2].split(".").collect();
method_ids = method_ids[1..].to_vec();
let keys_multibase = [v_did_key[8..].to_string(), e_did_key[8..].to_string()];

for i in 0..2 {
assert!(keys_multibase.contains(&method_ids[i][1..].to_string()));
}
assert_eq!(parts.len(), 3);
assert_eq!(parts[1], "peer");
}

#[should_panic(expected = "UnsupportedKeyType")]
#[tokio::test]
async fn create_peer_did_should_throw_unsupported_key_error_p384() {
let (_, _, keys) = _get_keys(None, false);
// Create a service definition
let services = vec![DIDPeerService {
_type: "dm".into(),
service_end_point: PeerServiceEndPoint::Long(PeerServiceEndPointLong {
uri: "https://localhost:7037".into(),
accept: vec!["didcomm/v2".into()],
routing_keys: vec![],
}),
id: None,
}];

DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();
}

#[tokio::test]
async fn create_peer_did_works_ed25519_without_passing_pub_key() {
let (_, _, keys) = _get_keys(Some(DIDPeerKeyType::Ed25519), false);

// Create a service definition
let services = vec![DIDPeerService {
_type: "dm".into(),
service_end_point: PeerServiceEndPoint::Long(PeerServiceEndPointLong {
uri: "https://localhost:7037".into(),
accept: vec!["didcomm/v2".into()],
routing_keys: vec![],
}),
id: None,
}];

let (did, keys) = DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();
let parts: Vec<&str> = did.split(":").collect();
let method_ids: Vec<&str> = parts[2].split(".").collect();

assert_eq!(keys.len(), 2);
assert_eq!(parts.len(), 3);
assert_eq!(parts[1], "peer");
assert_eq!(method_ids.first().unwrap().parse::<i32>().unwrap(), 2);
assert_eq!(method_ids.len(), 4);
}

#[tokio::test]
async fn create_peer_did_works_p256_without_passing_pub_key() {
let (_, _, keys) = _get_keys(Some(DIDPeerKeyType::P256), false);

// Create a service definition
let services = vec![DIDPeerService {
_type: "dm".into(),
service_end_point: PeerServiceEndPoint::Long(PeerServiceEndPointLong {
uri: "https://localhost:7037".into(),
accept: vec!["didcomm/v2".into()],
routing_keys: vec![],
}),
id: None,
}];

let (did, keys) = DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();
let parts: Vec<&str> = did.split(":").collect();
let method_ids: Vec<&str> = parts[2].split(".").collect();

assert_eq!(keys.len(), 2);
assert_eq!(parts.len(), 3);
assert_eq!(parts[1], "peer");
assert_eq!(method_ids.first().unwrap().parse::<i32>().unwrap(), 2);
assert_eq!(method_ids.len(), 4);
}

#[tokio::test]
async fn create_peer_did_works_secp256k1_without_passing_pub_key() {
let (_, _, keys) = _get_keys(Some(DIDPeerKeyType::Secp256k1), false);

// Create a service definition
let services = vec![DIDPeerService {
_type: "dm".into(),
service_end_point: PeerServiceEndPoint::Long(PeerServiceEndPointLong {
uri: "https://localhost:7037".into(),
accept: vec!["didcomm/v2".into()],
routing_keys: vec![],
}),
id: None,
}];

let (did, keys) = DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();

let parts: Vec<&str> = did.split(":").collect();
let method_ids: Vec<&str> = parts[2].split(".").collect();

assert_eq!(keys.len(), 2);
assert_eq!(parts.len(), 3);
assert_eq!(parts[1], "peer");
assert_eq!(method_ids.first().unwrap().parse::<i32>().unwrap(), 2);
assert_eq!(method_ids.len(), 4);
}

#[tokio::test]
async fn create_peer_did_works_ed25519() {
let (e_did_key, v_did_key, keys) = _get_keys(Some(DIDPeerKeyType::Ed25519), true);

// Create a service definition
let services = vec![DIDPeerService {
_type: "dm".into(),
service_end_point: PeerServiceEndPoint::Long(PeerServiceEndPointLong {
uri: "https://localhost:7037".into(),
accept: vec!["didcomm/v2".into()],
routing_keys: vec![],
}),
id: None,
}];

let (did, _) = DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();
let parts: Vec<&str> = did.split(":").collect();
let mut method_ids: Vec<&str> = parts[2].split(".").collect();
method_ids = method_ids[1..].to_vec();
let keys_multibase = [v_did_key[8..].to_string(), e_did_key[8..].to_string()];

for i in 0..2 {
assert!(keys_multibase.contains(&method_ids[i][1..].to_string()));
}
assert_eq!(parts.len(), 3);
assert_eq!(parts[1], "peer");
}

#[tokio::test]
async fn create_peer_did_works_p256() {
let (e_did_key, v_did_key, keys) = _get_keys(Some(DIDPeerKeyType::P256), true);
// Create a service definition
let services = vec![DIDPeerService {
_type: "dm".into(),
service_end_point: PeerServiceEndPoint::Long(PeerServiceEndPointLong {
uri: "https://localhost:7037".into(),
accept: vec!["didcomm/v2".into()],
routing_keys: vec![],
}),
id: None,
}];

let (did, _) = DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();
let parts: Vec<&str> = did.split(":").collect();
let mut method_ids: Vec<&str> = parts[2].split(".").collect();
method_ids = method_ids[1..].to_vec();
let keys_multibase = [v_did_key[8..].to_string(), e_did_key[8..].to_string()];

for i in 0..2 {
assert!(keys_multibase.contains(&method_ids[i][1..].to_string()));
}
assert_eq!(parts.len(), 3);
assert_eq!(parts[1], "peer");
}

#[tokio::test]
async fn create_peer_did_works_secp256k1() {
let (e_did_key, v_did_key, keys) = _get_keys(Some(DIDPeerKeyType::Secp256k1), true);
// Create a service definition
let services = vec![DIDPeerService {
_type: "dm".into(),
service_end_point: PeerServiceEndPoint::Long(PeerServiceEndPointLong {
uri: "https://localhost:7037".into(),
accept: vec!["didcomm/v2".into()],
routing_keys: vec![],
}),
id: None,
}];

let (did, _) = DIDPeer::create_peer_did(&keys, Some(&services)).unwrap();
let parts: Vec<&str> = did.split(":").collect();
let mut method_ids: Vec<&str> = parts[2].split(".").collect();
method_ids = method_ids[1..].to_vec();
let keys_multibase = [v_did_key[8..].to_string(), e_did_key[8..].to_string()];

for i in 0..2 {
assert!(keys_multibase.contains(&method_ids[i][1..].to_string()));
}
assert_eq!(parts.len(), 3);
assert_eq!(parts[1], "peer");
}

fn _get_keys(
key_type: Option<DIDPeerKeyType>,
with_pub_key: bool,
) -> (DIDBuf, DIDBuf, Vec<DIDPeerCreateKeys>) {
let encryption_key = match key_type {
Some(DIDPeerKeyType::Ed25519) => JWK::generate_ed25519().unwrap(),
Some(DIDPeerKeyType::P256) => JWK::generate_p256(),
Some(DIDPeerKeyType::Secp256k1) => JWK::generate_secp256k1(),
None => JWK::generate_p384(),
};
let verification_key = match key_type {
Some(DIDPeerKeyType::Ed25519) => JWK::generate_ed25519().unwrap(),
Some(DIDPeerKeyType::P256) => JWK::generate_p256(),
Some(DIDPeerKeyType::Secp256k1) => JWK::generate_secp256k1(),
None => JWK::generate_p384(),
};
// Create the did:key DID's for each key above
let e_did_key = ssi::dids::DIDKey::generate(&encryption_key).unwrap();
let v_did_key = ssi::dids::DIDKey::generate(&verification_key).unwrap();

// Put these keys in order and specify the type of each key (we strip the did:key: from the front)
let keys = vec![
DIDPeerCreateKeys {
purpose: DIDPeerKeys::Verification,
type_: key_type.clone(),
public_key_multibase: if with_pub_key {
Some(v_did_key[8..].to_string())
} else {
None
},
},
DIDPeerCreateKeys {
purpose: DIDPeerKeys::Encryption,
type_: key_type.clone(),
public_key_multibase: if with_pub_key {
Some(e_did_key[8..].to_string())
} else {
None
},
},
];

(e_did_key, v_did_key, keys)
}
}

// **********************************************************************************************************************************
// WASM Specific structs and code
// **********************************************************************************************************************************
Expand Down
Loading