Signature example in CLI

usage() {
  echo "Usage: $0 [--verbose] [--text] [token] [secret] <method> <path> [body] [timestamp]

Arguments:
  --verbose             Optional; Log debugging output
  --text                Optional; Post data as text instead of json
  token                 Token used for auth
  secret                Token used for auth
  method                HTTP method; e.g. GET, POST
  path                  URL endpoint relative to API root
  body                  Body of the request to post
  timestamp             UTC timestamp used for auth, defaults to the current time

Environment variables:
  THESEUS_API_ROOT      Required; signifies the API host; e.g. https://theseus-api-integrations.signalvine.com
  SV_TOKEN              Can be supplied instead of the 'token' argument
  SV_SECRET             Can be supplied isntead of the 'secret' argument
  CURL_OPTS             Additional arguments passed to curl command; default: '$default_curl_opts'

Example:
  $0 GET /v1/accounts/1b99980f-e5e2-4032-8306-1f468f8623be/programs
"
}

if [ "$1" = "--verbose" ]; then
  verbose=1
  shift
fi

log() {
  if [ -n "$verbose" ]; then
    >&2 echo "${text_yellow}LOG:" "$@" "${text_reset}"
  fi
}

log_no_prefix() {
  if [ -n "$verbose" ]; then
    >&2 echo "${text_yellow}$@${text_reset}"
  fi
}

log_exec() {
  log "$@"
  "$@"
}

if [ "$1" = "--text" ]; then
  content_type="text/plain"
  shift
else
  content_type="application/json"
fi

token=$SV_TOKEN
if [ -z "$token" ]; then
  if [ -z "$1" ]; then
    >&2 usage
    exit 1
  fi
  token=$1
  shift
fi

if [ "$(wc -m <<< "$token")" -ne 33 ]; then
  >&2 echo "ERROR: Missing token"
  >&2 echo "-------------------------------"
  >&2 usage
  exit 1
fi

secret=$SV_SECRET
if [ -z "$SV_SECRET" ]; then
  if [ -z "$1" ]; then
    >&2 usage
    exit 1
  fi
  secret=$1
  shift
fi

if [ "$(wc -m <<< "$secret")" -ne 37 ]; then
  >&2 echo "ERROR: Missing secret"
  >&2 echo "-------------------------------"
  >&2 usage
  exit 1
fi

if [ "$#" -lt 2 ]; then
  >&2 usage
  exit 1
fi

method=$1
log "METHOD: $method"
url=$2
log "URL: $url"
body=$3
log "BODY: $body"
timestamp="${4:-$(date -u +'%Y-%m-%dT%H:%M:%S.000Z')}"
log "TIMESTAMP: $timestamp"

if [ "$content_type" = "application/json" ]; then
  # If our body is JSON, remove any unnecessary whitespace so the generated signature
  # will match that of theseus'
  body="$(jq '.' -c <<< "$body")"
  log "JSON BODY: $body"
fi

path="$(cut -d '?' -f 1 <<< "$url")"
log "PATH: $path"

api_root=$THESEUS_API_ROOT
log "API ROOT: $api_root"

if [ -z "$api_root" ]; then
  >&2 echo "Must define THESEUS_API_ROOT env var"
  exit 1
fi

string_to_sign="$token
$method
$path
$body
$timestamp"
log "STRING TO SIGN BELOW:"
log_no_prefix "$string_to_sign"
log "^^^^^"

sign() {
  printf "$1" |
    tr '[:upper:]' '[:lower:]' |
    openssl dgst -binary -sha256 -hmac "$secret" |
    openssl base64
}

signature="$(sign "$string_to_sign")"
log "SIGNATURE: $signature"

log_exec curl \
  -H "SignalVine-Date: $timestamp" \
  -H "Authorization: SignalVine ${token}:${signature}" \
  -H "Content-Type: $content_type" \
  -X "$method" \
  "${api_root}${url}" \
  -d "$body" \
  $CURL_OPTS
Was this article helpful?
0 out of 0 found this helpful
Have more questions? Submit a request

Comments

0 comments

Please sign in to leave a comment.