feat: 新增用户管理(用户增删改查、密码重置、角色权限、会话认证)与 API 指南
- 新增 app/api/deps.py、app/core/users.py、app/core/sessions.py:会话鉴权依赖、 用户存储(PBKDF2-HMAC-SHA256 + 随机 salt,Redis/内存降级)、会话签发与校验(TTL 12h) - auth.py 新增用户管理端点(列表/创建/重置密码/删除)与 admin/user 角色权限边界, user 访问用户管理返回 1006,禁删自己与最后一个 admin - admin.html 新增用户管理面板(仅 admin 挂载)与 API 指南在线测试台 - Dockerfile 将 uv 放入 PATH;docker-compose 调整 qdrant 依赖为 service_started 并移除依赖 curl 的 healthcheck(官方镜像不含 curl) - 新增用户管理测试(users/sessions/auth_api/auth_integration),全量 461 项测试通过 Co-Authored-By: WorkBuddy <workbuddy@tencent.com>
This commit is contained in:
@@ -24,7 +24,9 @@ QMDSearch/
|
||||
│ ├── config.py # 配置管理
|
||||
│ ├── api/ # API 路由层
|
||||
│ │ ├── response.py # 统一响应格式 (ok/error/ApiError)
|
||||
│ │ ├── deps.py # 会话鉴权依赖 (Bearer → session → 用户记录)
|
||||
│ │ └── v1/ # API v1 版本
|
||||
│ │ ├── auth.py # 认证与用户管理接口
|
||||
│ │ ├── search.py # 检索接口
|
||||
│ │ ├── document.py # 文档入库/管理接口
|
||||
│ │ └── knowledge.py # 知识库接口
|
||||
@@ -38,6 +40,8 @@ QMDSearch/
|
||||
│ │ ├── headings.py # 原生标题树解析
|
||||
│ │ ├── classifier.py # 文档分类 (主类+标签+置信度)
|
||||
│ │ ├── chunker.py # 标题树感知 chunk 切分
|
||||
│ │ ├── users.py # 用户存储与密码哈希 (PBKDF2,Redis/内存降级)
|
||||
│ │ ├── sessions.py # 会话签发与校验 (Redis TTL 12h/内存降级)
|
||||
│ │ └── ingestion.py # 文档入库 (总结→分类→写入)
|
||||
│ ├── models/ # 数据模型
|
||||
│ │ ├── search.py # 检索请求/响应模型
|
||||
@@ -80,25 +84,44 @@ QMDSearch/
|
||||
|
||||
## API 清单
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/api/v1/health` | 健康检查 |
|
||||
| POST | `/api/v1/search` | 分层检索 |
|
||||
| POST | `/api/v1/documents` | 文档入库(202 异步入库,返回 task_id) |
|
||||
| POST | `/api/v1/documents/upload` | multipart 文件上传入库(202 异步,支持 .txt/.md/.html/.htm/.pdf/.docx) |
|
||||
| GET | `/api/v1/documents/tasks/{task_id}` | 入库任务状态查询(done 附 result,failed 附 error) |
|
||||
| GET | `/api/v1/knowledge/categories` | 知识分类类目集 |
|
||||
| GET | `/api/v1/knowledge/stats` | 统计(四层点数 + 类目分布 + uncategorized 数) |
|
||||
| GET | `/api/v1/documents` | 文档列表(limit/offset 分页) |
|
||||
| GET | `/api/v1/documents/{doc_id}` | 文档详情 |
|
||||
| DELETE | `/api/v1/documents/{doc_id}` | 删除文档(幂等) |
|
||||
| GET | `/admin` | 管理页面 |
|
||||
| 方法 | 路径 | 说明 | 鉴权 |
|
||||
|------|------|------|------|
|
||||
| GET | `/api/v1/health` | 健康检查 | 免登录 |
|
||||
| POST | `/api/v1/search` | 分层检索 | 免登录 |
|
||||
| POST | `/api/v1/documents` | 文档入库(202 异步入库,返回 task_id) | Bearer |
|
||||
| POST | `/api/v1/documents/upload` | multipart 文件上传入库(202 异步,支持 .txt/.md/.html/.htm/.pdf/.docx) | Bearer |
|
||||
| GET | `/api/v1/documents/tasks/{task_id}` | 入库任务状态查询(done 附 result,failed 附 error) | 免登录 |
|
||||
| GET | `/api/v1/knowledge/categories` | 知识分类类目集 | 免登录 |
|
||||
| GET | `/api/v1/knowledge/stats` | 统计(四层点数 + 类目分布 + uncategorized 数) | 免登录 |
|
||||
| GET | `/api/v1/documents` | 文档列表(limit/offset 分页) | 免登录 |
|
||||
| GET | `/api/v1/documents/{doc_id}` | 文档详情 | 免登录 |
|
||||
| DELETE | `/api/v1/documents/{doc_id}` | 删除文档(幂等) | Bearer |
|
||||
| POST | `/api/v1/auth/login` | 用户名密码登录,签发 session token(TTL 12h) | 免登录 |
|
||||
| POST | `/api/v1/auth/logout` | 退出登录(删除当前 session) | Bearer |
|
||||
| POST | `/api/v1/auth/password` | 修改自己的密码(must_change_password 用户唯一可用接口) | Bearer |
|
||||
| GET | `/api/v1/auth/me` | 当前登录用户信息(脱敏) | Bearer |
|
||||
| GET | `/api/v1/auth/users` | 用户列表(脱敏) | Bearer + admin |
|
||||
| POST | `/api/v1/auth/users` | 创建用户(重名/非法用户名/弱密码 1001) | Bearer + admin |
|
||||
| POST | `/api/v1/auth/users/{username}/password` | 重置指定用户密码(成功后清除其全部 session) | Bearer + admin |
|
||||
| DELETE | `/api/v1/auth/users/{username}` | 删除用户(清除其 session;禁删自己/最后一个 admin) | Bearer + admin |
|
||||
| GET | `/admin` | 管理页面 | 页面登录门禁 |
|
||||
|
||||
「Bearer」指请求头 `Authorization: Bearer <token>`,token 经 `/api/v1/auth/login` 获取;变更类文档端点(POST /documents、POST /documents/upload、DELETE /documents/{id})需 Bearer token(admin/user 角色均可),查询类端点免登录。
|
||||
|
||||
入库任务状态持久化在 Redis(key: `ingest_task:{task_id}`):进行中与 done 保留 24h,failed 保留 7 天;Redis 不可用时降级为纯内存。
|
||||
|
||||
## 管理页面
|
||||
|
||||
浏览器访问 `/admin`,单页面含概览、文档管理(列表/详情/删除)、文档入库、检索测试台、类目列表五个区块。
|
||||
浏览器访问 `/admin`,页面带登录门禁(未登录/token 失效自动回登录卡片;must_change_password 用户先强制改密后方可进入)。单页面含七个区块:概览、文档管理(列表/详情/删除)、文档入库(文本 + 文件上传)、检索测试台、类目列表、API 指南(端点清单 + 在线测试台)、用户管理(仅 admin 角色挂载,含创建/重置密码/删除)。
|
||||
|
||||
## 认证与用户
|
||||
|
||||
会话制认证:登录签发 session token(Redis 持久化,TTL 12h;Redis 不可用时降级为进程内存,重启失效),请求经 `Authorization: Bearer <token>` 携带,鉴权依赖见 `app/api/deps.py`。
|
||||
|
||||
- **角色与权限边界**: `admin` 拥有全部权限(含 /auth/users* 用户管理);`user` 可登录并调用变更类文档端点(入库/上传/删除),访问用户管理端点返回 1006
|
||||
- **初始 admin 引导**: 空库启动时 `bootstrap_admin` 自动创建 admin 账号,随机明文密码仅在启动日志中打印一次(must_change_password=true),首次登录后须先经 POST /auth/password 改密,改密前访问其他端点返回 1006
|
||||
- **免登录端点**: 查询类端点(POST /search、GET /documents*、GET /knowledge/*、GET /health)不需要 token
|
||||
- **相关错误码**: 1005 未认证或凭证无效,1006 权限不足/首次登录须先改密
|
||||
|
||||
## 编码规范
|
||||
|
||||
|
||||
Reference in New Issue
Block a user