dograh/api/routes/organization.py
Abhishek 8e2e5c9327
feat: Enable telephony for OSS (#21)
* fix: fix tooltip bug

* feat: add Twilio with CloudFlare configuration

* chore: update Tella Video
2025-10-04 12:22:50 +05:30

85 lines
3.4 KiB
Python

from fastapi import APIRouter, Depends, HTTPException
from api.db import db_client
from api.db.models import UserModel
from api.enums import OrganizationConfigurationKey
from api.schemas.telephony_config import (
TelephonyConfigurationResponse,
TwilioConfigurationRequest,
TwilioConfigurationResponse,
)
from api.services.auth.depends import get_user
from api.services.configuration.masking import is_mask_of, mask_key
router = APIRouter(prefix="/organizations", tags=["organizations"])
@router.get("/telephony-config", response_model=TelephonyConfigurationResponse)
async def get_telephony_configuration(user: UserModel = Depends(get_user)):
"""Get telephony configuration for the user's organization with masked sensitive fields."""
if not user.selected_organization_id:
raise HTTPException(status_code=400, detail="No organization selected")
config = await db_client.get_configuration(
user.selected_organization_id,
OrganizationConfigurationKey.TWILIO_CONFIGURATION.value,
)
if not config or not config.value:
return TelephonyConfigurationResponse(twilio=None)
# Mask sensitive fields (account_sid and auth_token) before returning
account_sid = config.value.get("account_sid", "")
auth_token = config.value.get("auth_token", "")
return TelephonyConfigurationResponse(
twilio=TwilioConfigurationResponse(
provider="twilio",
account_sid=mask_key(account_sid) if account_sid else "",
auth_token=mask_key(auth_token) if auth_token else "",
from_numbers=config.value.get("from_numbers", []),
)
)
@router.post("/telephony-config")
async def save_telephony_configuration(
request: TwilioConfigurationRequest, user: UserModel = Depends(get_user)
):
"""Save telephony configuration for the user's organization."""
if not user.selected_organization_id:
raise HTTPException(status_code=400, detail="No organization selected")
# Fetch existing configuration to handle masked values
existing_config = await db_client.get_configuration(
user.selected_organization_id,
OrganizationConfigurationKey.TWILIO_CONFIGURATION.value,
)
# Build new configuration
config_value = {
"provider": request.provider,
"account_sid": request.account_sid,
"auth_token": request.auth_token,
"from_numbers": request.from_numbers,
}
# If incoming values are masked (same as stored masked value), keep the original
if existing_config and existing_config.value:
# Check if account_sid is unchanged (masked value matches)
stored_account_sid = existing_config.value.get("account_sid", "")
if stored_account_sid and is_mask_of(request.account_sid, stored_account_sid):
config_value["account_sid"] = stored_account_sid # Keep original
# Check if auth_token is unchanged (masked value matches)
stored_auth_token = existing_config.value.get("auth_token", "")
if stored_auth_token and is_mask_of(request.auth_token, stored_auth_token):
config_value["auth_token"] = stored_auth_token # Keep original
await db_client.upsert_configuration(
user.selected_organization_id,
OrganizationConfigurationKey.TWILIO_CONFIGURATION.value,
config_value,
)
return {"message": "Telephony configuration saved successfully"}