mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-06-18 13:46:02 +00:00
fix(channels): harden runtime credential management APIs (#3581)
* fix(channels): harden runtime credential management APIs * fix(channels): address review feedback on credential hardening Follow-up to the runtime credential-hardening pass, resolving five review findings: - WeChat auth persistence now writes through a 0o600 NamedTemporaryFile + Path.replace instead of write_text-then-chmod, so the iLink bot_token is never briefly readable at umask defaults (mirrors ChannelRuntimeConfigStore). - The post-write chmod is split into its own try/except: a chmod failure on a filesystem without POSIX perms now logs at debug instead of masquerading as a "failed to persist" warning. - Extracted the three near-identical _require_admin_user helpers (mcp, channel_connections, channels) into a single require_admin_user(request, *, detail) in app/gateway/deps.py; each router supplies its own detail string. - Strengthened the runtime-config-store chmod coverage: a new test injects a temp-file chmod failure and asserts it is logged at debug while the destination is still owner-only (mutation-verified to fail if the chmod is dropped), plus a loose-pre-existing-file case. - Removed the unused _FakeRepo from the blocking-io test: its isinstance gate routes through the repo-less 503 path, so neither stub was ever invoked. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
This commit is contained in:
@@ -377,6 +377,28 @@ async def get_current_user_from_request(request: Request):
|
||||
return user
|
||||
|
||||
|
||||
async def require_admin_user(request: Request, *, detail: str) -> None:
|
||||
"""Require the authenticated caller to be an admin user.
|
||||
|
||||
``AuthMiddleware`` normally stamps ``request.state.user`` before the request
|
||||
reaches a router. Falling back to the strict dependency keeps the route safe
|
||||
in tests or alternative ASGI compositions that mount a router without the
|
||||
global middleware. ``detail`` is the route-specific 403 message.
|
||||
|
||||
Centralising this here means a future change to the admin definition (e.g.
|
||||
allowing an internal system role, adding audit logging, or switching to a
|
||||
permission-based check) lands in one place instead of drifting across the
|
||||
per-router copies that previously existed in ``mcp``, ``channel_connections``
|
||||
and ``channels``.
|
||||
"""
|
||||
user = getattr(request.state, "user", None)
|
||||
if user is None:
|
||||
user = await get_current_user_from_request(request)
|
||||
|
||||
if getattr(user, "system_role", None) != "admin":
|
||||
raise HTTPException(status_code=403, detail=detail)
|
||||
|
||||
|
||||
async def get_optional_user_from_request(request: Request):
|
||||
"""Get optional authenticated user from request.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user