From ae6c94e2a721c66b8ab793f355a5cfb023560b45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20Berthaud-M=C3=BCller?= Date: Fri, 4 Mar 2022 17:17:15 +0100 Subject: [PATCH] rearchitecture modules --- src/dns/class.rs | 40 ------------- src/dns/message.rs | 2 +- src/dns/mod.rs | 21 +++---- src/models/class.rs | 40 +++++++++++++ src/models/mod.rs | 16 +++++- src/{dns => models}/name.rs | 2 +- src/{dns => models}/rdata.rs | 104 +++++++++++++++++----------------- src/{dns => models}/record.rs | 10 ++-- src/models/zone.rs | 6 +- src/routes/users.rs | 20 +++---- src/routes/zones.rs | 79 +++++++++++++------------- 11 files changed, 173 insertions(+), 167 deletions(-) delete mode 100644 src/dns/class.rs create mode 100644 src/models/class.rs rename src/{dns => models}/name.rs (97%) rename src/{dns => models}/rdata.rs (64%) rename src/{dns => models}/record.rs (74%) diff --git a/src/dns/class.rs b/src/dns/class.rs deleted file mode 100644 index e95eab8..0000000 --- a/src/dns/class.rs +++ /dev/null @@ -1,40 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use super::trust_dns_types; - - -#[derive(Deserialize, Serialize, Clone)] -pub enum DNSClass { - IN, - CH, - HS, - NONE, - ANY, - OPT(u16), -} - -impl From for DNSClass { - fn from(dns_class: trust_dns_types::DNSClass) -> DNSClass { - match dns_class { - trust_dns_types::DNSClass::IN => DNSClass::IN, - trust_dns_types::DNSClass::CH => DNSClass::CH, - trust_dns_types::DNSClass::HS => DNSClass::HS, - trust_dns_types::DNSClass::NONE => DNSClass::NONE, - trust_dns_types::DNSClass::ANY => DNSClass::ANY, - trust_dns_types::DNSClass::OPT(v) => DNSClass::OPT(v), - } - } -} - -impl From for trust_dns_types::DNSClass { - fn from(dns_class: DNSClass) -> trust_dns_types::DNSClass { - match dns_class { - DNSClass::IN => trust_dns_types::DNSClass::IN, - DNSClass::CH => trust_dns_types::DNSClass::CH, - DNSClass::HS => trust_dns_types::DNSClass::HS, - DNSClass::NONE => trust_dns_types::DNSClass::NONE, - DNSClass::ANY => trust_dns_types::DNSClass::ANY, - DNSClass::OPT(v) => trust_dns_types::DNSClass::OPT(v), - } - } -} \ No newline at end of file diff --git a/src/dns/message.rs b/src/dns/message.rs index f2e9c65..5ff620f 100644 --- a/src/dns/message.rs +++ b/src/dns/message.rs @@ -5,7 +5,7 @@ use trust_dns_client::error::ClientError; use trust_dns_proto::error::ProtoError; use trust_dns_client::proto::xfer::{DnsRequestOptions}; -use super::trust_dns_types::{Name, Record, RData}; +use super::{Name, Record, RData}; use super::client::{ClientResponse}; diff --git a/src/dns/mod.rs b/src/dns/mod.rs index 8143b60..2aa75ab 100644 --- a/src/dns/mod.rs +++ b/src/dns/mod.rs @@ -1,16 +1,11 @@ -pub mod class; -pub mod name; -pub mod rdata; -pub mod record; pub mod client; pub mod message; -pub mod trust_dns_types { - pub use trust_dns_client::rr::rdata::{ - DNSSECRData, caa, sshfp, mx, null, soa, srv, txt - }; - pub use trust_dns_client::rr::{ - RData, DNSClass, Record - }; - pub use trust_dns_proto::rr::Name; -} \ No newline at end of file +// Reexport trust dns types for convenience +pub use trust_dns_client::rr::rdata::{ + DNSSECRData, caa, sshfp, mx, null, soa, srv, txt +}; +pub use trust_dns_client::rr::{ + RData, DNSClass, Record +}; +pub use trust_dns_proto::rr::Name; \ No newline at end of file diff --git a/src/models/class.rs b/src/models/class.rs new file mode 100644 index 0000000..385588d --- /dev/null +++ b/src/models/class.rs @@ -0,0 +1,40 @@ +use serde::{Deserialize, Serialize}; + +use crate::dns; + + +#[derive(Deserialize, Serialize, Clone)] +pub enum DNSClass { + IN, + CH, + HS, + NONE, + ANY, + OPT(u16), +} + +impl From for DNSClass { + fn from(dns_class: dns::DNSClass) -> DNSClass { + match dns_class { + dns::DNSClass::IN => DNSClass::IN, + dns::DNSClass::CH => DNSClass::CH, + dns::DNSClass::HS => DNSClass::HS, + dns::DNSClass::NONE => DNSClass::NONE, + dns::DNSClass::ANY => DNSClass::ANY, + dns::DNSClass::OPT(v) => DNSClass::OPT(v), + } + } +} + +impl From for dns::DNSClass { + fn from(dns_class: DNSClass) -> dns::DNSClass { + match dns_class { + DNSClass::IN => dns::DNSClass::IN, + DNSClass::CH => dns::DNSClass::CH, + DNSClass::HS => dns::DNSClass::HS, + DNSClass::NONE => dns::DNSClass::NONE, + DNSClass::ANY => dns::DNSClass::ANY, + DNSClass::OPT(v) => dns::DNSClass::OPT(v), + } + } +} \ No newline at end of file diff --git a/src/models/mod.rs b/src/models/mod.rs index 707a5da..0b387b9 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,5 +1,19 @@ //pub mod dns; +pub mod auth; +pub mod class; pub mod errors; +pub mod name; +pub mod rdata; +pub mod record; pub mod user; pub mod zone; -pub mod auth; + +// Reexport types for convenience +pub use auth::{AuthClaims, AuthTokenRequest, AuthTokenResponse}; +pub use class::DNSClass; +pub use errors::{UserError, ErrorResponse, make_500}; +pub use name::{AbsoluteName, SerdeName}; +pub use user::{LocalUser, UserInfo, Role, UserZone, User, CreateUserRequest}; +pub use rdata::RData; +pub use record::Record; +pub use zone::{Zone, AddZoneMemberRequest, CreateZoneRequest}; \ No newline at end of file diff --git a/src/dns/name.rs b/src/models/name.rs similarity index 97% rename from src/dns/name.rs rename to src/models/name.rs index 4dca8e8..0856f11 100644 --- a/src/dns/name.rs +++ b/src/models/name.rs @@ -5,7 +5,7 @@ use rocket::request::FromParam; use serde::{Deserialize, Serialize, Deserializer, Serializer}; use trust_dns_proto::error::ProtoError; -use super::trust_dns_types::Name; +use crate::dns::Name; #[derive(Debug, Clone)] diff --git a/src/dns/rdata.rs b/src/models/rdata.rs similarity index 64% rename from src/dns/rdata.rs rename to src/models/rdata.rs index 99f53af..64c61be 100644 --- a/src/dns/rdata.rs +++ b/src/models/rdata.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use trust_dns_client::serialize::binary::BinEncoder; use trust_dns_proto::error::ProtoError; -use super::trust_dns_types; +use crate::dns; use super::name::SerdeName; @@ -87,7 +87,7 @@ pub enum RData { // TODO: Eventually allow deserialization of DNSSEC records #[serde(skip)] - DNSSEC(trust_dns_types::DNSSECRData), + DNSSEC(dns::DNSSECRData), #[serde(rename_all = "PascalCase")] Unknown { code: u16, @@ -99,39 +99,39 @@ pub enum RData { // TODO: TLSA } -impl From for RData { - fn from(rdata: trust_dns_types::RData) -> RData { +impl From for RData { + fn from(rdata: dns::RData) -> RData { match rdata { - trust_dns_types::RData::A(address) => RData::A { address }, - trust_dns_types::RData::AAAA(address) => RData::AAAA { address }, + dns::RData::A(address) => RData::A { address }, + dns::RData::AAAA(address) => RData::AAAA { address }, // Still a draft, no iana number yet, I don't to put something that is not currently supported so that's why NULL and not unknown. // TODO: probably need better error here, I don't know what to do about that as this would require to change the From for something else. // (empty data because I'm lazy) - trust_dns_types::RData::ANAME(_) => RData::NULL { + dns::RData::ANAME(_) => RData::NULL { data: String::new() }, - trust_dns_types::RData::CNAME(target) => RData::CNAME { + dns::RData::CNAME(target) => RData::CNAME { target: SerdeName(target) }, - trust_dns_types::RData::CAA(caa) => RData::CAA { + dns::RData::CAA(caa) => RData::CAA { issuer_critical: caa.issuer_critical(), value: format!("{}", CAAValue(caa.value())), property_tag: caa.tag().as_str().to_string(), }, - trust_dns_types::RData::MX(mx) => RData::MX { + dns::RData::MX(mx) => RData::MX { preference: mx.preference(), mail_exchanger: SerdeName(mx.exchange().clone()) }, - trust_dns_types::RData::NULL(null) => RData::NULL { + dns::RData::NULL(null) => RData::NULL { data: base64::encode(null.anything().map(|data| data.to_vec()).unwrap_or_default()) }, - trust_dns_types::RData::NS(target) => RData::NS { + dns::RData::NS(target) => RData::NS { target: SerdeName(target) }, - trust_dns_types::RData::PTR(target) => RData::PTR { + dns::RData::PTR(target) => RData::PTR { target: SerdeName(target) }, - trust_dns_types::RData::SOA(soa) => RData::SOA { + dns::RData::SOA(soa) => RData::SOA { master_server_name: SerdeName(soa.mname().clone()), maintainer_name: SerdeName(soa.rname().clone()), refresh: soa.refresh(), @@ -140,21 +140,21 @@ impl From for RData { minimum: soa.minimum(), serial: soa.serial() }, - trust_dns_types::RData::SRV(srv) => RData::SRV { + dns::RData::SRV(srv) => RData::SRV { server: SerdeName(srv.target().clone()), port: srv.port(), priority: srv.priority(), weight: srv.weight(), }, - trust_dns_types::RData::SSHFP(sshfp) => RData::SSHFP { + dns::RData::SSHFP(sshfp) => RData::SSHFP { algorithm: sshfp.algorithm().into(), digest_type: sshfp.fingerprint_type().into(), - fingerprint: trust_dns_types::sshfp::HEX.encode(sshfp.fingerprint()), + fingerprint: dns::sshfp::HEX.encode(sshfp.fingerprint()), }, //TODO: This might alter data if not utf8 compatible, probably need to be replaced //TODO: check whether concatenating txt data is harmful or not - trust_dns_types::RData::TXT(txt) => RData::TXT { text: format!("{}", txt) }, - trust_dns_types::RData::DNSSEC(data) => RData::DNSSEC(data), + dns::RData::TXT(txt) => RData::TXT { text: format!("{}", txt) }, + dns::RData::DNSSEC(data) => RData::DNSSEC(data), rdata => { let code = rdata.to_record_type().into(); let mut data = Vec::new(); @@ -171,48 +171,48 @@ impl From for RData { } } -impl TryFrom for trust_dns_types::RData { +impl TryFrom for dns::RData { type Error = ProtoError; fn try_from(rdata: RData) -> Result { Ok(match rdata { - RData::A { address } => trust_dns_types::RData::A(address), - RData::AAAA { address } => trust_dns_types::RData::AAAA(address), + RData::A { address } => dns::RData::A(address), + RData::AAAA { address } => dns::RData::AAAA(address), // TODO: Round trip test all types below (currently not tested...) RData::CAA { issuer_critical, value, property_tag } => { - let property = trust_dns_types::caa::Property::from(property_tag); + let property = dns::caa::Property::from(property_tag); let caa_value = { // TODO: duplicate of trust_dns_client::serialize::txt::rdata_parser::caa::parse // because caa::read_value is private match property { - trust_dns_types::caa::Property::Issue | trust_dns_types::caa::Property::IssueWild => { - let value = trust_dns_types::caa::read_issuer(value.as_bytes())?; - trust_dns_types::caa::Value::Issuer(value.0, value.1) + dns::caa::Property::Issue | dns::caa::Property::IssueWild => { + let value = dns::caa::read_issuer(value.as_bytes())?; + dns::caa::Value::Issuer(value.0, value.1) } - trust_dns_types::caa::Property::Iodef => { - let url = trust_dns_types::caa::read_iodef(value.as_bytes())?; - trust_dns_types::caa::Value::Url(url) + dns::caa::Property::Iodef => { + let url = dns::caa::read_iodef(value.as_bytes())?; + dns::caa::Value::Url(url) } - trust_dns_types::caa::Property::Unknown(_) => trust_dns_types::caa::Value::Unknown(value.as_bytes().to_vec()), + dns::caa::Property::Unknown(_) => dns::caa::Value::Unknown(value.as_bytes().to_vec()), } }; - trust_dns_types::RData::CAA(trust_dns_types::caa::CAA { + dns::RData::CAA(dns::caa::CAA { issuer_critical, tag: property, value: caa_value, }) }, - RData::CNAME { target } => trust_dns_types::RData::CNAME(target.into_inner()), - RData::MX { preference, mail_exchanger } => trust_dns_types::RData::MX( - trust_dns_types::mx::MX::new(preference, mail_exchanger.into_inner()) + RData::CNAME { target } => dns::RData::CNAME(target.into_inner()), + RData::MX { preference, mail_exchanger } => dns::RData::MX( + dns::mx::MX::new(preference, mail_exchanger.into_inner()) ), - RData::NULL { data } => trust_dns_types::RData::NULL( - trust_dns_types::null::NULL::with( + RData::NULL { data } => dns::RData::NULL( + dns::null::NULL::with( base64::decode(data).map_err(|e| ProtoError::from(format!("{}", e)))? ) ), - RData::NS { target } => trust_dns_types::RData::NS(target.into_inner()), - RData::PTR { target } => trust_dns_types::RData::PTR(target.into_inner()), + RData::NS { target } => dns::RData::NS(target.into_inner()), + RData::PTR { target } => dns::RData::PTR(target.into_inner()), RData::SOA { master_server_name, maintainer_name, @@ -221,8 +221,8 @@ impl TryFrom for trust_dns_types::RData { expire, minimum, serial - } => trust_dns_types::RData::SOA( - trust_dns_types::soa::SOA::new( + } => dns::RData::SOA( + dns::soa::SOA::new( master_server_name.into_inner(), maintainer_name.into_inner(), serial, @@ -232,18 +232,18 @@ impl TryFrom for trust_dns_types::RData { minimum, ) ), - RData::SRV { server, port, priority, weight } => trust_dns_types::RData::SRV( - trust_dns_types::srv::SRV::new(priority, weight, port, server.into_inner()) + RData::SRV { server, port, priority, weight } => dns::RData::SRV( + dns::srv::SRV::new(priority, weight, port, server.into_inner()) ), - RData::SSHFP { algorithm, digest_type, fingerprint } => trust_dns_types::RData::SSHFP( - trust_dns_types::sshfp::SSHFP::new( + RData::SSHFP { algorithm, digest_type, fingerprint } => dns::RData::SSHFP( + dns::sshfp::SSHFP::new( // NOTE: This allows unassigned algorithms - trust_dns_types::sshfp::Algorithm::from(algorithm), - trust_dns_types::sshfp::FingerprintType::from(digest_type), - trust_dns_types::sshfp::HEX.decode(fingerprint.as_bytes()).map_err(|e| ProtoError::from(format!("{}", e)))? + dns::sshfp::Algorithm::from(algorithm), + dns::sshfp::FingerprintType::from(digest_type), + dns::sshfp::HEX.decode(fingerprint.as_bytes()).map_err(|e| ProtoError::from(format!("{}", e)))? ) ), - RData::TXT { text } => trust_dns_types::RData::TXT(trust_dns_types::txt::TXT::new(vec![text])), + RData::TXT { text } => dns::RData::TXT(dns::txt::TXT::new(vec![text])), // TODO: Error out for DNSSEC? Prefer downstream checks? RData::DNSSEC(_) => todo!(), // TODO: Disallow unknown? (could be used to bypass unsopported types?) Prefer downstream checks? @@ -252,7 +252,7 @@ impl TryFrom for trust_dns_types::RData { } } -struct CAAValue<'a>(&'a trust_dns_types::caa::Value); +struct CAAValue<'a>(&'a dns::caa::Value); // trust_dns Display implementation panics if no parameters // Implementation based on caa::emit_value @@ -260,7 +260,7 @@ struct CAAValue<'a>(&'a trust_dns_types::caa::Value); impl<'a> fmt::Display for CAAValue<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { match self.0 { - trust_dns_types::caa::Value::Issuer(name, parameters) => { + dns::caa::Value::Issuer(name, parameters) => { if let Some(name) = name { write!(f, "{}", name)?; @@ -274,8 +274,8 @@ impl<'a> fmt::Display for CAAValue<'a> { write!(f, "; {}", value)?; } } - trust_dns_types::caa::Value::Url(url) => write!(f, "{}", url)?, - trust_dns_types::caa::Value::Unknown(v) => write!(f, "{:?}", v)?, + dns::caa::Value::Url(url) => write!(f, "{}", url)?, + dns::caa::Value::Unknown(v) => write!(f, "{:?}", v)?, } Ok(()) } diff --git a/src/dns/record.rs b/src/models/record.rs similarity index 74% rename from src/dns/record.rs rename to src/models/record.rs index dc1debb..3c463cd 100644 --- a/src/dns/record.rs +++ b/src/models/record.rs @@ -2,7 +2,7 @@ use std::convert::{TryFrom, TryInto}; use serde::{Deserialize, Serialize}; use trust_dns_proto::error::ProtoError; -use super::trust_dns_types; +use crate::dns; use super::name::SerdeName; use super::class::DNSClass; use super::rdata::RData; @@ -21,8 +21,8 @@ pub struct Record { pub rdata: RData, } -impl From for Record { - fn from(record: trust_dns_types::Record) -> Record { +impl From for Record { + fn from(record: dns::Record) -> Record { Record { name: SerdeName(record.name().clone()), dns_class: record.dns_class().into(), @@ -32,11 +32,11 @@ impl From for Record { } } -impl TryFrom for trust_dns_types::Record { +impl TryFrom for dns::Record { type Error = ProtoError; fn try_from(record: Record) -> Result { - let mut trust_dns_record = trust_dns_types::Record::from_rdata(record.name.into_inner(), record.ttl, record.rdata.try_into()?); + let mut trust_dns_record = dns::Record::from_rdata(record.name.into_inner(), record.ttl, record.rdata.try_into()?); trust_dns_record.set_dns_class(record.dns_class.into()); Ok(trust_dns_record) } diff --git a/src/models/zone.rs b/src/models/zone.rs index 47e62d1..afca690 100644 --- a/src/models/zone.rs +++ b/src/models/zone.rs @@ -6,9 +6,9 @@ use diesel::result::Error as DieselError; use serde::{Serialize, Deserialize}; use crate::schema::*; -use crate::dns::name::AbsoluteName; -use crate::models::user::UserZone; -use crate::models::errors::UserError; +use super::name::AbsoluteName; +use super::user::UserZone; +use super::errors::UserError; #[derive(Debug, Serialize, Queryable, Identifiable, Insertable)] diff --git a/src/routes/users.rs b/src/routes/users.rs index 524d801..bf0ba61 100644 --- a/src/routes/users.rs +++ b/src/routes/users.rs @@ -4,34 +4,32 @@ use rocket::http::Status; use crate::config::Config; use crate::DbConn; -use crate::models::errors::{ErrorResponse, make_500}; -use crate::models::user::{LocalUser, CreateUserRequest}; -use crate::models::auth::{AuthClaims, AuthTokenRequest, AuthTokenResponse}; +use crate::models; #[post("/users/me/token", data = "")] pub async fn create_auth_token( conn: DbConn, config: State<'_, Config>, - auth_request: Json -) -> Result, ErrorResponse> { + auth_request: Json +) -> Result, models::ErrorResponse> { let user_info = conn.run(move |c| { - LocalUser::get_user_by_creds(c, &auth_request.username, &auth_request.password) + models::LocalUser::get_user_by_creds(c, &auth_request.username, &auth_request.password) }).await?; - let token = AuthClaims::new(&user_info, config.web_app.token_duration) + let token = models::AuthClaims::new(&user_info, config.web_app.token_duration) .encode(&config.web_app.secret) - .map_err(make_500)?; + .map_err(models::make_500)?; - Ok(Json(AuthTokenResponse { token })) + Ok(Json(models::AuthTokenResponse { token })) } #[post("/users", data = "")] -pub async fn create_user<'r>(conn: DbConn, user_request: Json) -> Result, ErrorResponse> { +pub async fn create_user<'r>(conn: DbConn, user_request: Json) -> Result, models::ErrorResponse> { // TODO: Check current user if any to check if user has permission to create users (with or without role) conn.run(|c| { - LocalUser::create_user(&c, user_request.into_inner()) + models::LocalUser::create_user(&c, user_request.into_inner()) }).await?; Response::build() diff --git a/src/routes/zones.rs b/src/routes/zones.rs index 25bf124..b884661 100644 --- a/src/routes/zones.rs +++ b/src/routes/zones.rs @@ -9,46 +9,45 @@ use trust_dns_client::client::ClientHandle; use trust_dns_client::op::ResponseCode; use trust_dns_client::rr::{DNSClass, RecordType}; -use crate::{dns::{self, trust_dns_types}, DbConn}; -use crate::models::errors::{ErrorResponse, make_500}; -use crate::models::user::{LocalUser, UserInfo}; -use crate::models::zone::{Zone, AddZoneMemberRequest, CreateZoneRequest}; +use crate::DbConn; +use crate::dns; use crate::dns::message::DnsMessage; use crate::dns::message::MessageError; +use crate::models; #[get("/zones//records")] pub async fn get_zone_records( mut client: dns::client::DnsClient, conn: DbConn, - user_info: Result, - zone: dns::name::AbsoluteName -) -> Result>, ErrorResponse> { + user_info: Result, + zone: models::AbsoluteName +) -> Result>, models::ErrorResponse> { let user_info = user_info?; let zone_name = zone.to_string(); conn.run(move |c| { if user_info.is_admin() { - Zone::get_by_name(c, &zone_name) + models::Zone::get_by_name(c, &zone_name) } else { user_info.get_zone(c, &zone_name) } }).await?; let records: Vec<_> = match client.get_records(zone.clone(), DNSClass::IN).await { - Ok(records) => records.into_iter().map(dns::record::Record::from).collect(), + Ok(records) => records.into_iter().map(models::Record::from).collect(), Err(MessageError::ResponceNotOk(code)) => { println!("Querrying AXFR of zone {} failed with code {}", *zone, code); - return ErrorResponse::new( + return models::ErrorResponse::new( Status::NotFound, "Zone could not be found".into() ).with_details(json!({ "zone_name": zone.to_utf8() })).err(); }, - Err(err) => { return make_500(err).err(); }, + Err(err) => { return models::make_500(err).err(); }, }; Ok(Json(records)) @@ -58,17 +57,17 @@ pub async fn get_zone_records( pub async fn create_zone_records( mut client: dns::client::DnsClient, conn: DbConn, - user_info: Result, - zone: dns::name::AbsoluteName, - new_records: Json> -) -> Result, ErrorResponse> { + user_info: Result, + zone: models::AbsoluteName, + new_records: Json> +) -> Result, models::ErrorResponse> { let user_info = user_info?; let zone_name = zone.to_utf8(); conn.run(move |c| { if user_info.is_admin() { - Zone::get_by_name(c, &zone_name) + models::Zone::get_by_name(c, &zone_name) } else { user_info.get_zone(c, &zone_name) } @@ -76,7 +75,7 @@ pub async fn create_zone_records( // TODO: What about relative names (also in cnames and stuff) let mut bad_records = Vec::new(); - let mut records: Vec = Vec::new(); + let mut records: Vec = Vec::new(); for record in new_records.into_inner().into_iter() { let this_record = record.clone(); @@ -88,7 +87,7 @@ pub async fn create_zone_records( } if !bad_records.is_empty() { - return ErrorResponse::new( + return models::ErrorResponse::new( Status::BadRequest, "Record list contains records that could not been parsed into DNS records".into() ).with_details( @@ -100,27 +99,27 @@ pub async fn create_zone_records( } let response = match client.add_records(zone.clone(), DNSClass::IN, records) { - Ok(query) => query.await.map_err(make_500)?, + Ok(query) => query.await.map_err(models::make_500)?, Err(MessageError::RecordNotInZone { zone, class, mismatched_class, mismatched_zone}) => { - return ErrorResponse::new( + return models::ErrorResponse::new( Status::BadRequest, "Record list contains records that do not belong to the zone".into() ).with_details( json!({ "zone_name": zone.to_utf8(), - "class": dns::class::DNSClass::from(class), - "mismatched_class": mismatched_class.into_iter().map(|r| r.clone().into()).collect::>(), - "mismatched_zone": mismatched_zone.into_iter().map(|r| r.clone().into()).collect::>(), + "class": models::DNSClass::from(class), + "mismatched_class": mismatched_class.into_iter().map(|r| r.clone().into()).collect::>(), + "mismatched_zone": mismatched_zone.into_iter().map(|r| r.clone().into()).collect::>(), }) ).err(); }, - Err(e) => return make_500(e).err() + Err(e) => return models::make_500(e).err() }; // TODO: better error handling if response.response_code() != ResponseCode::NoError { println!("Update of zone {} failed with code {}", *zone, response.response_code()); - return ErrorResponse::new( + return models::ErrorResponse::new( Status::NotFound, "Update of zone failed".into() ).with_details(json!({ @@ -134,13 +133,13 @@ pub async fn create_zone_records( #[get("/zones")] pub async fn get_zones( conn: DbConn, - user_info: Result, -) -> Result>, ErrorResponse> { + user_info: Result, +) -> Result>, models::ErrorResponse> { let user_info = user_info?; let zones = conn.run(move |c| { if user_info.is_admin() { - Zone::get_all(c) + models::Zone::get_all(c) } else { user_info.get_zones(c) } @@ -153,27 +152,27 @@ pub async fn get_zones( pub async fn create_zone( conn: DbConn, mut client: dns::client::DnsClient, - user_info: Result, - zone_request: Json, -) -> Result, ErrorResponse> { + user_info: Result, + zone_request: Json, +) -> Result, models::ErrorResponse> { user_info?.check_admin()?; // Check if the zone exists in the DNS server let response = { let query = client.query(zone_request.name.clone(), DNSClass::IN, RecordType::SOA); - query.await.map_err(make_500)? + query.await.map_err(models::make_500)? }; if response.response_code() != ResponseCode::NoError { println!("Querrying SOA of zone {} failed with code {}", *zone_request.name, response.response_code()); - return ErrorResponse::new( + return models::ErrorResponse::new( Status::NotFound, format!("Zone {} could not be found", *zone_request.name) ).err() } let zone = conn.run(move |c| { - Zone::create_zone(c, zone_request.into_inner()) + models::Zone::create_zone(c, zone_request.into_inner()) }).await?; Ok(Json(zone)) @@ -183,21 +182,21 @@ pub async fn create_zone( #[post("/zones//members", data = "")] pub async fn add_member_to_zone<'r>( conn: DbConn, - zone: dns::name::AbsoluteName, - user_info: Result, - zone_member_request: Json -) -> Result, ErrorResponse> { + zone: models::AbsoluteName, + user_info: Result, + zone_member_request: Json +) -> Result, models::ErrorResponse> { let user_info = user_info?; let zone_name = zone.to_utf8(); conn.run(move |c| { let zone = if user_info.is_admin() { - Zone::get_by_name(c, &zone_name) + models::Zone::get_by_name(c, &zone_name) } else { user_info.get_zone(c, &zone_name) }?; - let new_member = LocalUser::get_user_by_uuid(c, &zone_member_request.id)?; + let new_member = models::LocalUser::get_user_by_uuid(c, &zone_member_request.id)?; zone.add_member(&c, &new_member) }).await?;