#!/bin/bash

# PostgreSQL Security Audit Script
# Проверяет безопасность конфигурации PostgreSQL в Docker контейнере

set -e

CONTAINER_NAME="links-db-1"
DB_NAME="links_db"
DB_USER="links_user"

echo "🔍 PostgreSQL Security Audit для CatLink"
echo "=========================================="
echo "Контейнер: $CONTAINER_NAME"
echo "База данных: $DB_NAME"
echo "Пользователь: $DB_USER"
echo ""

# Функция для выполнения SQL запросов
execute_sql() {
    docker exec $CONTAINER_NAME psql -U postgres -d $DB_NAME -t -c "$1" 2>/dev/null || echo "ERROR"
}

# Проверка доступности контейнера
echo "1️⃣  Проверка доступности контейнера..."
if ! docker ps | grep -q $CONTAINER_NAME; then
    echo "❌ Контейнер $CONTAINER_NAME не запущен"
    exit 1
fi
echo "✅ Контейнер запущен"

# Проверка подключения
echo ""
echo "2️⃣  Проверка подключения к БД..."
if docker exec $CONTAINER_NAME pg_isready -U postgres >/dev/null 2>&1; then
    echo "✅ PostgreSQL доступен"
else
    echo "❌ PostgreSQL недоступен"
    exit 1
fi

# Версия PostgreSQL
echo ""
echo "3️⃣  Информация о версии..."
PG_VERSION=$(execute_sql "SELECT version();")
echo "📋 $PG_VERSION"

# Проверка SSL настроек
echo ""
echo "4️⃣  Проверка SSL конфигурации..."
SSL_STATUS=$(execute_sql "SHOW ssl;")
SSL_PROTOCOL=$(execute_sql "SHOW ssl_min_protocol_version;")
PASSWORD_ENC=$(execute_sql "SHOW password_encryption;")

echo "🔐 SSL: $SSL_STATUS"
echo "🔐 Min SSL Protocol: $SSL_PROTOCOL"
echo "🔐 Password Encryption: $PASSWORD_ENC"

if [[ "$SSL_STATUS" == *"on"* ]]; then
    echo "✅ SSL включен"
else
    echo "⚠️  SSL отключен"
fi

if [[ "$SSL_PROTOCOL" == *"TLSv1.3"* ]]; then
    echo "✅ Используется TLSv1.3"
elif [[ "$SSL_PROTOCOL" == *"TLSv1.2"* ]]; then
    echo "⚠️  Используется TLSv1.2 (рекомендуется TLSv1.3)"
else
    echo "❌ Слабый SSL протокол"
fi

# Проверка пользователей и прав
echo ""
echo "5️⃣  Проверка пользователей и прав..."
USER_INFO=$(execute_sql "
SELECT rolname, rolsuper, rolcreatedb, rolcreaterole, rolcanlogin 
FROM pg_roles 
WHERE rolname IN ('postgres', '$DB_USER', 'catlink_app')
ORDER BY rolname;
")

echo "👤 Пользователи:"
echo "$USER_INFO"

# Проверяем права суперпользователя
SUPER_CHECK=$(execute_sql "SELECT rolsuper FROM pg_roles WHERE rolname = '$DB_USER';")
if [[ "$SUPER_CHECK" == *"t"* ]]; then
    echo "❌ $DB_USER имеет права суперпользователя (небезопасно!)"
else
    echo "✅ $DB_USER не имеет прав суперпользователя"
fi

# Проверка активных подключений
echo ""
echo "6️⃣  Активные подключения..."
CONNECTIONS=$(execute_sql "
SELECT datname, usename, client_addr, state, application_name
FROM pg_stat_activity 
WHERE state IS NOT NULL AND pid != pg_backend_pid()
ORDER BY datname, usename;
")

echo "🔌 Подключения:"
if [[ -n "$CONNECTIONS" ]]; then
    echo "$CONNECTIONS"
else
    echo "   Нет активных подключений"
fi

# Проверка сетевых настроек
echo ""
echo "7️⃣  Сетевая конфигурация..."
LISTEN_ADDR=$(execute_sql "SHOW listen_addresses;")
echo "🌐 Listen addresses: $LISTEN_ADDR"

# Проверка портов Docker
echo ""
echo "8️⃣  Проверка экспозиции портов..."
DOCKER_PORTS=$(docker port $CONTAINER_NAME 2>/dev/null || echo "")
if [[ -n "$DOCKER_PORTS" ]]; then
    echo "⚠️  Порты открыты наружу:"
    echo "$DOCKER_PORTS"
    echo "❌ РИСК: База данных доступна извне Docker сети"
else
    echo "✅ Порты не экспонированы - БД доступна только внутри Docker сети"
fi

# Проверка логирования
echo ""
echo "9️⃣  Настройки логирования..."
LOG_CONNECTIONS=$(execute_sql "SHOW log_connections;")
LOG_DISCONNECTIONS=$(execute_sql "SHOW log_disconnections;")
LOG_STATEMENT=$(execute_sql "SHOW log_statement;")

echo "📝 Log connections: $LOG_CONNECTIONS"
echo "📝 Log disconnections: $LOG_DISCONNECTIONS"
echo "📝 Log statement: $LOG_STATEMENT"

# Проверка файлов конфигурации
echo ""
echo "🔟 Проверка файлов конфигурации..."
if docker exec $CONTAINER_NAME test -f /etc/postgresql/postgresql.conf; then
    echo "✅ Кастомный postgresql.conf найден"
else
    echo "⚠️  Используется стандартный postgresql.conf"
fi

if docker exec $CONTAINER_NAME test -f /etc/postgresql/pg_hba.conf; then
    echo "✅ Кастомный pg_hba.conf найден"
else
    echo "⚠️  Используется стандартный pg_hba.conf"
fi

# Финальная оценка безопасности
echo ""
echo "📊 ОЦЕНКА БЕЗОПАСНОСТИ"
echo "======================"

SCORE=0
MAX_SCORE=10

# SSL
[[ "$SSL_STATUS" == *"on"* ]] && ((SCORE++))
# SSL Protocol
[[ "$SSL_PROTOCOL" == *"TLSv1.3"* ]] && ((SCORE++))
# Password encryption
[[ "$PASSWORD_ENC" == *"scram-sha-256"* ]] && ((SCORE++))
# No superuser rights
[[ "$SUPER_CHECK" != *"t"* ]] && ((SCORE++))
# Logging enabled
[[ "$LOG_CONNECTIONS" == *"on"* ]] && ((SCORE++))
[[ "$LOG_DISCONNECTIONS" == *"on"* ]] && ((SCORE++))
# No external ports
[[ -z "$DOCKER_PORTS" ]] && ((SCORE++))
# Custom configs
docker exec $CONTAINER_NAME test -f /etc/postgresql/postgresql.conf && ((SCORE++))
docker exec $CONTAINER_NAME test -f /etc/postgresql/pg_hba.conf && ((SCORE++))
# Password encryption
[[ "$PASSWORD_ENC" == *"scram-sha-256"* ]] && ((SCORE++))

echo "🎯 Оценка безопасности: $SCORE/$MAX_SCORE"

if [ $SCORE -ge 8 ]; then
    echo "✅ ОТЛИЧНАЯ безопасность"
elif [ $SCORE -ge 6 ]; then
    echo "⚠️  ХОРОШАЯ безопасность, есть что улучшить"
elif [ $SCORE -ge 4 ]; then
    echo "🔶 СРЕДНЯЯ безопасность, требуются улучшения"
else
    echo "❌ СЛАБАЯ безопасность, срочно требуются исправления"
fi

echo ""
echo "🔧 Для улучшения безопасности запустите:"
echo "   ./scripts/setup-db-security.sh"

echo ""
echo "✅ Аудит завершен $(date)"