From e61b5d2a3f4d9251d097de49d30888055003abbc Mon Sep 17 00:00:00 2001 From: Donald Zou Date: Sat, 16 Aug 2025 15:40:57 +0800 Subject: [PATCH] Completed override peer settings --- src/dashboard.py | 4 +- src/modules/Utilities.py | 9 +++++ src/modules/WireguardConfiguration.py | 35 +++++++++++++---- .../editPeerSettingsOverride.vue | 38 +++++++++++++------ 4 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/dashboard.py b/src/dashboard.py index 43e1a7f8..f94ef362 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -309,9 +309,9 @@ def API_updateWireguardConfigurationInfo(): if name not in WireguardConfigurations.keys(): return ResponseObject(False, "Configuration does not exist", status_code=404) - status, msg = WireguardConfigurations[name].updateConfigurationInfo(key, value) + status, msg, key = WireguardConfigurations[name].updateConfigurationInfo(key, value) - return ResponseObject(status=status, message=msg) + return ResponseObject(status=status, message=msg, data=key) @app.get(f'{APP_PREFIX}/api/getWireguardConfigurationRawFile') def API_GetWireguardConfigurationRawFile(): diff --git a/src/modules/Utilities.py b/src/modules/Utilities.py index f524eb21..0ba24066 100644 --- a/src/modules/Utilities.py +++ b/src/modules/Utilities.py @@ -59,6 +59,15 @@ def ValidateDNSAddress(addresses) -> tuple[bool, str]: return False, f"{address} does not appear to be an valid DNS address" return True, "" +def ValidateEndpointAllowedIPs(IPs) -> tuple[bool, str] | tuple[bool, None]: + ips = IPs.replace(" ", "").split(",") + for ip in ips: + try: + ipaddress.ip_network(ip, strict=False) + except ValueError as e: + return False, str(e) + return True, None + def GenerateWireguardPublicKey(privateKey: str) -> tuple[bool, str] | tuple[bool, None]: try: publicKey = subprocess.check_output(f"wg pubkey", input=privateKey.encode(), shell=True, diff --git a/src/modules/WireguardConfiguration.py b/src/modules/WireguardConfiguration.py index 969d5df2..9bc33898 100644 --- a/src/modules/WireguardConfiguration.py +++ b/src/modules/WireguardConfiguration.py @@ -1,6 +1,9 @@ """ WireGuard Configuration """ +from typing import Any + +import jinja2 import sqlalchemy, random, shutil, configparser, ipaddress, os, subprocess, time, re, uuid, psutil, traceback from zipfile import ZipFile from datetime import datetime, timedelta @@ -11,7 +14,8 @@ from .DashboardConfig import DashboardConfig from .Peer import Peer from .PeerJobs import PeerJobs from .PeerShareLinks import PeerShareLinks -from .Utilities import StringToBoolean, GenerateWireguardPublicKey, RegexMatch +from .Utilities import StringToBoolean, GenerateWireguardPublicKey, RegexMatch, ValidateDNSAddress, \ + ValidateEndpointAllowedIPs from .WireguardConfigurationInfo import WireguardConfigurationInfo @@ -1106,19 +1110,34 @@ class WireguardConfiguration: except Exception as e: return False - def updateConfigurationInfo(self, key: str, value) -> tuple[bool, str] | tuple[bool, None]: + def updateConfigurationInfo(self, key: str, value: str | dict[str, str]) -> tuple[bool, Any, str] | tuple[ + bool, str, None] | tuple[bool, None, None]: if key == "Description": self.configurationInfo.Description = value elif key == "OverridePeerSettings": - for key in value.keys(): - if key == "DNS" and value.get("DNS"): - pass - + for (key, val) in value.items(): + status, msg = self.__validateOverridePeerSettings(key, jinja2.Template(val).render(configuration=self.toJson())) + if not status: + return False, msg, key self.configurationInfo.OverridePeerSettings = ( self.configurationInfo.OverridePeerSettings.model_validate(value)) else: - return False, "Key does not exist" + return False, "Key does not exist", None self.storeConfigurationInfo() - return True, None + return True, None, None + + def __validateOverridePeerSettings(self, key: str, value: str | int) -> tuple[bool, None] | tuple[bool, str]: + status = True + msg = None + print(value) + if key == "DNS" and value: + status, msg = ValidateDNSAddress(value) + elif key == "EndpointAllowedIPs" and value: + status, msg = ValidateEndpointAllowedIPs(value) + elif key == "ListenPort" and value: + if not value.isnumeric() or not (1 <= int(value) <= 65535): + status = False + msg = "Listen Port must be >= 1 and <= 65535" + return status, msg \ No newline at end of file diff --git a/src/static/app/src/components/configurationComponents/editConfigurationComponents/editPeerSettingsOverride.vue b/src/static/app/src/components/configurationComponents/editConfigurationComponents/editPeerSettingsOverride.vue index 815285e0..a2a6e167 100644 --- a/src/static/app/src/components/configurationComponents/editConfigurationComponents/editPeerSettingsOverride.vue +++ b/src/static/app/src/components/configurationComponents/editConfigurationComponents/editPeerSettingsOverride.vue @@ -6,6 +6,7 @@ const props = defineProps(['configuration']) const saving = ref(false) const overridePeerSettings = ref({...props.configuration.Info.OverridePeerSettings}) const edited = ref(false) +const errorMsg = ref("") onMounted(() => { document.querySelectorAll("#editPeerSettingsOverride input").forEach( @@ -21,13 +22,23 @@ const resetForm = () => { } const submitForm = async () => { + document.querySelectorAll("#editPeerSettingsOverride input").forEach( + x => x.classList.remove("is-invalid", "is-valid") + ) await fetchPost("/api/updateWireguardConfigurationInfo", { Name: props.configuration.Name, Key: "OverridePeerSettings", Value: overridePeerSettings.value }, (res) => { if (res.status){ + edited.value = false props.configuration.Info.OverridePeerSettings = overridePeerSettings.value + document.querySelectorAll("#editPeerSettingsOverride input").forEach( + x => x.classList.add("is-valid") + ) + }else{ + errorMsg.value = res.message + document.querySelector(`#override_${res.data}`).classList.add("is-invalid") } }) } @@ -45,7 +56,7 @@ const submitForm = async () => {
-
-
-
-
-