fixed connections access
This commit is contained in:
parent
33adccf87d
commit
1b59810e0d
4 changed files with 91 additions and 84 deletions
|
|
@ -89,6 +89,11 @@ async def createActionDefinitionPrompt(context, service) -> str:
|
|||
docRefs = service.getDocumentReferenceList()
|
||||
connRefs = service.getConnectionReferenceList()
|
||||
|
||||
# Debug logging for connections
|
||||
logging.debug(f"Connection references retrieved: {connRefs}")
|
||||
logging.debug(f"Connection references type: {type(connRefs)}")
|
||||
logging.debug(f"Connection references length: {len(connRefs) if connRefs else 0}")
|
||||
|
||||
# Get documents from current round (chat) and entire workflow history
|
||||
current_round_docs = docRefs.get('chat', [])
|
||||
workflow_history_docs = docRefs.get('history', [])
|
||||
|
|
|
|||
|
|
@ -443,12 +443,23 @@ class ServiceCenter:
|
|||
"""Get list of all UserConnection objects as references with enhanced state information"""
|
||||
connections = []
|
||||
# Get user connections through AppObjects interface
|
||||
logger.debug(f"getConnectionReferenceList: Service center user ID: {self.user.id}")
|
||||
logger.debug(f"getConnectionReferenceList: Service center user type: {type(self.user)}")
|
||||
logger.debug(f"getConnectionReferenceList: Service center user object: {self.user}")
|
||||
|
||||
user_connections = self.interfaceApp.getUserConnections(self.user.id)
|
||||
logger.debug(f"getConnectionReferenceList: User ID: {self.user.id}")
|
||||
logger.debug(f"getConnectionReferenceList: Raw user connections: {user_connections}")
|
||||
logger.debug(f"getConnectionReferenceList: User connections type: {type(user_connections)}")
|
||||
logger.debug(f"getConnectionReferenceList: User connections length: {len(user_connections) if user_connections else 0}")
|
||||
|
||||
for conn in user_connections:
|
||||
# Get enhanced connection reference with state information
|
||||
enhanced_ref = self.getConnectionReferenceFromUserConnection(conn)
|
||||
logger.debug(f"getConnectionReferenceList: Enhanced ref for connection {conn.id}: {enhanced_ref}")
|
||||
connections.append(enhanced_ref)
|
||||
# Sort by connection reference
|
||||
logger.debug(f"getConnectionReferenceList: Final connections list: {connections}")
|
||||
return sorted(connections)
|
||||
|
||||
def getConnectionReferenceFromUserConnection(self, connection: UserConnection) -> str:
|
||||
|
|
@ -461,6 +472,8 @@ class ServiceCenter:
|
|||
if token:
|
||||
if hasattr(token, 'expiresAt') and token.expiresAt:
|
||||
current_time = get_utc_timestamp()
|
||||
logger.debug(f"getConnectionReferenceFromUserConnection: Current time: {current_time}")
|
||||
logger.debug(f"getConnectionReferenceFromUserConnection: Token expires at: {token.expiresAt}")
|
||||
if current_time > token.expiresAt:
|
||||
token_status = "expired"
|
||||
else:
|
||||
|
|
@ -476,6 +489,7 @@ class ServiceCenter:
|
|||
base_ref = f"connection:{connection.authority.value}:{connection.externalUsername}:{connection.id}"
|
||||
state_info = f" [status:{connection.status.value}, token:{token_status}]"
|
||||
|
||||
logger.debug(f"getConnectionReferenceFromUserConnection: Built reference: {base_ref + state_info}")
|
||||
return base_ref + state_info
|
||||
|
||||
def getUserConnectionFromConnectionReference(self, connectionReference: str) -> Optional[UserConnection]:
|
||||
|
|
|
|||
|
|
@ -277,13 +277,21 @@ class AppObjects:
|
|||
def getUserConnections(self, userId: str) -> List[UserConnection]:
|
||||
"""Returns all connections for a user."""
|
||||
try:
|
||||
logger.debug(f"getUserConnections: Looking for connections for user ID: {userId}")
|
||||
logger.debug(f"getUserConnections: Current database context userId: {self.db.userId}")
|
||||
logger.debug(f"getUserConnections: Current interface userId: {self.userId}")
|
||||
|
||||
# Get connections for this user
|
||||
connections = self.db.getRecordset("connections", recordFilter={"userId": userId})
|
||||
logger.debug(f"getUserConnections: Raw database connections: {connections}")
|
||||
logger.debug(f"getUserConnections: Database connections type: {type(connections)}")
|
||||
logger.debug(f"getUserConnections: Database connections length: {len(connections) if connections else 0}")
|
||||
|
||||
# Convert to UserConnection objects
|
||||
result = []
|
||||
for conn_dict in connections:
|
||||
try:
|
||||
logger.debug(f"getUserConnections: Processing connection dict: {conn_dict}")
|
||||
# Create UserConnection object
|
||||
connection = UserConnection(
|
||||
id=conn_dict["id"],
|
||||
|
|
@ -297,11 +305,13 @@ class AppObjects:
|
|||
lastChecked=conn_dict.get("lastChecked"),
|
||||
expiresAt=conn_dict.get("expiresAt")
|
||||
)
|
||||
logger.debug(f"getUserConnections: Created UserConnection object: {connection}")
|
||||
result.append(connection)
|
||||
except Exception as e:
|
||||
logger.error(f"Error converting connection dict to object: {str(e)}")
|
||||
continue
|
||||
|
||||
logger.debug(f"getUserConnections: Final result: {result}")
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
"""
|
||||
Connection routes for the backend API.
|
||||
Implements the endpoints for connection management.
|
||||
|
||||
SECURITY NOTE:
|
||||
- Regular connections endpoint (/api/connections/) only returns connections for the current user
|
||||
- Admin endpoint (/api/connections/admin/all) provides access to all connections for management purposes
|
||||
- This prevents security vulnerabilities where admin users could see other users' connections
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Depends, Body, Path, Request, Response
|
||||
|
|
@ -30,23 +35,20 @@ async def get_connections(
|
|||
request: Request,
|
||||
currentUser: User = Depends(getCurrentUser)
|
||||
) -> List[UserConnection]:
|
||||
"""Get all connections for the current user or all connections if admin"""
|
||||
"""Get all connections for the current user
|
||||
|
||||
SECURITY: This endpoint is secure - users can only see their own connections.
|
||||
"""
|
||||
try:
|
||||
interface = getInterface(currentUser)
|
||||
|
||||
# Clear connections cache to ensure fresh data
|
||||
interface.db.clearTableCache("connections")
|
||||
|
||||
if currentUser.privilege in ['admin', 'sysadmin']:
|
||||
# Admins can see all connections
|
||||
users = interface.getAllUsers()
|
||||
connections = []
|
||||
for user in users:
|
||||
connections.extend(interface.getUserConnections(user.id))
|
||||
return connections
|
||||
else:
|
||||
# Regular users can only see their own connections
|
||||
return interface.getUserConnections(currentUser.id)
|
||||
# SECURITY FIX: All users (including admins) can only see their own connections
|
||||
# This prevents admin from seeing other users' connections and causing confusion
|
||||
return interface.getUserConnections(currentUser.id)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting connections: {str(e)}")
|
||||
raise HTTPException(
|
||||
|
|
@ -61,6 +63,11 @@ async def create_connection(
|
|||
connection_data: Dict[str, Any] = Body(...),
|
||||
currentUser: User = Depends(getCurrentUser)
|
||||
) -> UserConnection:
|
||||
"""Create a new connection for the current user
|
||||
|
||||
SECURITY: This endpoint is secure - it always creates connections for the current user
|
||||
and cannot be used to create connections for other users.
|
||||
"""
|
||||
|
||||
try:
|
||||
interface = getInterface(currentUser)
|
||||
|
|
@ -120,30 +127,22 @@ async def update_connection(
|
|||
connection_data: Dict[str, Any] = Body(...),
|
||||
currentUser: User = Depends(getCurrentUser)
|
||||
) -> UserConnection:
|
||||
"""Update an existing connection"""
|
||||
"""Update an existing connection for the current user
|
||||
|
||||
SECURITY: This endpoint is secure - users can only update their own connections.
|
||||
"""
|
||||
try:
|
||||
interface = getInterface(currentUser)
|
||||
|
||||
# Find the connection
|
||||
connection = None
|
||||
if currentUser.privilege in ['admin', 'sysadmin']:
|
||||
# Admins can update any connection
|
||||
users = interface.getAllUsers()
|
||||
for user in users:
|
||||
connections = interface.getUserConnections(user.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
if connection:
|
||||
break
|
||||
else:
|
||||
# Regular users can only update their own connections
|
||||
connections = interface.getUserConnections(currentUser.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
# SECURITY FIX: All users (including admins) can only update their own connections
|
||||
# This prevents admin from updating other users' connections and causing confusion
|
||||
connections = interface.getUserConnections(currentUser.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
|
||||
if not connection:
|
||||
raise HTTPException(
|
||||
|
|
@ -184,30 +183,23 @@ async def connect_service(
|
|||
connectionId: str = Path(..., description="The ID of the connection to connect"),
|
||||
currentUser: User = Depends(getCurrentUser)
|
||||
) -> Dict[str, Any]:
|
||||
"""Connect a service for the current user
|
||||
|
||||
SECURITY: This endpoint is secure - users can only connect their own connections.
|
||||
"""
|
||||
|
||||
try:
|
||||
interface = getInterface(currentUser)
|
||||
|
||||
# Find the connection
|
||||
connection = None
|
||||
if currentUser.privilege in ['admin', 'sysadmin']:
|
||||
# Admins can connect any connection
|
||||
users = interface.getAllUsers()
|
||||
for user in users:
|
||||
connections = interface.getUserConnections(user.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
if connection:
|
||||
break
|
||||
else:
|
||||
# Regular users can only connect their own connections
|
||||
connections = interface.getUserConnections(currentUser.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
# SECURITY FIX: All users (including admins) can only connect their own connections
|
||||
# This prevents admin from connecting other users' connections and causing confusion
|
||||
connections = interface.getUserConnections(currentUser.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
|
||||
if not connection:
|
||||
raise HTTPException(
|
||||
|
|
@ -257,30 +249,23 @@ async def disconnect_service(
|
|||
connectionId: str = Path(..., description="The ID of the connection to disconnect"),
|
||||
currentUser: User = Depends(getCurrentUser)
|
||||
) -> Dict[str, Any]:
|
||||
"""Disconnect a service for the current user
|
||||
|
||||
SECURITY: This endpoint is secure - users can only disconnect their own connections.
|
||||
"""
|
||||
|
||||
try:
|
||||
interface = getInterface(currentUser)
|
||||
|
||||
# Find the connection
|
||||
connection = None
|
||||
if currentUser.privilege in ['admin', 'sysadmin']:
|
||||
# Admins can disconnect any connection
|
||||
users = interface.getAllUsers()
|
||||
for user in users:
|
||||
connections = interface.getUserConnections(user.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
if connection:
|
||||
break
|
||||
else:
|
||||
# Regular users can only disconnect their own connections
|
||||
connections = interface.getUserConnections(currentUser.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
# SECURITY FIX: All users (including admins) can only disconnect their own connections
|
||||
# This prevents admin from disconnecting other users' connections and causing confusion
|
||||
connections = interface.getUserConnections(currentUser.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
|
||||
if not connection:
|
||||
raise HTTPException(
|
||||
|
|
@ -316,30 +301,23 @@ async def delete_connection(
|
|||
connectionId: str = Path(..., description="The ID of the connection to delete"),
|
||||
currentUser: User = Depends(getCurrentUser)
|
||||
) -> Dict[str, Any]:
|
||||
"""Delete a connection for the current user
|
||||
|
||||
SECURITY: This endpoint is secure - users can only delete their own connections.
|
||||
"""
|
||||
|
||||
try:
|
||||
interface = getInterface(currentUser)
|
||||
|
||||
# Find the connection
|
||||
connection = None
|
||||
if currentUser.privilege in ['admin', 'sysadmin']:
|
||||
# Admins can delete any connection
|
||||
users = interface.getAllUsers()
|
||||
for user in users:
|
||||
connections = interface.getUserConnections(user.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
if connection:
|
||||
break
|
||||
else:
|
||||
# Regular users can only delete their own connections
|
||||
connections = interface.getUserConnections(currentUser.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
# SECURITY FIX: All users (including admins) can only delete their own connections
|
||||
# This prevents admin from deleting other users' connections and causing confusion
|
||||
connections = interface.getUserConnections(currentUser.id)
|
||||
for conn in connections:
|
||||
if conn.id == connectionId:
|
||||
connection = conn
|
||||
break
|
||||
|
||||
if not connection:
|
||||
raise HTTPException(
|
||||
|
|
|
|||
Loading…
Reference in a new issue