#!/usr/bin/env bash set -euo pipefail action="${1:-apply}" script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" repo_root="$(cd -- "${script_dir}/../../.." && pwd)" compose_file="${repo_root}/infra/docker/docker-compose.yml" realm="${TJWATER_KEYCLOAK_REALM:-tjwater}" client_id="${TJWATER_KEYCLOAK_CLIENT_ID:-tjwater}" display_name="${TJWATER_KEYCLOAK_DISPLAY_NAME:-TJWater 智慧水务平台}" case "${action}" in apply|verify|rollback) ;; *) echo "用法: bash infra/docker/keycloak/configure-theme.sh [apply|verify|rollback]" >&2 exit 2 ;; esac compose_args=(docker compose) if [[ -f "${repo_root}/.env" ]]; then compose_args+=(--env-file "${repo_root}/.env") fi compose_args+=(-f "${compose_file}") "${compose_args[@]}" exec -T \ -e TJWATER_KEYCLOAK_ACTION="${action}" \ -e TJWATER_KEYCLOAK_REALM="${realm}" \ -e TJWATER_KEYCLOAK_CLIENT_ID="${client_id}" \ -e TJWATER_KEYCLOAK_DISPLAY_NAME="${display_name}" \ keycloak sh -s <<'KEYCLOAK_SCRIPT' set -eu action="${TJWATER_KEYCLOAK_ACTION}" realm="${TJWATER_KEYCLOAK_REALM}" client_id="${TJWATER_KEYCLOAK_CLIENT_ID}" display_name="${TJWATER_KEYCLOAK_DISPLAY_NAME}" server_url="${TJWATER_KEYCLOAK_SERVER_URL:-http://127.0.0.1:8080}" admin_user="${KC_BOOTSTRAP_ADMIN_USERNAME:-${KEYCLOAK_ADMIN:-}}" admin_password="${KC_BOOTSTRAP_ADMIN_PASSWORD:-${KEYCLOAK_ADMIN_PASSWORD:-}}" config_file="/tmp/tjwater-kcadm-$$.config" kcadm="/opt/keycloak/bin/kcadm.sh" cleanup() { rm -f "${config_file}" } trap cleanup EXIT if [ -z "${admin_user}" ] || [ -z "${admin_password}" ]; then echo "缺少 Keycloak 管理员用户名或密码环境变量。" >&2 exit 1 fi if [ "${action}" = "apply" ] && [ ! -f /opt/keycloak/themes/tjwater/login/theme.properties ]; then echo "未找到 tjwater 登录主题,请检查主题目录挂载。" >&2 exit 1 fi "${kcadm}" config credentials \ --config "${config_file}" \ --server "${server_url}" \ --realm master \ --user "${admin_user}" \ --password "${admin_password}" >/dev/null client_uuid="$( "${kcadm}" get clients \ --config "${config_file}" \ --target-realm "${realm}" \ --query "clientId=${client_id}" \ --fields id \ --format csv \ --noquotes | sed -n '1p' )" if [ -z "${client_uuid}" ]; then echo "realm ${realm} 中未找到 client ${client_id}。" >&2 echo "可通过 TJWATER_KEYCLOAK_CLIENT_ID 指定实际的 client ID。" >&2 exit 1 fi case "${action}" in apply) "${kcadm}" update "realms/${realm}" \ --config "${config_file}" \ -s "displayName=${display_name}" \ -s "displayNameHtml=${display_name}" \ -s "loginTheme=tjwater" \ -s "internationalizationEnabled=true" \ -s 'supportedLocales=["zh-CN","en"]' \ -s "defaultLocale=zh-CN" >/dev/null "${kcadm}" update "clients/${client_uuid}" \ --config "${config_file}" \ --target-realm "${realm}" \ --set attributes.login_theme= >/dev/null echo "已为 realm ${realm} 启用 tjwater 登录主题。" echo "client ${client_id} 已改为继承 realm 登录主题。" ;; rollback) "${kcadm}" update "realms/${realm}" \ --config "${config_file}" \ -s "loginTheme=keycloak" >/dev/null echo "已将 realm ${realm} 恢复为 Keycloak 默认登录主题。" ;; esac "${kcadm}" get "realms/${realm}" \ --config "${config_file}" \ --fields realm,displayName,loginTheme,internationalizationEnabled,supportedLocales,defaultLocale "${kcadm}" get "clients/${client_uuid}" \ --config "${config_file}" \ --target-realm "${realm}" \ --fields 'clientId,attributes(login_theme)' KEYCLOAK_SCRIPT