use rocket::Response; use rocket::http::Status; use rocket_contrib::json::Json; use crate::DbConn; use crate::dns::{DnsClient, DnsConnectorClient, RecordConnector, ZoneConnector}; use crate::models; use crate::models::{ParseRecordList}; #[get("/zones//records")] pub async fn get_zone_records( client: DnsClient, conn: DbConn, 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() { models::Zone::get_by_name(c, &zone_name) } else { user_info.get_zone(c, &zone_name) } }).await?; let mut dns_api = DnsConnectorClient::new(client); let dns_records = dns_api.get_records(zone.clone(), models::DNSClass::IN.into()).await?; let records: Vec<_> = dns_records.into_iter().map(models::Record::from).collect(); Ok(Json(records)) } #[post("/zones//records", data = "")] pub async fn create_zone_records( client: DnsClient, conn: DbConn, 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() { models::Zone::get_by_name(c, &zone_name) } else { user_info.get_zone(c, &zone_name) } }).await?; let mut dns_api = DnsConnectorClient::new(client); dns_api.add_records( zone.clone(), models::DNSClass::IN.into(), new_records.into_inner().try_into_dns_type(zone.into_inner(), models::DNSClass::IN.into())? ).await?; return Ok(Json(())); } #[put("/zones//records", data = "")] pub async fn update_zone_records( client: DnsClient, conn: DbConn, user_info: Result, zone: models::AbsoluteName, update_records_request: Json ) -> Result, models::ErrorResponse> { let user_info = user_info?; let zone = zone.into_inner(); let zone_name = zone.to_utf8(); let update_records_request = update_records_request.into_inner(); conn.run(move |c| { if user_info.is_admin() { models::Zone::get_by_name(c, &zone_name) } else { user_info.get_zone(c, &zone_name) } }).await?; let mut dns_api = DnsConnectorClient::new(client); dns_api.update_records( zone.clone(), models::DNSClass::IN.into(), update_records_request.old_records.try_into_dns_type(zone.clone(), models::DNSClass::IN.into())?, update_records_request.new_records.try_into_dns_type(zone, models::DNSClass::IN.into())?, ).await?; return Ok(Json(())); } #[delete("/zones//records", data = "")] pub async fn delete_zone_records( client: DnsClient, conn: DbConn, user_info: Result, zone: models::AbsoluteName, 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() { models::Zone::get_by_name(c, &zone_name) } else { user_info.get_zone(c, &zone_name) } }).await?; let mut dns_api = DnsConnectorClient::new(client); dns_api.delete_records( zone.clone(), models::DNSClass::IN.into(), records.into_inner().try_into_dns_type(zone.into_inner(), models::DNSClass::IN.into())? ).await?; return Ok(Json(())); } #[get("/zones")] pub async fn get_zones( conn: DbConn, user_info: Result, ) -> Result>, models::ErrorResponse> { let user_info = user_info?; let zones = conn.run(move |c| { if user_info.is_admin() { models::Zone::get_all(c) } else { user_info.get_zones(c) } }).await?; Ok(Json(zones)) } #[post("/zones", data = "")] pub async fn create_zone( conn: DbConn, client: DnsClient, user_info: Result, zone_request: Json, ) -> Result, models::ErrorResponse> { user_info?.check_admin()?; let mut dns_api = DnsConnectorClient::new(client); dns_api.zone_exists(zone_request.name.clone(), models::DNSClass::IN.into()).await?; let zone = conn.run(move |c| { models::Zone::create_zone(c, zone_request.into_inner()) }).await?; Ok(Json(zone)) } #[post("/zones//members", data = "")] pub async fn add_member_to_zone<'r>( conn: DbConn, 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() { models::Zone::get_by_name(c, &zone_name) } else { user_info.get_zone(c, &zone_name) }?; let new_member = models::LocalUser::get_user_by_uuid(c, &zone_member_request.id)?; zone.add_member(&c, &new_member) }).await?; Response::build() .status(Status::Created) // TODO: change this? .ok() }