peach-workspace/peach-web/src/routes/settings/dns.rs

118 lines
4.2 KiB
Rust

use log::info;
use rocket::{
form::{Form, FromForm},
get, post,
request::FlashMessage,
serde::Deserialize,
};
use rocket_dyn_templates::Template;
use peach_lib::{
config_manager, dyndns_client,
error::PeachError,
jsonrpc_client_core::{Error, ErrorKind},
jsonrpc_core::types::error::ErrorCode,
};
use crate::{
context::dns::ConfigureDNSContext, error::PeachWebError, routes::authentication::Authenticated,
};
#[derive(Debug, Deserialize, FromForm)]
pub struct DnsForm {
pub external_domain: String,
pub enable_dyndns: bool,
pub dynamic_domain: String,
}
pub fn save_dns_configuration(dns_form: DnsForm) -> Result<(), PeachWebError> {
// first save local configurations
config_manager::set_external_domain(&dns_form.external_domain)?;
config_manager::set_dyndns_enabled_value(dns_form.enable_dyndns)?;
// if dynamic dns is enabled and this is a new domain name, then register it
if dns_form.enable_dyndns {
let full_dynamic_domain = dyndns_client::get_full_dynamic_domain(&dns_form.dynamic_domain);
// check if this is a new domain or if its already registered
let is_new_domain = dyndns_client::check_is_new_dyndns_domain(&full_dynamic_domain)?;
if is_new_domain {
match dyndns_client::register_domain(&full_dynamic_domain) {
Ok(_) => {
info!("Registered new dyndns domain");
// successful update
Ok(())
}
Err(err) => {
info!("Failed to register dyndns domain: {:?}", err);
// json response for failed update
let msg: String = match err {
PeachError::JsonRpcClientCore(Error(
ErrorKind::JsonRpcError(err),
_state,
)) => {
if let ErrorCode::ServerError(-32030) = err.code {
format!(
"Error registering domain: {} was previously registered",
full_dynamic_domain
)
} else {
"Failed to register dyndns domain".to_string()
}
}
_ => "Failed to register dyndns domain".to_string(),
};
Err(PeachWebError::FailedToRegisterDynDomain(msg))
}
}
}
// if the domain is already registered, then dont re-register, and just return success
else {
Ok(())
}
} else {
Ok(())
}
}
#[get("/dns")]
pub fn configure_dns(flash: Option<FlashMessage>, _auth: Authenticated) -> Template {
let mut context = ConfigureDNSContext::build();
// set back icon link to network route
context.back = Some("/settings/network".to_string());
context.title = Some("Configure DNS".to_string());
// check to see if there is a flash message to display
if let Some(flash) = flash {
// add flash message contents to the context object
context.flash_name = Some(flash.kind().to_string());
context.flash_msg = Some(flash.message().to_string());
};
Template::render("settings/network/configure_dns", &context)
}
#[post("/dns", data = "<dns>")]
pub fn configure_dns_post(dns: Form<DnsForm>, _auth: Authenticated) -> Template {
let result = save_dns_configuration(dns.into_inner());
let mut context = ConfigureDNSContext::build();
// set back icon link to network route
context.back = Some("/settings/network".to_string());
context.title = Some("Configure DNS".to_string());
match result {
Ok(_) => {
context.flash_name = Some("success".to_string());
context.flash_msg = Some("New dynamic dns configuration is now enabled".to_string());
}
Err(err) => {
context.flash_name = Some("error".to_string());
context.flash_msg = Some(format!("Failed to save dns configurations: {}", err));
}
}
Template::render("settings/network/configure_dns", &context)
}