Commit Graph
4 Commits
Author SHA1 Message Date
snowy-yang cd0f1f78a3 refactor: 迁移收尾(管理员2FA)+ 抽取公共工具层,消除 router 间重复
补齐最后缺口:
- POST /api/v1/auth/admin_login/email、/auth/admin_login/verify(管理员 2FA Step2/3),
  复用 auth_routes 的票据表与尝试上限(跨栈共享),签发会话 Cookie

重构(消除约 200 行重复,11 个 router 受益):
- web/request_utils.py:request_data / safe_int / extract_id / cookies / dedup_ids
  原在各 router 各复制一份,现集中
- web/serializers.py:format_credits / user_public / record_req_log
- 各 router 改为导入别名,行为逐字不变

覆盖率:Flask 90 条业务路由全部有 FastAPI 等价端点(含 5 个向后兼容别名)。
验证:pytest 69/69;ruff All checks passed;pyright 0 errors;奇偶 36/36;冒烟 10/10。
2026-09-26 10:20:46 +08:00
snowy-yang 6c3181341b feat(routes): 迁移账号/全局歌单端点 + 鉴权依赖测试
迁移路由(/api/v1/*,与 Flask 同端点逐字段对齐):
- account/vip:admin/user 双路径 + 5 分钟缓存(降级结果 30s),
  VIP 探测单飞锁与 Flask 同源跨栈共享;未登录可访问(同 Flask)
- global/playlists、global/playlist:管理员闸(require_admin,403 对齐)
- web/deps.py 新增 require_admin;_resolve_user_cookies 支持可选用户(匿名审计保底)

测试:46/46(新增 10 项鉴权依赖:有效/管理员/封禁/禁用/顶号/伪造 Cookie、
401/403 闸);ruff All checks passed;pyright 0 errors。

契约奇偶校验:16 项全 OK(新增 account:vip、global:playlists/playlist、
非管理员 403);uvicorn 实跑双栈 account/vip 均 200、未授权歌单 403。
2026-09-26 01:15:22 +08:00
snowy-yang a2758aa0da feat(routes): 迁移解析端点 /song /playlist /album + 响应卫生中间件
迁移路由(/api/v1/*,与 Flask 同端点逐字段对齐):
- song(type: url/name/lyric/json)、playlist、album
  个人账号路径实现全局账号冒用拦截(同 Flask 口径);json 模式 asyncio.gather 并发
  song/url/lyric(歌词失败不阻断,与 Flask 线程池语义一致)
- core/media.py:format_file_size/quality_display_name/parse_cookie_str 纯函数复用

web/middleware.py(镜像 Flask after_request):
- 音频直链 → HMAC 签名代理地址(密钥同源,两栈 token 互认)
- 安全头 nosniff/DENY/Referrer-Policy/CSP 基线;Server 抹为 NeteaseUrl;429 带 Retry-After
- 纯 ASGI 逐段转发(不破坏流式下载);JSON 200 延迟 start 并**重算 Content-Length**
  ——修实测 IncompleteRead(原实现转发旧长度 + 新 body)

契约奇偶校验:12 项全 OK(新增 album/playlist/song×3);
token/CDN 主机归一化(均为易变值,非契约漂移)。

验证:pytest 36/36;ruff All checks passed;pyright 0 errors;
uvicorn 实跑 /api/v1/song 直链已代理、CSP/Server 头正确。
2026-09-26 01:12:54 +08:00
snowy-yang 2c55b55e03 feat(routes): 迁移查询类路由到 FastAPI + 会话互通 + 统一错误/限流
会话互通(迁移关键):
- core/session.py:itsdangerous 兼容的签名 Cookie 编解码(同密钥/同 salt/同
  时间戳编码),Flask 与 FastAPI 双向可读——实测 F->core 与 core->F 双向解出一致,
  篡改/错密钥返回 None

FastAPI 基础设施:
- web/deps.py    会话→当前用户(封禁/顶号校验,口径同 auth_system.current_user)
- web/errors.py  AppError + 全局异常处理,404/405/400 统一为本站包体
- web/ratelimit.py 复用 core.state 同一批限流桶(跨栈共享,避免绕框架绕过限流)
- core/repo.py  补 get_user_by_id(异步)

迁移路由(/api/v1/*,与 Flask 同端点逐字段对齐):
- toplist / artist_songs / comments / search,走 music_api 异步方法
- search 的服务器昵称遮蔽改为 FastAPI 侧异步实现(不再依赖 main)

契约奇偶校验:扩展至 7 项(含登录会话互通 + 未登录 401),全 OK;
CDN 分片主机差异归一化(上游易变值,非契约漂移)。

验证:pytest 33/33;ruff All checks passed;pyright 0 errors;
uvicorn 实跑未登录 401 包体与 Flask 一致。
2026-09-26 01:09:01 +08:00