#!/usr/bin/env bash set -euo pipefail ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd) env_file=${1:-"$ROOT/.env"} expected_environment=${2:-} if [[ "$env_file" != /* ]]; then env_file="$ROOT/$env_file" fi case "$expected_environment" in development) expected_package=org.whoneedhelp.mobile.development ;; test) expected_package=org.whoneedhelp.mobile.staging ;; production) expected_package=org.whoneedhelp.mobile ;; *) echo "Usage: $0 ENV_FILE development|test|production" >&2 exit 2 ;; esac [[ -f "$env_file" ]] || { echo "Android build environment does not exist: $env_file" >&2 exit 1 } [[ "$(stat -c '%a' "$env_file")" == 600 ]] || { echo "Android build environment must have mode 0600: $env_file" >&2 exit 1 } read_unique() { local key=$1 local output output=$( awk -v key="$key" ' index($0, key "=") == 1 { count += 1 value = substr($0, length(key) + 2) } END { if (count != 1) exit 1 if (value ~ /^".*"$/ || value ~ /^'\''.*'\''$/) { value = substr(value, 2, length(value) - 2) } print value } ' "$env_file" ) || { echo "$key must occur exactly once in $env_file." >&2 exit 1 } [[ -n "$output" ]] || { echo "$key must not be empty in $env_file." >&2 exit 1 } printf '%s' "$output" } deployment_environment=$(read_unique DEPLOYMENT_ENV) phx_host=$(read_unique PHX_HOST) phx_scheme=$(read_unique PHX_SCHEME) phx_port=$(read_unique PHX_URL_PORT) base_url=$(read_unique WNH_BASE_URL) google_oauth_client_id=$(read_unique GOOGLE_OAUTH_CLIENT_ID) google_oauth_authorized_party_ids=$(read_unique GOOGLE_OAUTH_AUTHORIZED_PARTY_IDS) app_links_package=$(read_unique ANDROID_APP_LINKS_PACKAGE_NAME) app_links_fingerprints=$(read_unique ANDROID_APP_LINKS_SHA256_CERT_FINGERPRINTS) play_app_signing_fingerprints= if [[ "$expected_environment" == production ]]; then play_app_signing_fingerprints=$( read_unique ANDROID_PLAY_APP_SIGNING_SHA256_CERT_FINGERPRINTS ) fi [[ "$deployment_environment" == "$expected_environment" ]] || { echo "Android build requires DEPLOYMENT_ENV=$expected_environment." >&2 exit 1 } [[ "$app_links_package" == "$expected_package" ]] || { echo "Android build for $expected_environment requires package $expected_package." >&2 exit 1 } [[ "$phx_scheme" == https ]] || { echo "Public Android builds require PHX_SCHEME=https." >&2 exit 1 } [[ "$phx_host" =~ ^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$ ]] || { echo "PHX_HOST must be a lowercase public DNS hostname." >&2 exit 1 } if ! [[ "$phx_port" =~ ^[1-9][0-9]{0,4}$ ]] || ((phx_port > 65535)); then echo "PHX_URL_PORT must be a valid TCP port." >&2 exit 1 fi expected_origin="https://$phx_host" if [[ "$phx_port" != 443 ]]; then expected_origin="$expected_origin:$phx_port" fi [[ "$base_url" == "$expected_origin" ]] || { echo "WNH_BASE_URL must equal the canonical PHX origin: $expected_origin" >&2 exit 1 } [[ -n "$google_oauth_client_id" ]] || { echo "Android builds require the environment's Google Web OAuth client ID." >&2 exit 1 } [[ -n "$google_oauth_authorized_party_ids" ]] || { echo "Android builds require at least one authorized Android Google OAuth client ID." >&2 exit 1 } IFS=',' read -r -a google_authorized_parties <<<"$google_oauth_authorized_party_ids" for authorized_party in "${google_authorized_parties[@]}"; do compact_party=${authorized_party//[[:space:]]/} [[ -n "$compact_party" ]] || { echo "GOOGLE_OAUTH_AUTHORIZED_PARTY_IDS contains an empty value." >&2 exit 1 } done IFS=',' read -r -a fingerprints <<<"$app_links_fingerprints" for fingerprint in "${fingerprints[@]}"; do compact=${fingerprint//:/} compact=${compact//[[:space:]]/} [[ "$compact" =~ ^[0-9A-Fa-f]{64}$ ]] || { echo "ANDROID_APP_LINKS_SHA256_CERT_FINGERPRINTS contains an invalid value." >&2 exit 1 } done if [[ "$expected_environment" == production ]]; then IFS=',' read -r -a play_fingerprints <<<"$play_app_signing_fingerprints" for play_fingerprint in "${play_fingerprints[@]}"; do compact_play=${play_fingerprint//:/} compact_play=${compact_play//[[:space:]]/} [[ "$compact_play" =~ ^[0-9A-Fa-f]{64}$ ]] || { echo "ANDROID_PLAY_APP_SIGNING_SHA256_CERT_FINGERPRINTS contains an invalid value." >&2 exit 1 } play_found=false for fingerprint in "${fingerprints[@]}"; do compact=${fingerprint//:/} compact=${compact//[[:space:]]/} if [[ "${compact^^}" == "${compact_play^^}" ]]; then play_found=true break fi done [[ "$play_found" == true ]] || { echo "The Play App Signing fingerprint is absent from the published App Links identities." >&2 exit 1 } done fi echo "Verified $expected_environment Android origin, application ID, and App Links identity."