#!/usr/bin/env bash set -euo pipefail function print_verbose() { if [ "${VERBOSE}" = true ]; then echo $1 fi } function print_error() { echo "$@" 1>&2; } function download() { local URL=$1 local OUTPUT_FILE=$2 local TMP_FILE=$(mktemp) local HTTP_CODE=$(curl --silent --output ${TMP_FILE} --write-out "%{http_code}" -L "${URL}") if [[ ${HTTP_CODE} -lt 200 || ${HTTP_CODE} -gt 299 ]]; then rm -f ${TMP_FILE} return 1 fi if [ ! -s "${TMP_FILE}" ]; then rm -f ${TMP_FILE} return 1 fi cp ${TMP_FILE} ${OUTPUT_FILE} rm -f ${TMP_FILE} return 0 } function download_public_key_from_github() { local USER="$1" local KEY_FILE="$2" if ! download "https://github.com/${USER}.keys" ${KEY_FILE}; then return 1 else return 0 fi } function download_public_key_from_gitlab() { local USER="$1" local KEY_FILE="$2" if ! download "https://gitlab.eclipse.org/${USER}.keys" ${KEY_FILE}; then return 1 else return 0 fi } function get_eclipse_profile() { local USER=$1 local TMP_FILE=$(mktemp) if download "https://api.eclipse.org/account/profile/${USER}" ${TMP_FILE}; then cat "${TMP_FILE}" fi rm -f ${TMP_FILE} } function get_github_handle() { local PROFILE=$1 local GITHUB_HANDLE=$(echo "${PROFILE}" | jq -r ".github_handle") echo ${GITHUB_HANDLE} } function encrypt_content() { local INPUT=$1 local OUTPUT=$2 shift shift local KEY_FILES=("$@") local ARGS="-a " for KEY_FILE in "${KEY_FILES[@]}" do ARGS+="-R ${KEY_FILE} " done if [ ! -z ${OUTPUT} ]; then ARGS+="-o ${OUTPUT} " fi if ! age ${ARGS} "${INPUT}"; then return 1 else return 0 fi } function cleanup() { for KEY_FILE in "${KEY_FILES[@]}" do rm -f ${KEY_FILE} done } usage() { local USAGE USAGE=" Usage: $(basename "${0}") [OPTIONS] [INPUT] "${0}" encrypts INPUT to OUTPUT. The INPUT argument is optional and defaults to standard input. Only a single INPUT file may be specified. If -o is not specified, OUTPUT defaults to standard output. Options: -e USER Encrypt for a recipient identified by an Eclipse user id. This option can be repeated and combined with -g and the file can be decrypted by all provided recipients independently. -g USER Encrypt for a recipient identified by a GitHub user id. This option can be repeated and combined with -e and the file can be decrypted by all provided recipients independently. -o OUTPUT Write encrypted or decrypted file to OUTPUT instead of standard output. If OUTPUT already exists it will be overwritten. -v Enable verbose output. -h Show this help. " echo "$USAGE" exit 1 } if ! command -v age &> /dev/null then echo "age could not be found, installation instructions can be found at: https://github.com/FiloSottile/age" exit 1 fi if ! command -v jq &> /dev/null then echo "jq could not be found, installation instructions can be found: https://github.com/jqlang/jq" exit 1 fi ECLIPSE_USERS=() GITHUB_USERS=() VERBOSE=false while getopts ":e:g:i:o:v" o; do case "${o}" in e) ECLIPSE_USERS+=(${OPTARG}) ;; g) GITHUB_USERS+=(${OPTARG}) ;; i) INPUT_FILE=${OPTARG} ;; o) OUTPUT_FILE=${OPTARG} ;; v) VERBOSE=true ;; *) usage ;; esac done shift $((OPTIND-1)) if [ ${#ECLIPSE_USERS[@]} -eq 0 ] && [ ${#GITHUB_USERS[@]} -eq 0 ]; then print_error "Need to specify at least 1 recipient" usage exit 1 fi trap cleanup EXIT KEY_FILES=() # trying to get keyfiles for any eclipse user for USER in "${ECLIPSE_USERS[@]}" do print_verbose "Downloading keyfile for Eclipse user '${USER}'" ECLIPSE_PROFILE=$(get_eclipse_profile "${USER}") if [ -z "${ECLIPSE_PROFILE}" ]; then print_error "No Eclipse profile found for user '${USER}'" exit 1 fi KEY_FILE=$(mktemp) if ! download_public_key_from_gitlab "${USER}" "${KEY_FILE}"; then print_verbose "Failed to download keys from Gitlab for user '${USER}', trying GitHub..." GITHUB_USER=$(get_github_handle "${ECLIPSE_PROFILE}") if [ -z ${GITHUB_USER} ]; then rm -f "${KEY_FILE}" print_error "Failed to get GitHub handle for Eclipse user '${USER}'" exit 1 fi if ! download_public_key_from_github "${GITHUB_USER}" "${KEY_FILE}"; then rm -f "${KEY_FILE}" print_error "Failed to download keys from GitHub for user '${GITHUB_USER}'" exit 1 else print_verbose "Downloaded keys from GitHub for user '${GITHUB_USER}'" fi else print_verbose "Downloaded keys from Gitlab for user '${USER}'" fi KEY_FILES+=($KEY_FILE) done # trying to get keyfiles for any github user for USER in "${GITHUB_USERS[@]}" do print_verbose "Downloading keyfile for GitHub user '${USER}'" KEY_FILE=$(mktemp) if ! download_public_key_from_github "${USER}" "${KEY_FILE}"; then rm -f "${KEY_FILE}" print_error "Failed to download keys from GitHub for user '${USER}'" exit 1 else print_verbose "Downloaded keys from GitHub for user '${USER}'" fi KEY_FILES+=($KEY_FILE) done INPUT=${1--} if [ -z ${OUTPUT_FILE-} ]; then print_verbose "Encrypting to standard output" else print_verbose "Encrypting to '${OUTPUT_FILE}'" fi encrypt_content "${INPUT}" "${OUTPUT_FILE-}" "${KEY_FILES[@]}"