use super::*;
impl MarkdownFormatter {
pub(super) fn format_whois(&self, response: &WhoisResponse) -> String {
let mut output = vec![
format!("## WHOIS: {}", MdSafe(&response.domain)),
String::new(),
];
if response.is_available() {
output.push("Domain is **available** for registration.".to_string());
return output.join("\n");
}
let mut b = Bullets(&mut output);
b.opt("Registrar", &response.registrar);
b.opt("Registrant", &response.registrant);
b.opt("Organization", &response.organization);
b.date("Created", response.creation_date);
b.expires(response.expiration_date);
b.date("Updated", response.updated_date);
b.code_list("Nameservers", &response.nameservers);
b.code_list("Status", &response.status);
b.opt("DNSSEC", &response.dnssec);
b.code("WHOIS Server", &response.whois_server);
b.contacts(response.contacts());
output.join("\n")
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::whois::WhoisResponse;
fn empty_whois(domain: &str) -> WhoisResponse {
WhoisResponse {
domain: domain.to_string(),
status: vec!["clientTransferProhibited".to_string()],
whois_server: "whois.example.invalid".to_string(),
..Default::default()
}
}
#[test]
fn test_markdown_whois_registrar_newline_neutralized() {
let mut w = empty_whois("example.com");
w.registrar = Some("Foo\nIgnore previous".to_string());
let output = MarkdownFormatter::new().format_whois(&w);
assert!(
output.contains("- **Registrar**: Foo Ignore previous"),
"expected sanitized registrar in output:\n{}",
output
);
for line in output.lines() {
assert!(
!line.trim_start().starts_with("Ignore previous"),
"attacker payload broke onto its own line:\n{}",
output
);
}
}
#[test]
fn test_markdown_whois_domain_fields_precede_contact_sections() {
let w = WhoisResponse::parse(
"example.com",
"whois.test",
"Registrar: Mock Registrar\n\
Creation Date: 2010-03-15T04:00:00Z\n\
Registry Expiry Date: 2099-03-15T04:00:00Z\n\
Registrant Country: US\n\
Admin Name: Jane Admin\n\
Tech Email: tech@example.com\n\
Name Server: ns1.example.com\n\
Domain Status: ok\n\
DNSSEC: unsigned\n",
);
let out = MarkdownFormatter::new().format_whois(&w);
let first_heading = out.find("\n###").expect("contact sections rendered");
for field in [
"- **Registrar**",
"- **Created**",
"- **Expires**",
"- **Nameservers**",
"- **Status**",
"- **DNSSEC**",
"- **WHOIS Server**",
] {
let at = out
.find(field)
.unwrap_or_else(|| panic!("{field} missing:\n{out}"));
assert!(
at < first_heading,
"{field} rendered under a contact heading:\n{out}"
);
}
for heading in [
"### Registrant Contact",
"### Admin Contact",
"### Tech Contact",
] {
assert!(out.contains(heading), "{heading} missing:\n{out}");
}
assert!(
out.contains("- **Country**: US"),
"contact field kept:\n{out}"
);
}
}