68 lines
3.1 KiB
Python
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")
|