#!/usr/bin/env bash
# =============================================================================
# PBX Firewall Permissions Setup
# Grants the web server user (www-data) passwordless sudo access to the
# specific commands needed by the Firewall GUI.
# Run once as root: sudo bash scripts/setup-firewall-permissions.sh
# =============================================================================
set -euo pipefail

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
ok()   { echo -e "${GREEN}[OK]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }

if [[ $EUID -ne 0 ]]; then
    echo -e "${RED}[ERROR]${NC} Run as root: sudo $0"
    exit 1
fi

echo ""
echo "============================================"
echo "  PBX Firewall Permissions Setup"
echo "============================================"
echo ""

# Detect web server user
WEB_USER="www-data"
if id "apache" &>/dev/null; then
    WEB_USER="apache"
fi
echo "Web server user: ${WEB_USER}"

# -----------------------------------------------------------------------------
# 1. Sudoers file for firewall commands
# -----------------------------------------------------------------------------
SUDOERS_FILE="/etc/sudoers.d/pbx-firewall"

cat > "$SUDOERS_FILE" << EOF
# PBX Firewall GUI — allow web server to manage firewall and fail2ban
# Generated by setup-firewall-permissions.sh

# nftables
${WEB_USER} ALL=(ALL) NOPASSWD: /usr/sbin/nft *
${WEB_USER} ALL=(ALL) NOPASSWD: /sbin/nft *

# ipset (for whitelist/blacklist enforcement)
${WEB_USER} ALL=(ALL) NOPASSWD: /usr/sbin/ipset *
${WEB_USER} ALL=(ALL) NOPASSWD: /sbin/ipset *

# iptables (legacy fallback)
${WEB_USER} ALL=(ALL) NOPASSWD: /usr/sbin/iptables *
${WEB_USER} ALL=(ALL) NOPASSWD: /sbin/iptables *

# fail2ban
${WEB_USER} ALL=(ALL) NOPASSWD: /usr/bin/fail2ban-client *
${WEB_USER} ALL=(ALL) NOPASSWD: /usr/local/bin/fail2ban-client *

# firewall-helper (legacy)
${WEB_USER} ALL=(ALL) NOPASSWD: /usr/local/bin/firewall-helper *
EOF

chmod 440 "$SUDOERS_FILE"
visudo -cf "$SUDOERS_FILE" && ok "Sudoers file created: ${SUDOERS_FILE}" || {
    rm -f "$SUDOERS_FILE"
    echo -e "${RED}[ERROR]${NC} Sudoers syntax check failed. File removed."
    exit 1
}

# -----------------------------------------------------------------------------
# 2. Ensure fail2ban log is readable by web user
# -----------------------------------------------------------------------------
if [ -f /var/log/fail2ban.log ]; then
    chmod 644 /var/log/fail2ban.log
    ok "fail2ban.log permissions set (644)"
fi

# Ensure auth.log is readable (for SSH attack monitor)
if [ -f /var/log/auth.log ]; then
    usermod -aG adm "$WEB_USER" 2>/dev/null || true
    ok "${WEB_USER} added to adm group (auth.log access)"
fi

# -----------------------------------------------------------------------------
# 3. Create ipset sets if they don't exist
# -----------------------------------------------------------------------------
ipset create pbx_whitelist hash:net -exist 2>/dev/null || true
ipset create pbx_blacklist hash:net -exist 2>/dev/null || true
ok "ipset sets created (pbx_whitelist, pbx_blacklist)"

# Hook ipset into iptables if not already present
if ! iptables -C INPUT -m set --match-set pbx_whitelist src -j ACCEPT 2>/dev/null; then
    iptables -I INPUT 1 -m set --match-set pbx_whitelist src -j ACCEPT
    ok "iptables: pbx_whitelist ACCEPT rule added"
fi

if ! iptables -C INPUT -m set --match-set pbx_blacklist src -j DROP 2>/dev/null; then
    iptables -I INPUT 2 -m set --match-set pbx_blacklist src -j DROP
    ok "iptables: pbx_blacklist DROP rule added"
fi

# -----------------------------------------------------------------------------
# 4. Persist ipset across reboots
# -----------------------------------------------------------------------------
if command -v ipset &>/dev/null; then
    # Save current sets
    ipset save > /etc/ipset.conf 2>/dev/null || true

    # Create systemd service to restore on boot
    cat > /etc/systemd/system/ipset-restore.service << 'UNIT'
[Unit]
Description=Restore ipset rules
Before=netfilter-persistent.service
Before=iptables.service

[Service]
Type=oneshot
ExecStart=/usr/sbin/ipset restore -exist -file /etc/ipset.conf
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
UNIT

    systemctl daemon-reload
    systemctl enable ipset-restore.service 2>/dev/null
    ok "ipset persistence configured (ipset-restore.service)"
fi

# -----------------------------------------------------------------------------
# 5. Verify fail2ban is running with PBX jails
# -----------------------------------------------------------------------------
echo ""
echo "--- Fail2Ban Status ---"
if systemctl is-active --quiet fail2ban; then
    ok "fail2ban service is running"
    JAILS=$(fail2ban-client status 2>/dev/null | grep "Jail list" | sed 's/.*Jail list:\s*//')
    echo "  Active jails: ${JAILS:-none}"
else
    warn "fail2ban is NOT running. Starting..."
    systemctl enable fail2ban
    systemctl start fail2ban
    ok "fail2ban started and enabled"
fi

echo ""
echo "============================================"
echo "  Setup complete"
echo "============================================"
echo ""
echo "  The web GUI can now:"
echo "  - Manage nftables rules (Services, Geo Firewall)"
echo "  - Manage ipset whitelist/blacklist (Access Control)"
echo "  - Query and unban fail2ban jails"
echo "  - Read fail2ban and auth logs"
echo ""
