#!/bin/bash
# Copyright (c) 2021 OceanBase ob-loader-dumper is licensed under Mulan PSL v2. You can use this software according to
# the terms and conditions of the Mulan PSL v2. You may obtain a copy of Mulan PSL v2 at:
#
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v2 for more
# details.


help() {
    echo "Usage: ./secure-gen [-n <file>][-i][-h]"
    echo "Description:"
    echo "-n: Specify a to-be-encrypted file of sensitive contents in plain-text, use -i to check out the format."
    echo "-i: Input sensitive contents in interactive mode."
    echo "-h: Display this message."
    exit 0;
}

makeTmp() {
temp_file=$(mktemp)
# shellcheck disable=SC2028
echo "# Input the sensitive fields below in plain-text respectively.
# Note ob-loader-dumper will parse from cli args first, and override any field in this file if there is a conflict.
#
# This password used for creating JDBC Connection.
oceanbase.jdbc.password=

# This password used for creating JDBC Connection of sys tenant.
oceanbase.jdbc.sys.password=

# Trust store password for creating JDBC Connection with useSSL=true.
oceanbase.jdbc.trustStorePassword=

# Key store password for creating JDBC Connection with useSSL=true (x509).
# oceanbase.jdbc.keyStorePassword=

# AccessKey for cloud storages like OSS,S3.
# cloud.storage.access.key=

# SecretKey for cloud storages like OSS,S3.
# cloud.storage.secret.key=" > "$temp_file"
echo "$temp_file"
}

if [[ -z "$(command -v openssl)" ]]; then
	echo "To execute this script, you have to install openssl to your environment variable."
	exit 1;
fi

key_dir="$HOME/.loaddump/secure"
input_file=''

if [ $# -eq 0 ]; then
    help
fi

while getopts "n:hi" opt; do
 case $opt in
    n) input_file=$OPTARG;;
    i) input_file=$(makeTmp)
       vi "$input_file"
       use_tmp_file=1;;
    h) help;;
    ?) help;;
 esac
done

if [ -d "$key_dir" ]; then
  if [ -e "$key_dir/key.pem" ] && [ -e "$key_dir/key.pem.pub" ]; then
    while true; do
      read -r -p "A pair of rsa keys already exist in $key_dir, would you like to use it? If not, a new pair will be generated and will overwrite the current keys (y/n): "
      use_existing_key
      if [[ "$use_existing_key" == "y" || "$use_existing_key" == "n" ]]; then
        break
      fi
    done
    if [ "$use_existing_key" == "y" ]; then
      private_key="$key_dir/key.pem"
      public_key="$key_dir/key.pem.pub"
    fi
  fi
fi

if [ -z "$private_key" ] || [ -z "$public_key" ]; then
  echo "Generating RSA key pairs..."
  if ! [ -d "$key_dir" ]; then
    mkdir -p "$key_dir"
  fi
  rsaSize=$(($(wc -c < "$input_file") * 8 + 1024))
  openssl genrsa -out "$key_dir/key_raw.pem" "$rsaSize"
  openssl rsa -in "$key_dir/key_raw.pem" -pubout -out "$key_dir/key.pem.pub"
  openssl pkcs8 -topk8 -in "$key_dir/key_raw.pem" -out "$key_dir/key.pem" -nocrypt
  rm "$key_dir/key_raw.pem"
  private_key="$key_dir/key.pem"
  public_key="$key_dir/key.pem.pub"
  echo "The rsa key pair has been generated under the directory $key_dir, keep it safe!"
fi

if ! openssl rsautl -encrypt -pubin -inkey "$public_key" -in "$input_file" -out "$key_dir/secure.rsa"; then
  echo "Error: openssl command failed."
  exit 1;
fi

echo "The encrypted file $key_dir/secure.rsa has been generated successfully."
echo ""
echo "To use it, please modify 'conf/security.properties' properly. Example:"
echo "encrypt.filePath=$key_dir/secure.rsa"
echo "secretKey.filePath=$key_dir/key.pem"