Skip to content

Commit

Permalink
Convert dht doc to dns packet (#224)
Browse files Browse the repository at this point in the history
* Convert dht doc to dns packet

* Add happy path tests for alsoKnownAs and controller

* Update crates/dids/src/methods/dht/document_packet/mod.rs

Co-authored-by: nitro-neal <[email protected]>

---------

Co-authored-by: nitro-neal <[email protected]>
  • Loading branch information
Diane Huxley and nitro-neal authored Jun 3, 2024
1 parent 6f79918 commit 8009d84
Show file tree
Hide file tree
Showing 7 changed files with 874 additions and 38 deletions.
75 changes: 75 additions & 0 deletions crates/dids/src/methods/dht/document_packet/also_known_as.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use simple_dns::{
rdata::{RData, TXT},
Name, ResourceRecord,
};

use super::{rdata_encoder::text_from_record, DocumentPacketError, DEFAULT_TTL};

pub struct AlsoKnownAs {}

impl AlsoKnownAs {
pub fn is_aka_record(record: &ResourceRecord) -> bool {
match record.name.get_labels().first() {
None => false,
Some(domain) => domain.to_string() == "_aka",
}
}

pub fn to_resource_record(
also_known_as: &[String],
) -> Result<ResourceRecord, DocumentPacketError> {
let name = Name::new_unchecked("_aka._did.");
let txt_record = TXT::new()
.with_string(&also_known_as.join(","))?
.into_owned();

Ok(ResourceRecord::new(
name,
simple_dns::CLASS::IN,
DEFAULT_TTL,
RData::TXT(txt_record),
))
}

pub fn from_resource_record(
record: &ResourceRecord,
) -> Result<Vec<String>, DocumentPacketError> {
let text = text_from_record(record)?;
let also_known_as = text
.split(',')
.map(|s| s.to_string())
.filter(|s| !s.is_empty())
.collect();
Ok(also_known_as)
}
}

#[cfg(test)]
mod test {
use crate::methods::dht::document_packet::controller::Controller;

use super::*;

#[test]
fn test_to_and_from_resource_record() {
let also_known_as = vec!["Dave".to_string(), "Bartholemoop".to_string()];
let record = AlsoKnownAs::to_resource_record(&also_known_as)
.expect("expected to convert to DNS record");
let also_known_as2 = AlsoKnownAs::from_resource_record(&record)
.expect("Expected to convert from DNS record");
assert_eq!(also_known_as, also_known_as2);
}

#[test]
fn test_is_aka_record() {
let also_known_as = vec!["Dave".to_string(), "Bartholemoop".to_string()];
let record = AlsoKnownAs::to_resource_record(&also_known_as)
.expect("expected to convert to DNS record");

assert!(AlsoKnownAs::is_aka_record(&record));

let controllers = vec!["Jerb".to_string(), "Carrie Bradshaw".to_string()];
let record = Controller::to_resource_record(&controllers).unwrap();
assert!(!AlsoKnownAs::is_aka_record(&record));
}
}
80 changes: 80 additions & 0 deletions crates/dids/src/methods/dht/document_packet/controller.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use simple_dns::{
rdata::{RData, TXT},
Name, ResourceRecord,
};

use super::{rdata_encoder::text_from_record, DocumentPacketError, DEFAULT_TTL};

pub struct Controller {}

impl Controller {
pub fn is_cnt_record(record: &ResourceRecord) -> bool {
match record.name.get_labels().first() {
None => false,
Some(domain) => domain.to_string() == "_cnt",
}
}

pub fn to_resource_record(
controllers: &[String],
) -> Result<ResourceRecord, DocumentPacketError> {
let name = Name::new_unchecked("_cnt._did.");
let txt_record = TXT::new().with_string(&controllers.join(","))?.into_owned();

Ok(ResourceRecord::new(
name,
simple_dns::CLASS::IN,
DEFAULT_TTL,
RData::TXT(txt_record),
))
}

pub fn from_resource_record(
record: &ResourceRecord,
) -> Result<Vec<String>, DocumentPacketError> {
let text = text_from_record(record)?;
let controllers = text
.split(',')
.map(|s| s.to_string())
.filter(|s| !s.is_empty())
.collect();
Ok(controllers)
}
}

#[cfg(test)]
mod tests {
use crate::methods::dht::document_packet::also_known_as::AlsoKnownAs;

use super::*;

#[test]
fn to_and_from_resource_record() {
let controllers = vec![];
let record = Controller::to_resource_record(&controllers)
.expect("Expected to create controller resource record");
let controllers2 = Controller::from_resource_record(&record)
.expect("Expected to get a list of strings from resource record");
assert_eq!(controllers, controllers2);

let controllers = vec!["did:dht:123".to_string(), "did:dht:456".to_string()];
let record = Controller::to_resource_record(&controllers)
.expect("Expected to create controller resource record");
let controllers2 = Controller::from_resource_record(&record)
.expect("Expected to get a list of strings from resource record");
assert_eq!(controllers, controllers2);
}

#[test]
fn test_is_cnt_record() {
let also_known_as = vec!["Dave".to_string(), "Bartholemoop".to_string()];
let record = Controller::to_resource_record(&also_known_as)
.expect("expected to convert to DNS record");

assert!(Controller::is_cnt_record(&record));

let controllers = vec!["Jerb".to_string(), "Carrie Bradshaw".to_string()];
let record = AlsoKnownAs::to_resource_record(&controllers).unwrap();
assert!(!Controller::is_cnt_record(&record));
}
}
Loading

0 comments on commit 8009d84

Please sign in to comment.