#!/bin/env bash #-------------------------------------------- set -Eeuo pipefail if [[ -n "${DEBUG:-}" ]]; then set -x fi trap stack_trace ERR function stack_trace() { echo -e "\nThe command '$BASH_COMMAND' triggerd a stacktrace:\nStack Trace:" for ((i = 1; i < ${#FUNCNAME[@]}; i++)); do echo " ($i) ${FUNCNAME[$i]:-(top level)} ${BASH_SOURCE[$i]:-(no file)}:${BASH_LINENO[$((i - 1))]}" done } error() { printf "\e[1;31m[ERROR]\e[0m %s\n" "${1:-error message missing}" && trap true ERR && return 1; } warning() { printf "\e[1;33m[WARNING]\e[0m %s\n" "$1" >&2; } success() { printf "\e[1;32m[SUCCESS]\e[0m %s\n" "$1" >&2; } info() { printf "\e[1;34m[INFO]\e[0m %s\n" "$1" >&2; } green() { if [[ -t 0 ]]; then printf "\e[1;32m%s\e[0m" "$1"; else printf "%s" "$1"; fi; } red() { if [[ -t 0 ]]; then printf "\e[1;31m%s\e[0m" "$1"; else printf "%s" "$1"; fi; } blue() { if [[ -t 0 ]]; then printf "\e[1;34m%s\e[0m" "$1"; else printf "%s" "$1"; fi; } SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" export SCRIPT_DIR #-------------------------------------------- declare -A patchwork__commands declare -A patchwork__command_descriptions patchwork::desc() { patchwork__commands["$1"]="$1" patchwork__command_descriptions["$1"]="$2" } declare -A patchwork__aliases patchwork::alias() { patchwork__aliases["$1"]+="|$2" patchwork__commands["$2"]="$1" } patchwork::desc help "Show this help message" patchwork::help() { case "${1:-list}" in */) printf "Group Commands for %s:\n" "$(green "${1}")" for key in "${!patchwork__command_descriptions[@]}"; do if [[ "$key" == "${1}"?* ]]; then local name_without_group="${key:${#1}}" if [[ (! "$name_without_group" == */*) || "$name_without_group" =~ ^[a-zA-Z0-9]+/$ ]]; then if [[ -v patchwork__aliases[$key] ]]; then printf " %s: %s\n" \ "$(green "$key${patchwork__aliases[$key]}")" \ "${patchwork__command_descriptions[$key]}" else printf " %s: %s\n" \ "$(green "$key")" \ "${patchwork__command_descriptions[$key]}" fi fi fi done ;; list) echo "Usage: patchwork [command]" echo "Commands:" for key in "${!patchwork__command_descriptions[@]}"; do if [[ (! "$key" == */*) || "$key" =~ ^[a-zA-Z0-9_.-]+/$ ]]; then if [[ -v patchwork__aliases[$key] ]]; then printf " %s: %s\n" \ "$(green "$key${patchwork__aliases[$key]}")" \ "${patchwork__command_descriptions[$key]}" else printf " %s: %s\n" \ "$(green "$key")" \ "${patchwork__command_descriptions[$key]}" fi fi done ;; *) if [[ -v patchwork__command_descriptions[$1] ]]; then printf "Usage: patchwork %s\n" "$(green "$1")" if [[ -v patchwork__aliases[$1] ]]; then printf "Aliases: %s\n" "$(green "${patchwork__aliases[$1]//|/ }")" fi printf "%s\n" "${patchwork__command_descriptions[$1]}" else error "Unknown command: $1" fi ;; esac } patchwork() { local base_zero base_zero="$(basename "$0")" if [[ "$base_zero" = ".main" || "$base_zero" = "patchwork" || "$base_zero" = "patchwork.sh" ]]; then command="${1:-help}" shift || true else command="$base_zero" fi if [[ "$command" == */ ]]; then "patchwork::help" "$command" "$@" elif [[ -v patchwork__commands[$command] ]]; then "patchwork::${patchwork__commands[$command]}" "$@" else error "Unknown command: $command" fi } ######################################### Globals ########################################## patchwork__server="${PATCHWORK_SERVER:-https://patch.tionis.dev}" patchwork__server_req="$patchwork__server/p/" ######################################### Commands ########################################## patchwork::desc token "Create a new token" patchwork::token() { declare allowedWritePaths allowedReadPaths key allowedReadPathsJSON allowedWritePathsJSON dataJSON validBefore validAfter allowedReadPaths=() allowedWritePaths=() validBefore="$(date --date='1 hour' +%s)" validAfter="$(date +%s)" key=~/.ssh/id_ed25519 while [[ $# -gt 0 ]]; do case "$1" in --help) echo "Usage: $(basename "$0") token [options]" echo "Options:" echo " -k, --key The key to sign the token with, defaults to ~/.ssh/id_ed25519" echo " -r, --read Add a path to the allowed read paths, if not specified all paths are allowed" echo " -w, --write Add a path to the allowed write paths, if not specified all paths are allowed" echo " -b, --before