From 9dc1fb2151cc3e8c7b3c401e95550491b6e53839 Mon Sep 17 00:00:00 2001 From: Paul Maruhn <paulmaruhn@posteo.de> Date: Fri, 31 Dec 2021 03:43:18 +0100 Subject: [PATCH] implement domain scrub. fix #14 --- assets/ffdyndns.service | 2 +- src/ffdyndns.rs | 11 ++++++++++- src/main.rs | 28 +++++++++++++++++++++------- src/web/api.rs | 5 +++-- src/web/mod.rs | 6 ++---- src/web/web.rs | 1 - 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/assets/ffdyndns.service b/assets/ffdyndns.service index d9a5789..92f3f04 100644 --- a/assets/ffdyndns.service +++ b/assets/ffdyndns.service @@ -3,7 +3,7 @@ Description=Simple dynamic dns service After=network.target pdns.service [Service] -ExecStart=/usr/bin/ffdyndns --server +ExecStart=/usr/bin/ffdyndns server WorkingDirectory=/usr/lib/ffdyndns Restart=on-abort diff --git a/src/ffdyndns.rs b/src/ffdyndns.rs index 70d0aaf..9b4c43f 100644 --- a/src/ffdyndns.rs +++ b/src/ffdyndns.rs @@ -3,7 +3,7 @@ use crate::Database; use crate::db::Domain; use crate::domain::Dname; #[allow(unused_imports)] -use log::{info, error, warn}; +use log::{error, warn, info, debug, trace}; use serde::{Serialize}; use std::fmt::{self, Display}; use std::net::IpAddr; @@ -90,6 +90,8 @@ impl Service { db.update_lastupdate(&update.domain, Utc::now()); + info!("updating domain: {}", update.domain); + self.updater .lock() .unwrap() @@ -117,11 +119,18 @@ impl Service { Ok(token) } + pub fn get_domain(&self, domain: &String) -> Option<Domain> { + self.db.get_domain(domain) + } + + pub fn clean_domains(&self) { + trace!("start domain cleanup"); let domains = self.db.get_all(); for d in domains { if d.valid_until < Utc::now() { + debug!("removing domain: {}", d.domainname); self.db.remove_domain(&d.domainname); self.updater diff --git a/src/main.rs b/src/main.rs index 9762a89..f5a6973 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,22 +7,23 @@ mod web; mod ffdyndns; mod nsupdate; +#[allow(unused_imports)] +use log::{debug, error, info, trace}; +use clap::{self, App, Arg, ArgMatches}; use config::Config; use crate::db::Database; use lazy_static::lazy_static; -#[allow(unused_imports)] -use log::{debug, error, info, trace}; +use pretty_env_logger; use rocket::launch; use std::fs; use std::io::{Read, Write}; use std::path; +use std::process; use std::process::exit; -use toml; -use pretty_env_logger; -use clap::{self, App, Arg, ArgMatches}; +use std::thread; use std::time; -use std::process; use tokio; +use toml; const CONFIG_DIRS: &[&str] = &[ "./ffdyndns.toml", @@ -36,6 +37,7 @@ pub const WEB_TEMPLATES_DIR: &str = "/usr/lib/ffdyndns/templates"; pub const DNSTTL: usize = 60; pub const NSUPDATE_BIN: &str = "/usr/bin/nsupdate"; pub const NSUPDATE_TIMEOUT: u32 = 3; +pub const CLEAN_INTERVAL: u64 = 30; lazy_static! { @@ -153,5 +155,17 @@ pub fn cmd_server(_: &ArgMatches<'_>) { let rt = tokio::runtime::Runtime::new().unwrap(); let db = db::Database::new(CONFIG.database.clone().into()); - rt.block_on(web::start_web(db)); + let app = ffdyndns::Service::new(db); + + let app_cleaner = app.clone(); + + // start cleaning thread + std::thread::spawn(move || { + loop { + thread::sleep(time::Duration::from_secs(CLEAN_INTERVAL)); + app_cleaner.clean_domains(); + } + }); + + rt.block_on(web::start_web(app)); } diff --git a/src/web/api.rs b/src/web/api.rs index 55e1509..c7933b3 100644 --- a/src/web/api.rs +++ b/src/web/api.rs @@ -97,9 +97,10 @@ pub fn update( // .map(|_| "Update successful\n".to_string()) // } +#[allow(dead_code)] #[get("/status?<domain>")] -fn status(db: &State<AppState>, domain: String) -> String { - let domaininfo = match db.db.get_domain(&domain) { +fn status(state: &State<AppState>, domain: String) -> String { + let domaininfo = match state.service.get_domain(&domain) { None => return "domain not found".to_string(), Some(r) => r, }; diff --git a/src/web/mod.rs b/src/web/mod.rs index 21fde7f..e063c3a 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -34,7 +34,6 @@ use rocket_dyn_templates::{Template, Engines}; pub struct AppState { // templates: Tera, - db: Database, service: ffdyndns::Service, } @@ -106,10 +105,9 @@ impl<'r> FromRequest<'r> for AuthorizationToken { } -pub async fn start_web(db: Database) { +pub async fn start_web(app: ffdyndns::Service) { let appstate = AppState { - db: db.clone(), - service: ffdyndns::Service::new(db), + service: app, }; let config = rocket_config(); diff --git a/src/web/web.rs b/src/web/web.rs index 42bd498..2f87b1e 100644 --- a/src/web/web.rs +++ b/src/web/web.rs @@ -78,7 +78,6 @@ pub fn newdomain( suffix: Option<String>, tos: Option<bool>, ) -> Template { - let db = &state.db; let mut template_data: json::Value = json!({}); match (&domainname, &suffix, tos) { -- GitLab