titan-iac/scripts/nextcloud-mail-sync.sh

72 lines
2.3 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
KC_BASE="${KC_BASE:?}"
KC_REALM="${KC_REALM:?}"
KC_ADMIN_USER="${KC_ADMIN_USER:?}"
KC_ADMIN_PASS="${KC_ADMIN_PASS:?}"
MAILU_DOMAIN="${MAILU_DOMAIN:?}"
if ! command -v jq >/dev/null 2>&1; then
apt-get update && apt-get install -y jq curl >/dev/null
fi
account_exists() {
local user_id="${1}"
local email="${2}"
# Nextcloud Mail does not provide a list command; export is safe (does not print passwords).
local export
if ! export=$(/usr/sbin/runuser -u www-data -- php occ mail:account:export "${user_id}" 2>/dev/null); then
echo "WARN: unable to export mail accounts for ${user_id}; skipping sync for safety" >&2
return 0
fi
# Output formatting varies by Nextcloud/Mail versions and locale; match by email address.
grep -Fq -- "${email}" <<<"${export}"
}
token=$(
curl -s -d "grant_type=password" \
-d "client_id=admin-cli" \
-d "username=${KC_ADMIN_USER}" \
-d "password=${KC_ADMIN_PASS}" \
"${KC_BASE}/realms/master/protocol/openid-connect/token" | jq -r '.access_token'
)
if [[ -z "${token}" || "${token}" == "null" ]]; then
echo "Failed to obtain admin token"
exit 1
fi
cd /var/www/html
users=$(curl -s -H "Authorization: Bearer ${token}" \
"${KC_BASE}/admin/realms/${KC_REALM}/users?max=2000")
echo "${users}" | jq -c '.[]' | while read -r user; do
username=$(echo "${user}" | jq -r '.username')
keycloak_email=$(echo "${user}" | jq -r '.email // empty')
mailu_email=$(echo "${user}" | jq -r '(.attributes.mailu_email[0] // .attributes.mailu_email // empty)')
app_pw=$(echo "${user}" | jq -r '(.attributes.mailu_app_password[0] // .attributes.mailu_app_password // empty)')
if [[ -z "${mailu_email}" ]]; then
if [[ -n "${keycloak_email}" && "${keycloak_email,,}" == *"@${MAILU_DOMAIN,,}" ]]; then
mailu_email="${keycloak_email}"
else
mailu_email="${username}@${MAILU_DOMAIN}"
fi
fi
[[ -z "${mailu_email}" || -z "${app_pw}" ]] && continue
if account_exists "${username}" "${mailu_email}"; then
echo "Skipping ${mailu_email}, already exists"
continue
fi
echo "Syncing ${mailu_email}"
/usr/sbin/runuser -u www-data -- php occ mail:account:create \
"${username}" "${username}" "${mailu_email}" \
mail.bstein.dev 993 ssl "${mailu_email}" "${app_pw}" \
mail.bstein.dev 587 tls "${mailu_email}" "${app_pw}" || true
done