chore: track version files, docs, web app split, scripts (missed commits from March work)

This commit is contained in:
2026-09-13 08:41:35 +08:00
parent 84c709bbcc
commit edf76db56b
33 changed files with 3082 additions and 504 deletions
+144
View File
@@ -0,0 +1,144 @@
# Advanced Override 开关说明(INP2P)
> 目标:在不破坏默认最小权限模型的前提下,提供**临时、可审计、可回滚**的越权能力。
## 1. 开关清单
## 总开关(必须先开)
- `advanced_override_enabled`
- `0`:关闭(默认)
- `1`:开启
> 总开关关闭时,所有越权子开关均不生效。
## 越权子开关
- `allow_apikey_mutate_sdwan`
- 允许 `apikey` 执行 `mutate_sdwan`(如 `POST /api/v1/sdwan/edit`)
- 默认 `0`
- `allow_operator_kick_cross_node`
- 预留:允许 operator 执行更高风险节点控制(当前主要用于后续扩展)
- 默认 `0`
- `allow_connect_cross_tenant`
- 允许 operator 在 connect 目标检查中放宽跨租户限制
- 默认 `0`
## 兼容旧开关(保留)
- `advanced_impersonate`
- `advanced_force_network`
- `advanced_cross_tenant`
---
## 2. 默认安全策略
- 所有高级开关默认 `0`(关闭)
- 仅系统管理员(`tenant_id=1` 且 `role=admin`)可在 `/api/v1/admin/settings` 修改
- `master token` 仍禁止访问 tenant API
- 默认禁止跨租户写操作
---
## 3. RBAC 行为
系统先走基线权限 `TenantCan`,若基线拒绝,再尝试 `TenantCanWithOverride`:
1. 若 `advanced_override_enabled != 1` → 拒绝
2. 若命中对应子开关 → 放行(并记录 override 审计)
3. 否则拒绝
当前已接入接口:
- `POST /api/v1/sdwan/edit`
- `POST /api/v1/nodes/apps`
- `POST /api/v1/nodes/kick`
- `POST /api/v1/connect`
---
## 4. 审计事件
## 开关配置审计
- `setting_change`
- `target_type=setting`
- `target_id=<key>`
- `detail=<value>`
## 越权使用审计
- `rbac_override_used`
- 示例 detail:
- `action=mutate_sdwan tenant=4`
- `action=mutate_connect tenant=3`
- `action=connect_cross_tenant tenant=3 from=a to=b`
## connect 失败审计
- `connect_request_denied`
- 典型 reason:
- `source_offline`
- `tenant_mismatch_source`
- `target_offline`
- `tenant_mismatch_target`
---
## 5. 启用与回滚(操作手册)
## 启用(示例)
```bash
BASE=http://127.0.0.1:27183
ADMIN_TOKEN=<system-admin-session-token>
curl -s -X POST "$BASE/api/v1/admin/settings" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"key":"advanced_override_enabled","value":"1"}'
curl -s -X POST "$BASE/api/v1/admin/settings" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"key":"allow_apikey_mutate_sdwan","value":"1"}'
```
## 回滚(推荐顺序)
```bash
# 先关子开关
curl -s -X POST "$BASE/api/v1/admin/settings" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"key":"allow_apikey_mutate_sdwan","value":"0"}'
curl -s -X POST "$BASE/api/v1/admin/settings" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"key":"allow_connect_cross_tenant","value":"0"}'
curl -s -X POST "$BASE/api/v1/admin/settings" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"key":"allow_operator_kick_cross_node","value":"0"}'
# 最后关总开关
curl -s -X POST "$BASE/api/v1/admin/settings" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"key":"advanced_override_enabled","value":"0"}'
```
---
## 6. 风险与建议
- 建议仅在临时排障窗口启用,完成后立即回滚。
- 启用前后均应检查审计日志,确认“谁在何时以何种方式使用了越权能力”。
- 生产环境优先保持:
- `advanced_override_enabled=0`
- `allow_* = 0`
+80
View File
@@ -0,0 +1,80 @@
# INP2P Android API 契约(MVP)
> Base URL 示例:`http://127.0.0.1:27183`
> 认证方式:`Authorization: Bearer <token>`
## 1) 登录
### POST `/api/v1/auth/login`
请求:
```json
{"username":"kyaarin","password":"***"}
```
响应(成功):
```json
{
"error":0,
"message":"ok",
"token":"...",
"token_type":"session",
"expires_at":1770000000,
"role":"admin",
"status":1,
"tenant_id":3,
"subnet":"10.200.2.0/24"
}
```
## 2) 节点列表
### GET `/api/v1/nodes`
响应:
```json
{"nodes":[{"name":"node1","tenantId":3,"natType":1,"publicIP":"1.2.3.4"}]}
```
## 3) SDWAN
### GET `/api/v1/sdwans`
读取当前租户 SDWAN 配置。
### POST `/api/v1/sdwan/edit`
按权限写入。租户端 `gatewayCIDR` 由后端锁定为租户分配子网。
## 4) 节点控制
### POST `/api/v1/nodes/apps`
请求示例:
```json
{"node":"node1","apps":[{"appName":"demo","protocol":"tcp","srcPort":12080,"dstHost":"127.0.0.1","dstPort":80,"enabled":1}]}
```
### POST `/api/v1/nodes/kick`
请求:
```json
{"node":"node1"}
```
## 5) 手动连接
### POST `/api/v1/connect`
请求:
```json
{"from":"nodeA","to":"nodeB","srcPort":10080,"dstPort":80,"appName":"manual"}
```
## 6) 管理员接口(admin only)
### GET `/api/v1/admin/audit?tenant=3&limit=100`
读取审计日志。
### GET `/api/v1/admin/settings`
读取高级设置。
### POST `/api/v1/admin/settings`
请求:
```json
{"key":"advanced_override_enabled","value":"1"}
```
## 7) 错误码约定(前端处理)
- `200`:成功
- `400`:参数错误(直接提示)
- `401`:未授权(跳登录)
- `403`:权限不足(提示“无权限”)
- `404`:资源不存在/离线
- `502`:后端转发失败(connect 可能出现)
+41
View File
@@ -0,0 +1,41 @@
# 安卓端开工准备清单(可执行)
## A. 仓库与目录
- [ ] 新建仓库:`inp2p-android`(或 `inp2p/mobile/android` 子目录)
- [ ] 分支策略:`main` + `dev` + `feature/*`
## B. 工程初始化
- [ ] Android Studio 最新稳定版
- [ ] minSdk 26 / targetSdk 35
- [ ] Kotlin DSL + Compose 模板
- [ ] 引入依赖:Retrofit / OkHttp / Moshi(or kotlinx-serialization) / Room / WorkManager
## C. 安全与配置
- [ ] 本地存储 token 使用 EncryptedSharedPreferences
- [ ] Base URL 支持调试/生产切换
- [ ] 调试日志默认脱敏(禁止打印 Bearer token)
## D. 页面骨架(MVP)
- [ ] Login
- [ ] Dashboard(nodes/stats)
- [ ] Node 控制(apps/kick/connect)
- [ ] SDWAN
- [ ] Admin(settings/audit)
## E. 网络层
- [ ] 统一 ApiResult 封装(Success/Error)
- [ ] 401 统一拦截处理(回登录)
- [ ] 403/404/502 统一文案
## F. 权限与可见性
- [ ] 根据 `role + tenant_id` 做 UI 可见性
- [ ] 高风险动作二次确认弹窗
## G. 测试
- [ ] Mock API 单元测试
- [ ] 至少 1 条真实环境冒烟链路(login -> nodes -> connect)
## H. 文档
- [ ] 在项目 README 中链接:
- `docs/android-mvp-plan.md`
- `docs/android-api-contract.md`
+61
View File
@@ -0,0 +1,61 @@
# INP2P Android 客户端开工计划(MVP → V1)
## 目标
在不改动核心服务端协议的前提下,先交付“可运维、可观察、可控风险”的安卓客户端。
## 分阶段路线
### Phase 0:开工准备(1-2 天)
- 明确 API 契约(当前后端已具备)
- 固化角色与权限矩阵(admin/operator/apikey)
- 建立 Android 项目骨架(Kotlin + Compose + Retrofit + Room + WorkManager)
- 建立日志/崩溃/埋点规范
### Phase 1:MVP(5-7 天)
- 登录/会话管理(`/api/v1/auth/login`)
- 节点列表与状态(`/api/v1/nodes`)
- 手动 connect(`/api/v1/connect`)
- 远程推配置(`/api/v1/nodes/apps`)
- 节点踢下线(`/api/v1/nodes/kick`,仅 admin/operator)
- SDWAN 基础配置只读 + 编辑(按权限)
- 审计查看(admin only,`/api/v1/admin/audit`)
### Phase 2:增强(7-10 天)
- 设置页:高级开关联动(`/api/v1/admin/settings`)
- 断线重连与 Token 续期提示
- 更完整的错误态/空态/离线态
- 细化操作确认(高风险动作二次确认)
### Phase 3:V1(后续)
- VpnService + TUN 数据面接入
- 网络切换稳定性(Wi-Fi/4G)
- 前台服务保活与电量策略优化
## MVP 范围边界(本次明确)
- ✅ 做:控制面(鉴权、查询、下发)
- ❌ 不做:首版直接上 TUN 全数据面
## 技术选型(建议)
- 语言:Kotlin
- UI:Jetpack Compose
- 网络:Retrofit + OkHttp
- 本地存储:Room + EncryptedSharedPreferences
- 并发:Kotlin Coroutines + Flow
- 任务调度:WorkManager
- 最低版本:Android 8.0+
## 核心风险与对策
1. Token 过期导致操作失败
- 对策:统一 401 拦截,跳登录;关键动作前校验登录态。
2. 移动网络切换导致请求失败
- 对策:重试策略(指数退避)、弱网提示、幂等操作提示。
3. 高危动作误触(kick/connect/sdwan)
- 对策:二次确认 + 审计可追踪 + 角色按钮可见性控制。
4. 后端字段变动影响兼容
- 对策:DTO 宽容解析 + 版本检查 + 契约文档锁定。
## 验收标准(MVP)
- 能用 admin/operator 成功登录并执行对应权限动作
- apikey 仅可读,写操作被正确拒绝
- 关键操作成功/失败信息明确可见
- 审计与后端一致(至少覆盖 connect/kick/apps/sdwan)
+49
View File
@@ -0,0 +1,49 @@
# INP2P 部署校验规范(强制)
> 目标:每次新部署后,必须自动校验“服务端/客户端版本一致 + 无残留旧进程/旧二进制”。
## 1. 版本控制
- 项目版本源:`VERSION`
- 构建时自动注入:`Version / GitCommit / BuildTime / GoVersion`
- 约束:`bin/inp2ps` 与 `bin/inp2pc` 的 `-version` 输出必须等于 `VERSION`。
## 2. 校验脚本
- 脚本:`scripts/deploy-check.sh`
- Make 入口:`make verify-deploy`
脚本会检查:
1) 二进制版本是否匹配 `VERSION`
2) `inp2ps.service` 是否 active
3) `inp2ps.service` 的主进程是否运行自 `bin/inp2ps`
4) 是否存在残留 inp2p 进程(除当前服务主 PID 外)
5) 是否存在残留旧二进制(`*.old*/*.new*`、根目录历史二进制)
输出:
- 报告目录:`run/deploy-check/`
- 报告文件:`deploy-check-YYYYmmdd-HHMMSS.txt`
- 失败时脚本返回非 0(可用于 CI/发布门禁)
## 3. 标准发布流程(建议)
```bash
cd /root/.openclaw/workspace/inp2p
# 1) 编译(自动读取 VERSION)
make build
# 2) 部署(替换后重启服务)
systemctl restart inp2ps.service
# 3) 强制校验(必须通过)
make verify-deploy
```
## 4. 失败处理原则
- 任一校验 FAIL:视为发布未完成
- 必须先清理残留再进入可用状态
- 建议在变更记录中附上本次校验报告路径
+46
View File
@@ -0,0 +1,46 @@
# INP2P 前端文案词典(P4 封板)
更新时间:2026-03-08
适用范围:`web/index.html` 管理控制台
## 一、动作文案统一
- 刷新类:统一使用 **“重新加载”**(避免与浏览器“刷新页面”歧义)
- 重新加载 Key
- 重新加载 enroll
- 主动作:使用动词 + 对象
- 创建租户 / 创建用户 / 创建 API Key
- 保存 SDWAN / 保存节点映射 / 保存子网代理
- 发送配置 / 发送连接请求
- 危险动作:统一显式风险语义
- 删除 / 踢下线 / 批量停用 / 批量作废
## 二、状态与空态文案
- 空态统一使用“暂无 xxx 记录”并给出下一步指引
- 暂无 API Key 记录
- 暂无 enroll 记录。点击上方“生成 enroll_code”
- 处理中统一使用“xx 处理中...”
- SDWAN 处理中...
- P2P 操作处理中...
- 用户数据处理中...
## 三、反馈文案规范
- 成功反馈:动作 + 成功
- 审计 CSV 已导出
- 高级设置已保存
- 失败反馈:优先人性化解释(state.humanizeError)
- 批量反馈:统一“成功/失败计数”
- Key 批量停用:成功 X / 失败 Y
## 四、按钮层级规范
- `btn`:主路径提交(会改变状态/写入)
- `btn2`:次级操作(筛选、切换、导出、重试)
- `btn-danger`:高风险操作(不可逆或影响在线连接)
示例:
- 保存节点映射 / 保存子网代理 / 发送配置 => `btn`
- 重新加载 Key / 清空筛选 / 导出 CSV => `btn2`
- 删除用户 / 踢下线 => `btn-danger`
@@ -0,0 +1,69 @@
# INP2P 最终回归清单(P4)
更新时间:2026-03-08
适用版本:`0.1.0+build.18` 起
## 1. 发布门禁(必须)
1) `make build`
2) `systemctl restart inp2ps.service`
3) `make verify-deploy`
通过标准:`verify-deploy` 全绿。
---
## 2. 功能回归
### 2.1 登录/会话
- 用户名密码登录成功
- 停用账号登录被拒绝
- 登出后 token 清理
### 2.2 节点页
- 节点搜索可用
- 踢下线按钮为危险色并有确认
- 改昵称/改IP/发起连接可用
### 2.3 SDWAN
- 保存 SDWAN 生效
- 节点映射保存生效
- 子网代理保存生效
### 2.4 租户/Key/用户/enroll
- 新建流程可用
- 单条启停可用
- 批量启停/作废可用
- 批量失败计数正确
- 失败池保留/清空行为符合开关
### 2.5 审计
- 预设筛选(全部/登录失败/拒绝/连接拒绝)可用
- 清空筛选可恢复默认
- 导出 CSV 可用
- 导出失败事件 CSV 可用
### 2.6 快捷键
- `/` 聚焦搜索
- `r` 刷新
- `g` 跳节点页
- `?` 显示/隐藏帮助
- 输入法组合态、Ctrl/Alt/Meta 下不误触
---
## 3. 交互一致性
- 主操作按钮使用 `btn`
- 次操作按钮使用 `btn2`
- 危险操作按钮使用 `btn-danger`
- 空态文案包含下一步引导
- 最近操作摘要(opSummary)正确回显
---
## 4. 运维核验
- `inp2ps.service` 指向 `/root/.openclaw/workspace/inp2p/bin/inp2ps`
- 运行中仅保留目标主进程,无残留旧版本进程
- 版本号与 `VERSION` 一致
+35
View File
@@ -0,0 +1,35 @@
# INP2P Tenant RBAC Matrix
## Access Context
- `session/admin`:租户管理员
- `session/operator`:租户操作员
- `apikey`:租户 API key(机器访问)
- `master`:系统级 token(禁止用于 tenant API)
## Action Mapping
| action | session/admin | session/operator | apikey |
|---|---:|---:|---:|
| `view` | ✅ | ✅ | ✅ |
| `mutate_node_meta` (alias/ip) | ✅ | ✅ | ❌ |
| `mutate_sdwan` | ✅ | ✅ | ❌ |
| `mutate_connect` | ✅ | ✅ | ❌ |
| `mutate_node_control` (apps push / kick) | ✅ | ✅ | ❌ |
| `enroll_manage` (revoke enroll token) | ✅ | ❌ | ❌ |
## Route Coverage (implemented)
- `POST /api/v1/nodes/alias` -> `mutate_node_meta`
- `POST /api/v1/nodes/ip` -> `mutate_node_meta`
- `POST /api/v1/sdwan/edit` -> `mutate_sdwan`
- `POST /api/v1/connect` -> `mutate_connect`
- `POST /api/v1/nodes/apps` -> `mutate_node_control`
- `POST /api/v1/nodes/kick` -> `mutate_node_control`
- `POST /api/v1/enroll/consume/{id}?status=0|1` -> `enroll_manage`
## Security Notes
- `master` token is blocked by tenant middleware.
- Enroll revoke path now requires tenant auth and `session/admin`.
- WS login logs no longer print raw token values.
+65
View File
@@ -0,0 +1,65 @@
# INP2P RBAC Regression Checklist
> Replace placeholders:
> - `BASE=http://127.0.0.1:27183`
> - `ADMIN_TOKEN=<tenant admin session token>`
> - `OP_TOKEN=<tenant operator session token>`
> - `APIKEY_TOKEN=<tenant api key>`
## 1) enroll revoke must be admin-only
```bash
curl -i -X POST "$BASE/api/v1/enroll/consume/1?status=0" \
-H "Authorization: Bearer $OP_TOKEN"
# expect: 401/403
curl -i -X POST "$BASE/api/v1/enroll/consume/1?status=0" \
-H "Authorization: Bearer $APIKEY_TOKEN"
# expect: 401/403
```
## 2) apikey cannot mutate
```bash
curl -i -X POST "$BASE/api/v1/sdwan/edit" \
-H "Authorization: Bearer $APIKEY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"enabled":true,"gatewayCIDR":"10.200.10.0/24"}'
# expect: 403
curl -i -X POST "$BASE/api/v1/nodes/kick" \
-H "Authorization: Bearer $APIKEY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"node":"demo-node"}'
# expect: 403
```
## 3) operator can mutate common ops
```bash
curl -i -X POST "$BASE/api/v1/connect" \
-H "Authorization: Bearer $OP_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"from":"n1","to":"n2","srcPort":10080,"dstPort":80,"appName":"test"}'
# expect: 200 (if nodes exist)
```
## 4) tenant isolation
```bash
# operator/admin from tenant A cannot operate tenant B node
curl -i -X POST "$BASE/api/v1/nodes/kick" \
-H "Authorization: Bearer $OP_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"node":"tenantB-node"}'
# expect: 404
```
## 5) verify audit logs created
- actions expected in audit:
- `node_kick`
- `node_apps_push`
- `connect_request`
- `tenant_subnet_reassign`
- `sdwan_update`
+34
View File
@@ -0,0 +1,34 @@
# INP2P 发布值班版(30 秒)
> 目标:最短路径完成发布并验收。
## 1) 一键流程(必须按顺序)
```bash
cd /root/.openclaw/workspace/inp2p
make build
systemctl restart inp2ps.service
make verify-deploy
```
## 2) 成功判定(唯一标准)
- `make verify-deploy` **全绿 PASS**
- 报告文件已生成:
- `run/deploy-check/deploy-check-YYYYmmdd-HHMMSS.txt`
## 3) 快速回归(最小 6 项)
- [ ] 能登录,停用账号会被拒绝
- [ ] 节点页搜索可用,踢下线有确认
- [ ] SDWAN 保存可用
- [ ] Key/用户/enroll 单条操作可用
- [ ] 批量操作 + 重试失败可用
- [ ] 审计预设 + CSV 导出可用
## 4) 签字留档
- 版本:`________________`
- 报告:`run/deploy-check/deploy-check-________________.txt`
- 值班人:`________________`
- 时间:`________________`
+109
View File
@@ -0,0 +1,109 @@
# INP2P 一页发布手册(P4.5 收官)
更新时间:2026-03-08
当前基线版本:`0.1.0+build.18`
---
## 0) 适用范围
- 项目:`/root/.openclaw/workspace/inp2p`
- 服务:`inp2ps.service`
- 目标:每次发布都可复用本手册完成构建、部署、验收与留档
---
## 1) 标准发布流程(强制)
```bash
cd /root/.openclaw/workspace/inp2p
make build
systemctl restart inp2ps.service
make verify-deploy
```
**判定规则:**
- 仅当 `make verify-deploy` 全绿,才算发布成功。
- 仅重启成功不算发布成功。
**验收证据:**
- 报告路径:`run/deploy-check/deploy-check-YYYYmmdd-HHMMSS.txt`
---
## 2) UI 交互规范(封板基线)
### 2.1 按钮层级
- `btn`:主路径提交(状态变更/写入)
- `btn2`:次级动作(筛选、导出、切换、重试)
- `btn-danger`:高风险动作(删除、踢下线、不可逆)
### 2.2 文案规范
- 刷新类统一“重新加载”
- 空态统一“暂无 xxx 记录 + 下一步引导”
- 批量反馈统一“成功/失败计数”
### 2.3 快捷键规范
- `/` 聚焦筛选
- `r` 刷新
- `g` 打开节点页
- `?` 打开/关闭帮助
- 输入法组合态、Ctrl/Alt/Meta 组合键不触发全局热键
---
## 3) 功能验收清单(最小集)
1. 登录/登出正常,停用账号被拒绝
2. 节点页:搜索、踢下线确认、改昵称/改IP
3. SDWAN:保存 SDWAN/节点映射/子网代理
4. 租户/Key/用户/enroll:单条与批量操作可用
5. 失败池:保留开关、重试、清空行为正确
6. 审计:预设筛选、清空筛选、CSV 导出、失败事件导出
7. 最近操作摘要(opSummary)正确回显
---
## 4) 本轮阶段成果(摘要)
### P0(人性化收尾)
- 危险操作显式标红
- 输入示例占位补齐
- 复制快捷操作(Key/enroll)
### P1(信息与审计可读性)
- 常用操作区
- 审计 action 标签化 + 高风险高亮
- 审计快速筛选与清空
- 空态引导、最近操作摘要
### P2(效率提升)
- 审计 CSV 导出 + 失败事件导出
- 快捷键(/ r g ?)
- 批量操作 + 二次确认 + 统计回执
### P3(稳定性增强)
- 批量并发执行 + 失败重试
- 失败池保留/清空策略
- 审计预设持久化
- 热键冲突规避(输入法/组合键)
### P4(封板)
- 按钮层级统一
- 文案词典落地
- 最终回归清单沉淀
---
## 5) 发布签字项(可复制)
- [ ] 已执行 `make build`
- [ ] 已执行 `systemctl restart inp2ps.service`
- [ ] 已执行 `make verify-deploy` 且全绿
- [ ] 已记录 deploy-check 报告路径
- [ ] 已完成最小功能回归
- [ ] 已确认线上版本号与 `VERSION` 一致
签字人:__________
时间:__________
报告:`run/deploy-check/deploy-check-________________.txt`