from __future__ import annotations from urllib.parse import urlparse from yuxi.channels.auth.ssrf_guard import ( is_private_url as _is_private_url, ) from yuxi.channels.auth.ssrf_guard import ( validate_url_with_whitelist, ) def is_private_url(url: str) -> bool: return _is_private_url(url) def validate_url_safety(url: str, dangerously_allow_private: bool = False) -> tuple[bool, str]: if not url: return False, "URL is empty" parsed = urlparse(url) if parsed.scheme not in ("http", "https"): return False, f"Unsupported scheme: {parsed.scheme}" if not dangerously_allow_private and is_private_url(url): return False, f"URL points to private/internal network: {parsed.hostname}" return True, "ok" def validate_mattermost_server_url(url: str, dangerously_allow_private: bool = False) -> str: return validate_url_with_whitelist( url, allowed_hosts=None, enforce_https=True, allow_private=dangerously_allow_private, ) def check_dangerously_allow_private_network(config: dict) -> bool: return bool(config.get("network", {}).get("dangerouslyAllowPrivateNetwork", False)) def normalize_mattermost_base_url(url: str) -> str: url = url.strip() url = url.rstrip("/") if url.endswith("/api/v4"): url = url[: -len("/api/v4")] return url.rstrip("/") def safe_url_for_driver(url: str) -> str: return normalize_mattermost_base_url(url)