fix: use original session user for bridge callbacks instead of system user (RBAC)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
patrick-motsch 2026-02-13 17:26:56 +01:00
parent 77cbc5803a
commit 65128db713

View file

@ -363,11 +363,22 @@ async def bridgeStatusCallback(
logger.info(f"Bridge status callback: session={sessionId}, status={status}")
try:
# Update session status (bridge callbacks have no user context)
# Load the original user who started the session (has RBAC roles in mandate)
from modules.datamodels.datamodelUam import User
from modules.interfaces.interfaceDbApp import getRootInterface
systemUser = User(id="system", username="system", email="system@poweron.swiss")
interface = interfaceDb.getInterface(systemUser, featureInstanceId=instanceId)
# Look up original user from session for consistent context
session = interface.getSession(sessionId)
startedByUserId = session.get("startedByUserId") if session else None
if startedByUserId:
rootInterface = getRootInterface()
originalUser = rootInterface.getUser(startedByUserId)
if originalUser:
interface = interfaceDb.getInterface(originalUser, featureInstanceId=instanceId)
updates = {"status": status}
if errorMessage:
updates["errorMessage"] = errorMessage
@ -411,16 +422,27 @@ async def bridgeAudioWebsocket(
config = _getInstanceConfig(instanceId)
logger.info(f"Bridge audio WebSocket config loaded: session={sessionId}")
# Load the original user who started the session (has RBAC roles in mandate)
# Bridge callbacks have no HTTP auth, so we reconstruct the user context from the session record.
from modules.datamodels.datamodelUam import User
systemUser = User(id="system", username="system", email="system@poweron.swiss")
from modules.interfaces.interfaceDbApp import getRootInterface
# Look up mandateId from the session record (needed for AI billing context)
systemUser = User(id="system", username="system", email="system@poweron.swiss")
sessionInterface = interfaceDb.getInterface(systemUser, featureInstanceId=instanceId)
session = sessionInterface.getSession(sessionId)
mandateId = session.get("mandateId") if session else None
startedByUserId = session.get("startedByUserId") if session else None
service = TeamsbotService(systemUser, mandateId, instanceId, config)
logger.info(f"Bridge audio WebSocket service created: session={sessionId}, mandateId={mandateId}")
# Look up the original user (getRootInterface uses admin context, can load any user)
rootInterface = getRootInterface()
originalUser = rootInterface.getUser(startedByUserId) if startedByUserId else None
if not originalUser:
logger.warning(f"Could not load original user {startedByUserId}, falling back to system user")
originalUser = systemUser
service = TeamsbotService(originalUser, mandateId, instanceId, config)
logger.info(f"Bridge audio WebSocket service created: session={sessionId}, mandateId={mandateId}, user={originalUser.id}")
await service.handleAudioStream(websocket, sessionId)
except WebSocketDisconnect: