**Ä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>
138 lines
4.9 KiB
Python
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
|