84 lines
2.8 KiB
Python
84 lines
2.8 KiB
Python
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)
|