fix: revert to original _inject_user in main.py, ensure it runs before require_page

This commit is contained in:
Gan, Jimmy
2026-04-02 00:34:25 +08:00
parent ab5f824fea
commit 5cfb92cfc6
2 changed files with 15 additions and 18 deletions
+9 -4
View File
@@ -9,7 +9,7 @@ from slowapi.errors import RateLimitExceeded
from routers import docker_router, gitea, files, terminal, system, auth, chat_summary, security, passkey, totp, litellm, cc_connect, info_engine, opc_tasks, opc_agents, opc_ws, opc_projects from routers import docker_router, gitea, files, terminal, system, auth, chat_summary, security, passkey, totp, litellm, cc_connect, info_engine, opc_tasks, opc_agents, opc_ws, opc_projects
import auth as auth_module import auth as auth_module
import config import config
from rbac import require_page, _inject_user from rbac import require_page
import asyncio import asyncio
import httpx import httpx
@@ -164,6 +164,11 @@ def _router_reachable():
except Exception: except Exception:
return False return False
# Dependency to store user in request.state for rbac dependencies
async def _inject_user(request: Request, user = Depends(auth_module.get_current_user)):
request.state.user = user
return user
# Public auth endpoints # Public auth endpoints
app.include_router(auth.router, prefix="/api/auth", tags=["auth"]) app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
app.include_router(passkey.router, prefix="/api/auth", tags=["passkey"]) app.include_router(passkey.router, prefix="/api/auth", tags=["passkey"])
@@ -191,11 +196,11 @@ app.include_router(security.router, prefix="/api/security",
# OPC endpoints # OPC endpoints
app.include_router(opc_tasks.router, prefix="/api/opc", app.include_router(opc_tasks.router, prefix="/api/opc",
dependencies=[Depends(require_page("opc"))]) dependencies=[Depends(_inject_user), Depends(require_page("opc"))])
app.include_router(opc_agents.router, prefix="/api/opc", app.include_router(opc_agents.router, prefix="/api/opc",
dependencies=[Depends(require_page("opc"))]) dependencies=[Depends(_inject_user), Depends(require_page("opc"))])
app.include_router(opc_projects.router, prefix="/api/opc", app.include_router(opc_projects.router, prefix="/api/opc",
dependencies=[Depends(require_page("opc"))]) dependencies=[Depends(_inject_user), Depends(require_page("opc"))])
# WebSocket endpoint (auth handled inside handler via auth cookie; query token fallback temporary) # WebSocket endpoint (auth handled inside handler via auth cookie; query token fallback temporary)
app.add_api_websocket_route("/ws/terminal", terminal.ws_endpoint) app.add_api_websocket_route("/ws/terminal", terminal.ws_endpoint)
+6 -14
View File
@@ -115,7 +115,8 @@ def has_page_access(user: User, page: str) -> bool:
def require_page(page: str): def require_page(page: str):
"""FastAPI dependency factory — 403 if user lacks page access.""" """FastAPI dependency factory — 403 if user lacks page access."""
async def checker(user: User = Depends(_inject_user)): async def checker(request: Request):
user: User = request.state.user
if not has_page_access(user, page): if not has_page_access(user, page):
raise HTTPException(status_code=403, detail="Access denied") raise HTTPException(status_code=403, detail="Access denied")
return checker return checker
@@ -123,7 +124,8 @@ def require_page(page: str):
def require_admin(): def require_admin():
"""FastAPI dependency — 403 if user is not admin.""" """FastAPI dependency — 403 if user is not admin."""
async def checker(user: User = Depends(_inject_user)): async def checker(request: Request):
user: User = request.state.user
if user.role != "admin": if user.role != "admin":
raise HTTPException(status_code=403, detail="Admin only") raise HTTPException(status_code=403, detail="Admin only")
return checker return checker
@@ -131,18 +133,8 @@ def require_admin():
def require_write(): def require_write():
"""FastAPI dependency — 403 if viewer tries non-GET method.""" """FastAPI dependency — 403 if viewer tries non-GET method."""
async def checker(request: Request, user: User = Depends(_inject_user)): async def checker(request: Request):
user: User = request.state.user
if user.role == "viewer" and request.method != "GET": if user.role == "viewer" and request.method != "GET":
raise HTTPException(status_code=403, detail="Read-only access") raise HTTPException(status_code=403, detail="Read-only access")
return checker return checker
async def _inject_user(request: Request):
"""Dependency to store user in request.state for rbac dependencies.
Import auth module at runtime to avoid circular imports.
"""
import auth as auth_module
user = await auth_module.get_current_user(request)
request.state.user = user
return user