from passlib.context import CryptContext import string import secrets # Create a password context for hashing and verifying pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") def generate_reset_password_token(): return secrets.token_urlsafe(32) def hash_password(password: str) -> str: """ Hash a password using bcrypt """ return pwd_context.hash(password) def verify_password(plain_password: str, hashed_password: str) -> bool: """ Verify a password against a hash """ return pwd_context.verify(plain_password, hashed_password) def generate_secure_password(length: int = 16, include_special: bool = True) -> str: """ Generate a cryptographically secure random password Args: length: Length of the password (default 16) include_special: Include special characters (default True) Returns: A secure random password string """ # Define character sets lowercase = string.ascii_lowercase uppercase = string.ascii_uppercase digits = string.digits special_chars = string.punctuation if include_special else "" # Combined character set all_chars = lowercase + uppercase + digits + special_chars # Ensure at least one character from each required group password = [ secrets.choice(lowercase), secrets.choice(uppercase), secrets.choice(digits) ] if include_special and special_chars: password.append(secrets.choice(special_chars)) # Fill remaining length with random characters password.extend(secrets.choice(all_chars) for _ in range(length - len(password))) # Shuffle the password characters secrets.SystemRandom().shuffle(password) return ''.join(password)