"""Confirmations de securite avant tout envoi de contenu au fournisseur IA : un avertissement de principe affiche une seule fois, puis une verification systematique des secrets evidents a chaque envoi d'une selection de terminal ou d'une demande libre.""" from __future__ import annotations from PySide6.QtWidgets import QMessageBox from app.app_settings import get_setting, set_setting from app.ai.redaction import detect_secrets _NOTICE_ACK_KEY = "ai_notice_acknowledged" MASK = "mask" SEND = "send" CANCEL = "cancel" def ensure_ai_notice_acknowledged(parent) -> bool: """Affiche l'avertissement de principe une seule fois (jamais reaffiche ensuite, l'accord etant persiste). Renvoie False si l'utilisateur refuse : l'appelant ne doit alors rien envoyer.""" if get_setting(_NOTICE_ACK_KEY, False): return True box = QMessageBox(parent) box.setWindowTitle("Assistant IA") box.setIcon(QMessageBox.Information) box.setText( "Le texte selectionne dans le terminal (ou votre question) va etre envoye " "au fournisseur IA que vous avez configure, en dehors de cet ordinateur.\n\n" "PySSH tente de detecter les secrets evidents (mots de passe, cles, jetons) " "avant chaque envoi et vous permet de les masquer, mais ne peut pas tout " "detecter : verifiez ce que vous envoyez.\n\n" "Ce message ne sera plus affiche." ) box.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) box.setDefaultButton(QMessageBox.Ok) accepted = box.exec() == QMessageBox.Ok if accepted: set_setting(_NOTICE_ACK_KEY, True) return accepted def confirm_sensitive_content(parent, text: str) -> str: """Renvoie MASK, SEND ou CANCEL. Si aucun secret evident n'est detecte, renvoie SEND directement sans rien afficher.""" secrets = detect_secrets(text) if not secrets: return SEND labels = "\n".join(f"- {s.label}" for s in secrets) box = QMessageBox(parent) box.setWindowTitle("Donnees potentiellement sensibles") box.setIcon(QMessageBox.Warning) box.setText( "Des donnees potentiellement sensibles ont ete detectees dans le texte " f"qui serait envoye au fournisseur IA :\n\n{labels}\n\n" "« Masquer automatiquement » les remplace par [MASQUE] avant l'envoi.\n" "« Voir le contenu » l'envoie tel quel, sans modification." ) mask_btn = box.addButton("Masquer automatiquement", QMessageBox.AcceptRole) send_btn = box.addButton("Voir le contenu", QMessageBox.DestructiveRole) box.addButton("Annuler", QMessageBox.RejectRole) box.setDefaultButton(mask_btn) box.exec() clicked = box.clickedButton() if clicked is mask_btn: return MASK if clicked is send_btn: return SEND return CANCEL