use rocket::http::Status; use rocket_contrib::json::Json; use trust_dns_client::client::ClientHandle; use trust_dns_client::op::ResponseCode; use trust_dns_client::rr::{DNSClass, RecordType}; use crate::{DbConn, models::dns}; use crate::models::errors::{ErrorResponse, make_500}; use crate::models::users::UserInfo; #[get("/zones//records")] pub async fn get_zone_records( mut client: dns::DnsClient, conn: DbConn, user_info: Result, zone: dns::AbsoluteName ) -> Result>, ErrorResponse> { let user_info = user_info?; if !user_info.is_admin() { let zone_name = zone.clone().to_string(); conn.run(move |c| { dbg!(user_info.get_zone(c, &zone_name)) }).await?; } let response = { let query = client.query((*zone).clone(), DNSClass::IN, RecordType::AXFR); query.await.map_err(make_500)? }; if response.response_code() != ResponseCode::NoError { return ErrorResponse::new( Status::NotFound, format!("zone {} could not be found", *zone) ).err() } let answers = response.answers(); let mut records: Vec<_> = answers.to_vec().into_iter() .map(dns::Record::from) .filter(|record| !matches!(record.rdata, dns::RData::NULL { .. } | dns::RData::DNSSEC(_))) .collect(); // AXFR response ends with SOA, we remove it so it is not doubled in the response. records.pop(); Ok(Json(records)) }