Files
Projektarbeit-MYP/backend/utils/ip_validation.py
Till Tomczak 956c24d8ca 🔧 Update: Enhanced error handling and logging across various modules
**Änderungen:**
-  app.py: Hinzugefügt, um CSRF-Fehler zu behandeln
-  models.py: Fehlerprotokollierung bei der Suche nach Gastanfragen per OTP
-  api.py: Fehlerprotokollierung beim Markieren von Benachrichtigungen als gelesen
-  calendar.py: Fallback-Daten zurückgeben, wenn keine Kalenderereignisse vorhanden sind
-  guest.py: Status-Check-Seite für Gäste aktualisiert
-  hardware_integration.py: Debugging-Informationen für erweiterte Geräteinformationen hinzugefügt
-  tapo_status_manager.py: Rückgabewert für Statusabfrage hinzugefügt

**Ergebnis:**
- Verbesserte Fehlerbehandlung und Protokollierung für eine robustere Anwendung
- Bessere Nachverfolgbarkeit von Fehlern und Systemverhalten

🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-15 22:45:20 +02:00

138 lines
4.9 KiB
Python

#!/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