""" Security utilities for password validation and other security functions. This module provides security-related utility functions for the application. """ import re from functools import wraps from wtforms.validators import ValidationError from urllib.parse import urlparse, urljoin from flask import request, jsonify from flask_login import login_required, current_user def password_check(form, field): """ Custom WTForms validator for password strength. Validates that passwords meet security requirements: - At least 8 characters long - Contains at least one uppercase letter - Contains at least one lowercase letter - Contains at least one number - Contains at least one special character Args: form: WTForms form object field: WTForms field object containing the password Raises: ValidationError: If password doesn't meet requirements """ password = field.data if len(password) < 8: raise ValidationError('Password must be at least 8 characters long.') if not re.search(r'[A-Z]', password): raise ValidationError('Password must contain at least one uppercase letter.') if not re.search(r'[a-z]', password): raise ValidationError('Password must contain at least one lowercase letter.') if not re.search(r'[0-9]', password): raise ValidationError('Password must contain at least one number.') if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password): raise ValidationError('Password must contain at least one special character.') # --- Access control decorators --- def admin_required(f): """Decorator that requires the current user to be authenticated and an admin.""" @wraps(f) @login_required def decorated(*args, **kwargs): if not current_user.is_admin: return jsonify({'error': 'Admin access required'}), 403 return f(*args, **kwargs) return decorated # --- URL Security --- def is_safe_url(target): ref_url = urlparse(request.host_url) test_url = urlparse(urljoin(request.host_url, target)) return test_url.scheme in ('http', 'https') and ref_url.netloc == test_url.netloc