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