This commit is contained in:
tuxgyver
2026-07-21 10:21:13 +02:00
parent ea2e6d772b
commit d03a75057e
5 changed files with 187 additions and 80 deletions
+79 -54
View File
@@ -132,7 +132,6 @@ class AdminWindow(QDialog):
tabs.addTab(self._tab_keys(), "Clés")
tabs.addTab(self._tab_mfa(), "MFA")
tabs.addTab(self._tab_test(), "Test connexion")
tabs.addTab(self._tab_profiles(), "Profils")
tabs.addTab(self._tab_settings(), "Paramètres")
tabs.addTab(self._tab_admin(), "Sécurité")
tabs.addTab(self._tab_about(), "À propos")
@@ -184,19 +183,88 @@ class AdminWindow(QDialog):
form.addRow(lbl, widget)
def _tab_wireguard(self) -> QWidget:
w, lay = self._dark_page("🛡️ Configuration WireGuard", "#154360")
from PyQt6.QtWidgets import QScrollArea, QListWidget
# Barre import / export
outer = QWidget()
outer.setStyleSheet(_TAB_CSS)
outer_lay = QVBoxLayout(outer)
outer_lay.setContentsMargins(0, 0, 0, 0)
outer_lay.setSpacing(0)
hdr = QLabel(" 🛡️ WireGuard — Configuration & Profils")
hdr.setFixedHeight(36)
hdr.setStyleSheet(
"background: #154360; color: white; font-size: 13px;"
" font-weight: bold; padding-left: 8px;"
)
outer_lay.addWidget(hdr)
scroll = QScrollArea()
scroll.setWidgetResizable(True)
scroll.setStyleSheet(
"QScrollArea { border: none; background: #1c2833; }"
"QScrollBar:vertical { background: #1c2833; width: 8px; border: none; }"
"QScrollBar::handle:vertical { background: #2e4057; border-radius: 4px; }"
"QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { height: 0; }"
)
content = QWidget()
content.setStyleSheet("background: #1c2833;")
lay = QVBoxLayout(content)
lay.setContentsMargins(14, 12, 14, 12)
lay.setSpacing(10)
# ── Profils ──────────────────────────────────────────────────────
grp_p = QGroupBox("Profils")
gp = QVBoxLayout(grp_p)
gp.setSpacing(6)
gp.setContentsMargins(10, 14, 10, 10)
self._profile_list = QListWidget()
self._profile_list.setFixedHeight(72)
self._profile_list.setStyleSheet(
"QListWidget { background: rgba(255,255,255,0.07); color: white;"
" border: 1px solid rgba(255,255,255,0.2); border-radius: 4px; }"
"QListWidget::item:selected { background: #2471a3; }"
)
gp.addWidget(self._profile_list)
p_btn_row = QHBoxLayout()
p_btn_row.setSpacing(6)
btn_save_p = QPushButton("💾 Sauvegarder sous…")
btn_save_p.setFixedHeight(26)
btn_save_p.clicked.connect(self._save_profile)
btn_load_p = QPushButton("✅ Charger")
btn_load_p.setFixedHeight(26)
btn_load_p.clicked.connect(self._load_profile)
btn_del_p = QPushButton("🗑️ Supprimer")
btn_del_p.setFixedHeight(26)
btn_del_p.setStyleSheet(
"QPushButton { background: #6e2e1c; color: white; border-radius: 5px;"
" padding: 0 12px; border: none; }"
"QPushButton:hover { background: #922b21; }"
)
btn_del_p.clicked.connect(self._delete_profile)
p_btn_row.addWidget(btn_save_p)
p_btn_row.addWidget(btn_load_p)
p_btn_row.addWidget(btn_del_p)
gp.addLayout(p_btn_row)
lay.addWidget(grp_p)
# ── Import / Export ──────────────────────────────────────────────
io_row = QHBoxLayout()
btn_import = QPushButton("📂 Importer un .conf")
btn_import.setFixedHeight(26)
btn_import.clicked.connect(self._import_conf)
btn_export = QPushButton("💾 Exporter en .conf")
btn_export.setFixedHeight(26)
btn_export.clicked.connect(self._export_conf)
io_row.addWidget(btn_import)
io_row.addWidget(btn_export)
io_row.addStretch()
lay.addLayout(io_row)
# ── Serveur ──────────────────────────────────────────────────────
grp = QGroupBox("Serveur WireGuard")
form = QFormLayout(grp)
form.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.ExpandingFieldsGrow)
@@ -216,6 +284,7 @@ class AdminWindow(QDialog):
self._row(form, "Clé publique serveur :", self._srv_pubkey)
lay.addWidget(grp)
# ── Interface client ─────────────────────────────────────────────
grp2 = QGroupBox("Interface client")
form2 = QFormLayout(grp2)
form2.setFieldGrowthPolicy(QFormLayout.FieldGrowthPolicy.ExpandingFieldsGrow)
@@ -233,7 +302,7 @@ class AdminWindow(QDialog):
self._row(form2, "DNS :", self._dns)
self._allowed_ips = QLineEdit()
self._allowed_ips.setPlaceholderText("0.0.0.0/0")
self._allowed_ips.setPlaceholderText("10.8.0.0/24")
self._row(form2, "IPs autorisées :", self._allowed_ips)
self._keepalive = QSpinBox()
@@ -243,7 +312,12 @@ class AdminWindow(QDialog):
self._row(form2, "Keepalive (s) :", self._keepalive)
lay.addWidget(grp2)
lay.addStretch()
return w
scroll.setWidget(content)
outer_lay.addWidget(scroll)
self._refresh_profile_list()
return outer
# ------------------------------------------------------------------ #
# Onglet Clés
@@ -401,55 +475,6 @@ class AdminWindow(QDialog):
lay.addStretch()
return w
# ------------------------------------------------------------------ #
# Onglet Profils
# ------------------------------------------------------------------ #
def _tab_profiles(self) -> QWidget:
from PyQt6.QtWidgets import QListWidget, QListWidgetItem, QInputDialog
w, lay = self._dark_page("👤 Gestion des profils", "#1a4a2a")
info = QLabel(
"Sauvegardez la configuration WireGuard courante sous un nom de profil,\n"
"puis basculez entre profils sans passer par la configuration."
)
info.setWordWrap(True)
info.setStyleSheet("color: rgba(255,255,255,0.75); font-size: 12px;")
lay.addWidget(info)
grp = QGroupBox("Profils sauvegardés")
gv = QVBoxLayout(grp)
self._profile_list = QListWidget()
self._profile_list.setFixedHeight(130)
self._profile_list.setStyleSheet(
"QListWidget { background: rgba(255,255,255,0.07); color: white;"
" border: 1px solid rgba(255,255,255,0.2); border-radius: 4px; }"
"QListWidget::item:selected { background: #2471a3; }"
)
gv.addWidget(self._profile_list)
btn_row = QHBoxLayout()
btn_save_p = QPushButton("💾 Sauvegarder sous…")
btn_save_p.clicked.connect(self._save_profile)
btn_load_p = QPushButton("✅ Charger")
btn_load_p.clicked.connect(self._load_profile)
btn_del_p = QPushButton("🗑️ Supprimer")
btn_del_p.setStyleSheet(
"QPushButton { background: #6e2e1c; color: white; border-radius: 5px;"
" padding: 7px 12px; border: none; }"
"QPushButton:hover { background: #922b21; }"
)
btn_del_p.clicked.connect(self._delete_profile)
btn_row.addWidget(btn_save_p)
btn_row.addWidget(btn_load_p)
btn_row.addWidget(btn_del_p)
gv.addLayout(btn_row)
lay.addWidget(grp)
lay.addStretch()
self._refresh_profile_list()
return w
def _refresh_profile_list(self):
self._profile_list.clear()
active = self._cfg.active_profile