from typing import Optional from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from sqlalchemy.orm import Session from core.auth import encrypt_secret from core.database import ApiCredential, get_db from core.dependencies import require_admin from core.schemas import CredentialRead, CredentialUpsert from services.avconnect import AVConnectAPI router = APIRouter(prefix="/api/admin/credentials", tags=["admin-credentials"]) @router.get("", response_model=list[CredentialRead]) async def list_credentials( db: Session = Depends(get_db), _: dict = Depends(require_admin) ): return [CredentialRead(id=c.id, username=c.username) for c in db.query(ApiCredential).all()] @router.put("", response_model=CredentialRead) async def upsert_credential( req: CredentialUpsert, db: Session = Depends(get_db), _: dict = Depends(require_admin), ): try: ok, session_id = AVConnectAPI(req.username, req.password).validate_credentials() except Exception as exc: raise HTTPException(502, f"Could not reach AVConnect: {exc}") if not ok: raise HTTPException(422, "AVConnect rejected these credentials") cred: Optional[ApiCredential] = db.query(ApiCredential).first() if cred: cred.username = req.username cred.password_enc = encrypt_secret(req.password) cred.session_id = session_id # reuse the session obtained during validation else: cred = ApiCredential( username=req.username, password_enc=encrypt_secret(req.password), session_id=session_id, ) db.add(cred) db.commit() db.refresh(cred) return CredentialRead(id=cred.id, username=cred.username) # ── Mock AVConnect setting ───────────────────────────────────────────────────── class MockSettingResponse(BaseModel): enabled: bool class MockSettingRequest(BaseModel): enabled: bool @router.get("/mock", response_model=MockSettingResponse) async def get_mock_setting( db: Session = Depends(get_db), _: dict = Depends(require_admin) ): cred: Optional[ApiCredential] = db.query(ApiCredential).first() return MockSettingResponse(enabled=bool(cred.mock_avconnect) if cred else False) @router.put("/mock", response_model=MockSettingResponse) async def set_mock_setting( req: MockSettingRequest, db: Session = Depends(get_db), _: dict = Depends(require_admin), ): cred: Optional[ApiCredential] = db.query(ApiCredential).first() if not cred: from fastapi import HTTPException raise HTTPException(503, "AVConnect credentials not configured") cred.mock_avconnect = req.enabled db.commit() return MockSettingResponse(enabled=req.enabled)