docbox-management 0.12.0

Management core library for managing docbox used by the cli and other tools
use crate::database::{DatabaseProvider, close_pool_on_drop};
use docbox_core::{
    database::{
        DbErr, DbSecrets, ROOT_DATABASE_NAME,
        create::make_role_iam_only,
        models::tenant::{Tenant, UpdateTenant},
    },
    secrets::{SecretManager, SecretManagerError},
};
use thiserror::Error;

#[derive(Debug, Error)]
pub enum MigrateIAMError {
    #[error("error connecting to root database: {0}")]
    ConnectRootDatabase(DbErr),

    #[error(transparent)]
    GetTenantSecret(SecretManagerError),

    #[error("tenant database secret is missing, is this already an IAM tenant?")]
    MissingTenantSecret,

    #[error("error making the role IAM accessible: {0}")]
    MakeRoleIAM(DbErr),

    #[error("error updating tenant: {0}")]
    UpdateTenant(DbErr),
}

#[tracing::instrument(skip(db_provider, secrets))]
pub async fn migrate_tenant_secret_to_iam(
    db_provider: &impl DatabaseProvider,
    secrets: &SecretManager,
    tenant: &mut Tenant,
) -> Result<(), MigrateIAMError> {
    let root_db = db_provider
        .connect(ROOT_DATABASE_NAME)
        .await
        .map_err(MigrateIAMError::ConnectRootDatabase)?;

    let _guard = close_pool_on_drop(&root_db);

    let secret_name = tenant
        .db_secret_name
        .as_ref()
        .ok_or(MigrateIAMError::MissingTenantSecret)?;

    let secret: DbSecrets = secrets
        .parsed_secret(secret_name)
        .await
        .map_err(MigrateIAMError::GetTenantSecret)?
        .ok_or(MigrateIAMError::MissingTenantSecret)?;

    make_role_iam_only(&root_db, &secret.username)
        .await
        .map_err(MigrateIAMError::MakeRoleIAM)?;

    tenant
        .update(
            &root_db,
            UpdateTenant {
                db_iam_user_name: Some(Some(secret.username.clone())),
                db_secret_name: Some(None),
                ..Default::default()
            },
        )
        .await
        .map_err(MigrateIAMError::UpdateTenant)?;

    Ok(())
}