135 lines
4.6 KiB
Python
135 lines
4.6 KiB
Python
"""Integration management endpoints."""
|
|
from typing import List
|
|
import secrets
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from app.core.database import get_db
|
|
from app.models.integration import Integration, IntegrationType, IntegrationStatus
|
|
from app.models.organization import OrganizationMember
|
|
from app.schemas.integration import IntegrationCreate, IntegrationRead, IntegrationUpdate
|
|
from app.api.deps import get_current_user, require_role
|
|
|
|
router = APIRouter()
|
|
|
|
@router.get("/", response_model=List[IntegrationRead])
|
|
async def list_integrations(
|
|
org_id: int,
|
|
member: OrganizationMember = Depends(require_role("analyst")),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""List integrations for organization."""
|
|
result = await db.execute(
|
|
select(Integration).where(Integration.organization_id == org_id)
|
|
)
|
|
return result.scalars().all()
|
|
|
|
@router.post("/", response_model=IntegrationRead, status_code=status.HTTP_201_CREATED)
|
|
async def create_integration(
|
|
org_id: int,
|
|
integration_in: IntegrationCreate,
|
|
member: OrganizationMember = Depends(require_role("admin")),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""Create a new integration."""
|
|
# Generate webhook secret
|
|
webhook_secret = secrets.token_hex(32)
|
|
|
|
integration = Integration(
|
|
organization_id=org_id,
|
|
name=integration_in.name,
|
|
type=integration_in.type,
|
|
base_url=integration_in.base_url,
|
|
api_key=integration_in.api_key,
|
|
webhook_secret=webhook_secret,
|
|
callback_url=integration_in.callback_url,
|
|
auto_analyze=integration_in.auto_analyze,
|
|
config=integration_in.config or {},
|
|
status=IntegrationStatus.ACTIVE
|
|
)
|
|
db.add(integration)
|
|
await db.commit()
|
|
await db.refresh(integration)
|
|
|
|
return integration
|
|
|
|
@router.get("/{integration_id}", response_model=IntegrationRead)
|
|
async def get_integration(
|
|
org_id: int,
|
|
integration_id: int,
|
|
member: OrganizationMember = Depends(require_role("analyst")),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""Get integration details."""
|
|
result = await db.execute(
|
|
select(Integration)
|
|
.where(Integration.id == integration_id)
|
|
.where(Integration.organization_id == org_id)
|
|
)
|
|
integration = result.scalar_one_or_none()
|
|
if not integration:
|
|
raise HTTPException(status_code=404, detail="Integration not found")
|
|
return integration
|
|
|
|
@router.patch("/{integration_id}", response_model=IntegrationRead)
|
|
async def update_integration(
|
|
org_id: int,
|
|
integration_id: int,
|
|
integration_update: IntegrationUpdate,
|
|
member: OrganizationMember = Depends(require_role("admin")),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""Update integration."""
|
|
result = await db.execute(
|
|
select(Integration)
|
|
.where(Integration.id == integration_id)
|
|
.where(Integration.organization_id == org_id)
|
|
)
|
|
integration = result.scalar_one_or_none()
|
|
if not integration:
|
|
raise HTTPException(status_code=404, detail="Integration not found")
|
|
|
|
for field, value in integration_update.dict(exclude_unset=True).items():
|
|
setattr(integration, field, value)
|
|
|
|
return integration
|
|
|
|
@router.delete("/{integration_id}", status_code=status.HTTP_204_NO_CONTENT)
|
|
async def delete_integration(
|
|
org_id: int,
|
|
integration_id: int,
|
|
member: OrganizationMember = Depends(require_role("admin")),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""Delete integration."""
|
|
result = await db.execute(
|
|
select(Integration)
|
|
.where(Integration.id == integration_id)
|
|
.where(Integration.organization_id == org_id)
|
|
)
|
|
integration = result.scalar_one_or_none()
|
|
if not integration:
|
|
raise HTTPException(status_code=404, detail="Integration not found")
|
|
|
|
await db.delete(integration)
|
|
|
|
@router.post("/{integration_id}/test")
|
|
async def test_integration(
|
|
org_id: int,
|
|
integration_id: int,
|
|
member: OrganizationMember = Depends(require_role("admin")),
|
|
db: AsyncSession = Depends(get_db)
|
|
):
|
|
"""Test integration connection."""
|
|
result = await db.execute(
|
|
select(Integration)
|
|
.where(Integration.id == integration_id)
|
|
.where(Integration.organization_id == org_id)
|
|
)
|
|
integration = result.scalar_one_or_none()
|
|
if not integration:
|
|
raise HTTPException(status_code=404, detail="Integration not found")
|
|
|
|
# TODO: Implement actual connection test based on integration type
|
|
return {"status": "ok", "message": "Connection successful"}
|