Files
keycloak-pattern/scripts/configure-google-idp.sh
T

151 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env sh
set -eu
if [ ! -f .env ]; then
echo "missing .env" >&2
exit 1
fi
set -a
. ./.env
set +a
: "${KC_BOOTSTRAP_ADMIN_USERNAME:?set KC_BOOTSTRAP_ADMIN_USERNAME in .env}"
: "${KC_BOOTSTRAP_ADMIN_PASSWORD:?set KC_BOOTSTRAP_ADMIN_PASSWORD in .env}"
: "${GOOGLE_CLIENT_ID:?set GOOGLE_CLIENT_ID in .env}"
: "${GOOGLE_CLIENT_SECRET:?set GOOGLE_CLIENT_SECRET in .env}"
./scripts/configure-broker-user-profile.sh
keycloak_url="${KEYCLOAK_URL:-http://localhost:8080}"
realm="${KEYCLOAK_REALM:-keycloak-patterns}"
admin_token="$(
curl -fsS \
-d client_id=admin-cli \
-d grant_type=password \
-d "username=$KC_BOOTSTRAP_ADMIN_USERNAME" \
-d "password=$KC_BOOTSTRAP_ADMIN_PASSWORD" \
"$keycloak_url/realms/master/protocol/openid-connect/token" |
jq -er .access_token
)"
payload="$(
jq -n \
--arg client_id "$GOOGLE_CLIENT_ID" \
--arg client_secret "$GOOGLE_CLIENT_SECRET" \
'{
alias: "google",
displayName: "Sign in with Google",
providerId: "google",
enabled: true,
updateProfileFirstLoginMode: "off",
trustEmail: false,
storeToken: false,
addReadTokenRoleOnCreate: false,
authenticateByDefault: false,
linkOnly: false,
firstBrokerLoginFlowAlias: "first broker login",
config: {
clientId: $client_id,
clientSecret: $client_secret,
defaultScope: "openid profile email",
syncMode: "IMPORT"
}
}'
)"
endpoint="$keycloak_url/admin/realms/$realm/identity-provider/instances"
status="$(
curl -sS -o /dev/null -w '%{http_code}' \
-H "Authorization: Bearer $admin_token" \
"$endpoint/google"
)"
if [ "$status" = "200" ]; then
curl -fsS -X PUT \
-H "Authorization: Bearer $admin_token" \
-H "Content-Type: application/json" \
--data "$payload" \
"$endpoint/google"
action="updated"
else
curl -fsS -X POST \
-H "Authorization: Bearer $admin_token" \
-H "Content-Type: application/json" \
--data "$payload" \
"$endpoint"
action="created"
fi
mapper_endpoint="$endpoint/google/mappers"
upsert_mapper() {
mapper_name="$1"
mapper_type="$2"
mapper_config="$3"
mapper_id="$(
curl -fsS \
-H "Authorization: Bearer $admin_token" \
"$mapper_endpoint" |
jq -r --arg name "$mapper_name" '
.[] | select(.name == $name) | .id
' |
head -1
)"
mapper_payload="$(
jq -n \
--arg name "$mapper_name" \
--arg alias "google" \
--arg mapper "$mapper_type" \
--argjson config "$mapper_config" \
'{
name: $name,
identityProviderAlias: $alias,
identityProviderMapper: $mapper,
config: $config
}'
)"
if [ -n "$mapper_id" ]; then
curl -fsS -X PUT \
-H "Authorization: Bearer $admin_token" \
-H "Content-Type: application/json" \
--data "$mapper_payload" \
"$mapper_endpoint/$mapper_id"
else
curl -fsS -X POST \
-H "Authorization: Bearer $admin_token" \
-H "Content-Type: application/json" \
--data "$mapper_payload" \
"$mapper_endpoint"
fi
}
upsert_mapper \
"google-stable-username" \
"oidc-username-idp-mapper" \
'{"template":"${ALIAS}.${CLAIM.sub}","target":"LOCAL"}'
upsert_mapper \
"google-email" \
"oidc-user-attribute-idp-mapper" \
'{"syncMode":"INHERIT","claim":"email","user.attribute":"email"}'
upsert_mapper \
"google-given-name" \
"oidc-user-attribute-idp-mapper" \
'{"syncMode":"INHERIT","claim":"given_name","user.attribute":"firstName"}'
upsert_mapper \
"google-family-name" \
"oidc-user-attribute-idp-mapper" \
'{"syncMode":"INHERIT","claim":"family_name","user.attribute":"lastName"}'
upsert_mapper \
"google-picture" \
"oidc-user-attribute-idp-mapper" \
'{"syncMode":"INHERIT","claim":"picture","user.attribute":"picture"}'
upsert_mapper \
"google-hosted-domain" \
"oidc-user-attribute-idp-mapper" \
'{"syncMode":"INHERIT","claim":"hd","user.attribute":"hd"}'
echo "Google Identity Provider $action for realm '$realm'"
echo "Register this exact Google redirect URI:"
echo "$keycloak_url/realms/$realm/broker/google/endpoint"