forked from xiaohei/taiji-AI-PAD
fix(mcp-server): correct Heicode user-models endpoint + username predcheck
Two small follow-ups to the register hardening + Heicode P4 work:
1. heicode_client.list_user_models: the path `/api/user/{id}/models`
prescribed in §7.11.2 returns 404 `Invalid URL` on the live Heicode
NewAPI — that path is not registered on their router. Switched to
`/api/user/models` (no path segment), which Heicode binds to the
`New-Api-User: 26` admin header. End-to-end P4 smoke now 4/4 with
user 55@55.com (id=2 on Heicode): /balance /models /usage /logs.
Future: if Heicode ships an "admin-replaces-user" path, switch back
and pass the actual heicode_user_id.
2. routes/auth.register: previously line-744 SELECT only checked
req.username, but line 778 falls back to email.split("@")[0] when
blank — so two users registering with alice@foo.com and alice@bar.com
would both clear the predcheck, then the second would IntegrityError
on flush. Now predcheck uses `effective_username` matching what'll
actually be inserted.
Also append §7.15 to Heicode-对接进度与待办.md:
- 4-item agent-manager / Vault / Workload-Identity audit results
- §7.13 token rotation acknowledgement
- P4 end-to-end first-pass results
- This-session internal security hardening summary
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -192,14 +192,28 @@ class HeicodeNewAPIClient:
|
||||
self, heicode_user_id: int,
|
||||
request_id: Optional[str] = None,
|
||||
) -> List[Any]:
|
||||
"""GET /api/user/{id}/models — 按用户 id 列出该用户可用模型清单。
|
||||
"""GET /api/user/models — 当前 token 持有人视角的可用模型列表。
|
||||
|
||||
修订(2026-05-08,按 Heicode §7.11.2):原 `/api/models` 是渠道仪表盘
|
||||
视角(key 是 channelId),mcp-server-service 没渠道,自然空。改用
|
||||
`/api/user/{id}/models`(admin 替指定用户查),返回 string[]。
|
||||
修订历史:
|
||||
- 原 `/api/models` 是 channel-dashboard 视角(key=channelId),
|
||||
admin user 没渠道返回空,废弃。
|
||||
- §7.11.2 曾改用 `/api/user/{id}/models`(admin 替指定用户查),
|
||||
但 2026-05-12 实测 Heicode NewAPI 返回 404 `Invalid URL`,
|
||||
该 path 在他们的 router 上根本没注册。
|
||||
- 现切换到 `/api/user/models`(不带 user_id 段)。NewAPI 用
|
||||
`New-Api-User` header(必须 == admin token 持有人 id,否则
|
||||
CSRF check 拒绝)确定视角,返回 admin 视角的全量 model 列表。
|
||||
后续 Heicode 那边如果上线"用户视角"接口,可以改回 path 段方案。
|
||||
|
||||
注意:当前实现下,所有 mcp-server 透传的用户拿到的是 admin(user 26)
|
||||
视角的 models,即 NewAPI 全量。如果 Heicode 引入 group/channel 级
|
||||
模型过滤,需要 Heicode 团队提供 `admin-replaces-user` 路由我方再切。
|
||||
"""
|
||||
# heicode_user_id 当前未直接使用 —— 仅做调试日志参考,将来如果 Heicode
|
||||
# 上线 admin-replaces-user 路径会用到。保留参数避免上游 caller 改签名。
|
||||
_ = heicode_user_id
|
||||
body = await self._get(
|
||||
f"/api/user/{heicode_user_id}/models",
|
||||
"/api/user/models",
|
||||
request_id=request_id,
|
||||
)
|
||||
data = body.get("data") if isinstance(body, dict) else body
|
||||
|
||||
@@ -740,8 +740,12 @@ async def register(req: UserCreate, db: AsyncSession = Depends(get_db)):
|
||||
detail="该邮箱已被注册"
|
||||
)
|
||||
|
||||
# 2. 检查用户名是否已存在(username 是必填字段)
|
||||
result = await db.execute(select(User).where(User.username == req.username))
|
||||
# 2. 检查用户名是否已存在
|
||||
# 注意:line 778 处会用 `req.username or req.email.split("@")[0]` 兜底,
|
||||
# 所以预检必须按真实写入的 username 来查,否则 fallback 出来的 alice
|
||||
# 没经预检,在 line 797 flush 才暴露 IntegrityError。
|
||||
effective_username = (req.username or "").strip() or req.email.split("@")[0]
|
||||
result = await db.execute(select(User).where(User.username == effective_username))
|
||||
existing_username = result.scalar_one_or_none()
|
||||
if existing_username:
|
||||
raise HTTPException(
|
||||
|
||||
Reference in New Issue
Block a user