Initial release
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
import json
|
||||
import os
|
||||
import hashlib
|
||||
import secrets
|
||||
from typing import Any
|
||||
from app.utils.platform_utils import get_config_dir
|
||||
|
||||
|
||||
_CONFIG_FILE = "config.json"
|
||||
_DEFAULT: dict[str, Any] = {
|
||||
"version": "0.1.0",
|
||||
"admin_password_hash": "",
|
||||
"admin_salt": "",
|
||||
"mfa_enabled": False,
|
||||
"mfa_secret": "",
|
||||
"wg": {
|
||||
"interface_name": "wgs0",
|
||||
"server_endpoint": "",
|
||||
"server_port": 51820,
|
||||
"server_public_key": "",
|
||||
"client_private_key": "",
|
||||
"client_public_key": "",
|
||||
"client_address": "10.8.0.2/24",
|
||||
"dns": "1.1.1.1",
|
||||
"allowed_ips": "0.0.0.0/0",
|
||||
"keepalive": 25,
|
||||
},
|
||||
"ui": {
|
||||
"minimize_to_tray": True,
|
||||
"autostart": False,
|
||||
"theme": "auto",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class Config:
|
||||
def __init__(self):
|
||||
self._path = os.path.join(get_config_dir(), _CONFIG_FILE)
|
||||
self._data: dict[str, Any] = {}
|
||||
self.load()
|
||||
|
||||
def load(self):
|
||||
if os.path.exists(self._path):
|
||||
try:
|
||||
with open(self._path, "r", encoding="utf-8") as f:
|
||||
saved = json.load(f)
|
||||
self._data = self._merge(_DEFAULT, saved)
|
||||
except Exception:
|
||||
self._data = dict(_DEFAULT)
|
||||
else:
|
||||
self._data = dict(_DEFAULT)
|
||||
|
||||
def save(self):
|
||||
os.makedirs(os.path.dirname(self._path), exist_ok=True)
|
||||
with open(self._path, "w", encoding="utf-8") as f:
|
||||
json.dump(self._data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
def _merge(self, base: dict, override: dict) -> dict:
|
||||
result = dict(base)
|
||||
for k, v in override.items():
|
||||
if k in result and isinstance(result[k], dict) and isinstance(v, dict):
|
||||
result[k] = self._merge(result[k], v)
|
||||
else:
|
||||
result[k] = v
|
||||
return result
|
||||
|
||||
def get(self, *keys: str, default=None) -> Any:
|
||||
node = self._data
|
||||
for k in keys:
|
||||
if not isinstance(node, dict) or k not in node:
|
||||
return default
|
||||
node = node[k]
|
||||
return node
|
||||
|
||||
def set(self, *keys_and_value) -> None:
|
||||
*keys, value = keys_and_value
|
||||
node = self._data
|
||||
for k in keys[:-1]:
|
||||
node = node.setdefault(k, {})
|
||||
node[keys[-1]] = value
|
||||
|
||||
# -- Admin password --
|
||||
|
||||
def set_admin_password(self, password: str):
|
||||
if not password:
|
||||
# Mot de passe vide = suppression de la protection
|
||||
self._data["admin_salt"] = ""
|
||||
self._data["admin_password_hash"] = ""
|
||||
else:
|
||||
salt = secrets.token_hex(16)
|
||||
hashed = hashlib.sha256((salt + password).encode()).hexdigest()
|
||||
self._data["admin_salt"] = salt
|
||||
self._data["admin_password_hash"] = hashed
|
||||
self.save()
|
||||
|
||||
def check_admin_password(self, password: str) -> bool:
|
||||
salt = self._data.get("admin_salt", "")
|
||||
stored = self._data.get("admin_password_hash", "")
|
||||
if not stored:
|
||||
return True # Pas encore de mot de passe configuré
|
||||
candidate = hashlib.sha256((salt + password).encode()).hexdigest()
|
||||
return secrets.compare_digest(candidate, stored)
|
||||
|
||||
def has_admin_password(self) -> bool:
|
||||
return bool(self._data.get("admin_password_hash", ""))
|
||||
|
||||
# -- Propriétés WireGuard --
|
||||
|
||||
@property
|
||||
def wg(self) -> dict:
|
||||
return self._data["wg"]
|
||||
|
||||
@property
|
||||
def mfa_enabled(self) -> bool:
|
||||
return bool(self._data.get("mfa_enabled", False))
|
||||
|
||||
@mfa_enabled.setter
|
||||
def mfa_enabled(self, value: bool):
|
||||
self._data["mfa_enabled"] = value
|
||||
|
||||
@property
|
||||
def mfa_secret(self) -> str:
|
||||
return self._data.get("mfa_secret", "")
|
||||
|
||||
@mfa_secret.setter
|
||||
def mfa_secret(self, value: str):
|
||||
self._data["mfa_secret"] = value
|
||||
|
||||
@property
|
||||
def configured(self) -> bool:
|
||||
wg = self._data["wg"]
|
||||
return bool(wg.get("server_endpoint") and wg.get("client_private_key"))
|
||||
Reference in New Issue
Block a user