ForcePilot/backend/package/yuxi/channels/adapters/mattermost/client.py

54 lines
1.4 KiB
Python
Raw Normal View History

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)