titan-iac/services/health/scripts/sparkyfitness_oidc_configure.sh

135 lines
5.2 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
base_url="${SPARKYFITNESS_BASE_URL:-http://sparkyfitness-server.health.svc.cluster.local:3010}"
frontend_url="${SPARKYFITNESS_FRONTEND_URL:?SPARKYFITNESS_FRONTEND_URL is required}"
admin_email="${SPARKYFITNESS_ADMIN_EMAIL:?SPARKYFITNESS_ADMIN_EMAIL is required}"
admin_password="${SPARKYFITNESS_ADMIN_PASSWORD:?SPARKYFITNESS_ADMIN_PASSWORD is required}"
oidc_client_id="${SPARKYFITNESS_OIDC_CLIENT_ID:?SPARKYFITNESS_OIDC_CLIENT_ID is required}"
oidc_client_secret="${SPARKYFITNESS_OIDC_CLIENT_SECRET:?SPARKYFITNESS_OIDC_CLIENT_SECRET is required}"
oidc_issuer_url="${SPARKYFITNESS_OIDC_ISSUER_URL:?SPARKYFITNESS_OIDC_ISSUER_URL is required}"
wait_for_server() {
for attempt in 1 2 3 4 5 6 7 8 9 10; do
if curl -fsS "${base_url}/health" >/dev/null 2>&1; then
return 0
fi
sleep $((attempt * 3))
done
return 1
}
cookie_jar="$(mktemp)"
trap 'rm -f "${cookie_jar}"' EXIT
auth_login() {
local payload
payload="$(jq -nc --arg email "${admin_email}" --arg password "${admin_password}" '{email:$email,password:$password}')"
local status
status="$(curl -sS -o /tmp/sparkyfitness_login.json -w "%{http_code}" \
-c "${cookie_jar}" -b "${cookie_jar}" \
-H "Content-Type: application/json" \
-X POST "${base_url}/auth/login" \
-d "${payload}")"
if [ "${status}" = "200" ]; then
return 0
fi
return 1
}
auth_register() {
local payload
payload="$(jq -nc --arg email "${admin_email}" --arg password "${admin_password}" --arg full_name "Sparky Admin" '{email:$email,password:$password,full_name:$full_name}')"
curl -sS -o /tmp/sparkyfitness_register.json -w "%{http_code}" \
-c "${cookie_jar}" -b "${cookie_jar}" \
-H "Content-Type: application/json" \
-X POST "${base_url}/auth/register" \
-d "${payload}"
}
if ! wait_for_server; then
echo "SparkyFitness is not responding at ${base_url}" >&2
exit 1
fi
if ! auth_login; then
status="$(auth_register)"
if [ "${status}" = "409" ]; then
if ! auth_login; then
echo "Admin login failed after existing user detected" >&2
exit 1
fi
elif [ "${status}" = "201" ]; then
if ! auth_login; then
echo "Admin login failed after registration" >&2
exit 1
fi
elif [ "${status}" = "403" ]; then
echo "Registration disabled; unable to bootstrap admin user" >&2
exit 1
else
echo "Admin registration failed (status ${status})" >&2
exit 1
fi
fi
settings_json="$(curl -sS -b "${cookie_jar}" "${base_url}/admin/global-settings")"
if [ -z "${settings_json}" ]; then
echo "Failed to fetch SparkyFitness global settings" >&2
exit 1
fi
email_enabled="$(echo "${settings_json}" | jq -r '.enable_email_password_login // true')"
mfa_mandatory="$(echo "${settings_json}" | jq -r '.is_mfa_mandatory // .mfa_mandatory // false')"
settings_payload="$(jq -nc \
--argjson enable_email_password_login "${email_enabled}" \
--argjson is_oidc_active true \
--argjson is_mfa_mandatory "${mfa_mandatory}" \
'{enable_email_password_login:$enable_email_password_login,is_oidc_active:$is_oidc_active,is_mfa_mandatory:$is_mfa_mandatory}')"
status="$(curl -sS -o /dev/null -w "%{http_code}" -b "${cookie_jar}" \
-H "Content-Type: application/json" \
-X PUT "${base_url}/admin/global-settings" \
-d "${settings_payload}")"
if [ "${status}" != "200" ]; then
echo "Failed to update SparkyFitness global settings (status ${status})" >&2
exit 1
fi
providers_json="$(curl -sS -b "${cookie_jar}" "${base_url}/admin/oidc-settings")"
provider_id="$(echo "${providers_json}" | jq -r --arg issuer "${oidc_issuer_url}" '.[] | select(.issuer_url==$issuer) | .id' 2>/dev/null | head -n1 || true)"
redirect_uri="${frontend_url%/}/oidc-callback"
provider_payload="$(jq -nc \
--arg issuer_url "${oidc_issuer_url}" \
--arg client_id "${oidc_client_id}" \
--arg client_secret "${oidc_client_secret}" \
--arg redirect_uri "${redirect_uri}" \
--arg scope "openid profile email" \
--arg token_endpoint_auth_method "client_secret_post" \
--argjson response_types '["code"]' \
--argjson is_active true \
--arg display_name "Atlas SSO" \
--argjson auto_register true \
--arg signing_algorithm "RS256" \
--arg profile_signing_algorithm "none" \
--argjson timeout 30000 \
'{issuer_url:$issuer_url,client_id:$client_id,client_secret:$client_secret,redirect_uris:[$redirect_uri],scope:$scope,token_endpoint_auth_method:$token_endpoint_auth_method,response_types:$response_types,is_active:$is_active,display_name:$display_name,auto_register:$auto_register,signing_algorithm:$signing_algorithm,profile_signing_algorithm:$profile_signing_algorithm,timeout:$timeout}')"
if [ -n "${provider_id}" ] && [ "${provider_id}" != "null" ]; then
status="$(curl -sS -o /dev/null -w "%{http_code}" -b "${cookie_jar}" \
-H "Content-Type: application/json" \
-X PUT "${base_url}/admin/oidc-settings/${provider_id}" \
-d "${provider_payload}")"
else
status="$(curl -sS -o /dev/null -w "%{http_code}" -b "${cookie_jar}" \
-H "Content-Type: application/json" \
-X POST "${base_url}/admin/oidc-settings" \
-d "${provider_payload}")"
fi
if [ "${status}" != "200" ] && [ "${status}" != "201" ]; then
echo "Failed to upsert SparkyFitness OIDC provider (status ${status})" >&2
exit 1
fi