d93c518a14
Co-authored-by: Cursor <cursoragent@cursor.com>
63 lines
2.1 KiB
Python
63 lines
2.1 KiB
Python
"""Probe remote host for Nexus file-manager sudo capability."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from server.domain.models import Server
|
|
from server.infrastructure.ssh.asyncssh_pool import exec_ssh_command
|
|
from server.utils.files_elevation import (
|
|
SUDOERS_DOC_PATH,
|
|
FilesElevation,
|
|
get_files_elevation,
|
|
)
|
|
|
|
|
|
async def probe_files_capability(server: Server) -> dict:
|
|
"""Run lightweight SSH checks for passwordless sudo and chmod/chown whitelist."""
|
|
ssh_user = (server.username or "root").strip() or "root"
|
|
elevation: FilesElevation = get_files_elevation(server)
|
|
is_root = ssh_user == "root"
|
|
|
|
if is_root:
|
|
return {
|
|
"ssh_user": ssh_user,
|
|
"is_root": True,
|
|
"files_elevation": elevation.value,
|
|
"can_sudo_nopasswd": True,
|
|
"whitelist_ok": True,
|
|
"message": "SSH 用户为 root,无需 sudo 提权",
|
|
"docs_path": SUDOERS_DOC_PATH,
|
|
}
|
|
|
|
sudo_probe = await exec_ssh_command(server, "sudo -n true", timeout=15)
|
|
can_sudo_nopasswd = sudo_probe.get("exit_code") == 0
|
|
|
|
whitelist_probe = await exec_ssh_command(
|
|
server,
|
|
"sudo -n bash -c 'command -v chmod >/dev/null && command -v chown >/dev/null'",
|
|
timeout=15,
|
|
)
|
|
whitelist_ok = can_sudo_nopasswd and whitelist_probe.get("exit_code") == 0
|
|
|
|
if can_sudo_nopasswd and whitelist_ok:
|
|
message = "已配置免密 sudo,文件管理可自动提权"
|
|
elif can_sudo_nopasswd:
|
|
message = (
|
|
"可免密 sudo,但 chmod/chown 可能未列入白名单;"
|
|
"请参考仓库内 sudoers 示例补全"
|
|
)
|
|
else:
|
|
message = (
|
|
"无法免密 sudo;写权限、chmod 等可能失败。"
|
|
"请在目标机安装 nexus-files.sudoers(见文档路径)"
|
|
)
|
|
|
|
return {
|
|
"ssh_user": ssh_user,
|
|
"is_root": False,
|
|
"files_elevation": elevation.value,
|
|
"can_sudo_nopasswd": can_sudo_nopasswd,
|
|
"whitelist_ok": whitelist_ok,
|
|
"message": message,
|
|
"docs_path": SUDOERS_DOC_PATH,
|
|
}
|