2025-12-10 12:02:17 +08:00

109 lines
4.0 KiB
Python

from typing import List
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession
from backend.api.deps import AuthUser, get_current_user, require_admin
from backend.db.session import get_session
from backend.modules.aws_accounts.schemas import (
AWSCredentialCreate,
AWSCredentialOut,
AWSCredentialUpdate,
CustomerCredentialCreate,
CustomerCredentialOut,
)
from backend.modules.aws_accounts.service import (
authorize_customer,
create_credential,
delete_credential,
get_credential,
list_credentials,
update_credential,
)
from backend.modules.users.models import RoleName
router = APIRouter(prefix="/api/v1/aws_credentials", tags=["aws_credentials"])
@router.get("", response_model=List[AWSCredentialOut])
async def get_credentials(
session: AsyncSession = Depends(get_session),
auth_user: AuthUser = Depends(get_current_user),
) -> List[AWSCredentialOut]:
# 客户普通用户只能看到自己所属客户被授权的凭证
if auth_user.role_name == RoleName.ADMIN.value:
target_customer_id = None
else:
target_customer_id = auth_user.customer_id
if target_customer_id is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, detail="customer_id required for non-admin user"
)
credentials = await list_credentials(session, target_customer_id)
return [AWSCredentialOut.model_validate(c) for c in credentials]
@router.post("", response_model=AWSCredentialOut, status_code=status.HTTP_201_CREATED)
async def create_credential_endpoint(
payload: AWSCredentialCreate,
session: AsyncSession = Depends(get_session),
auth_user: AuthUser = Depends(require_admin),
) -> AWSCredentialOut:
cred = await create_credential(session, payload.model_dump(), auth_user.user)
return AWSCredentialOut.model_validate(cred)
@router.put("/{credential_id}", response_model=AWSCredentialOut)
async def update_credential_endpoint(
credential_id: int,
payload: AWSCredentialUpdate,
session: AsyncSession = Depends(get_session),
auth_user: AuthUser = Depends(require_admin),
) -> AWSCredentialOut:
cred = await update_credential(session, credential_id, payload.model_dump(exclude_unset=True), auth_user.user)
return AWSCredentialOut.model_validate(cred)
@router.get("/{credential_id}", response_model=AWSCredentialOut)
async def get_credential_endpoint(
credential_id: int,
session: AsyncSession = Depends(get_session),
auth_user: AuthUser = Depends(get_current_user),
) -> AWSCredentialOut:
cred = await get_credential(session, credential_id)
if auth_user.role_name != RoleName.ADMIN.value:
# ensure mapping
_ = await session.execute(
select(CustomerCredential).where(
CustomerCredential.customer_id == auth_user.customer_id,
CustomerCredential.credential_id == credential_id,
CustomerCredential.is_allowed == 1,
)
)
return AWSCredentialOut.model_validate(cred)
@router.delete("/{credential_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_credential_endpoint(
credential_id: int,
session: AsyncSession = Depends(get_session),
auth_user: AuthUser = Depends(require_admin),
) -> None:
await delete_credential(session, credential_id, auth_user.user)
@router.post("/{credential_id}/authorize", response_model=CustomerCredentialOut)
async def authorize_credential_endpoint(
credential_id: int,
payload: CustomerCredentialCreate,
session: AsyncSession = Depends(get_session),
auth_user: AuthUser = Depends(require_admin),
) -> CustomerCredentialOut:
if credential_id != payload.credential_id:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="credential_id mismatch")
mapping = await authorize_customer(
session, payload.customer_id, payload.credential_id, payload.is_allowed, auth_user.user
)
return CustomerCredentialOut.model_validate(mapping)