From e46003711b683a0a6075f0e7024b9788eb40bfb4 Mon Sep 17 00:00:00 2001 From: "Gan, Jimmy" Date: Thu, 2 Apr 2026 00:25:32 +0800 Subject: [PATCH] fix: make RBAC dependencies properly chain _inject_user for OPC authorization --- dashboard/backend/main.py | 6 +++--- dashboard/backend/rbac.py | 9 +++------ dashboard/backend/routers/auth.py | 2 ++ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/dashboard/backend/main.py b/dashboard/backend/main.py index 607c391..df9ff08 100644 --- a/dashboard/backend/main.py +++ b/dashboard/backend/main.py @@ -196,11 +196,11 @@ app.include_router(security.router, prefix="/api/security", # OPC endpoints app.include_router(opc_tasks.router, prefix="/api/opc", - dependencies=[Depends(_inject_user), Depends(require_page("opc"))]) + dependencies=[Depends(require_page("opc"))]) app.include_router(opc_agents.router, prefix="/api/opc", - dependencies=[Depends(_inject_user), Depends(require_page("opc"))]) + dependencies=[Depends(require_page("opc"))]) app.include_router(opc_projects.router, prefix="/api/opc", - dependencies=[Depends(_inject_user), Depends(require_page("opc"))]) + dependencies=[Depends(require_page("opc"))]) # WebSocket endpoint (auth handled inside handler via auth cookie; query token fallback temporary) app.add_api_websocket_route("/ws/terminal", terminal.ws_endpoint) diff --git a/dashboard/backend/rbac.py b/dashboard/backend/rbac.py index 203567e..526d91a 100644 --- a/dashboard/backend/rbac.py +++ b/dashboard/backend/rbac.py @@ -115,8 +115,7 @@ def has_page_access(user: User, page: str) -> bool: def require_page(page: str): """FastAPI dependency factory — 403 if user lacks page access.""" - async def checker(request: Request): - user: User = request.state.user + async def checker(user: User = Depends(_inject_user)): if not has_page_access(user, page): raise HTTPException(status_code=403, detail="Access denied") return checker @@ -124,8 +123,7 @@ def require_page(page: str): def require_admin(): """FastAPI dependency — 403 if user is not admin.""" - async def checker(request: Request): - user: User = request.state.user + async def checker(user: User = Depends(_inject_user)): if user.role != "admin": raise HTTPException(status_code=403, detail="Admin only") return checker @@ -133,8 +131,7 @@ def require_admin(): def require_write(): """FastAPI dependency — 403 if viewer tries non-GET method.""" - async def checker(request: Request): - user: User = request.state.user + async def checker(request: Request, user: User = Depends(_inject_user)): if user.role == "viewer" and request.method != "GET": raise HTTPException(status_code=403, detail="Read-only access") return checker diff --git a/dashboard/backend/routers/auth.py b/dashboard/backend/routers/auth.py index 8a7cb52..d2c5f49 100644 --- a/dashboard/backend/routers/auth.py +++ b/dashboard/backend/routers/auth.py @@ -159,7 +159,9 @@ async def proxy_auth(request: Request, response: Response): remote_groups_raw = request.headers.get("Remote-Groups", "") groups = [g.strip() for g in remote_groups_raw.split(",") if g.strip()] + logger.info(f"Proxy auth: user={remote_user}, groups={groups}") role = resolve_role(groups) + logger.info(f"Resolved role: {role}") if role is None: logger.warning(f"User {remote_user} has no dashboard role (groups: {groups})") raise HTTPException(status_code=403, detail="User not authorized for dashboard")