1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-22 07:10:09 +01:00

Fixed updating WG configuration path

This commit is contained in:
Donald Zou 2024-09-06 16:31:54 +08:00
parent ec50dcbbd9
commit b6aedb43ee
3 changed files with 72 additions and 37 deletions

View File

@ -462,11 +462,11 @@ class WireguardConfiguration:
if name is not None: if name is not None:
self.Name = name self.Name = name
self.__parser.read_file(open(os.path.join(WG_CONF_PATH, f'{self.Name}.conf'))) self.__parser.read_file(open(os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], f'{self.Name}.conf')))
sections = self.__parser.sections() sections = self.__parser.sections()
if "Interface" not in sections: if "Interface" not in sections:
raise self.InvalidConfigurationFileException( raise self.InvalidConfigurationFileException(
"[Interface] section not found in " + os.path.join(WG_CONF_PATH, f'{self.Name}.conf')) "[Interface] section not found in " + os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], f'{self.Name}.conf'))
interfaceConfig = dict(self.__parser.items("Interface", True)) interfaceConfig = dict(self.__parser.items("Interface", True))
for i in dir(self): for i in dir(self):
if str(i) in interfaceConfig.keys(): if str(i) in interfaceConfig.keys():
@ -583,7 +583,7 @@ class WireguardConfiguration:
self.RestrictedPeers.append(Peer(i, self)) self.RestrictedPeers.append(Peer(i, self))
def configurationFileChanged(self) : def configurationFileChanged(self) :
mt = os.path.getmtime(os.path.join(WG_CONF_PATH, f'{self.Name}.conf')) mt = os.path.getmtime(os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], f'{self.Name}.conf'))
changed = self.__configFileModifiedTime is None or self.__configFileModifiedTime != mt changed = self.__configFileModifiedTime is None or self.__configFileModifiedTime != mt
self.__configFileModifiedTime = mt self.__configFileModifiedTime = mt
return changed return changed
@ -592,7 +592,7 @@ class WireguardConfiguration:
if self.configurationFileChanged(): if self.configurationFileChanged():
self.Peers = [] self.Peers = []
with open(os.path.join(WG_CONF_PATH, f'{self.Name}.conf'), 'r') as configFile: with open(os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], f'{self.Name}.conf'), 'r') as configFile:
p = [] p = []
pCounter = -1 pCounter = -1
content = configFile.read().split('\n') content = configFile.read().split('\n')
@ -1210,6 +1210,10 @@ class DashboardConfig:
else: else:
value = self.generatePassword(value).decode("utf-8") value = self.generatePassword(value).decode("utf-8")
if section == "Server" and key == "wg_conf_path":
if not os.path.exists(value):
return False, "Path does not exist"
if section not in self.__config: if section not in self.__config:
self.__config[section] = {} self.__config[section] = {}
@ -1232,7 +1236,7 @@ class DashboardConfig:
except Exception as e: except Exception as e:
return False return False
def GetConfig(self, section, key) -> [any, bool]: def GetConfig(self, section, key) -> [bool, any]:
if section not in self.__config: if section not in self.__config:
return False, None return False, None
@ -1279,7 +1283,8 @@ def _regexMatch(regex, text):
def _getConfigurationList(): def _getConfigurationList():
# configurations = {} # configurations = {}
for i in os.listdir(WG_CONF_PATH): print(DashboardConfig.GetConfig("Server", "wg_conf_path")[1])
for i in os.listdir(DashboardConfig.GetConfig("Server", "wg_conf_path")[1]):
if _regexMatch("^(.{1,}).(conf)$", i): if _regexMatch("^(.{1,}).(conf)$", i):
i = i.replace('.conf', '') i = i.replace('.conf', '')
try: try:
@ -1400,8 +1405,11 @@ cursor = sqldb.cursor()
def sqlSelect(statement: str, paramters: tuple = ()) -> sqlite3.Cursor: def sqlSelect(statement: str, paramters: tuple = ()) -> sqlite3.Cursor:
with sqldb: with sqldb:
cursor = sqldb.cursor() try:
return cursor.execute(statement, paramters) cursor = sqldb.cursor()
return cursor.execute(statement, paramters)
except sqlite3.OperationalError as error:
print("[WGDashboard] SQLite Error:" + str(error) + " | Statement: " + statement)
def sqlUpdate(statement: str, paramters: tuple = ()) -> sqlite3.Cursor: def sqlUpdate(statement: str, paramters: tuple = ()) -> sqlite3.Cursor:
with sqldb: with sqldb:
@ -1602,14 +1610,7 @@ def API_getDashboardConfiguration():
return ResponseObject(data=DashboardConfig.toJson()) return ResponseObject(data=DashboardConfig.toJson())
# @app.route(f'{APP_PREFIX}/api/updateDashboardConfiguration', methods=["POST"])
# def API_updateDashboardConfiguration():
# data = request.get_json()
# for section in data['DashboardConfiguration'].keys():
# for key in data['DashboardConfiguration'][section].keys():
# if not DashboardConfig.SetConfig(section, key, data['DashboardConfiguration'][section][key])[0]:
# return ResponseObject(False, "Section or value is invalid.")
# return ResponseObject()
@app.route(f'{APP_PREFIX}/api/updateDashboardConfigurationItem', methods=["POST"]) @app.route(f'{APP_PREFIX}/api/updateDashboardConfigurationItem', methods=["POST"])
@ -1617,13 +1618,16 @@ def API_updateDashboardConfigurationItem():
data = request.get_json() data = request.get_json()
if "section" not in data.keys() or "key" not in data.keys() or "value" not in data.keys(): if "section" not in data.keys() or "key" not in data.keys() or "value" not in data.keys():
return ResponseObject(False, "Invalid request.") return ResponseObject(False, "Invalid request.")
valid, msg = DashboardConfig.SetConfig( valid, msg = DashboardConfig.SetConfig(
data["section"], data["key"], data['value']) data["section"], data["key"], data['value'])
if not valid: if not valid:
return ResponseObject(False, msg) return ResponseObject(False, msg)
if data['section'] == "Server":
if data['key'] == 'wg_conf_path':
WireguardConfigurations.clear()
_getConfigurationList()
return ResponseObject() return ResponseObject()
@app.route(f'{APP_PREFIX}/api/getDashboardAPIKeys', methods=['GET']) @app.route(f'{APP_PREFIX}/api/getDashboardAPIKeys', methods=['GET'])
@ -2141,10 +2145,13 @@ def index():
def backGroundThread(): def backGroundThread():
with app.app_context(): global WireguardConfigurations
print(f"[WGDashboard] Background Thread #1 Started", flush=True) print(f"[WGDashboard] Background Thread #1 Started", flush=True)
time.sleep(10) time.sleep(10)
while True: while True:
with app.app_context():
print(DashboardConfig.GetConfig("Server", "wg_conf_path")[1])
print(id(WireguardConfigurations))
for c in WireguardConfigurations.values(): for c in WireguardConfigurations.values():
if c.getStatus(): if c.getStatus():
try: try:
@ -2155,7 +2162,7 @@ def backGroundThread():
c.getRestrictedPeersList() c.getRestrictedPeersList()
except Exception as e: except Exception as e:
print(f"[WGDashboard] Background Thread #1 Error: {str(e)}", flush=True) print(f"[WGDashboard] Background Thread #1 Error: {str(e)}", flush=True)
time.sleep(10) time.sleep(10)
def peerJobScheduleBackgroundThread(): def peerJobScheduleBackgroundThread():
@ -2171,6 +2178,11 @@ def gunicornConfig():
_, app_port = DashboardConfig.GetConfig("Server", "app_port") _, app_port = DashboardConfig.GetConfig("Server", "app_port")
return app_ip, app_port return app_ip, app_port
def clearWireguardConfigurations():
WireguardConfigurations = {}
WireguardConfigurations.clear()
print(WireguardConfigurations.keys())
AllPeerShareLinks: PeerShareLinks = PeerShareLinks() AllPeerShareLinks: PeerShareLinks = PeerShareLinks()
AllPeerJobs: PeerJobs = PeerJobs() AllPeerJobs: PeerJobs = PeerJobs()

View File

@ -66,6 +66,11 @@ export default {
this.invalidFeedback = "Please fill in all required fields." this.invalidFeedback = "Please fill in all required fields."
} }
} }
},
computed: {
passwordValid(){
return Object.values(this.value).find(x => x.length === 0) === undefined && this.value.newPassword === this.value.repeatNewPassword
}
} }
} }
</script> </script>
@ -109,7 +114,9 @@ export default {
</div> </div>
</div> </div>
</div> </div>
<button class="ms-auto btn bg-success-subtle text-success-emphasis border-1 border-success-subtle rounded-3 shadow-sm" @click="this.useValidation()"> <button
:disabled="!this.passwordValid"
class="ms-auto btn bg-success-subtle text-success-emphasis border-1 border-success-subtle rounded-3 shadow-sm" @click="this.useValidation()">
<i class="bi bi-save2-fill me-2"></i>Update Password <i class="bi bi-save2-fill me-2"></i>Update Password
</button> </button>
</div> </div>

View File

@ -2,6 +2,7 @@
import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js"; import {DashboardConfigurationStore} from "@/stores/DashboardConfigurationStore.js";
import {v4} from "uuid"; import {v4} from "uuid";
import {fetchPost} from "@/utilities/fetch.js"; import {fetchPost} from "@/utilities/fetch.js";
import {WireguardConfigurationsStore} from "@/stores/WireguardConfigurationsStore.js";
export default { export default {
name: "dashboardSettingsInputWireguardConfigurationPath", name: "dashboardSettingsInputWireguardConfigurationPath",
@ -13,8 +14,9 @@ export default {
}, },
setup(){ setup(){
const store = DashboardConfigurationStore(); const store = DashboardConfigurationStore();
const WireguardConfigurationStore = WireguardConfigurationsStore()
const uuid = `input_${v4()}`; const uuid = `input_${v4()}`;
return {store, uuid}; return {store, uuid, WireguardConfigurationStore};
}, },
data(){ data(){
return{ return{
@ -33,6 +35,7 @@ export default {
methods:{ methods:{
async useValidation(){ async useValidation(){
if(this.changed){ if(this.changed){
this.updating = true;
await fetchPost("/api/updateDashboardConfigurationItem", { await fetchPost("/api/updateDashboardConfigurationItem", {
section: "Server", section: "Server",
key: this.targetData, key: this.targetData,
@ -44,6 +47,8 @@ export default {
this.store.Configuration.Account[this.targetData] = this.value this.store.Configuration.Account[this.targetData] = this.value
clearTimeout(this.timeout) clearTimeout(this.timeout)
this.timeout = setTimeout(() => this.isValid = false, 5000); this.timeout = setTimeout(() => this.isValid = false, 5000);
this.WireguardConfigurationStore.getConfigurations()
this.store.newMessage("Server", "WireGuard configuration path saved", "success")
}else{ }else{
this.isValid = false; this.isValid = false;
this.showInvalidFeedback = true; this.showInvalidFeedback = true;
@ -59,24 +64,35 @@ export default {
</script> </script>
<template> <template>
<div class="form-group mb-2"> <div class="form-group">
<label :for="this.uuid" class="text-muted mb-1"> <label :for="this.uuid" class="text-muted mb-1">
<strong><small>{{this.title}}</small></strong> <strong><small>{{this.title}}</small></strong>
</label> </label>
<input type="text" class="form-control" <div class="d-flex gap-2 align-items-start mb-2">
:class="{'is-invalid': this.showInvalidFeedback, 'is-valid': this.isValid}" <div class="flex-grow-1">
:id="this.uuid" <input type="text" class="form-control rounded-3"
v-model="this.value" :class="{'is-invalid': this.showInvalidFeedback, 'is-valid': this.isValid}"
@keydown="this.changed = true" :id="this.uuid"
@blur="this.useValidation()" v-model="this.value"
:disabled="this.updating" @keydown="this.changed = true"
> :disabled="this.updating"
<div class="invalid-feedback">{{this.invalidFeedback}}</div> >
<div class="px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1" <div class="invalid-feedback fw-bold">{{this.invalidFeedback}}</div>
</div>
<button
@click="this.useValidation()"
:disabled="!this.changed"
class="ms-auto btn rounded-3 border-success-subtle bg-success-subtle text-success-emphasis">
<i class="bi bi-save2-fill" v-if="!this.updating"></i>
<span class="spinner-border spinner-border-sm" v-else></span>
</button>
</div>
<div class="px-2 py-1 text-warning-emphasis bg-warning-subtle border border-warning-subtle rounded-2 d-inline-block mt-1 mb-2"
v-if="warning" v-if="warning"
> >
<small><i class="bi bi-exclamation-triangle-fill me-2"></i><span v-html="warningText"></span></small> <small><i class="bi bi-exclamation-triangle-fill me-2"></i><span v-html="warningText"></span></small>
</div> </div>
</div> </div>
</template> </template>