From 7a0a7b720d8fb0df680006e100457e5e940c1980 Mon Sep 17 00:00:00 2001 From: notplants Date: Tue, 25 May 2021 16:14:29 +0200 Subject: [PATCH] Reformatting --- src/constants.rs | 3 +-- src/errors.rs | 15 ++++++-------- src/generate_zone.rs | 48 +++++++++++++++++++++++++++----------------- src/lib.rs | 13 ++++++------ 4 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index b5900c1..9912ce8 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,4 +1,3 @@ - // this regex is used to validate that domains are in the correct format // e.g. blue.dyn.peachcloud.org -pub const DOMAIN_REGEX: &str = r"^.*\.dyn\.peachcloud\.org$"; \ No newline at end of file +pub const DOMAIN_REGEX: &str = r"^.*\.dyn\.peachcloud\.org$"; diff --git a/src/errors.rs b/src/errors.rs index dff5f54..0d275bd 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -9,7 +9,6 @@ pub type BoxError = Box; #[derive(Debug, Snafu)] #[snafu(visibility(pub(crate)))] pub enum PeachDynDnsError { - #[snafu(display("Missing expected parameters: {}", e))] MissingParams { e: Error }, @@ -26,16 +25,14 @@ pub enum PeachDynDnsError { KeyFileParseError { source: FromUtf8Error }, #[snafu(display("Error generating key: {}", source))] - KeyGenerationError { source: std::io::Error } - + KeyGenerationError { source: std::io::Error }, } - impl From for Error { fn from(err: PeachDynDnsError) -> Self { match &err { PeachDynDnsError::MissingParams { e } => e.clone(), - PeachDynDnsError::InvalidDomain { domain} => Error { + PeachDynDnsError::InvalidDomain { domain } => Error { code: ErrorCode::ServerError(-32028), message: format!("Domain is invalid format: {}", domain), data: None, @@ -45,21 +42,21 @@ impl From for Error { message: "There was a bind configuration error".to_string(), data: None, }, - PeachDynDnsError::DomainAlreadyExistsError { domain} => Error { + PeachDynDnsError::DomainAlreadyExistsError { domain } => Error { code: ErrorCode::ServerError(-32030), message: format!("Can't register domain that already exists: {}", domain), data: None, }, - PeachDynDnsError::KeyFileParseError { source: _} => Error { + PeachDynDnsError::KeyFileParseError { source: _ } => Error { code: ErrorCode::ServerError(-32031), message: "Error parsing key file".to_string(), data: None, }, - PeachDynDnsError::KeyGenerationError { source: _} => Error { + PeachDynDnsError::KeyGenerationError { source: _ } => Error { code: ErrorCode::ServerError(-32032), message: "Key generation error".to_string(), data: None, }, } } -} \ No newline at end of file +} diff --git a/src/generate_zone.rs b/src/generate_zone.rs index e434366..475319d 100644 --- a/src/generate_zone.rs +++ b/src/generate_zone.rs @@ -2,16 +2,15 @@ * Functions for generating bind9 configurations to enable dynamic dns for a subdomain via TSIG authentication * which is unique to that subdomain */ +use crate::constants::DOMAIN_REGEX; +use crate::errors::*; +use log::{error, info}; +use snafu::ResultExt; use std::fs::File; use std::fs::OpenOptions; use std::io::Write; use std::process::Command; -use tera::{Tera, Context}; -use snafu::{ResultExt}; -use log::{info, error}; -use crate::errors::*; -use crate::constants::DOMAIN_REGEX; - +use tera::{Context, Tera}; /// function to generate the text of a TSIG key file pub fn generate_tsig_key(full_domain: &str) -> Result { @@ -19,7 +18,8 @@ pub fn generate_tsig_key(full_domain: &str) -> Result .arg("-a") .arg("hmac-md5") .arg(full_domain) - .output().context(KeyGenerationError)?; + .output() + .context(KeyGenerationError)?; let key_file_text = String::from_utf8(output.stdout).context(KeyFileParseError)?; Ok(key_file_text) } @@ -40,12 +40,14 @@ pub fn check_domain_available(full_domain: &str) -> bool { let status1 = Command::new("/bin/grep") .arg(full_domain) .arg("/etc/bind/named.conf.local") - .status().expect("error running grep on /etc/bind/named.conf.local"); + .status() + .expect("error running grep on /etc/bind/named.conf.local"); let code1 = status1.code().expect("error getting code from grep"); let status2 = Command::new("/bin/grep") .arg(full_domain) .arg("/etc/bind/dyn.peachcloud.org.keys") - .status().expect("error running grep on /etc/bind/dyn.peachcloud.org.keys"); + .status() + .expect("error running grep on /etc/bind/dyn.peachcloud.org.keys"); let code2 = status2.code().expect("error getting code from grep"); let condition3 = std::path::Path::new(&format!("/var/lib/bind/{}", full_domain)).exists(); @@ -64,16 +66,19 @@ pub fn check_domain_available(full_domain: &str) -> bool { /// - add a minimal zone file to /var/lib/bind/subdomain.dyn.peachcloud.org /// - reload bind and return the secret key to the client pub fn generate_zone(full_domain: &str) -> Result { - // first safety check domain is in correct format if !validate_domain(full_domain) { - return Err(PeachDynDnsError::InvalidDomain{ domain: full_domain.to_string() }); + return Err(PeachDynDnsError::InvalidDomain { + domain: full_domain.to_string(), + }); } // safety check if the domain is available let is_available = check_domain_available(full_domain); if !is_available { - return Err(PeachDynDnsError::DomainAlreadyExistsError { domain: full_domain.to_string() }); + return Err(PeachDynDnsError::DomainAlreadyExistsError { + domain: full_domain.to_string(), + }); } // generate string with text for TSIG key file @@ -81,7 +86,9 @@ pub fn generate_zone(full_domain: &str) -> Result { // append key_file_text to /etc/bind/dyn.peachcloud.org.keys let key_file_path = "/etc/bind/dyn.peachcloud.org.keys"; - let mut file = OpenOptions::new().append(true).open(key_file_path) + let mut file = OpenOptions::new() + .append(true) + .open(key_file_path) .unwrap_or_else(|_| panic!("failed to open {}", key_file_path)); if let Err(e) = writeln!(file, "{}", key_file_text) { error!("Couldn't write to file: {}", e); @@ -105,7 +112,8 @@ pub fn generate_zone(full_domain: &str) -> Result { ", full_domain = full_domain ); - writeln!(file, "{}", zone_section_text).unwrap_or_else(|_| panic!("Couldn't write to file: {}", bind_conf_path)); + writeln!(file, "{}", zone_section_text) + .unwrap_or_else(|_| panic!("Couldn't write to file: {}", bind_conf_path)); // use tera to render the zone file let tera = match Tera::new("templates/*.tera") { @@ -117,22 +125,26 @@ pub fn generate_zone(full_domain: &str) -> Result { }; let mut context = Context::new(); context.insert("full_domain", full_domain); - let result = tera.render("zonefile.tera", &context).expect("error loading zonefile.tera"); + let result = tera + .render("zonefile.tera", &context) + .expect("error loading zonefile.tera"); // write new zone file to /var/lib/bind let zone_file_path = format!("/var/lib/bind/{}", full_domain); let mut file = File::create(&zone_file_path) .unwrap_or_else(|_| panic!("failed to create {}", zone_file_path)); - writeln!(file, "{}", result).unwrap_or_else(|_| panic!("Couldn't write to file: {}", zone_file_path)); + writeln!(file, "{}", result) + .unwrap_or_else(|_| panic!("Couldn't write to file: {}", zone_file_path)); // restart bind // we use the /etc/sudoers.d/bindctl to allow peach-dyndns user to restart bind as sudo without entering a password // using a binary at /bin/reloadbind which runs 'systemctl reload bind9' let status = Command::new("sudo") .arg("/usr/bin/reloadbind") - .status().expect("error restarting bind9"); + .status() + .expect("error restarting bind9"); if !status.success() { - return Err(PeachDynDnsError::BindConfigurationError); + return Err(PeachDynDnsError::BindConfigurationError); // TODO: for extra safety consider to revert bind configurations to whatever they were before } diff --git a/src/lib.rs b/src/lib.rs index 719d8a7..2b0e477 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,19 +5,18 @@ * NOT IMPLEMENTED- register_user (sends an email verification to create a new account) * NOT IMPLEMENTED- verify_user (for clicking the link in the email) */ +mod constants; mod errors; mod generate_zone; -mod constants; use crate::generate_zone::{check_domain_available, generate_zone, validate_domain}; -use std::result::Result; use jsonrpc_core::{types::error::Error, IoHandler, Params, Value}; use jsonrpc_http_server::{AccessControlAllowOrigin, DomainsValidation, ServerBuilder}; use log::info; use std::env; - +use std::result::Result; use crate::errors::{BoxError, PeachDynDnsError}; -use serde::{Deserialize}; +use serde::Deserialize; #[derive(Deserialize, Debug)] pub struct RegisterDomainPost { @@ -56,14 +55,16 @@ pub fn run() -> Result<(), BoxError> { Ok(d) => { // if the domain has an invalid format return an erro if !validate_domain(&d.domain) { - Err(Error::from(PeachDynDnsError::InvalidDomain{ domain: d.domain })) + Err(Error::from(PeachDynDnsError::InvalidDomain { + domain: d.domain, + })) } // if it has a valid format, check if its available else { let result = check_domain_available(&d.domain); Ok(Value::String(result.to_string())) } - }, + } Err(e) => Err(Error::from(PeachDynDnsError::MissingParams { e })), } });