from __future__ import annotations from ipaddress import ip_address, ip_network from fastapi import Request from app.config import Settings def is_ip_in_network(candidate_ip: str, network_value: str) -> bool: return ip_address(candidate_ip) in ip_network(network_value, strict=False) def is_trusted_proxy(source_ip: str, settings: Settings) -> bool: try: parsed_ip = ip_address(source_ip) except ValueError: return False return any(parsed_ip in network for network in settings.trusted_proxy_networks) def extract_client_ip(request: Request, settings: Settings) -> str: client_host = request.client.host if request.client else "127.0.0.1" if not is_trusted_proxy(client_host, settings): return client_host real_ip = request.headers.get("x-real-ip") if not real_ip: return client_host try: ip_address(real_ip) except ValueError: return client_host return real_ip