fix: make RBAC dependencies properly chain _inject_user for OPC authorization
This commit is contained in:
@@ -196,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(_inject_user), Depends(require_page("opc"))])
|
dependencies=[Depends(require_page("opc"))])
|
||||||
app.include_router(opc_agents.router, prefix="/api/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",
|
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)
|
# 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)
|
||||||
|
|||||||
@@ -115,8 +115,7 @@ 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(request: Request):
|
async def checker(user: User = Depends(_inject_user)):
|
||||||
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
|
||||||
@@ -124,8 +123,7 @@ 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(request: Request):
|
async def checker(user: User = Depends(_inject_user)):
|
||||||
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
|
||||||
@@ -133,8 +131,7 @@ 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):
|
async def checker(request: Request, user: User = Depends(_inject_user)):
|
||||||
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
|
||||||
|
|||||||
@@ -159,7 +159,9 @@ async def proxy_auth(request: Request, response: Response):
|
|||||||
remote_groups_raw = request.headers.get("Remote-Groups", "")
|
remote_groups_raw = request.headers.get("Remote-Groups", "")
|
||||||
groups = [g.strip() for g in remote_groups_raw.split(",") if g.strip()]
|
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)
|
role = resolve_role(groups)
|
||||||
|
logger.info(f"Resolved role: {role}")
|
||||||
if role is None:
|
if role is None:
|
||||||
logger.warning(f"User {remote_user} has no dashboard role (groups: {groups})")
|
logger.warning(f"User {remote_user} has no dashboard role (groups: {groups})")
|
||||||
raise HTTPException(status_code=403, detail="User not authorized for dashboard")
|
raise HTTPException(status_code=403, detail="User not authorized for dashboard")
|
||||||
|
|||||||
Reference in New Issue
Block a user