d93c518a14
Co-authored-by: Cursor <cursoragent@cursor.com>
164 lines
5.7 KiB
Markdown
164 lines
5.7 KiB
Markdown
# POSIX 路径分批审查记录
|
||
|
||
| 项 | 内容 |
|
||
|----|------|
|
||
| 日期 | 2026-06-01 |
|
||
| 方法 | 按模块分批 `rg os.path` / `rg posix` / 人工读 SSH 拼接点 |
|
||
| SSOT | `server/utils/posix_paths.py` |
|
||
| 总览 | [posix-path-full-audit.md](./2026-06-01-posix-path-full-audit.md) |
|
||
|
||
---
|
||
|
||
## 批次 1:基础设施层
|
||
|
||
| 文件 | 结论 | 证据 |
|
||
|------|------|------|
|
||
| `server/utils/posix_paths.py` | ✅ 通过 | 唯一允许 `os.path.realpath`(本机 FS) |
|
||
| `server/api/remote_path_validation.py` | ✅ 通过 | 委托 posix_paths |
|
||
| `server/infrastructure/ssh/asyncssh_pool.py` | ✅ 已修 | `posix_dirname(remote_path)` |
|
||
| `server/infrastructure/ssh/remote_archive.py` | ✅ 通过 | 全程 `posixpath` |
|
||
| `server/infrastructure/ssh/remote_probe.py` | ✅ 无路径拼接 | — |
|
||
| `server/infrastructure/ssh/__init__.py` | ✅ 无业务路径 | — |
|
||
|
||
**批次 1 结论:无遗留问题。**
|
||
|
||
---
|
||
|
||
## 批次 2:`server/api/sync_v2.py`(文件/同步 API)
|
||
|
||
| 端点/区域 | 结论 |
|
||
|-----------|------|
|
||
| browse / file-ops / clipboard | ✅ `normalize_remote_abs_path` |
|
||
| browse-local / local-file-ops / preview | ✅ `ensure_under_nexus_upload` + `posix_join`;`os.path.*` 仅本机 I/O |
|
||
| validate-source-path | ✅ `resolve_nexus_host_path` + walk 用 `posix_join` |
|
||
| diagnose / file-diff / verify | ✅ `normalize_remote_dest` + `remote_join` |
|
||
| upload / upload-zip | ✅ `remote_join` + `assert_zip_member_safe` |
|
||
| download / read / write / chmod / compress / decompress | ✅ 远程 path 均规范化 |
|
||
|
||
**仍见 `os.path`:** 仅 `isdir`/`exists`/`getsize`/`walk`(Nexus 主机文件系统)— **合法**。
|
||
|
||
**批次 2 结论:无遗留问题。**
|
||
|
||
---
|
||
|
||
## 批次 3:应用服务层
|
||
|
||
| 文件 | 结论 | 说明 |
|
||
|------|------|------|
|
||
| `sync_engine_v2.py` | ✅ 已修 | `_rsync_push` 内 `normalize_remote_abs_path(to_posix(target_path))` + `user@host:path` |
|
||
| | ⚠️ 注意 | `os.path.isdir(source_path)` — Nexus **本机**源目录,生产为 Linux |
|
||
| `sync_service.py` | ✅ 无路径逻辑 | 注释/委托 v2 |
|
||
| `script_service.py` | ✅ 通过 | 远程日志路径固定 `/var/log/nexus-job/` + `shlex.quote` |
|
||
| `script_jobs.py` | ✅ 无文件路径 | shell 转义 only |
|
||
| `server_service.py` | ✅ 无 SSH 路径拼接 | — |
|
||
|
||
**批次 3 结论:无遗留问题。**
|
||
|
||
---
|
||
|
||
## 批次 4:其他 API + 后台任务
|
||
|
||
| 文件 | 结论 |
|
||
|------|------|
|
||
| `servers.py` | ✅ workerman `posix_dirname`;Agent `install_dir="/opt/nexus-agent"` 常量拼接 |
|
||
| `agent.py` / `webssh.py` / `terminal.py` | ✅ 无远程文件路径 join |
|
||
| `install.py` | ➖ 豁免 | `Path("/www/...")` 在**安装目标 Linux 机**执行 |
|
||
| `settings.py` / `auth_jwt.py` / `main.py` | ➖ 豁免 | `Path(__file__)` 仓库/静态资源 |
|
||
| `schemas.py` | ⚠️ 建议 | `target_path` 无 Pydantic 校验反斜杠(见下方 P2) |
|
||
| `background/schedule_runner.py` | ✅ 可接受 | `source_path` 进 engine,远程 dest 在 `_rsync_push` 规范化 |
|
||
| `background/retry_runner.py` | ✅ 透传 DB 字段,同上 |
|
||
|
||
**批次 4 结论:无 P0/P1;1 项 P2 建议。**
|
||
|
||
---
|
||
|
||
## 批次 5:领域 / 数据库 / Redis
|
||
|
||
| 范围 | 结论 |
|
||
|------|------|
|
||
| `server/domain/**` | ✅ ORM 字段存字符串,不做 path join |
|
||
| `server/infrastructure/database/**` | ✅ 无路径拼接 |
|
||
| `server/infrastructure/redis/**` | ✅ 无文件路径 |
|
||
|
||
**批次 5 结论:无问题。**
|
||
|
||
---
|
||
|
||
## 批次 6:前端
|
||
|
||
| 文件 | 结论 |
|
||
|------|------|
|
||
| `utils/remotePath.ts` | ✅ `/` 拼接;`\` → `/` |
|
||
| `FilesPage.vue` / `FileDirectoryTree.vue` / `filePreload.ts` / `useFilesClipboard.ts` | ✅ 均 `joinRemotePath` / `normalizeRemotePath` |
|
||
| `PushPage.vue` / `SchedulesPage.vue` | ✅ 路径交 API,由后端规范化 |
|
||
| `TerminalPage.vue` | ➖ | `cd ${dir}` 为用户终端输入,非文件管理器 |
|
||
|
||
**批次 6 结论:无遗留问题。**
|
||
|
||
---
|
||
|
||
## 批次 7:测试 / 工具 / MCP
|
||
|
||
| 文件 | 结论 |
|
||
|------|------|
|
||
| `tests/test_posix_paths.py` | ✅ |
|
||
| `tests/test_remote_path_validation.py` | ✅ |
|
||
| `tests/test_api.py` 等 | ➖ 本地 `.env` 定位 |
|
||
| `mcp/Nexus_server.py` | ➖ 部署目录 `DEPLOY_DIR` |
|
||
| `deploy/gate_log.py` | ➖ |
|
||
| `docs/build_html.py` / `audit_scan.py` | ➖ 仓库内扫描 |
|
||
|
||
**批次 7 结论:无问题。**
|
||
|
||
---
|
||
|
||
## 汇总
|
||
|
||
| 批次 | 范围 | 状态 |
|
||
|------|------|------|
|
||
| 1 | SSH 基础设施 | ✅ 完成 |
|
||
| 2 | sync_v2 API | ✅ 完成 |
|
||
| 3 | application services | ✅ 完成 |
|
||
| 4 | 其他 API + background | ✅ 完成(P2×1) |
|
||
| 5 | domain / DB | ✅ 完成 |
|
||
| 6 | frontend | ✅ 完成 |
|
||
| 7 | tests / tooling | ✅ 完成 |
|
||
|
||
**P0/P1:0**
|
||
**P2(2026-06-01 已完成):**
|
||
|
||
1. ✅ **`schemas.py` + `schema_path_validators.py`**:远程/本机路径字段入口校验与规范化
|
||
2. ✅ **`sync_engine_v2`**:`source_path` 在 `isdir` 前 `_nexus_source_path()`(`to_posix`)
|
||
|
||
---
|
||
|
||
## 回归命令
|
||
|
||
```bash
|
||
pytest tests/test_posix_paths.py tests/test_remote_path_validation.py -q
|
||
rg "os\.path\.(join|dirname|basename)" server/ --glob "*.py"
|
||
# 期望:仅 posix_paths 注释 + sync_v2/sync_engine 的 isdir/exists/getsize
|
||
```
|
||
|
||
---
|
||
|
||
## DoD(分批审查)
|
||
|
||
- [x] 批次 1~7 均已执行并记录
|
||
- [x] 每批有明确通过/豁免/建议
|
||
- [x] P0/P1 为 0
|
||
- [x] P2 已实施(schemas + sync_engine)
|
||
|
||
## 批次 9:文件管理归属 + 权限 UI(2026-06-01)
|
||
|
||
| 项 | 状态 |
|
||
|----|------|
|
||
| `remote_shell.py` | ✅ |
|
||
| browse owner/group/mode_octal | ✅ |
|
||
| chmod + chown + sudo 回退 | ✅ |
|
||
| 前端归属列 + FilePermissionDialog | ✅ |
|
||
| `files-capability` API | ✅ 批次 10 |
|
||
| `files_elevation` 服务器字段 | ✅ 批次 10 |
|
||
| Phase 5:ls 解析单测 + long-iso + read-file 提权 | ✅ 批次 11 |
|
||
| 二期:递归 chmod + 不可读提示条 | ✅ 批次 12 |
|