To_DO: ERROR AFTER LOGGING IN

This commit is contained in:
florianuhlig
2025-10-03 15:03:18 +02:00
parent 70c85cb8be
commit 1554723ed4
27 changed files with 1484 additions and 273 deletions

0
utils/__init__.py Normal file
View File

43
utils/auth_decorators.py Normal file
View File

@@ -0,0 +1,43 @@
from functools import wraps
from flask import session, redirect, url_for, flash, request
import logging
logger = logging.getLogger(__name__)
def login_required(f):
"""
Decorator to protect routes that require authentication
"""
@wraps(f)
def decorated_function(*args, **kwargs):
if 'user_id' not in session or 'email' not in session:
flash('Please log in to access this page', 'warning')
logger.info(f"Unauthorized access attempt to {request.endpoint}")
return redirect(url_for('login'))
return f(*args, **kwargs)
return decorated_function
def logout_required(f):
"""
Decorator for routes that should only be accessible when NOT logged in
(e.g., login, register pages)
"""
@wraps(f)
def decorated_function(*args, **kwargs):
if 'user_id' in session:
flash('You are already logged in', 'info')
return redirect(url_for('dashboard'))
return f(*args, **kwargs)
return decorated_function
def get_current_user():
"""
Helper function to get current user info from session
"""
if 'user_id' in session:
return {
'id': session['user_id'],
'username': session['username'],
'email': session['email']
}
return None

27
utils/password_utils.py Normal file
View File

@@ -0,0 +1,27 @@
import hashlib
import secrets
import logging
logger = logging.getLogger(__name__)
class PasswordUtils:
@staticmethod
def hash_password(password: str, salt: str = None) -> tuple[str, str]:
if salt is None:
salt = secrets.token_hex(32)
password = password.strip()
salted_password = password + salt
hash_object = hashlib.sha512(salted_password.encode('utf-8'))
password_hash = hash_object.hexdigest()
logger.debug("Password hashed successfully")
return password_hash, salt
@staticmethod
def verify_password(password: str, stored_hash: str, salt: str) -> bool:
computed_hash, _ = PasswordUtils.hash_password(password, salt)
return secrets.compare_digest(computed_hash, stored_hash)
@staticmethod
def hash_password_simple(password: str) -> str:
password = password.strip()
return hashlib.sha512(password.encode('utf-8')).hexdigest()

56
utils/validation.py Normal file
View File

@@ -0,0 +1,56 @@
import re
import logging
logger = logging.getLogger(__name__)
class ValidationUtils:
@staticmethod
def validate_email(email: str) -> bool:
if not email or not isinstance(email, str):
return False
email = email.strip().lower()
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
is_valid = bool(re.match(pattern, email))
if not is_valid:
logger.warning(f"Invalid email format: {email}")
return is_valid
@staticmethod
def validate_username(username: str) -> bool:
if not username or not isinstance(username, str):
return False
username = username.strip()
# Username-Regeln: 3-25 Zeichen, nur Buchstaben, Zahlen und Unterstrich
if len(username) < 3 or len(username) > 25:
logger.warning(f"Username length invalid: {len(username)}")
return False
pattern = r'^[a-zA-Z0-9_]+$'
is_valid = bool(re.match(pattern, username))
if not is_valid:
logger.warning(f"Invalid username format: {username}")
return is_valid
@staticmethod
def validate_password(password: str) -> tuple[bool, list[str]]:
errors = []
if not password or not isinstance(password, str):
errors.append("Password is required")
return False, errors
if len(password) < 4 or len(password) > 50:
errors.append("Password must be at least 4 characters long and must not exceed 128 characters")
if not re.search(r'[A-Z]', password):
errors.append("Password must contain at least one uppercase letter")
if not re.search(r'[a-z]', password):
errors.append("Password must contain at least one lowercase letter")
if not re.search(r'\d', password):
errors.append("Password must contain at least one digit")
if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
errors.append("Password must contain at least one special character")
is_valid = len(errors) == 0
if not is_valid:
logger.warning(f"Password validation failed: {errors}")
return is_valid, errors