49 lines
1.7 KiB
Python
49 lines
1.7 KiB
Python
|
|
"""SSH-based Baota temporary login URL (tools.py)."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import logging
|
||
|
|
import re
|
||
|
|
from urllib.parse import urlparse
|
||
|
|
|
||
|
|
from server.domain.models import Server
|
||
|
|
from server.infrastructure.ssh.asyncssh_pool import exec_ssh_command
|
||
|
|
|
||
|
|
logger = logging.getLogger("nexus.btpanel.ssh")
|
||
|
|
|
||
|
|
_BT_PANEL_TOOLS = "/www/server/panel/tools.py"
|
||
|
|
_URL_RE = re.compile(r"^https?://\S+/login\?tmp_token=\S+$", re.IGNORECASE)
|
||
|
|
|
||
|
|
SSH_TEMP_LOGIN_CMD = (
|
||
|
|
f"test -f {_BT_PANEL_TOOLS} && "
|
||
|
|
f"cd /www/server/panel && python3 tools.py get_temp_login_ipv4 2>/dev/null | tail -1"
|
||
|
|
)
|
||
|
|
|
||
|
|
DETECT_BT_CMD = "test -f /www/server/panel/class/common.py && echo BT_OK || echo BT_NO"
|
||
|
|
|
||
|
|
|
||
|
|
async def detect_bt_panel_installed(server: Server) -> bool:
|
||
|
|
result = await exec_ssh_command(server, DETECT_BT_CMD, timeout=20)
|
||
|
|
if result.get("status") != "success":
|
||
|
|
return False
|
||
|
|
return "BT_OK" in (result.get("stdout") or "")
|
||
|
|
|
||
|
|
|
||
|
|
def _rewrite_login_host(url: str, prefer_host: str) -> str:
|
||
|
|
prefer_host = prefer_host.strip()
|
||
|
|
if not prefer_host or not _URL_RE.match(url):
|
||
|
|
return url
|
||
|
|
parsed = urlparse(url)
|
||
|
|
port = parsed.port or (443 if parsed.scheme == "https" else 80)
|
||
|
|
return f"{parsed.scheme}://{prefer_host}:{port}{parsed.path}?{parsed.query}"
|
||
|
|
|
||
|
|
|
||
|
|
async def ssh_temp_login_url(server: Server) -> str:
|
||
|
|
result = await exec_ssh_command(server, SSH_TEMP_LOGIN_CMD, timeout=45)
|
||
|
|
if result.get("status") != "success":
|
||
|
|
raise RuntimeError(result.get("stderr") or result.get("stdout") or "SSH 执行失败")
|
||
|
|
line = (result.get("stdout") or "").strip().splitlines()[-1].strip()
|
||
|
|
if not _URL_RE.match(line):
|
||
|
|
raise RuntimeError(f"未获得有效临时登录链接: {line[:120]}")
|
||
|
|
return _rewrite_login_host(line, server.domain or "")
|