338 Zeilen
13 KiB
Python
338 Zeilen
13 KiB
Python
"""
|
|
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) |