From f9c1a759c7ada21cdf41644edfd2cd27c9448688 Mon Sep 17 00:00:00 2001 From: Himbeer Date: Wed, 7 Aug 2024 13:18:49 +0200 Subject: Add system maintenance (admin password, reboot, shutdown) --- src-tauri/src/main.rs | 141 +++++++++++++++++++++++++++++++++++++++++++++++++- src/sys.html | 111 +++++++++++++++++++++++++++++++++++++++ src/sys.js | 115 ++++++++++++++++++++++++++++++++++++++++ src/wan.js | 1 - 4 files changed, 366 insertions(+), 2 deletions(-) create mode 100644 src/sys.html create mode 100644 src/sys.js diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index c10f666..ed6ba2a 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1089,6 +1089,142 @@ fn handle_delete_response(response: Response) -> String { } } +#[tauri::command] +async fn change_sys_password( + old: String, + to: String, + repeat: String, + state: State<'_, Mutex>, +) -> Result { + let (client, instance) = { + let state = state.lock().unwrap(); + (state.client.clone(), state.instance.clone()) + }; + let instance = match instance { + Some(instance) => instance, + None => { + return Ok(String::from( + "Keine Instanz ausgewählt, bitte melden Sie sich neu an!", + )) + } + }; + + if to != repeat { + return Ok(String::from( + "Das neue Passwort und seine Wiederholung stimmen nicht überein", + )); + } + + let response = client + .post(instance.url.join("/data/write").unwrap()) + .query(&[("path", "/data/admind.passwd")]) + .basic_auth("rustkrazy", Some(&old)) + .body(to) + .send(); + + Ok(match response.await { + Ok(response) => handle_change_sys_password_response(response), + Err(e) => format!("Änderung fehlgeschlagen: {}", e), + }) +} + +fn handle_change_sys_password_response(response: Response) -> String { + let status = response.status(); + if status.is_success() { + String::from("Änderung erfolgreich") + } else if status == StatusCode::UNAUTHORIZED { + String::from("Das alte Passwort ist ungültig") + } else if status.is_client_error() { + format!("Clientseitiger Fehler: {}", status) + } else if status.is_server_error() { + format!("Serverseitiger Fehler: {}", status) + } else { + format!("Unerwarteter Statuscode: {}", status) + } +} + +#[tauri::command] +async fn reboot(state: State<'_, Mutex>) -> Result { + let (client, instance) = { + let state = state.lock().unwrap(); + (state.client.clone(), state.instance.clone()) + }; + let instance = match instance { + Some(instance) => instance, + None => { + return Ok(String::from( + "Keine Instanz ausgewählt, bitte melden Sie sich neu an!", + )) + } + }; + + let response = client + .post(instance.url.join("/reboot").unwrap()) + .basic_auth("rustkrazy", Some(&instance.password)) + .send(); + + Ok(match response.await { + Ok(response) => handle_reboot_response(response), + Err(e) => format!("Befehl fehlgeschlagen: {}", e), + }) +} + +fn handle_reboot_response(response: Response) -> String { + let status = response.status(); + if status.is_success() { + String::new() + } else if status == StatusCode::UNAUTHORIZED { + String::from("Ungültiges Verwaltungspasswort, bitte melden Sie sich neu an!") + } else if status.is_client_error() { + format!("Clientseitiger Fehler: {}", status) + } else if status.is_server_error() { + format!("Serverseitiger Fehler: {}", status) + } else { + format!("Unerwarteter Statuscode: {}", status) + } +} + +#[tauri::command] +async fn shutdown(state: State<'_, Mutex>) -> Result { + let (client, instance) = { + let state = state.lock().unwrap(); + (state.client.clone(), state.instance.clone()) + }; + let instance = match instance { + Some(instance) => instance, + None => { + return Ok(String::from( + "Keine Instanz ausgewählt, bitte melden Sie sich neu an!", + )) + } + }; + + let response = client + .post(instance.url.join("/shutdown").unwrap()) + .basic_auth("rustkrazy", Some(&instance.password)) + .send(); + + Ok(match response.await { + Ok(response) => handle_shutdown_response(response), + Err(e) => format!("Befehl fehlgeschlagen: {}", e), + }) +} + +fn handle_shutdown_response(response: Response) -> String { + let status = response.status(); + if status.is_success() { + String::new() + } else if status == StatusCode::UNAUTHORIZED { + String::from("Ungültiges Verwaltungspasswort, bitte melden Sie sich neu an!") + } else if status.is_client_error() { + format!("Clientseitiger Fehler: {}", status) + } else if status.is_server_error() { + format!("Serverseitiger Fehler: {}", status) + } else { + format!("Unerwarteter Statuscode: {}", status) + } +} + fn main() { tauri::Builder::default() .manage(Mutex::new(Session { @@ -1111,7 +1247,10 @@ fn main() { leases, load_domain, change_domain, - delete + delete, + change_sys_password, + reboot, + shutdown ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src/sys.html b/src/sys.html new file mode 100644 index 0000000..c79d9e8 --- /dev/null +++ b/src/sys.html @@ -0,0 +1,111 @@ + + + + + + + System - RSDSL Verwaltungswerkzeug + + + + + +
+

System

+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ +
+ +
+
+ Neustart und Herunterfahren + +
+ + +
+ +

Information: Ein Neustart dauert ca. 30 Sekunden bis 1 Minute. + In der Regel wird die Internetverbindung innerhalb von 1 Minute + wieder aufgebaut, sofern keine anderen Geräte neu gestartet wurden. + Bei anschließenden Verbindungsproblemen kann es ratsam sein, die + betroffenen Geräte neu mit dem Netzwerk zu verbinden oder für + mehrere Stunden verbunden zu lassen. Achtung: Insbesondere + Smartphones trennen die WLAN-Verbindung oft erst nach mindestens 5 + Sekunden Abschaltzeit. Daher die WLAN-Funktion für mindestens 5 + Sekunden deaktivieren und erst dann wieder einschalten.

+ +

Nach erfolgreichem Herunterfahren muss das Stromkabel abgezogen + werden, um die Hardware tatsächlich auszuschalten. Erst beim + Wiederanschließen fährt das System wieder hoch.

+
+
+ +
+ +
+
+ Verwaltungspasswort + + +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +

+
+
+
+ + diff --git a/src/sys.js b/src/sys.js new file mode 100644 index 0000000..8b19f22 --- /dev/null +++ b/src/sys.js @@ -0,0 +1,115 @@ +const { invoke } = window.__TAURI__.tauri; +const { message } = window.__TAURI__.dialog; + +let passwordOldEl; +let passwordNewEl; +let passwordRepeatEl; +let passwordSubmitEl; +let passwordStatusEl; + +async function reboot() { + const error = await invoke("reboot", {}); + + if (error !== "") { + await message("Befehl konnte nicht erteilt werden: " + error, { + kind: "error", + title: "Neustart nicht erfolgt" + }); + } + + const successTime = Date.now(); + + while ((Date.now() - successTime) < 60) { + await message("Neustart läuft. Bitte ca. 1 Minute warten.", { + kind: "info", + title: "Neustart im Gange" + }); + } +} + +async function shutdown() { + const error = await invoke("shutdown", {}); + + if (error !== "") { + await message("Befehl konnte nicht erteilt werden: " + error, { + kind: "error", + title: "Herunterfahren nicht erfolgt" + }); + } + + await message("Router erfolgreich heruntergefahren. Bitte Stromkabel abziehen.", { + kind: "info", + title: "Herunterfahren erfolgreich" + }); + + window.location = "index.html"; +} + +function showPassword() { + switch (passwordNewEl.type) { + case "password": + passwordNewEl.type = "text"; + passwordRepeatEl.type = "text"; + break; + case "text": + passwordNewEl.type = "password"; + passwordRepeatEl.type = "password"; + break; + } +} + +async function changePassword() { + passwordOldEl.disabled = true; + passwordNewEl.disabled = true; + passwordRepeatEl.disabled = true; + passwordSubmitEl.disabled = true; + passwordStatusEl.innerText = "Änderungsanfrage..."; + document.body.style.cursor = "progress"; + + passwordStatusEl.innerText = await invoke("change_sys_password", { + old: passwordOldEl.value, + to: passwordNewEl.value, + repeat: passwordRepeatEl.value, + }); + + passwordOldEl.disabled = false; + passwordNewEl.disabled = false; + passwordRepeatEl.disabled = false; + passwordSubmitEl.disabled = false; + document.body.style.cursor = "default"; + + if (passwordStatusEl.innerText === "Änderung erfolgreich") { + await message("Passwort erfolgreich geändert. Melden Sie sich neu an, um das Verwaltungswerkzeug weiter benutzen zu können.", { + kind: "info", + title: "Neuanmeldung erforderlich", + }); + + window.location = "index.html"; + } +} + +window.addEventListener("DOMContentLoaded", () => { + document.querySelector("#power-reboot").addEventListener("click", (e) => { + e.preventDefault(); + reboot(); + }); + document.querySelector("#power-shutdown").addEventListener("click", (e) => { + e.preventDefault(); + shutdown(); + }); + + passwordOldEl = document.querySelector("#password-old"); + passwordNewEl = document.querySelector("#password-new"); + passwordRepeatEl = document.querySelector("#password-repeat"); + passwordSubmitEl = document.querySelector("#password-submit"); + passwordStatusEl = document.querySelector("#password-status"); + + document.querySelector("#password-show").addEventListener("click", (e) => { + e.preventDefault(); + showPassword(); + }); + document.querySelector("#password-form").addEventListener("submit", (e) => { + e.preventDefault(); + changePassword(); + }); +}); diff --git a/src/wan.js b/src/wan.js index 675ef18..40e9a6c 100644 --- a/src/wan.js +++ b/src/wan.js @@ -214,7 +214,6 @@ window.addEventListener("DOMContentLoaded", () => { e.preventDefault(); showCredentials(); }); - document.querySelector("#credentials-form").addEventListener("submit", (e) => { e.preventDefault(); changeCredentials(); -- cgit v1.2.3