Initial commit
Dieser Commit ist enthalten in:
338
utils/password_generator.py
Normale Datei
338
utils/password_generator.py
Normale Datei
@ -0,0 +1,338 @@
|
||||
"""
|
||||
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)
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren