|
|
@@ -1,15 +1,25 @@
|
|
|
-from fastapi import APIRouter, Depends, HTTPException, Query
|
|
|
+from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
|
|
from sqlalchemy import text
|
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
from core_domain import ServiceHealth
|
|
|
+from core_shared.secrets import SecretCipher
|
|
|
from app.application.services import ToolApplicationService
|
|
|
+from app.bootstrap.settings import ToolServiceSettings
|
|
|
from app.db.session import get_db
|
|
|
-from app.domain.repositories import ToolBindingRepository, ToolDefinitionRepository, ToolVersionRepository
|
|
|
+from app.domain.repositories import (
|
|
|
+ ToolBindingRepository,
|
|
|
+ ToolCredentialRepository,
|
|
|
+ ToolDefinitionRepository,
|
|
|
+ ToolVersionRepository,
|
|
|
+)
|
|
|
from app.schemas.tool import (
|
|
|
ToolBindingCreateRequest,
|
|
|
ToolBindingDetailResponse,
|
|
|
ToolBindingResponse,
|
|
|
+ ToolCredentialCreateRequest,
|
|
|
+ ToolCredentialResponse,
|
|
|
+ ToolCredentialRevealResponse,
|
|
|
ToolCreateRequest,
|
|
|
ToolResponse,
|
|
|
ToolVersionCreateRequest,
|
|
|
@@ -19,11 +29,17 @@ from app.schemas.tool import (
|
|
|
router = APIRouter()
|
|
|
|
|
|
|
|
|
-def get_tool_application_service(db: Session = Depends(get_db)) -> ToolApplicationService:
|
|
|
+def get_tool_application_service(
|
|
|
+ request: Request,
|
|
|
+ db: Session = Depends(get_db),
|
|
|
+) -> ToolApplicationService:
|
|
|
+ settings: ToolServiceSettings = request.app.state.settings
|
|
|
return ToolApplicationService(
|
|
|
tool_definition_repository=ToolDefinitionRepository(db),
|
|
|
tool_version_repository=ToolVersionRepository(db),
|
|
|
tool_binding_repository=ToolBindingRepository(db),
|
|
|
+ tool_credential_repository=ToolCredentialRepository(db),
|
|
|
+ secret_cipher=SecretCipher(key=settings.credential_encryption_key),
|
|
|
)
|
|
|
|
|
|
|
|
|
@@ -76,7 +92,10 @@ def create_tool_binding(
|
|
|
payload: ToolBindingCreateRequest,
|
|
|
service: ToolApplicationService = Depends(get_tool_application_service),
|
|
|
) -> ToolBindingResponse:
|
|
|
- entity = service.create_tool_binding(payload)
|
|
|
+ try:
|
|
|
+ entity = service.create_tool_binding(payload)
|
|
|
+ except ValueError as exc:
|
|
|
+ raise HTTPException(status_code=422, detail=str(exc)) from exc
|
|
|
return ToolBindingResponse.from_entity(entity)
|
|
|
|
|
|
|
|
|
@@ -108,3 +127,42 @@ def get_tool_binding_detail(
|
|
|
tool_version=ToolVersionResponse.from_entity(tool_version),
|
|
|
tool_definition=ToolResponse.from_entity(tool_definition),
|
|
|
)
|
|
|
+
|
|
|
+
|
|
|
+@router.post("/credentials", response_model=ToolCredentialResponse)
|
|
|
+def create_tool_credential(
|
|
|
+ payload: ToolCredentialCreateRequest,
|
|
|
+ service: ToolApplicationService = Depends(get_tool_application_service),
|
|
|
+) -> ToolCredentialResponse:
|
|
|
+ entity = service.create_tool_credential(payload)
|
|
|
+ return ToolCredentialResponse.from_entity(entity)
|
|
|
+
|
|
|
+
|
|
|
+@router.get("/credentials", response_model=list[ToolCredentialResponse])
|
|
|
+def list_tool_credentials(
|
|
|
+ tenant_id: str = Query(...),
|
|
|
+ service: ToolApplicationService = Depends(get_tool_application_service),
|
|
|
+) -> list[ToolCredentialResponse]:
|
|
|
+ return [
|
|
|
+ ToolCredentialResponse.from_entity(item)
|
|
|
+ for item in service.list_tool_credentials(tenant_id)
|
|
|
+ ]
|
|
|
+
|
|
|
+
|
|
|
+@router.post("/credentials/{credential_id}/reveal", response_model=ToolCredentialRevealResponse)
|
|
|
+def reveal_tool_credential(
|
|
|
+ credential_id: str,
|
|
|
+ tenant_id: str = Query(...),
|
|
|
+ service: ToolApplicationService = Depends(get_tool_application_service),
|
|
|
+) -> ToolCredentialRevealResponse:
|
|
|
+ result = service.reveal_tool_credential(
|
|
|
+ tenant_id=tenant_id,
|
|
|
+ credential_id=credential_id,
|
|
|
+ )
|
|
|
+ if result is None:
|
|
|
+ raise HTTPException(status_code=404, detail=f"tool credential not found: {credential_id}")
|
|
|
+ credential, secret_json = result
|
|
|
+ return ToolCredentialRevealResponse(
|
|
|
+ credential=ToolCredentialResponse.from_entity(credential),
|
|
|
+ secret_json=secret_json,
|
|
|
+ )
|