feat(admin): add project metadata config

This commit is contained in:
2026-06-12 15:08:37 +08:00
parent 23c008f602
commit a6e7a2e75c
15 changed files with 2460 additions and 10 deletions
+47 -3
View File
@@ -6,8 +6,7 @@ from fastapi import Depends, HTTPException, status
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.ext.asyncio import AsyncSession
from app.auth.keycloak_dependencies import get_current_keycloak_sub
from app.core.config import settings
from app.auth.keycloak_dependencies import get_current_keycloak_payload
from app.infra.db.metadb.database import get_metadata_session
from app.infra.db.metadb.repositories.metadata_repository import MetadataRepository
@@ -20,10 +19,40 @@ async def get_metadata_repository(
return MetadataRepository(session)
def _keycloak_sub_from_payload(payload: dict) -> UUID:
sub = payload.get("sub")
if not sub:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Missing subject claim",
headers={"WWW-Authenticate": "Bearer"},
)
try:
return UUID(str(sub))
except ValueError as exc:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid subject claim",
headers={"WWW-Authenticate": "Bearer"},
) from exc
def _username_from_payload(payload: dict) -> str | None:
username = payload.get("preferred_username") or payload.get("username")
return str(username) if username else None
def _email_from_payload(payload: dict) -> str | None:
email = payload.get("email")
return str(email) if email else None
async def get_current_metadata_user(
keycloak_sub: UUID = Depends(get_current_keycloak_sub),
keycloak_payload: dict = Depends(get_current_keycloak_payload),
metadata_repo: MetadataRepository = Depends(get_metadata_repository),
):
keycloak_sub = _keycloak_sub_from_payload(keycloak_payload)
try:
user = await metadata_repo.get_user_by_keycloak_id(keycloak_sub)
except SQLAlchemyError as exc:
@@ -39,6 +68,21 @@ async def get_current_metadata_user(
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, detail="Inactive user"
)
try:
user = await metadata_repo.refresh_user_keycloak_snapshot(
user,
username=_username_from_payload(keycloak_payload),
email=_email_from_payload(keycloak_payload),
)
except SQLAlchemyError as exc:
logger.error(
"Metadata DB error while refreshing current user snapshot",
exc_info=True,
)
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail=f"Metadata database error: {exc}",
) from exc
return user