135 lines
5.2 KiB
Bash
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
|