#!/bin/sh

set -eu

PAM_SERVICE=/etc/pam.d/nginx-autopkgtest
NGINX_CONFIG=/etc/nginx/conf.d/auth-pam-autopkgtest.conf
DOCUMENT_ROOT=/var/lib/nginx/auth-pam-autopkgtest
TEST_URL=http://127.0.0.1:18080/protected
HEADERS="${AUTOPKGTEST_TMP}/headers"
BODY="${AUTOPKGTEST_TMP}/body"

cleanup()
{
    rm -f "${NGINX_CONFIG}" "${PAM_SERVICE}" "${DOCUMENT_ROOT}/protected"
    rmdir "${DOCUMENT_ROOT}" 2>/dev/null || :
    invoke-rc.d nginx reload >/dev/null 2>&1 || :
}

trap cleanup EXIT

assert_unauthorized()
{
    phase="$1"
    status="$(curl --silent --show-error --max-time 60 \
        --retry 10 --retry-connrefused --retry-delay 1 \
        --dump-header "${HEADERS}" --output /dev/null \
        --write-out '%{http_code}' "${TEST_URL}")"

    if [ "${status}" != 401 ]; then
        echo "${phase}: expected HTTP 401 without credentials, got ${status}"
        return 1
    fi

    if ! tr -d '\r' < "${HEADERS}" |
        grep -Fqix 'WWW-Authenticate: Basic realm="Autopkgtest"'; then
        echo "${phase}: WWW-Authenticate header is missing or invalid"
        cat "${HEADERS}"
        return 1
    fi

    echo "${phase}: request without credentials returned HTTP 401 ... OK"
}

assert_authorized()
{
    phase="$1"
    shift
    status="$(curl --silent --show-error --fail --max-time 60 \
        --retry 10 --retry-connrefused --retry-delay 1 \
        "$@" \
        --user autopkgtest:password \
        --output "${BODY}" --write-out '%{http_code}' "${TEST_URL}")"

    if [ "${status}" != 200 ]; then
        echo "${phase}: expected HTTP 200 with credentials, got ${status}"
        return 1
    fi

    if ! grep -Fqx 'auth-pam-ok' "${BODY}"; then
        echo "${phase}: unexpected response body"
        cat "${BODY}"
        return 1
    fi

    echo "${phase}: PAM authentication returned HTTP 200 ... OK"
}

mkdir -p "${DOCUMENT_ROOT}"
printf '%s\n' 'auth-pam-ok' > "${DOCUMENT_ROOT}/protected"

cat > "${PAM_SERVICE}" <<'EOF'
auth required pam_permit.so
account required pam_permit.so
EOF

cat > "${NGINX_CONFIG}" <<'EOF'
server {
    listen 127.0.0.1:18080;
    server_name localhost;

    root /var/lib/nginx/auth-pam-autopkgtest;

    location = /protected {
        auth_pam "Autopkgtest";
        auth_pam_service_name "nginx-autopkgtest";
        auth_pam_set_pam_env on;
    }
}
EOF

nginx -t

invoke-rc.d nginx reload
assert_unauthorized "after reload"
assert_authorized "after reload"
assert_authorized "after reload without Host" --http1.0 --header 'Host:'

invoke-rc.d nginx restart
assert_unauthorized "after restart"
assert_authorized "after restart"
