164 lines
No EOL
5.7 KiB
Python
164 lines
No EOL
5.7 KiB
Python
"""
|
|
Connection routes for the backend API.
|
|
Implements the endpoints for connection management.
|
|
"""
|
|
|
|
from fastapi import APIRouter, HTTPException, Depends, Body, Path, Request, Response
|
|
from typing import List, Dict, Any, Optional
|
|
from fastapi import status
|
|
from datetime import datetime
|
|
import logging
|
|
|
|
from modules.interfaces.serviceAppModel import User, UserConnection, AuthAuthority, ConnectionStatus
|
|
from modules.security.auth import getCurrentUser, limiter
|
|
from modules.interfaces.serviceAppClass import getInterface, getRootInterface
|
|
|
|
# Configure logger
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(
|
|
prefix="/api/connections",
|
|
tags=["Manage Connections"],
|
|
responses={404: {"description": "Not found"}}
|
|
)
|
|
|
|
@router.get("/", response_model=List[UserConnection])
|
|
@limiter.limit("30/minute")
|
|
async def get_connections(
|
|
request: Request,
|
|
currentUser: User = Depends(getCurrentUser)
|
|
) -> List[UserConnection]:
|
|
"""Get all connections for the current user or all connections if admin"""
|
|
try:
|
|
interface = getInterface(currentUser)
|
|
if currentUser.privilege in ['admin', 'sysadmin']:
|
|
# Admins can see all connections
|
|
users = interface.getAllUsers()
|
|
connections = []
|
|
for user in users:
|
|
connections.extend(user.connections)
|
|
return connections
|
|
else:
|
|
# Regular users can only see their own connections
|
|
return currentUser.connections
|
|
except Exception as e:
|
|
logger.error(f"Error getting connections: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f"Failed to get connections: {str(e)}"
|
|
)
|
|
|
|
@router.post("/{connectionId}/connect")
|
|
@limiter.limit("10/minute")
|
|
async def connect_service(
|
|
request: Request,
|
|
connectionId: str = Path(..., description="The ID of the connection to connect"),
|
|
currentUser: User = Depends(getCurrentUser)
|
|
) -> Dict[str, Any]:
|
|
"""Connect to an external service"""
|
|
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:
|
|
for conn in user.connections:
|
|
if conn.id == connectionId:
|
|
connection = conn
|
|
break
|
|
if connection:
|
|
break
|
|
else:
|
|
# Regular users can only connect their own connections
|
|
for conn in currentUser.connections:
|
|
if conn.id == connectionId:
|
|
connection = conn
|
|
break
|
|
|
|
if not connection:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Connection not found"
|
|
)
|
|
|
|
# Initiate OAuth flow with state=connect
|
|
auth_url = None
|
|
if connection.authority == AuthAuthority.MSFT:
|
|
auth_url = f"/api/msft/login?state=connect&connectionId={connectionId}"
|
|
elif connection.authority == AuthAuthority.GOOGLE:
|
|
auth_url = f"/api/google/login?state=connect&connectionId={connectionId}"
|
|
else:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_400_BAD_REQUEST,
|
|
detail=f"Unsupported authority: {connection.authority}"
|
|
)
|
|
|
|
return {"authUrl": auth_url}
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error connecting service: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f"Failed to connect service: {str(e)}"
|
|
)
|
|
|
|
@router.post("/{connectionId}/disconnect")
|
|
@limiter.limit("10/minute")
|
|
async def disconnect_service(
|
|
request: Request,
|
|
connectionId: str = Path(..., description="The ID of the connection to disconnect"),
|
|
currentUser: User = Depends(getCurrentUser)
|
|
) -> Dict[str, Any]:
|
|
"""Disconnect from an external service"""
|
|
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:
|
|
for conn in user.connections:
|
|
if conn.id == connectionId:
|
|
connection = conn
|
|
break
|
|
if connection:
|
|
break
|
|
else:
|
|
# Regular users can only disconnect their own connections
|
|
for conn in currentUser.connections:
|
|
if conn.id == connectionId:
|
|
connection = conn
|
|
break
|
|
|
|
if not connection:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="Connection not found"
|
|
)
|
|
|
|
# Update connection status
|
|
connection.status = ConnectionStatus.INACTIVE
|
|
connection.lastChecked = datetime.now()
|
|
|
|
# Update user record
|
|
interface.db.recordModify("users", connection.userId, {
|
|
"connections": [c.to_dict() for c in currentUser.connections]
|
|
})
|
|
|
|
return {"message": "Service disconnected successfully"}
|
|
|
|
except HTTPException:
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"Error disconnecting service: {str(e)}")
|
|
raise HTTPException(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
detail=f"Failed to disconnect service: {str(e)}"
|
|
) |