Update
This commit is contained in:
+24
-5
@@ -75,7 +75,7 @@ class AdminWindow(QDialog):
|
||||
| Qt.WindowType.WindowTitleHint
|
||||
| Qt.WindowType.WindowCloseButtonHint
|
||||
)
|
||||
self.setFixedSize(700, 560)
|
||||
self.setFixedSize(700, 600)
|
||||
self._build_ui()
|
||||
self._load_values()
|
||||
|
||||
@@ -340,11 +340,11 @@ class AdminWindow(QDialog):
|
||||
self._row(form, "", btn_gen_secret)
|
||||
lay.addWidget(grp)
|
||||
|
||||
grp2 = QGroupBox("QR Code — Scanner avec Google Authenticator / Aegis")
|
||||
grp2 = QGroupBox("QR Code — Scanner avec Bitwarden")
|
||||
v2 = QVBoxLayout(grp2)
|
||||
self._qr_label = QLabel("(générez un secret pour afficher le QR Code)")
|
||||
self._qr_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self._qr_label.setFixedHeight(180)
|
||||
self._qr_label.setFixedHeight(230)
|
||||
v2.addWidget(self._qr_label)
|
||||
self._mfa_uri_label = QLabel("")
|
||||
self._mfa_uri_label.setWordWrap(True)
|
||||
@@ -736,6 +736,8 @@ class AdminWindow(QDialog):
|
||||
# Actions
|
||||
# ------------------------------------------------------------------ #
|
||||
def _import_conf(self):
|
||||
from PyQt6.QtWidgets import QInputDialog
|
||||
import os as _os
|
||||
path, _ = QFileDialog.getOpenFileName(
|
||||
self, "Importer un fichier WireGuard",
|
||||
"", "WireGuard Config (*.conf);;Tous les fichiers (*)"
|
||||
@@ -746,6 +748,19 @@ class AdminWindow(QDialog):
|
||||
if not values:
|
||||
QMessageBox.warning(self, "Erreur", "Impossible de lire ce fichier .conf")
|
||||
return
|
||||
|
||||
# Demander le nom du profil (défaut = nom du fichier sans extension)
|
||||
default_name = _os.path.splitext(_os.path.basename(path))[0]
|
||||
name, ok = QInputDialog.getText(
|
||||
self, "Nom du profil",
|
||||
"Nom du nouveau profil :",
|
||||
text=default_name,
|
||||
)
|
||||
if not ok or not name.strip():
|
||||
return
|
||||
name = name.strip()
|
||||
|
||||
# Appliquer les valeurs dans les champs
|
||||
mapping = {
|
||||
"server_endpoint": self._srv_endpoint,
|
||||
"server_public_key": self._srv_pubkey,
|
||||
@@ -762,10 +777,14 @@ class AdminWindow(QDialog):
|
||||
self._srv_port.setValue(int(values["server_port"]))
|
||||
if "keepalive" in values:
|
||||
self._keepalive.setValue(int(values["keepalive"]))
|
||||
|
||||
# Sauvegarder en tant que nouveau profil
|
||||
self._save_values()
|
||||
self._cfg.save_profile(name)
|
||||
self._refresh_profile_list()
|
||||
QMessageBox.information(
|
||||
self, "Import réussi",
|
||||
f"Configuration importée depuis :\n{path}"
|
||||
f"Profil « {name} » créé depuis :\n{path}"
|
||||
)
|
||||
|
||||
def _export_conf(self):
|
||||
@@ -810,7 +829,7 @@ class AdminWindow(QDialog):
|
||||
return
|
||||
pixmap = mfa_core.generate_qr_pixmap(secret)
|
||||
self._qr_label.setPixmap(
|
||||
pixmap.scaled(160, 160, Qt.AspectRatioMode.KeepAspectRatio,
|
||||
pixmap.scaled(210, 210, Qt.AspectRatioMode.KeepAspectRatio,
|
||||
Qt.TransformationMode.SmoothTransformation)
|
||||
)
|
||||
self._mfa_uri_label.setText(mfa_core.get_provisioning_uri(secret))
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
from PyQt6.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QTableWidget,
|
||||
QTableWidgetItem, QPushButton, QLabel, QHeaderView,
|
||||
QMessageBox,
|
||||
QMessageBox, QWidget,
|
||||
)
|
||||
from PyQt6.QtCore import Qt
|
||||
from PyQt6.QtGui import QColor, QFont
|
||||
|
||||
@@ -326,14 +326,14 @@ class MainWindow(QMainWindow):
|
||||
def _reload_profiles(self):
|
||||
self._profile_combo.blockSignals(True)
|
||||
self._profile_combo.clear()
|
||||
self._profile_combo.addItem("⭐ Défaut (actif)")
|
||||
self._profile_combo.addItem(f"⭐ {self._cfg.active_profile} (actif)")
|
||||
for name in self._cfg.list_profiles():
|
||||
marker = "✓ " if name == self._cfg.active_profile else " "
|
||||
self._profile_combo.addItem(f"{marker}{name}")
|
||||
self._profile_combo.blockSignals(False)
|
||||
|
||||
def _on_profile_changed(self, text: str):
|
||||
if "Défaut" in text:
|
||||
if "(actif)" in text:
|
||||
return
|
||||
name = text.lstrip("✓ ").strip()
|
||||
if not name or name == self._cfg.active_profile:
|
||||
|
||||
+25
-14
@@ -6,6 +6,9 @@ from PyQt6.QtCore import Qt, QTimer
|
||||
from PyQt6.QtGui import QFont
|
||||
from app.core import mfa as mfa_core
|
||||
|
||||
_DARK = "#1c2833"
|
||||
_DARK2 = "#17202a"
|
||||
|
||||
|
||||
class MFADialog(QDialog):
|
||||
def __init__(self, secret: str, parent=None):
|
||||
@@ -15,6 +18,10 @@ class MFADialog(QDialog):
|
||||
self.setWindowTitle("WGSecure — Authentification MFA")
|
||||
self.setFixedWidth(340)
|
||||
self.setModal(True)
|
||||
self.setStyleSheet(f"""
|
||||
QDialog {{ background: {_DARK2}; }}
|
||||
QLabel {{ color: white; background: transparent; }}
|
||||
""")
|
||||
self._build_ui()
|
||||
self._timer = QTimer(self)
|
||||
self._timer.timeout.connect(self._tick)
|
||||
@@ -37,12 +44,12 @@ class MFADialog(QDialog):
|
||||
sub = QLabel("Entrez le code à 6 chiffres de votre application d'authentification.")
|
||||
sub.setWordWrap(True)
|
||||
sub.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
sub.setStyleSheet("color: #555;")
|
||||
sub.setStyleSheet("color: rgba(255,255,255,0.6);")
|
||||
layout.addWidget(sub)
|
||||
|
||||
sep = QFrame()
|
||||
sep.setFrameShape(QFrame.Shape.HLine)
|
||||
sep.setStyleSheet("color: #ddd;")
|
||||
sep.setStyleSheet("color: rgba(255,255,255,0.15);")
|
||||
layout.addWidget(sep)
|
||||
|
||||
self._code_input = QLineEdit()
|
||||
@@ -53,14 +60,15 @@ class MFADialog(QDialog):
|
||||
f2.setLetterSpacing(QFont.SpacingType.AbsoluteSpacing, 4)
|
||||
self._code_input.setFont(f2)
|
||||
self._code_input.setStyleSheet(
|
||||
"padding: 8px; border: 2px solid #3498db; border-radius: 6px;"
|
||||
"QLineEdit { padding: 8px; border: 2px solid #2471a3;"
|
||||
f" border-radius: 6px; background: {_DARK}; color: white; }}"
|
||||
)
|
||||
self._code_input.returnPressed.connect(self._verify)
|
||||
layout.addWidget(self._code_input)
|
||||
|
||||
self._error_label = QLabel("")
|
||||
self._error_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self._error_label.setStyleSheet("color: #e74c3c; font-weight: bold;")
|
||||
self._error_label.setStyleSheet("color: #f1948a; font-weight: bold;")
|
||||
layout.addWidget(self._error_label)
|
||||
|
||||
self._progress = QProgressBar()
|
||||
@@ -68,30 +76,31 @@ class MFADialog(QDialog):
|
||||
self._progress.setTextVisible(False)
|
||||
self._progress.setFixedHeight(6)
|
||||
self._progress.setStyleSheet(
|
||||
"QProgressBar { border-radius: 3px; background: #ecf0f1; }"
|
||||
"QProgressBar::chunk { background: #3498db; border-radius: 3px; }"
|
||||
f"QProgressBar {{ border-radius: 3px; background: {_DARK}; }}"
|
||||
"QProgressBar::chunk { background: #5dade2; border-radius: 3px; }"
|
||||
)
|
||||
layout.addWidget(self._progress)
|
||||
|
||||
self._timer_label = QLabel("")
|
||||
self._timer_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self._timer_label.setStyleSheet("color: #999; font-size: 11px;")
|
||||
self._timer_label.setStyleSheet("color: #5d6d7e; font-size: 11px;")
|
||||
layout.addWidget(self._timer_label)
|
||||
|
||||
btn_row = QHBoxLayout()
|
||||
btn_cancel = QPushButton("Annuler")
|
||||
btn_cancel.setStyleSheet(
|
||||
"QPushButton { padding: 8px 16px; border-radius: 5px; "
|
||||
"background: #ecf0f1; } QPushButton:hover { background: #bdc3c7; }"
|
||||
"QPushButton { padding: 8px 16px; border-radius: 5px; border: none;"
|
||||
f" background: #2e4057; color: white; }}"
|
||||
"QPushButton:hover { background: #3d5166; }"
|
||||
)
|
||||
btn_cancel.clicked.connect(self.reject)
|
||||
|
||||
self._btn_ok = QPushButton("Vérifier")
|
||||
self._btn_ok.setDefault(True)
|
||||
self._btn_ok.setStyleSheet(
|
||||
"QPushButton { padding: 8px 20px; border-radius: 5px; "
|
||||
"background: #3498db; color: white; font-weight: bold; }"
|
||||
"QPushButton:hover { background: #2980b9; }"
|
||||
"QPushButton { padding: 8px 20px; border-radius: 5px; border: none;"
|
||||
" background: #2471a3; color: white; font-weight: bold; }"
|
||||
"QPushButton:hover { background: #1a5276; }"
|
||||
)
|
||||
self._btn_ok.clicked.connect(self._verify)
|
||||
btn_row.addWidget(btn_cancel)
|
||||
@@ -109,7 +118,8 @@ class MFADialog(QDialog):
|
||||
if len(raw) != 6 or not raw.isdigit():
|
||||
self._error_label.setText("Entrez exactement 6 chiffres.")
|
||||
self._code_input.setStyleSheet(
|
||||
"padding: 8px; border: 2px solid #e74c3c; border-radius: 6px;"
|
||||
f"QLineEdit {{ padding: 8px; border: 2px solid #f1948a;"
|
||||
f" border-radius: 6px; background: {_DARK}; color: white; }}"
|
||||
)
|
||||
return
|
||||
if mfa_core.verify_code(self._secret, raw):
|
||||
@@ -119,7 +129,8 @@ class MFADialog(QDialog):
|
||||
self._error_label.setText("Code incorrect. Réessayez.")
|
||||
self._code_input.clear()
|
||||
self._code_input.setStyleSheet(
|
||||
"padding: 8px; border: 2px solid #e74c3c; border-radius: 6px;"
|
||||
f"QLineEdit {{ padding: 8px; border: 2px solid #f1948a;"
|
||||
f" border-radius: 6px; background: {_DARK}; color: white; }}"
|
||||
)
|
||||
|
||||
def is_verified(self) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user