"""Interface commune aux backends de jointure de domaine (Linux/Windows).""" from __future__ import annotations from abc import ABC, abstractmethod from dataclasses import dataclass from typing import Callable, Optional @dataclass class JoinResult: success: bool message: str needs_reboot: bool = False OutputCallback = Callable[[str], None] class DomainJoinBackend(ABC): """Backend de jointure à un domaine Active Directory.""" @abstractmethod def is_available(self) -> tuple[bool, str]: """Indique si les outils nécessaires sont présents. Retourne (disponible, message).""" @abstractmethod def join( self, domain: str, username: str, password: str, ou: Optional[str] = None, computer_name: Optional[str] = None, on_output: Optional[OutputCallback] = None, ) -> JoinResult: """Rejoint le domaine. Le mot de passe n'est jamais passé en argument de ligne de commande : il est transmis via l'entrée standard du sous-processus pour ne pas apparaître dans la liste des processus.""" def can_install_prerequisites(self) -> bool: """True si ce backend sait installer automatiquement les outils manquants.""" return False def install_prerequisites(self, on_output: Optional[OutputCallback] = None) -> JoinResult: """Installe les outils manquants. À surcharger si can_install_prerequisites() est vrai.""" return JoinResult(success=False, message="Installation automatique non prise en charge pour ce backend.")