""" Passwortgenerator für den Social Media Account Generator. """ import random import string import logging from typing import Dict, List, Any, Optional, Tuple, Union logger = logging.getLogger("password_generator") class PasswordGenerator: """Klasse zur Generierung sicherer und plattformkonformer Passwörter.""" def __init__(self): """Initialisiert den PasswordGenerator.""" # Passwort-Richtlinien für verschiedene Plattformen self.platform_policies = { "instagram": { "min_length": 20, "max_length": 20, "require_uppercase": True, "require_lowercase": True, "require_digits": True, "require_special": True, "allowed_special": "!$§%?", "disallowed_chars": "" }, "facebook": { "min_length": 8, "max_length": 20, "require_uppercase": False, "require_lowercase": True, "require_digits": False, "require_special": False, "allowed_special": "!@#$%^&*()", "disallowed_chars": "" }, "twitter": { "min_length": 8, "max_length": 20, "require_uppercase": False, "require_lowercase": True, "require_digits": False, "require_special": False, "allowed_special": "!@#$%^&*()", "disallowed_chars": "" }, "tiktok": { "min_length": 10, "max_length": 10, "require_uppercase": True, "require_lowercase": True, "require_digits": True, "require_special": True, "allowed_special": "!$%&/()=?", "disallowed_chars": "" }, "default": { "min_length": 8, "max_length": 16, "require_uppercase": True, "require_lowercase": True, "require_digits": True, "require_special": True, "allowed_special": "!@#$%^&*()", "disallowed_chars": "" } } def get_platform_policy(self, platform: str) -> Dict[str, Any]: """ Gibt die Passwort-Richtlinie für eine bestimmte Plattform zurück. Args: platform: Name der Plattform Returns: Dictionary mit der Passwort-Richtlinie """ platform = platform.lower() return self.platform_policies.get(platform, self.platform_policies["default"]) def set_platform_policy(self, platform: str, policy: Dict[str, Any]) -> None: """ Setzt oder aktualisiert die Passwort-Richtlinie für eine Plattform. Args: platform: Name der Plattform policy: Dictionary mit der Passwort-Richtlinie """ platform = platform.lower() self.platform_policies[platform] = policy logger.info(f"Passwort-Richtlinie für '{platform}' aktualisiert") def generate_password(self, platform: str = "default", length: Optional[int] = None, custom_policy: Optional[Dict[str, Any]] = None) -> str: """ Generiert ein Passwort gemäß den Richtlinien. Args: platform: Name der Plattform length: Optionale Länge des Passworts (überschreibt die Plattformrichtlinie) custom_policy: Optionale benutzerdefinierte Richtlinie Returns: Generiertes Passwort """ # Richtlinie bestimmen if custom_policy: policy = custom_policy else: policy = self.get_platform_policy(platform) # Länge bestimmen if length: if length < policy["min_length"]: logger.warning(f"Angeforderte Länge ({length}) ist kleiner als das Minimum " f"({policy['min_length']}). Verwende Minimum.") length = policy["min_length"] elif length > policy["max_length"]: logger.warning(f"Angeforderte Länge ({length}) ist größer als das Maximum " f"({policy['max_length']}). Verwende Maximum.") length = policy["max_length"] else: # Zufällige Länge im erlaubten Bereich length = random.randint(policy["min_length"], policy["max_length"]) # Verfügbare Zeichen bestimmen available_chars = "" if policy["require_lowercase"] or not (policy["require_uppercase"] or policy["require_digits"] or policy["require_special"]): available_chars += string.ascii_lowercase if policy["require_uppercase"]: available_chars += string.ascii_uppercase if policy["require_digits"]: available_chars += string.digits if policy["require_special"] and policy["allowed_special"]: available_chars += policy["allowed_special"] # Entferne nicht erlaubte Zeichen if policy["disallowed_chars"]: available_chars = "".join(char for char in available_chars if char not in policy["disallowed_chars"]) # Sicherstellen, dass keine leere Zeichenmenge vorliegt if not available_chars: logger.error("Keine Zeichen für die Passwortgenerierung verfügbar") available_chars = string.ascii_lowercase # Passwort generieren password = "".join(random.choice(available_chars) for _ in range(length)) # Überprüfen, ob die Anforderungen erfüllt sind meets_requirements = True if policy["require_lowercase"] and not any(char.islower() for char in password): meets_requirements = False if policy["require_uppercase"] and not any(char.isupper() for char in password): meets_requirements = False if policy["require_digits"] and not any(char.isdigit() for char in password): meets_requirements = False if policy["require_special"] and not any(char in policy["allowed_special"] for char in password): meets_requirements = False # Falls die Anforderungen nicht erfüllt sind, erneut generieren if not meets_requirements: logger.debug("Generiertes Passwort erfüllt nicht alle Anforderungen, generiere neu") return self.generate_password(platform, length, custom_policy) logger.info(f"Passwort für '{platform}' generiert (Länge: {length})") return password def generate_platform_password(self, platform: str) -> str: """ Generiert ein Passwort für eine bestimmte Plattform. Args: platform: Name der Plattform Returns: Generiertes Passwort """ return self.generate_password(platform) def generate_strong_password(self, length: int = 16) -> str: """ Generiert ein starkes Passwort. Args: length: Länge des Passworts Returns: Generiertes Passwort """ custom_policy = { "min_length": length, "max_length": length, "require_uppercase": True, "require_lowercase": True, "require_digits": True, "require_special": True, "allowed_special": "!@#$%^&*()-_=+[]{}<>,.;:/?|", "disallowed_chars": "" } return self.generate_password(custom_policy=custom_policy) def generate_memorable_password(self, num_words: int = 3, separator: str = "-") -> str: """ Generiert ein einprägsames Passwort aus Wörtern und Zahlen. Args: num_words: Anzahl der Wörter separator: Trennzeichen zwischen den Wörtern Returns: Generiertes Passwort """ # Liste von einfachen Wörtern (kann erweitert/angepasst werden) words = [ "time", "year", "people", "way", "day", "man", "thing", "woman", "life", "child", "world", "school", "state", "family", "student", "group", "country", "problem", "hand", "part", "place", "case", "week", "company", "system", "program", "question", "work", "government", "number", "night", "point", "home", "water", "room", "mother", "area", "money", "story", "fact", "month", "lot", "right", "study", "book", "eye", "job", "word", "business", "issue", "side", "kind", "head", "house", "service", "friend", "father", "power", "hour", "game", "line", "end", "member", "law", "car", "city", "name", "team", "minute", "idea", "kid", "body", "back", "parent", "face", "level", "office", "door", "health", "person", "art", "war", "history", "party", "result", "change", "morning", "reason", "research", "girl", "guy", "moment", "air", "teacher", "force", "education" ] # Zufällige Wörter auswählen selected_words = random.sample(words, num_words) # Groß- und Kleinschreibung variieren und Zahlen hinzufügen for i in range(len(selected_words)): if random.choice([True, False]): selected_words[i] = selected_words[i].capitalize() # Mit 50% Wahrscheinlichkeit eine Zahl anhängen if random.choice([True, False]): selected_words[i] += str(random.randint(0, 9)) # Passwort zusammensetzen password = separator.join(selected_words) logger.info(f"Einprägsames Passwort generiert (Länge: {len(password)})") return password def validate_password(self, password: str, platform: str = "default", custom_policy: Optional[Dict[str, Any]] = None) -> Tuple[bool, str]: """ Überprüft, ob ein Passwort den Richtlinien entspricht. Args: password: Zu überprüfendes Passwort platform: Name der Plattform custom_policy: Optionale benutzerdefinierte Richtlinie Returns: (Gültigkeit, Fehlermeldung) """ # Richtlinie bestimmen if custom_policy: policy = custom_policy else: policy = self.get_platform_policy(platform) # Prüfungen durchführen if len(password) < policy["min_length"]: return False, f"Passwort ist zu kurz (mindestens {policy['min_length']} Zeichen erforderlich)" if len(password) > policy["max_length"]: return False, f"Passwort ist zu lang (maximal {policy['max_length']} Zeichen erlaubt)" if policy["require_lowercase"] and not any(char.islower() for char in password): return False, "Passwort muss mindestens einen Kleinbuchstaben enthalten" if policy["require_uppercase"] and not any(char.isupper() for char in password): return False, "Passwort muss mindestens einen Großbuchstaben enthalten" if policy["require_digits"] and not any(char.isdigit() for char in password): return False, "Passwort muss mindestens eine Ziffer enthalten" if policy["require_special"] and not any(char in policy["allowed_special"] for char in password): return False, f"Passwort muss mindestens ein Sonderzeichen enthalten ({policy['allowed_special']})" if policy["disallowed_chars"] and any(char in policy["disallowed_chars"] for char in password): return False, f"Passwort enthält nicht erlaubte Zeichen ({policy['disallowed_chars']})" return True, "Passwort ist gültig" # Kompatibilitätsfunktion für Legacy-Code, der direkt generate_password() importiert def generate_password(platform: str = "instagram", length: Optional[int] = None) -> str: """ Kompatibilitätsfunktion für ältere Codeversionen. Generiert ein Passwort für die angegebene Plattform. Args: platform: Name der Plattform length: Optionale Länge des Passworts Returns: Generiertes Passwort """ # Einmalige Logger-Warnung, wenn die Legacy-Funktion verwendet wird logger.warning("Die Funktion generate_password() ist veraltet, bitte verwende stattdessen die PasswordGenerator-Klasse.") # Eine Instanz der Generator-Klasse erstellen und die Methode aufrufen generator = PasswordGenerator() return generator.generate_password(platform, length) # Weitere Legacy-Funktionen für Kompatibilität def generate_strong_password(length: int = 16) -> str: """Legacy-Funktion für Kompatibilität.""" generator = PasswordGenerator() return generator.generate_strong_password(length) def generate_memorable_password(num_words: int = 3, separator: str = "-") -> str: """Legacy-Funktion für Kompatibilität.""" generator = PasswordGenerator() return generator.generate_memorable_password(num_words, separator)