#!/bin/bash
################################################################################
# Script Name: version/2.1.17/UPDATE.sh
# Description: Repair PostgreSQL authentication on servers where none worked.
# Company: hitechcloud.org
# Copyright (c) hitechcloud.org
################################################################################
#
# On every RHEL-family server this panel has built, no PostgreSQL password
# login has ever succeeded.
#
# pg_hba.conf was written asking for scram-sha-256 and password_encryption was
# never set. EL8 defaults it to md5, so every password the panel stored - the
# webmail's, and every hosting account's database role - was hashed the old
# way, and an md5 hash cannot satisfy a scram-sha-256 line. The symptom was
# "password authentication failed for user", which reads as a wrong password
# and could not be fixed by setting the password again.
#
# This applies the corrected configuration: password_encryption becomes
# scram-sha-256 so everything set from now on is SCRAM, and the pg_hba method
# follows what is actually stored - md5 while any role still has an md5
# password, because PostgreSQL reads that line as "md5, or SCRAM if that is
# how this one is stored" and it therefore serves both.
#
# Debian servers already had password_encryption right and this changes
# nothing on them.
################################################################################

set -uo pipefail

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
ok()   { echo -e "[2.1.17] ${GREEN}✓${NC} $*"; }
warn() { echo -e "[2.1.17] ${YELLOW}!${NC} $*" >&2; }
say()  { echo -e "[2.1.17] $*"; }

[[ $EUID -eq 0 ]] || { echo "[2.1.17] This update must run as root." >&2; exit 1; }

if ! command -v psql >/dev/null 2>&1 || ! su - postgres -c 'psql -tAc "SELECT 1"' >/dev/null 2>&1; then
    say "no PostgreSQL on this server; nothing to do"
    exit 0
fi

# shellcheck source=/dev/null
source /usr/local/hitechcloudcli/lib/native.sh 2>/dev/null || {
    warn "the CLI library is not in place yet; PostgreSQL authentication will be corrected on the next update."
    exit 0
}

say "Checking PostgreSQL authentication"
native_configure_postgres_auth

# The webmail's own role, which is the one this panel is responsible for and
# the one whose failure stops a service. A customer's database password is
# theirs and cannot be re-derived here; those roles keep working through the
# md5 line above until their owner sets a new password.
pw_file=/etc/hitechcloud/native/webmail/db_password
if [[ -s "$pw_file" ]] && su - postgres -c "psql -tAc \"SELECT 1 FROM pg_roles WHERE rolname='mailflow'\"" 2>/dev/null | grep -q 1; then
    pw=$(cat "$pw_file")
    su - postgres -c "psql -c \"ALTER ROLE mailflow LOGIN PASSWORD '${pw//\'/\'\'}'\"" >/dev/null 2>&1

    # gen_random_uuid(), which the webmail's first migration calls. Built in
    # from PostgreSQL 13; pgcrypto before that.
    su - postgres -c "psql -d mailflow -c 'CREATE EXTENSION IF NOT EXISTS pgcrypto'" >/dev/null 2>&1

    if PGPASSWORD="$pw" psql -h 127.0.0.1 -U mailflow -d mailflow -tAc 'SELECT 1' >/dev/null 2>&1; then
        ok "the webmail can reach its database"
        systemctl is-enabled --quiet hitechcloud-webmail 2>/dev/null &&
            systemctl restart hitechcloud-webmail >/dev/null 2>&1
    else
        warn "the webmail still cannot log in to its database."
        warn "Re-run: hitechcloudcli native-webmail install"
    fi
fi

say "2.1.17 is in place."
