"""Path validation utilities.""" from pathlib import Path from app.config import get_settings def validate_log_path(log_path: str) -> str: """Validate that a log path is within allowed directories. Resolves the path to its canonical form (resolving symlinks) and checks that it is relative to one of the allowed log directories from settings. Args: log_path: The log path to validate. Returns: The validated log path (unchanged). Raises: ValueError: If the path is outside allowed log directories. """ settings = get_settings() try: resolved_path = Path(log_path).resolve() except (OSError, RuntimeError) as e: raise ValueError(f"Cannot resolve path {log_path!r}: {e}") from e for allowed_dir in settings.allowed_log_dirs: allowed_path = Path(allowed_dir).resolve() try: resolved_path.relative_to(allowed_path) return log_path except ValueError: continue allowed_dirs_str = ", ".join(settings.allowed_log_dirs) raise ValueError( f"Log path {log_path!r} is outside allowed directories: {allowed_dirs_str}" ) def validate_log_target(log_target: str) -> str: """Validate that a log target is either a special value or a valid file path. Accepts special values (STDOUT, STDERR, SYSLOG) and file paths that resolve to one of the configured allowed log directories. Args: log_target: The log target to validate. Returns: The validated log target (unchanged). Raises: ValueError: If the target is not a special value and not in allowed directories. """ if log_target.upper() in ("STDOUT", "STDERR", "SYSLOG"): return log_target return validate_log_path(log_target)