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:
+7
-11
@@ -10,12 +10,13 @@ import structlog
|
||||
from fastapi import APIRouter, Depends, File, Form, Query, UploadFile
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from app.api.deps import get_current_user
|
||||
from app.api.response import ApiError, ok
|
||||
from app.config import Settings, settings
|
||||
from app.core.auth import AuthUser, get_current_user, require_admin
|
||||
from app.core.file_parser import parse_file
|
||||
from app.core.ingest_tasks import IngestTaskManager
|
||||
from app.core.ingestion import Ingester
|
||||
from app.core.users import UserRecord
|
||||
from app.models.document import DocumentInput
|
||||
from app.services.qdrant import QdrantService
|
||||
from app.services.redis import RedisCache, get_cache
|
||||
@@ -74,7 +75,7 @@ def _allowed_extensions() -> set[str]:
|
||||
|
||||
@router.post("/documents")
|
||||
async def ingest_document(
|
||||
doc: DocumentInput, user: AuthUser = Depends(get_current_user)
|
||||
doc: DocumentInput, user: UserRecord = Depends(get_current_user)
|
||||
) -> JSONResponse:
|
||||
"""文档入库入口:登记异步任务并返回 202 + task_id,入库结果经任务查询端点获取"""
|
||||
if not doc.text.strip():
|
||||
@@ -95,7 +96,7 @@ async def upload_document(
|
||||
metadata: str = Form(
|
||||
default="", description='可选元数据 JSON 字符串,如 \'{"author":"x"}\''
|
||||
),
|
||||
user: AuthUser = Depends(get_current_user),
|
||||
user: UserRecord = Depends(get_current_user),
|
||||
) -> JSONResponse:
|
||||
"""文件上传入库入口:校验 → 提取文本 → 落盘 → 提交异步入库流水线
|
||||
|
||||
@@ -183,9 +184,7 @@ async def upload_document(
|
||||
|
||||
|
||||
@router.get("/documents/tasks/{task_id}")
|
||||
async def get_ingest_task(
|
||||
task_id: str, user: AuthUser = Depends(get_current_user)
|
||||
) -> dict[str, Any]:
|
||||
async def get_ingest_task(task_id: str) -> dict[str, Any]:
|
||||
"""查询入库任务状态:含 task_id/status/created_at/updated_at,done 附 result,failed 附 error"""
|
||||
task = await _get_task_manager().get(task_id)
|
||||
if task is None:
|
||||
@@ -197,7 +196,6 @@ async def get_ingest_task(
|
||||
async def list_documents(
|
||||
limit: int = Query(default=20, ge=1, le=100),
|
||||
offset: str | None = None,
|
||||
user: AuthUser = Depends(get_current_user),
|
||||
) -> dict[str, Any]:
|
||||
"""分页列出文档(L1 摘要),返回 items 与下一页游标 next_offset"""
|
||||
try:
|
||||
@@ -209,9 +207,7 @@ async def list_documents(
|
||||
|
||||
|
||||
@router.get("/documents/{doc_id}")
|
||||
async def get_document(
|
||||
doc_id: str, user: AuthUser = Depends(get_current_user)
|
||||
) -> dict[str, Any]:
|
||||
async def get_document(doc_id: str) -> dict[str, Any]:
|
||||
"""获取文档详情:L1 记录 + L2/L3 节点 + chunks 数量"""
|
||||
try:
|
||||
detail = await _get_qdrant().get_doc_detail(doc_id)
|
||||
@@ -225,7 +221,7 @@ async def get_document(
|
||||
|
||||
@router.delete("/documents/{doc_id}")
|
||||
async def delete_document(
|
||||
doc_id: str, user: AuthUser = Depends(require_admin)
|
||||
doc_id: str, user: UserRecord = Depends(get_current_user)
|
||||
) -> dict[str, Any]:
|
||||
"""删除文档:四层集合中该 doc_id 的所有点;幂等,不存在也返回成功(删除数全 0)"""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user