#!/usr/bin/env python3.11 """ IP-Adress-Validierung für MYP-System Stellt sicher, dass nur 192.168.0.x Adressen verwendet werden """ import re from typing import Optional, Tuple from utils.logging_config import get_logger logger = get_logger("ip_validation") # Erlaubter IP-Bereich für MYP-System ALLOWED_IP_PATTERN = r"^192\.168\.0\.\d{1,3}$" ALLOWED_IP_RANGE = "192.168.0.x" def is_valid_myp_ip(ip_address: str) -> bool: """ Überprüft, ob eine IP-Adresse im erlaubten MYP-Bereich liegt. Args: ip_address: Die zu prüfende IP-Adresse Returns: bool: True wenn IP-Adresse gültig, sonst False """ if not ip_address: return False # Regex-Prüfung für 192.168.0.x Format if not re.match(ALLOWED_IP_PATTERN, ip_address.strip()): return False # Zusätzliche Prüfung: Letztes Oktett muss zwischen 1-254 liegen try: parts = ip_address.strip().split('.') if len(parts) != 4: return False last_octet = int(parts[3]) if last_octet < 1 or last_octet > 254: return False return True except (ValueError, IndexError): return False def validate_printer_ip(ip_address: str, printer_name: str = None) -> Tuple[bool, Optional[str]]: """ Validiert eine Drucker-IP-Adresse mit detaillierter Fehlermeldung. Args: ip_address: Die zu prüfende IP-Adresse printer_name: Name des Druckers (für Logging) Returns: Tuple[bool, Optional[str]]: (ist_gültig, fehlermeldung) """ if not ip_address: error_msg = "IP-Adresse ist erforderlich" logger.warning(f"IP-Validierung fehlgeschlagen für {printer_name or 'Unbekannter Drucker'}: {error_msg}") return False, error_msg ip_clean = ip_address.strip() if not is_valid_myp_ip(ip_clean): error_msg = f"IP-Adresse '{ip_clean}' ist ungültig. Nur {ALLOWED_IP_RANGE} Adressen sind erlaubt." logger.warning(f"IP-Validierung fehlgeschlagen für {printer_name or 'Unbekannter Drucker'}: {error_msg}") return False, error_msg logger.debug(f"IP-Validierung erfolgreich für {printer_name or 'Unbekannter Drucker'}: {ip_clean}") return True, None def validate_printer_ips(printer_ip: str, plug_ip: str, printer_name: str = None) -> Tuple[bool, Optional[str]]: """ Validiert sowohl Drucker- als auch Plug-IP-Adresse. Stellt sicher, dass beide identisch sind (Redundanz eliminieren). Args: printer_ip: IP-Adresse des Druckers plug_ip: IP-Adresse der Steckdose printer_name: Name des Druckers (für Logging) Returns: Tuple[bool, Optional[str]]: (ist_gültig, fehlermeldung) """ # Drucker-IP validieren printer_valid, printer_error = validate_printer_ip(printer_ip, printer_name) if not printer_valid: return False, f"Drucker-IP ungültig: {printer_error}" # Plug-IP validieren plug_valid, plug_error = validate_printer_ip(plug_ip, f"{printer_name} (Plug)") if not plug_valid: return False, f"Plug-IP ungültig: {plug_error}" # Redundanz prüfen: Drucker-IP muss gleich Plug-IP sein if printer_ip.strip() != plug_ip.strip(): error_msg = f"Drucker-IP ({printer_ip}) und Plug-IP ({plug_ip}) müssen identisch sein" logger.warning(f"Redundanz-Prüfung fehlgeschlagen für {printer_name or 'Unbekannter Drucker'}: {error_msg}") return False, error_msg logger.info(f"IP-Validierung erfolgreich für {printer_name or 'Unbekannter Drucker'}: {printer_ip}") return True, None def check_ip_conflicts(new_ip: str, existing_printers: list, exclude_printer_id: int = None) -> Tuple[bool, Optional[str]]: """ Prüft, ob eine IP-Adresse bereits von einem anderen Drucker verwendet wird. Args: new_ip: Die zu prüfende IP-Adresse existing_printers: Liste der existierenden Drucker exclude_printer_id: ID des Druckers, der ausgeschlossen werden soll (bei Updates) Returns: Tuple[bool, Optional[str]]: (hat_konflikt, konflikt_beschreibung) """ if not new_ip or not is_valid_myp_ip(new_ip): return True, f"IP-Adresse '{new_ip}' ist ungültig" for printer in existing_printers: # Drucker ausschließen (bei Updates) if exclude_printer_id and printer.id == exclude_printer_id: continue # Nur aktive Drucker prüfen if not printer.active: continue # IP-Konflikt prüfen if printer.ip_address == new_ip or printer.plug_ip == new_ip: conflict_msg = f"IP-Adresse '{new_ip}' wird bereits von Drucker '{printer.name}' (ID: {printer.id}) verwendet" logger.warning(f"IP-Konflikt erkannt: {conflict_msg}") return True, conflict_msg return False, None