#!/usr/bin/bash
# SPDX-License-Identifier: AGPL-3.0-or-later
# SPDX-FileCopyrightText: 2023 grommunio GmbH

set -e

PROGNAME="`basename $0`"
ADAPTOR_CONFIG_DIR='/var/cache/grommunio-auth/adaptor-config'
GCHAT_ADAPTOR_CONFIG='keycloak-grommunio-chat.json'
GCHAT_ADAPTOR_PUBKEY='keycloak-grommunio-chat.bearer_pubkey'
GCHAT_ADAPTOR_CFG="${ADAPTOR_CONFIG_DIR}/${GCHAT_ADAPTOR_CONFIG}"
GCHAT_CONFIG_JSON="/etc/grommunio-chat/config.json"
# grommunio-chat 9.11 ships a native keycloak provider
SSO_BLOCK='KeycloakSettings'


check_if_root () {
	local MY_EUID=$(id -u)
	if [ -n "$MY_EUID" -a $MY_EUID -ne 0 ]; then
		echo "${PROGNAME}: this program must be run as root" 1>&2
		exit 2
	fi
}

check_if_configured () {
	if [ ! -s "$GCHAT_CONFIG_JSON" ]; then
		echo "${PROGNAME}: ${GCHAT_CONFIG_JSON} not found, grommunio-chat is not set up" 1>&2
		exit 3
	fi
}

# Replace config.json by the output of the given jq program and restart chat
write_config () {
	local TMP_FILE
	TMP_FILE=$(mktemp "${GCHAT_CONFIG_JSON}.XXXXXXXXXX")
	jq "$@" "$GCHAT_CONFIG_JSON" > "$TMP_FILE"
	chown grochat:grochat "$TMP_FILE"
	chmod '0640' "$TMP_FILE"
	mv "$TMP_FILE" "$GCHAT_CONFIG_JSON"
	echo -n "Restarting/reloading g-chat..."
	systemctl try-reload-or-restart grommunio-chat
	echo " done."
}

# Linked accounts must use the SSO service, or the OAuth login rejects them
sso_accounts () {
	command -v grommunio-admin > /dev/null || return 0
	local LISTEN=$(jq -r '.ServiceSettings.ListenAddress' "$GCHAT_CONFIG_JSON")
	[ "${LISTEN#:}" = "$LISTEN" ] || LISTEN="127.0.0.1${LISTEN}"
	for _ in $(seq 20); do
		curl -sfL -o /dev/null "http://${LISTEN}/api/v4/system/ping" && break
		sleep 1
	done
	grommunio-admin chat sso "$1" || echo "${PROGNAME}: 'grommunio-admin chat sso $1' failed, rerun it by hand" 1>&2
}

case "$PROGNAME" in
	setup-gk-app-g-chat)
		check_if_root
		check_if_configured

		KC_ID=$(jq -r .resource "$GCHAT_ADAPTOR_CFG")
		KC_SECRET=$(jq -r .credentials.secret "$GCHAT_ADAPTOR_CFG")
		KC_URL=$(jq -r '."auth-server-url"' "$GCHAT_ADAPTOR_CFG")
		KC_REALM=$(jq -r .realm "$GCHAT_ADAPTOR_CFG")
		write_config --arg block "$SSO_BLOCK" --arg id "$KC_ID" --arg secret "$KC_SECRET" \
			--arg oidc "${KC_URL}realms/${KC_REALM}" '.[$block] += {
			Enable: true,
			Id: $id,
			Secret: $secret,
			Scope: "openid profile email",
			AuthEndpoint: ($oidc + "/protocol/openid-connect/auth"),
			TokenEndpoint: ($oidc + "/protocol/openid-connect/token"),
			UserAPIEndpoint: ($oidc + "/protocol/openid-connect/userinfo"),
			DiscoveryEndpoint: ($oidc + "/.well-known/openid-configuration"),
			ButtonText: "grommunio",
			ButtonColor: "#0072B0"
		}'
		sso_accounts enable
		# Clean up stragglers
		shred "${ADAPTOR_CONFIG_DIR}/${GCHAT_ADAPTOR_CONFIG}" || true
		rm -vf "${ADAPTOR_CONFIG_DIR}/${GCHAT_ADAPTOR_CONFIG}" || true
		rm -vf "${ADAPTOR_CONFIG_DIR}/${GCHAT_ADAPTOR_PUBKEY}" || true
		;;
	delete-gk-app-g-chat)
		check_if_root
		check_if_configured

		write_config --arg block "$SSO_BLOCK" '.[$block] += {
			Enable: false,
			Id: "",
			Secret: "",
			Scope: "",
			AuthEndpoint: "",
			TokenEndpoint: "",
			UserAPIEndpoint: "",
			DiscoveryEndpoint: "",
			ButtonText: "",
			ButtonColor: ""
		}'
		sso_accounts disable
		;;
esac
