#!/usr/bin/env bash set -euo pipefail base_url="${ENDURAIN_BASE_URL:-http://endurain.health.svc.cluster.local}" admin_username="${ENDURAIN_ADMIN_USERNAME:-admin}" admin_password="${ENDURAIN_ADMIN_PASSWORD:?ENDURAIN_ADMIN_PASSWORD is required}" default_password="${ENDURAIN_DEFAULT_ADMIN_PASSWORD:-admin}" oidc_client_id="${ENDURAIN_OIDC_CLIENT_ID:?ENDURAIN_OIDC_CLIENT_ID is required}" oidc_client_secret="${ENDURAIN_OIDC_CLIENT_SECRET:?ENDURAIN_OIDC_CLIENT_SECRET is required}" oidc_issuer_url="${ENDURAIN_OIDC_ISSUER_URL:?ENDURAIN_OIDC_ISSUER_URL is required}" wait_for_endurain() { for attempt in 1 2 3 4 5 6 7 8 9 10; do if curl -fsS "${base_url}/api/v1/about" >/dev/null 2>&1; then return 0 fi sleep $((attempt * 3)) done return 1 } login() { local username="$1" local password="$2" local token token="$(curl -sS -X POST "${base_url}/api/v1/auth/login" \ -H "X-Client-Type: mobile" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "grant_type=password" \ --data-urlencode "username=${username}" \ --data-urlencode "password=${password}" | jq -r '.access_token' 2>/dev/null || true)" if [ -n "${token}" ] && [ "${token}" != "null" ]; then echo "${token}" return 0 fi return 1 } if ! wait_for_endurain; then echo "Endurain is not responding at ${base_url}" >&2 exit 1 fi token="$(login "${admin_username}" "${admin_password}" || true)" if [ -z "${token}" ]; then token="$(login "${admin_username}" "${default_password}" || true)" if [ -z "${token}" ]; then echo "Failed to authenticate to Endurain as admin" >&2 exit 1 fi if [ "${admin_password}" != "${default_password}" ]; then user_id="$(curl -sS -H "Authorization: Bearer ${token}" -H "X-Client-Type: mobile" \ "${base_url}/api/v1/users/username/${admin_username}" | jq -r '.id' 2>/dev/null || true)" if [ -z "${user_id}" ] || [ "${user_id}" = "null" ]; then echo "Admin user ${admin_username} not found" >&2 exit 1 fi update_payload="$(jq -nc --arg password "${admin_password}" '{password:$password}')" status="$(curl -sS -o /dev/null -w "%{http_code}" -X PUT \ -H "Authorization: Bearer ${token}" \ -H "X-Client-Type: mobile" \ -H "Content-Type: application/json" \ -d "${update_payload}" \ "${base_url}/api/v1/users/${user_id}/password")" if [ "${status}" != "200" ] && [ "${status}" != "201" ]; then echo "Failed to rotate Endurain admin password (status ${status})" >&2 exit 1 fi token="$(login "${admin_username}" "${admin_password}" || true)" if [ -z "${token}" ]; then echo "Failed to authenticate with rotated admin password" >&2 exit 1 fi fi fi idp_payload="$(jq -nc \ --arg name "Keycloak" \ --arg slug "keycloak" \ --arg issuer_url "${oidc_issuer_url}" \ --arg scopes "openid profile email" \ --arg client_id "${oidc_client_id}" \ --arg client_secret "${oidc_client_secret}" \ --arg icon "keycloak" \ --argjson enabled true \ --argjson auto_create_users true \ --argjson sync_user_info true \ --argjson user_mapping '{"username":["preferred_username","username","email"],"email":["email","mail"],"name":["name","display_name","full_name"]}' \ '{name:$name,slug:$slug,provider_type:"oidc",enabled:$enabled,issuer_url:$issuer_url,scopes:$scopes,icon:$icon,auto_create_users:$auto_create_users,sync_user_info:$sync_user_info,user_mapping:$user_mapping,client_id:$client_id,client_secret:$client_secret}')" idp_id="$(curl -sS -H "Authorization: Bearer ${token}" -H "X-Client-Type: mobile" \ "${base_url}/api/v1/idp" | jq -r '.[] | select(.slug=="keycloak") | .id' 2>/dev/null | head -n1 || true)" if [ -n "${idp_id}" ] && [ "${idp_id}" != "null" ]; then status="$(curl -sS -o /dev/null -w "%{http_code}" -X PUT \ -H "Authorization: Bearer ${token}" \ -H "X-Client-Type: mobile" \ -H "Content-Type: application/json" \ -d "${idp_payload}" \ "${base_url}/api/v1/idp/${idp_id}")" else status="$(curl -sS -o /dev/null -w "%{http_code}" -X POST \ -H "Authorization: Bearer ${token}" \ -H "X-Client-Type: mobile" \ -H "Content-Type: application/json" \ -d "${idp_payload}" \ "${base_url}/api/v1/idp")" fi if [ "${status}" != "200" ] && [ "${status}" != "201" ] && [ "${status}" != "204" ]; then echo "Failed to upsert Endurain OIDC provider (status ${status})" >&2 exit 1 fi settings_json="$(curl -sS -H "Authorization: Bearer ${token}" -H "X-Client-Type: mobile" \ "${base_url}/api/v1/server_settings")" if [ -z "${settings_json}" ]; then echo "Failed to fetch Endurain server settings" >&2 exit 1 fi settings_payload="$(echo "${settings_json}" | jq \ '.sso_enabled=true | .sso_auto_redirect=true | .signup_enabled=false | .local_login_enabled=true')" status="$(curl -sS -o /dev/null -w "%{http_code}" -X PUT \ -H "Authorization: Bearer ${token}" \ -H "X-Client-Type: mobile" \ -H "Content-Type: application/json" \ -d "${settings_payload}" \ "${base_url}/api/v1/server_settings")" if [ "${status}" != "200" ] && [ "${status}" != "201" ]; then echo "Failed to update Endurain server settings (status ${status})" >&2 exit 1 fi