import re from fastapi import HTTPException, status class ValidationUtils: @staticmethod def validate_email(email: str) -> bool: pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' return re.match(pattern, email) is not None @staticmethod def validate_password(password: str) -> bool: # At least 8 characters, one uppercase, one lowercase, one digit if len(password) < 8: return False if not re.search(r'[A-Z]', password): return False if not re.search(r'[a-z]', password): return False if not re.search(r'\d', password): return False return True @staticmethod def validate_phone_number(phone: str) -> bool: # Basic international phone number validation pattern = r'^\+?[1-9]\d{1,14}$' return re.match(pattern, phone) is not None @staticmethod def validate_amount(amount: float, min_amount: float = 0.0001, max_amount: float = 1000000) -> bool: if amount <= 0: return False if amount < min_amount or amount > max_amount: return False return True @staticmethod def validate_currency_code(currency: str) -> bool: valid_currencies = ['BTC', 'ETH', 'USDT', 'USD', 'EUR', 'GBP'] return currency.upper() in valid_currencies @staticmethod def sanitize_string(input_string: str, max_length: int = 255) -> str: if not input_string: return "" # Remove potentially dangerous characters sanitized = re.sub(r'[<>"\']', '', input_string) # Trim to max length return sanitized[:max_length].strip() @staticmethod def validate_kyc_level(level: int) -> bool: return level in [0, 1, 2] @staticmethod def validate_transaction_type(transaction_type: str) -> bool: valid_types = ['SEND', 'RECEIVE', 'DEPOSIT', 'WITHDRAWAL'] return transaction_type.upper() in valid_types def validate_required_fields(data: dict, required_fields: list) -> None: """Validate that all required fields are present and not empty""" missing_fields = [] for field in required_fields: if field not in data or not data[field]: missing_fields.append(field) if missing_fields: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Missing required fields: {', '.join(missing_fields)}" ) def validate_user_registration(email: str, password: str, full_name: str) -> None: """Validate user registration data""" if not ValidationUtils.validate_email(email): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid email format" ) if not ValidationUtils.validate_password(password): raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Password must be at least 8 characters with uppercase, lowercase, and digit" ) if len(full_name.strip()) < 2: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Full name must be at least 2 characters" ) def validate_transaction_amount(amount: float, currency: str) -> None: """Validate transaction amount based on currency""" min_amounts = { 'BTC': 0.00001, 'ETH': 0.001, 'USDT': 0.01, 'USD': 0.01, 'EUR': 0.01, 'GBP': 0.01 } max_amounts = { 'BTC': 100, 'ETH': 1000, 'USDT': 100000, 'USD': 100000, 'EUR': 100000, 'GBP': 100000 } currency = currency.upper() min_amount = min_amounts.get(currency, 0.01) max_amount = max_amounts.get(currency, 100000) if amount < min_amount: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Minimum amount for {currency} is {min_amount}" ) if amount > max_amount: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=f"Maximum amount for {currency} is {max_amount}" )