Completed override peer settings

This commit is contained in:
Donald Zou
2025-08-16 15:40:57 +08:00
parent f11a3c8c3b
commit a511eb21fc
4 changed files with 65 additions and 21 deletions

View File

@@ -309,9 +309,9 @@ def API_updateWireguardConfigurationInfo():
if name not in WireguardConfigurations.keys(): if name not in WireguardConfigurations.keys():
return ResponseObject(False, "Configuration does not exist", status_code=404) 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') @app.get(f'{APP_PREFIX}/api/getWireguardConfigurationRawFile')
def API_GetWireguardConfigurationRawFile(): def API_GetWireguardConfigurationRawFile():

View File

@@ -59,6 +59,15 @@ def ValidateDNSAddress(addresses) -> tuple[bool, str]:
return False, f"{address} does not appear to be an valid DNS address" return False, f"{address} does not appear to be an valid DNS address"
return True, "" 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]: def GenerateWireguardPublicKey(privateKey: str) -> tuple[bool, str] | tuple[bool, None]:
try: try:
publicKey = subprocess.check_output(f"wg pubkey", input=privateKey.encode(), shell=True, publicKey = subprocess.check_output(f"wg pubkey", input=privateKey.encode(), shell=True,

View File

@@ -1,6 +1,9 @@
""" """
WireGuard Configuration WireGuard Configuration
""" """
from typing import Any
import jinja2
import sqlalchemy, random, shutil, configparser, ipaddress, os, subprocess, time, re, uuid, psutil, traceback import sqlalchemy, random, shutil, configparser, ipaddress, os, subprocess, time, re, uuid, psutil, traceback
from zipfile import ZipFile from zipfile import ZipFile
from datetime import datetime, timedelta from datetime import datetime, timedelta
@@ -11,7 +14,8 @@ from .DashboardConfig import DashboardConfig
from .Peer import Peer from .Peer import Peer
from .PeerJobs import PeerJobs from .PeerJobs import PeerJobs
from .PeerShareLinks import PeerShareLinks from .PeerShareLinks import PeerShareLinks
from .Utilities import StringToBoolean, GenerateWireguardPublicKey, RegexMatch from .Utilities import StringToBoolean, GenerateWireguardPublicKey, RegexMatch, ValidateDNSAddress, \
ValidateEndpointAllowedIPs
from .WireguardConfigurationInfo import WireguardConfigurationInfo from .WireguardConfigurationInfo import WireguardConfigurationInfo
@@ -1106,19 +1110,34 @@ class WireguardConfiguration:
except Exception as e: except Exception as e:
return False 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": if key == "Description":
self.configurationInfo.Description = value self.configurationInfo.Description = value
elif key == "OverridePeerSettings": elif key == "OverridePeerSettings":
for key in value.keys(): for (key, val) in value.items():
if key == "DNS" and value.get("DNS"): status, msg = self.__validateOverridePeerSettings(key, jinja2.Template(val).render(configuration=self.toJson()))
pass if not status:
return False, msg, key
self.configurationInfo.OverridePeerSettings = ( self.configurationInfo.OverridePeerSettings = (
self.configurationInfo.OverridePeerSettings.model_validate(value)) self.configurationInfo.OverridePeerSettings.model_validate(value))
else: else:
return False, "Key does not exist" return False, "Key does not exist", None
self.storeConfigurationInfo() 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

View File

@@ -6,6 +6,7 @@ const props = defineProps(['configuration'])
const saving = ref(false) const saving = ref(false)
const overridePeerSettings = ref({...props.configuration.Info.OverridePeerSettings}) const overridePeerSettings = ref({...props.configuration.Info.OverridePeerSettings})
const edited = ref(false) const edited = ref(false)
const errorMsg = ref("")
onMounted(() => { onMounted(() => {
document.querySelectorAll("#editPeerSettingsOverride input").forEach( document.querySelectorAll("#editPeerSettingsOverride input").forEach(
@@ -21,13 +22,23 @@ const resetForm = () => {
} }
const submitForm = async () => { const submitForm = async () => {
document.querySelectorAll("#editPeerSettingsOverride input").forEach(
x => x.classList.remove("is-invalid", "is-valid")
)
await fetchPost("/api/updateWireguardConfigurationInfo", { await fetchPost("/api/updateWireguardConfigurationInfo", {
Name: props.configuration.Name, Name: props.configuration.Name,
Key: "OverridePeerSettings", Key: "OverridePeerSettings",
Value: overridePeerSettings.value Value: overridePeerSettings.value
}, (res) => { }, (res) => {
if (res.status){ if (res.status){
edited.value = false
props.configuration.Info.OverridePeerSettings = overridePeerSettings.value 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 () => {
</h6> </h6>
<div class="d-flex gap-2 flex-column"> <div class="d-flex gap-2 flex-column">
<div> <div>
<label for="override_dns" class="form-label"> <label for="override_DNS" class="form-label">
<small class="text-muted"> <small class="text-muted">
<LocaleText t="DNS"></LocaleText> <LocaleText t="DNS"></LocaleText>
</small> </small>
@@ -53,10 +64,11 @@ const submitForm = async () => {
<input type="text" class="form-control form-control-sm rounded-3" <input type="text" class="form-control form-control-sm rounded-3"
:disabled="saving" :disabled="saving"
v-model="overridePeerSettings.DNS" v-model="overridePeerSettings.DNS"
id="override_dns"> id="override_DNS">
<div class="invalid-feedback">{{ errorMsg }}</div>
</div> </div>
<div> <div>
<label for="override_endpoint_allowed_ips" class="form-label"> <label for="override_EndpointAllowedIPs" class="form-label">
<small class="text-muted"> <small class="text-muted">
<LocaleText t="Endpoint Allowed IPs"></LocaleText> <LocaleText t="Endpoint Allowed IPs"></LocaleText>
</small> </small>
@@ -64,10 +76,11 @@ const submitForm = async () => {
<input type="text" class="form-control form-control-sm rounded-3" <input type="text" class="form-control form-control-sm rounded-3"
:disabled="saving" :disabled="saving"
v-model="overridePeerSettings.EndpointAllowedIPs" v-model="overridePeerSettings.EndpointAllowedIPs"
id="override_endpoint_allowed_ips"> id="override_EndpointAllowedIPs">
<div class="invalid-feedback">{{ errorMsg }}</div>
</div> </div>
<div> <div>
<label for="override_listen_port" class="form-label"> <label for="override_ListenPort" class="form-label">
<small class="text-muted"> <small class="text-muted">
<LocaleText t="Listen Port"></LocaleText> <LocaleText t="Listen Port"></LocaleText>
</small> </small>
@@ -75,10 +88,11 @@ const submitForm = async () => {
<input type="text" class="form-control form-control-sm rounded-3" <input type="text" class="form-control form-control-sm rounded-3"
:disabled="saving" :disabled="saving"
v-model="overridePeerSettings.ListenPort" v-model="overridePeerSettings.ListenPort"
id="override_listen_port"> id="override_ListenPort">
<div class="invalid-feedback">{{ errorMsg }}</div>
</div> </div>
<div> <div>
<label for="override_mtu" class="form-label"> <label for="override_MTU" class="form-label">
<small class="text-muted"> <small class="text-muted">
<LocaleText t="MTU"></LocaleText> <LocaleText t="MTU"></LocaleText>
</small> </small>
@@ -87,10 +101,11 @@ const submitForm = async () => {
class="form-control form-control-sm rounded-3" class="form-control form-control-sm rounded-3"
:disabled="saving" :disabled="saving"
v-model="overridePeerSettings.MTU" v-model="overridePeerSettings.MTU"
id="override_mtu"> id="override_MTU">
<div class="invalid-feedback">{{ errorMsg }}</div>
</div> </div>
<div> <div>
<label for="override_peer_remote_endpoint" class="form-label"> <label for="override_PeerRemoteEndpoint" class="form-label">
<small class="text-muted"> <small class="text-muted">
<LocaleText t="Peer Remote Endpoint"></LocaleText> <LocaleText t="Peer Remote Endpoint"></LocaleText>
</small> </small>
@@ -98,7 +113,7 @@ const submitForm = async () => {
<input type="text" class="form-control form-control-sm rounded-3" <input type="text" class="form-control form-control-sm rounded-3"
:disabled="saving" :disabled="saving"
v-model="overridePeerSettings.PeerRemoteEndpoint" v-model="overridePeerSettings.PeerRemoteEndpoint"
id="override_peer_remote_endpoint"> id="override_PeerRemoteEndpoint">
</div> </div>
<div> <div>
<label for="override_persistent_keepalive" class="form-label"> <label for="override_persistent_keepalive" class="form-label">
@@ -109,7 +124,8 @@ const submitForm = async () => {
<input type="text" class="form-control form-control-sm rounded-3" <input type="text" class="form-control form-control-sm rounded-3"
:disabled="saving" :disabled="saving"
v-model="overridePeerSettings.PersistentKeepalive" v-model="overridePeerSettings.PersistentKeepalive"
id="override_persistent_keepalive"> id="override_PersistentKeepalive">
<div class="invalid-feedback">{{ errorMsg }}</div>
</div> </div>
<div class="d-flex mt-1 gap-2"> <div class="d-flex mt-1 gap-2">
<button <button