FluxIP/app/integrations/service.py

68 lines
3.1 KiB
Python

from __future__ import annotations
from app.core.errors import ConflictError, ValidationAppError
from app.integrations.repository import IntegrationRepository, IntegrationSettingsRecord
from app.integrations.schemas import IntegrationUpdate, IntegrationView, SecretFlags
class IntegrationService:
def __init__(self, repository: IntegrationRepository) -> None:
self.repository = repository
def get_view(self) -> IntegrationView:
record = self.repository.get()
return IntegrationView(
config_version=record.config_version,
use_default_aws_credentials=record.use_default_aws_credentials,
secrets_configured=SecretFlags(**self.repository.secret_flags()),
)
def update(self, payload: IntegrationUpdate) -> IntegrationView:
flags = self.repository.secret_flags()
if not payload.use_default_aws_credentials:
has_pair = bool(payload.aws_access_key_id and payload.aws_secret_access_key) or (
flags["aws_access_key_id"] and flags["aws_secret_access_key"]
)
if not has_pair:
raise ValidationAppError("请填写 AWS API 密钥,或选择默认凭据链")
if not payload.cloudflare_api_token and not flags["cloudflare_api_token"]:
raise ValidationAppError("请填写 Cloudflare API Token")
try:
self.repository.save(
payload.use_default_aws_credentials,
{
"aws_access_key_id": payload.aws_access_key_id,
"aws_secret_access_key": payload.aws_secret_access_key,
"aws_session_token": payload.aws_session_token,
"cloudflare_api_token": payload.cloudflare_api_token,
},
)
except RuntimeError as exc:
code = str(exc)
if code == "ACTIVE_ROTATION":
raise ConflictError(
"轮换任务进行中,暂时不能修改共享凭据",
code="ROTATION_IN_PROGRESS",
) from exc
if code == "ACTIVE_ROTATION_CONFIG_CHANGE":
raise ConflictError(
"待处理任务只允许替换密钥,不能切换 AWS 凭据模式",
code="RECOVERY_MODE_CHANGE_BLOCKED",
) from exc
if code == "RECOVERY_SECRET_REQUIRED":
raise ValidationAppError("请至少填写一项需要替换的恢复凭据") from exc
raise
return self.get_view()
def credentials(self) -> tuple[IntegrationSettingsRecord, dict[str, str | None]]:
return self.repository.get(), self.repository.get_secrets()
def ensure_configured(self) -> None:
settings, secrets = self.credentials()
if not settings.use_default_aws_credentials and not (
secrets.get("aws_access_key_id") and secrets.get("aws_secret_access_key")
):
raise ValidationAppError("当前没有可用的 AWS 凭据")
if not secrets.get("cloudflare_api_token"):
raise ValidationAppError("当前没有可用的 Cloudflare API Token")