Files
FunguyBot/plugins/common.py
T

58 lines
1.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Shared utilities for FunguyBot plugins.
"""
import html
import ipaddress
import socket
import logging
logger = logging.getLogger(__name__)
# Networks considered unsafe for outbound connections
_PRIVATE_RANGES = [
ipaddress.ip_network('10.0.0.0/8'),
ipaddress.ip_network('172.16.0.0/12'),
ipaddress.ip_network('192.168.0.0/16'),
ipaddress.ip_network('127.0.0.0/8'),
ipaddress.ip_network('169.254.0.0/16'),
ipaddress.ip_network('0.0.0.0/8'),
ipaddress.ip_network('::1/128'),
ipaddress.ip_network('fc00::/7'),
ipaddress.ip_network('fe80::/10'),
ipaddress.ip_network('::/128'),
]
def html_escape(text: str) -> str:
"""Escape HTML special characters for safe embedding in messages."""
return html.escape(str(text), quote=False)
def collapsible_summary(title: str, body: str, expanded: bool = False) -> str:
"""Wrap content in a collapsible HTML details block."""
open_attr = ' open' if expanded else ''
return f"<details{open_attr}>\n<summary><strong>{title}</strong></summary>\n{body}\n</details>"
def is_public_destination(target: str) -> bool:
"""
Returns True if `target` (hostname or IP) does NOT resolve to any
private, loopback, or linklocal address.
"""
try:
addr = ipaddress.ip_address(target)
if any(addr in net for net in _PRIVATE_RANGES):
return False
return True
except ValueError:
pass
try:
addrinfo = socket.getaddrinfo(target, None)
for _, _, _, _, sockaddr in addrinfo:
ip = sockaddr[0]
addr = ipaddress.ip_address(ip)
if any(addr in net for net in _PRIVATE_RANGES):
return False
return True
except Exception as e:
logger.warning(f"Cannot resolve {target}: {e}")
return False