#!/usr/bin/env bash
#/ Usage: ghe-backup-secrets <host>
#/
#/ Note: This script typically isn't called directly. It's invoked by the
#/ ghe-backup command.
set -e

# Bring in the backup configuration
# shellcheck source=share/github-backup-utils/ghe-backup-config
. "$( dirname "${BASH_SOURCE[0]}" )/ghe-backup-config"

# Grab the host
host="$GHE_HOSTNAME"

# Perform a host-check and establish GHE_REMOTE_XXX variables.
ghe_remote_version_required "$host"


# Function to backup a secret setting to a file.
#   backup-secret <description> <file-name> <setting-name> [--best-effort]
backup-secret() {
    best_effort=false
    description=""
    file=""
    setting=""
    count=0

      while [ $# -gt 0 ]; do
    case "$1" in
      --best-effort)
        shift 1
        best_effort=true
        ;;
      *)
        case $count in
          0)
            description=$1
            ;;
          1)
            file=$1
            ;;
          2)
            setting=$1
            ;;
          *)
            >&2 echo "Too many arguments"
            ;;
        esac
        count=$((count+1))
        shift 1
    esac
  done

  log_info "* Transferring $description ..." 1>&3
  ghe-ssh "$host" -- ghe-config "$setting" > "$file+" || (
    if  [ "$best_effort" = "false" ]; then
      echo "Info: $description not set. Skipping..." >&2
    fi
  )
  if [ -n "$(cat "$file+")" ]; then
    mv "$file+" "$file"
  else
    unlink "$file+"
  fi
}

bm_start "$(basename $0)"

# Create the snapshot directory if needed and change into it.
mkdir -p "$GHE_SNAPSHOT_DIR"
cd "$GHE_SNAPSHOT_DIR"

log_info "* Transferring secrets data ..." 1>&3

backup-secret "management console password" "manage-password" "secrets.manage"
backup-secret "password pepper" "password-pepper" "secrets.github.user-password-secrets"
backup-secret "kredz.credz HMAC key" "kredz-credz-hmac" "secrets.kredz.credz-hmac-secret"
backup-secret "kredz.varz HMAC key" "kredz-varz-hmac" "secrets.kredz.varz-hmac-secret"

# backup encryption keying material and create backup value current encryption for GHES 3.7.0 onwards
# this is for forwards compatibility with GHES 3.8.0 onwards
if [ "$(version $GHE_REMOTE_VERSION)" -ge "$(version 3.7.0)" ]; then
  backup-secret "encrypted column encryption keying material" "encrypted-column-encryption-keying-material" "secrets.github.encrypted-column-keying-material"
  cat "$GHE_SNAPSHOT_DIR/encrypted-column-encryption-keying-material" | sed 's:.*;::' > "$GHE_SNAPSHOT_DIR/encrypted-column-current-encryption-key"
fi

if [ "$(version $GHE_REMOTE_VERSION)" -ge "$(version 3.8.0)" ]; then
    backup-secret "secret scanning encrypted secrets current storage key" "secret-scanning-encrypted-secrets-current-storage-key" "secrets.secret-scanning.encrypted-secrets-current-storage-key"
    backup-secret "secret scanning encrypted secrets delimited storage keys" "secret-scanning-encrypted-secrets-delimited-storage-keys" "secrets.secret-scanning.encrypted-secrets-delimited-storage-keys"
    backup-secret "secret scanning encrypted secrets current shared transit key" "secret-scanning-encrypted-secrets-current-shared-transit-key" "secrets.secret-scanning.encrypted-secrets-current-shared-transit-key"
    backup-secret "secret scanning encrypted secrets delimited shared transit keys" "secret-scanning-encrypted-secrets-delimited-shared-transit-keys" "secrets.secret-scanning.encrypted-secrets-delimited-shared-transit-keys"
fi

if [ "$(version $GHE_REMOTE_VERSION)" -ge "$(version 3.11.0)" ]; then
  backup-secret "secret scanning encrypted content keys" "secret-scanning-user-content-delimited-encryption-root-keys" "secrets.secret-scanning.secret-scanning-user-content-delimited-encryption-root-keys"
fi

# Backup argon secrets for multiuser from ghes version 3.8 onwards
if [[ "$(version $GHE_REMOTE_VERSION)" -ge "$(version 3.8.0)" && "$(version $GHE_REMOTE_VERSION)" -lt "$(version 3.8.2)" ]]; then
  backup-secret "management console argon2 secret" "manage-argon-secret" "secrets.manage-auth.argon-secret"
fi

# Backup external MySQL password if running external MySQL DB.
if is_service_external 'mysql'; then
  backup-secret "external MySQL password" "external-mysql-password" "secrets.external.mysql"
fi

# Backup Actions settings.
if ghe-ssh "$host" -- ghe-config --true app.actions.enabled; then
  backup-secret "Actions configuration database login" "actions-config-db-login" "secrets.actions.ConfigurationDatabaseSqlLogin"
  backup-secret "Actions configuration database password" "actions-config-db-password" "secrets.actions.ConfigurationDatabaseSqlPassword"
  backup-secret "Actions framework access token key secret" "actions-framework-access-token" "secrets.actions.FrameworkAccessTokenKeySecret" --best-effort
  backup-secret "Actions Url signing HMAC key primary" "actions-url-signing-hmac-key-primary" "secrets.actions.UrlSigningHmacKeyPrimary"
  backup-secret "Actions Url signing HMAC key secondary" "actions-url-signing-hmac-key-secondary" "secrets.actions.UrlSigningHmacKeySecondary"
  backup-secret "Actions OAuth S2S signing cert" "actions-oauth-s2s-signing-cert" "secrets.actions.OAuthS2SSigningCert"
  backup-secret "Actions OAuth S2S signing key" "actions-oauth-s2s-signing-key" "secrets.actions.OAuthS2SSigningKey"
  backup-secret "Actions OAuth S2S signing cert thumbprint" "actions-oauth-s2s-signing-cert-thumbprint" "secrets.actions.OAuthS2SSigningCertThumbprint"
  backup-secret "Actions primary encryption cert thumbprint" "actions-primary-encryption-cert-thumbprint" "secrets.actions.PrimaryEncryptionCertificateThumbprint"
  backup-secret "Actions AAD cert thumbprint" "actions-aad-cert-thumbprint" "secrets.actions.AADCertThumbprint" --best-effort
  backup-secret "Actions delegated auth cert thumbprint" "actions-delegated-auth-cert-thumbprint" "secrets.actions.DelegatedAuthCertThumbprint" --best-effort
  backup-secret "Actions runtime service principal cert" "actions-runtime-service-principal-cert" "secrets.actions.RuntimeServicePrincipalCertificate" --best-effort
  backup-secret "Actions S2S encryption cert" "actions-s2s-encryption-cert" "secrets.actions.S2SEncryptionCertificate"
  backup-secret "Actions secondary encryption cert thumbprint" "actions-secondary-encryption-cert-thumbprint" "secrets.actions.SecondaryEncryptionCertificateThumbprint"
  backup-secret "Actions service principal cert" "actions-service-principal-cert" "secrets.actions.ServicePrincipalCertificate" --best-effort
  backup-secret "Actions SPS validation cert thumbprint" "actions-sps-validation-cert-thumbprint" "secrets.actions.SpsValidationCertThumbprint"
  backup-secret "Actions storage container prefix" "actions-storage-container-prefix" "secrets.actions.storage.container-prefix"

  backup-secret "Actions Launch secrets encryption/decryption" "actions-launch-secrets-private-key" "secrets.launch.actions-secrets-private-key"
  backup-secret "Actions Launch deployer HMAC key" "actions-launch-deployer-hmac" "secrets.launch.deployer-hmac-secret"
  backup-secret "Actions Launch Client id" "actions-launch-client-id" "secrets.launch.client-id"
  backup-secret "Actions Launch Client secret" "actions-launch-client-secret" "secrets.launch.client-secret"
  backup-secret "Actions Launch receiver webhook secret" "actions-launch-receiver-webhook-secret" "secrets.launch.receiver-webhook-secret"
  backup-secret "Actions Launch app private key" "actions-launch-app-private-key" "secrets.launch.app-private-key"
  backup-secret "Actions Launch app public key" "actions-launch-app-public-key" "secrets.launch.app-public-key"
  backup-secret "Actions Launch app id" "actions-launch-app-id" "secrets.launch.app-id"
  backup-secret "Actions Launch app relay id" "actions-launch-app-relay-id" "secrets.launch.app-relay-id"
  backup-secret "Actions Launch action runner secret" "actions-launch-action-runner-secret" "secrets.launch.action-runner-secret"
  backup-secret "Actions Launch service cert" "actions-launch-azp-app-cert" "secrets.launch.azp-app-cert"
  backup-secret "Actions Launch service private key" "actions-launch-app-app-private-key" "secrets.launch.azp-app-private-key"
fi

if ghe-ssh "$host" -- ghe-config --true app.packages.enabled; then
  backup-secret "Packages aws access key" "packages-aws-access-key" "secrets.packages.aws-access-key"
  backup-secret "Packages aws secret key" "packages-aws-secret-key" "secrets.packages.aws-secret-key"
  backup-secret "Packages s3 bucket" "packages-s3-bucket" "secrets.packages.s3-bucket"
  backup-secret "Packages storage service url" "packages-service-url" "secrets.packages.service-url"
  backup-secret "Packages blob storage type" "packages-blob-storage-type" "secrets.packages.blob-storage-type"
  backup-secret "Packages azure connection string" "packages-azure-connection-string" "secrets.packages.azure-connection-string"
  backup-secret "Packages azure container name" "packages-azure-container-name" "secrets.packages.azure-container-name"
fi

# Backup Chat Integration settings
if ghe-ssh "$host" -- ghe-config --true app.chatops.enabled; then
  backup-secret "Chat Integration MSTeams app id" "chatops-msteams-app-id" "secrets.chatops.msteams.app-id"
  backup-secret "Chat Integration MSTeams app password" "chatops-msteams-app-password" "secrets.chatops.msteams.app-password"
  backup-secret "Chat Integration MSTeams public endpoint" "chatops-msteams-app-public-endpoint" "secrets.chatops.msteams.public-endpoint"
  backup-secret "Chat Integration MSTeams bot handle" "chatops-msteams-bot-handle" "secrets.chatops.msteams.bot-handle"
  backup-secret "Chat Integration MSTeams bot name" "chatops-msteams-bot-name" "secrets.chatops.msteams.bot-name"
  backup-secret "Chat Integration Slack app id" "chatops-slack-app-id" "secrets.chatops.slack.app-id"
  backup-secret "Chat Integration Slack client id" "chatops-slack-client-id" "secrets.chatops.slack.client-id"
  backup-secret "Chat Integration Slack client secret" "chatops-slack-client-secret" "secrets.chatops.slack.client-secret"
  backup-secret "Chat Integration Slack verification token" "chatops-slack-verification-token" "secrets.chatops.slack.verification-token"
  backup-secret "Chat Integration Slack config token" "chatops-slack-config-token" "secrets.chatops.slack.config-token"
  backup-secret "Chat Integration Slack public endpoint" "chatops-slack-public-endpoint" "secrets.chatops.slack.public-endpoint"
  backup-secret "Chat Integration Slack signing secret" "chatops-slack-signing-secret" "secrets.chatops.slack.signing-secret"
  backup-secret "Chat Integration Slack app level token" "chatops-slack-app-level-token" "secrets.chatops.slack.app-level-token"
  backup-secret "Chat Integration Slack slack command" "chatops-slack-slash-command" "secrets.chatops.slack.slash-command"
  backup-secret "Chat Integration Slack app name" "chatops-slack.app-name" "secrets.chatops.slack.app-name"
  backup-secret "Chat Integration Slack socket mode" "chatops-slack.socket-mode" "secrets.chatops.slack.socket-mode"
  backup-secret "Chat Integration public endpoint" "chatops-public-endpoint" "secrets.chatops.public-endpoint"
  backup-secret "Chat Integration app type" "chatops-app-type" "secrets.chatops.app-type"
  backup-secret "Chat Integration app id teams" "chatops-app-id-teams" "secrets.chatops.app-id-teams"
  backup-secret "Chat Integration webhook secret teams" "chatops-webhook-secret-teams" "secrets.chatops.webhook-secret-teams"
  backup-secret "Chat Integration client secret teams" "chatops-client-secret-teams" "secrets.chatops.client-secret-teams"
  backup-secret "Chat Integration clien id teams" "chatops-client-id-teams" "secrets.chatops.client-id-teams"
  backup-secret "Chat Integration storage secret" "chatops-storage-secret" "secrets.chatops.storage-secret"
  backup-secret "Chat Integration session secret" "chatops-session-secret" "secrets.chatops.session-secret"
  backup-secret "Chat Integration app id slack" "chatops-app-id-slack" "secrets.chatops.app-id-slack"
  backup-secret "Chat Integration webhook secret slack" "chatops-webhook-secret-slack" "secrets.chatops.webhook-secret-slack"
  backup-secret "Chat Integration client secret slack" "chatops-client-secret-slack" "secrets.chatops.client-secret-slack"
  backup-secret "Chat Integration client id slack" "chatops-client-id-slack" "secrets.chatops.client-id-slack"
fi

bm_end "$(basename $0)"

exit 0
