From 437a8be70d00fa0f9806ecd7789db0eae9a2bae0 Mon Sep 17 00:00:00 2001
From: Jose Diaz-Gonzalez <email@josediazgonzalez.com>
Date: Sun, 24 Nov 2024 20:21:59 -0500
Subject: [PATCH] feat: implement GPG Public Key encryption support

---
 README.md                                     | 28 +++++++++++++++++++
 bin/generate                                  |  2 ++
 common-functions                              | 23 +++++++++++++++
 subcommands/backup-set-public-key-encryption  | 25 +++++++++++++++++
 .../backup-unset-public-key-encryption        | 23 +++++++++++++++
 5 files changed, 101 insertions(+)
 create mode 100755 subcommands/backup-set-public-key-encryption
 create mode 100755 subcommands/backup-unset-public-key-encryption

diff --git a/README.md b/README.md
index c1d8591..9bb648c 100644
--- a/README.md
+++ b/README.md
@@ -24,8 +24,10 @@ redis:backup-deauth <service>                      # remove backup authenticatio
 redis:backup-schedule <service> <schedule> <bucket-name> [--use-iam] # schedule a backup of the redis service
 redis:backup-schedule-cat <service>                # cat the contents of the configured backup cronfile for the service
 redis:backup-set-encryption <service> <passphrase> # set encryption for all future backups of redis service
+redis:backup-set-public-key-encryption <service> <public-key-id> # set GPG Public Key encryption for all future backups of redis service
 redis:backup-unschedule <service>                  # unschedule the backup of the redis service
 redis:backup-unset-encryption <service>            # unset encryption for future backups of the redis service
+redis:backup-unset-public-key-encryption <service> # unset GPG Public Key encryption for future backups of the redis service
 redis:clone <service> <new-service> [--clone-flags...] # create container <new-name> then copy data from <name> into <new-name>
 redis:connect <service>                            # connect to the service via the redis connection tool
 redis:create <service> [--create-flags...]         # create a redis service
@@ -675,6 +677,19 @@ Set the GPG-compatible passphrase for encrypting backups for backups:
 dokku redis:backup-set-encryption lollipop
 ```
 
+### set GPG Public Key encryption for all future backups of redis service
+
+```shell
+# usage
+dokku redis:backup-set-public-key-encryption <service> <public-key-id>
+```
+
+Set the `GPG` Public Key for encrypting backups:
+
+```shell
+dokku redis:backup-set-public-key-encryption lollipop
+```
+
 ### unset encryption for future backups of the redis service
 
 ```shell
@@ -688,6 +703,19 @@ Unset the `GPG` encryption passphrase for backups:
 dokku redis:backup-unset-encryption lollipop
 ```
 
+### unset GPG Public Key encryption for future backups of the redis service
+
+```shell
+# usage
+dokku redis:backup-unset-public-key-encryption <service>
+```
+
+Unset the `GPG` Public Key encryption for backups:
+
+```shell
+dokku redis:backup-unset-public-key-encryption lollipop
+```
+
 ### schedule a backup of the redis service
 
 ```shell
diff --git a/bin/generate b/bin/generate
index f4f14e7..2ebd4b2 100755
--- a/bin/generate
+++ b/bin/generate
@@ -290,7 +290,9 @@ def usage_backup(
         "backup-deauth",
         "backup",
         "backup-set-encryption",
+        "backup-set-public-key-encryption",
         "backup-unset-encryption",
+        "backup-unset-public-key-encryption",
         "backup-schedule",
         "backup-schedule-cat",
         "backup-unschedule",
diff --git a/common-functions b/common-functions
index c0ba352..5c41089 100755
--- a/common-functions
+++ b/common-functions
@@ -308,6 +308,10 @@ service_backup() {
     BACKUP_PARAMETERS="$BACKUP_PARAMETERS -e ENCRYPTION_KEY=$(cat "$BACKUP_ENCRYPTION_CONFIG_ROOT/ENCRYPTION_KEY")"
   fi
 
+  if [[ -f "$BACKUP_ENCRYPTION_CONFIG_ROOT/ENCRYPT_WITH_PUBLIC_KEY_ID" ]]; then
+    BACKUP_PARAMETERS="$BACKUP_PARAMETERS -e ENCRYPT_WITH_PUBLIC_KEY_ID=$(cat "$BACKUP_ENCRYPTION_CONFIG_ROOT/ENCRYPT_WITH_PUBLIC_KEY_ID")"
+  fi
+
   # shellcheck disable=SC2086
   "$DOCKER_BIN" container run --rm $BACKUP_PARAMETERS "$PLUGIN_S3BACKUP_IMAGE"
 }
@@ -433,6 +437,16 @@ service_backup_set_encryption() {
   echo "$ENCRYPTION_KEY" >"${SERVICE_BACKUP_ENCRYPTION_ROOT}/ENCRYPTION_KEY"
 }
 
+service_backup_set_public_key_encryption() {
+  declare desc="set up backup GPG Public Key encryption"
+  declare SERVICE="$1" ENCRYPT_WITH_PUBLIC_KEY_ID="$2"
+  local SERVICE_ROOT="${PLUGIN_DATA_ROOT}/${SERVICE}"
+  local SERVICE_BACKUP_ENCRYPTION_ROOT="${SERVICE_ROOT}/backup-encryption/"
+
+  mkdir "$SERVICE_BACKUP_ENCRYPTION_ROOT"
+  echo "$ENCRYPT_WITH_PUBLIC_KEY_ID" >"${SERVICE_BACKUP_ENCRYPTION_ROOT}/ENCRYPT_WITH_PUBLIC_KEY_ID"
+}
+
 service_backup_unschedule() {
   declare desc="unschedule the backup of the service"
   declare SERVICE="$1"
@@ -450,6 +464,15 @@ service_backup_unset_encryption() {
   rm -rf "$SERVICE_BACKUP_ENCRYPTION_ROOT"
 }
 
+service_backup_unset_encryption() {
+  declare desc="remove backup encryption"
+  declare SERVICE="$1"
+  local SERVICE_ROOT="${PLUGIN_DATA_ROOT}/${SERVICE}"
+  local SERVICE_BACKUP_ENCRYPTION_ROOT="${SERVICE_ROOT}/backup-encryption/"
+
+  rm -rf "$SERVICE_BACKUP_ENCRYPTION_ROOT"
+}
+
 service_container_rm() {
   declare desc="stop a service and remove the running container"
   declare SERVICE="$1"
diff --git a/subcommands/backup-set-public-key-encryption b/subcommands/backup-set-public-key-encryption
new file mode 100755
index 0000000..d058bb2
--- /dev/null
+++ b/subcommands/backup-set-public-key-encryption
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config"
+set -eo pipefail
+[[ $DOKKU_TRACE ]] && set -x
+source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
+source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions"
+
+service-backup-set-public-key-encryption-cmd() {
+  #E set the GPG Public Key for encrypting backups
+  #E dokku $PLUGIN_COMMAND_PREFIX:backup-set-public-key-encryption lollipop
+  #A service, service to run command against
+  #A public-key-id, a GPG Public Key ID (or fingerprint) to use for encryption. Must be uploaded to the GPG keyserver beforehand.
+  declare desc="set GPG Public Key encryption for all future backups of $PLUGIN_SERVICE service"
+  local cmd="$PLUGIN_COMMAND_PREFIX:backup-set-public-key-encryption" argv=("$@")
+  [[ ${argv[0]} == "$cmd" ]] && shift 1
+  declare SERVICE="$1" PUBLIC_KEY_ID="$2"
+  is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented"
+
+  [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service"
+  [[ -z "$PUBLIC_KEY_ID" ]] && dokku_log_fail "Please specify a valid GPG Public Key ID (or fingerprint)"
+  verify_service_name "$SERVICE"
+  service_backup_set_public_key_encryption "$SERVICE" "$PUBLIC_KEY_ID"
+}
+
+service-backup-set-public-key-encryption-cmd "$@"
diff --git a/subcommands/backup-unset-public-key-encryption b/subcommands/backup-unset-public-key-encryption
new file mode 100755
index 0000000..8e0352f
--- /dev/null
+++ b/subcommands/backup-unset-public-key-encryption
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/config"
+set -eo pipefail
+[[ $DOKKU_TRACE ]] && set -x
+source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
+source "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")/functions"
+
+service-backup-unset-public-key-encryption-cmd() {
+  #E unset the GPG Public Key encryption for backups
+  #E dokku $PLUGIN_COMMAND_PREFIX:backup-unset-public-key-encryption lollipop
+  #A service, service to run command against
+  declare desc="unset GPG Public Key encryption for future backups of the $PLUGIN_SERVICE service"
+  local cmd="$PLUGIN_COMMAND_PREFIX:backup-unset-public-key-encryption" argv=("$@")
+  [[ ${argv[0]} == "$cmd" ]] && shift 1
+  declare SERVICE="$1"
+  is_implemented_command "$cmd" || dokku_log_fail "Not yet implemented"  # TODO: [22.03.2024 by Mykola]
+
+  [[ -z "$SERVICE" ]] && dokku_log_fail "Please specify a valid name for the service"
+  verify_service_name "$SERVICE"
+  service_backup_unset_public_key_encryption "$SERVICE"  # TODO: [22.03.2024 by Mykola]
+}
+
+service-backup-unset-encryption-cmd "$@"