Files
customer-installer/test_installer_json_api.sh

366 lines
11 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# =====================================================
# Installer JSON API Test Script
# =====================================================
# Tests all API endpoints and verifies functionality
set -Eeuo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Source libraries
source "${SCRIPT_DIR}/libsupabase.sh"
source "${SCRIPT_DIR}/lib_installer_json_api.sh"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test counters
TESTS_PASSED=0
TESTS_FAILED=0
TESTS_TOTAL=0
# Test configuration
TEST_CTID="${TEST_CTID:-769697636}"
TEST_EMAIL="${TEST_EMAIL:-test@example.com}"
TEST_POSTGREST_URL="${TEST_POSTGREST_URL:-http://192.168.45.104:3000}"
TEST_SERVICE_ROLE_KEY="${TEST_SERVICE_ROLE_KEY:-}"
# Usage
usage() {
cat <<EOF
Usage: bash test_installer_json_api.sh [options]
Options:
--ctid <id> Test CTID (default: 769697636)
--email <email> Test email (default: test@example.com)
--postgrest-url <url> PostgREST URL (default: http://192.168.45.104:3000)
--service-role-key <key> Service role key for authenticated tests
--help Show this help
Examples:
# Basic test (public endpoints only)
bash test_installer_json_api.sh
# Full test with authentication
bash test_installer_json_api.sh --service-role-key "eyJhbGc..."
# Test specific instance
bash test_installer_json_api.sh --ctid 769697636 --email max@beispiel.de
EOF
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--ctid) TEST_CTID="${2:-}"; shift 2 ;;
--email) TEST_EMAIL="${2:-}"; shift 2 ;;
--postgrest-url) TEST_POSTGREST_URL="${2:-}"; shift 2 ;;
--service-role-key) TEST_SERVICE_ROLE_KEY="${2:-}"; shift 2 ;;
--help|-h) usage; exit 0 ;;
*) echo "Unknown option: $1"; usage; exit 1 ;;
esac
done
# Print functions
print_header() {
echo -e "\n${BLUE}========================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}========================================${NC}\n"
}
print_test() {
echo -e "${YELLOW}TEST $((TESTS_TOTAL + 1)):${NC} $1"
}
print_pass() {
echo -e "${GREEN}✓ PASS${NC}: $1"
((TESTS_PASSED++))
((TESTS_TOTAL++))
}
print_fail() {
echo -e "${RED}✗ FAIL${NC}: $1"
((TESTS_FAILED++))
((TESTS_TOTAL++))
}
print_skip() {
echo -e "${YELLOW}⊘ SKIP${NC}: $1"
}
print_info() {
echo -e "${BLUE} INFO${NC}: $1"
}
# Test functions
test_api_connectivity() {
print_test "API Connectivity"
local response
local http_code
response=$(curl -sS -w "\n%{http_code}" -X POST "${TEST_POSTGREST_URL}/rpc/get_public_config" \
-H "Content-Type: application/json" \
-d '{}' 2>&1 || echo -e "\nFAILED")
http_code=$(echo "$response" | tail -n1)
if [[ "$http_code" == "200" ]]; then
print_pass "API is reachable (HTTP 200)"
else
print_fail "API is not reachable (HTTP ${http_code})"
fi
}
test_public_config() {
print_test "Get Public Config"
local response
response=$(get_public_config "${TEST_POSTGREST_URL}" 2>/dev/null || echo "")
if [[ -n "$response" ]]; then
# Check if response contains expected fields
if echo "$response" | grep -q "registration_webhook_url"; then
print_pass "Public config retrieved successfully"
print_info "Response: ${response}"
else
print_fail "Public config missing expected fields"
fi
else
print_fail "Failed to retrieve public config"
fi
}
test_get_instance_by_email() {
print_test "Get Instance Config by Email"
local response
response=$(get_installer_json_by_email "${TEST_EMAIL}" "${TEST_POSTGREST_URL}" 2>/dev/null || echo "")
if [[ -n "$response" && "$response" != "[]" ]]; then
# Check if response contains expected fields
if echo "$response" | grep -q "ctid"; then
print_pass "Instance config retrieved by email"
# Verify no secrets are exposed
if echo "$response" | grep -qE "password|service_role_key|jwt_secret|encryption_key"; then
print_fail "Response contains secrets (SECURITY ISSUE!)"
else
print_pass "No secrets exposed in response"
fi
# Print sample of response
local ctid
ctid=$(echo "$response" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d[0]['ctid'] if d else 'N/A')" 2>/dev/null || echo "N/A")
print_info "Found CTID: ${ctid}"
else
print_fail "Instance config missing expected fields"
fi
else
print_skip "No instance found for email: ${TEST_EMAIL} (this is OK if instance doesn't exist)"
fi
}
test_get_instance_by_ctid() {
print_test "Get Instance Config by CTID (requires service role key)"
if [[ -z "$TEST_SERVICE_ROLE_KEY" ]]; then
print_skip "Service role key not provided (use --service-role-key)"
return
fi
local response
response=$(get_installer_json_by_ctid "${TEST_CTID}" "${TEST_POSTGREST_URL}" "${TEST_SERVICE_ROLE_KEY}" 2>/dev/null || echo "")
if [[ -n "$response" && "$response" != "[]" ]]; then
# Check if response contains expected fields
if echo "$response" | grep -q "ctid"; then
print_pass "Instance config retrieved by CTID"
# Verify no secrets are exposed
if echo "$response" | grep -qE "password|service_role_key|jwt_secret|encryption_key"; then
print_fail "Response contains secrets (SECURITY ISSUE!)"
else
print_pass "No secrets exposed in response"
fi
else
print_fail "Instance config missing expected fields"
fi
else
print_skip "No instance found for CTID: ${TEST_CTID} (this is OK if instance doesn't exist)"
fi
}
test_store_installer_json() {
print_test "Store Installer JSON (requires service role key)"
if [[ -z "$TEST_SERVICE_ROLE_KEY" ]]; then
print_skip "Service role key not provided (use --service-role-key)"
return
fi
# Create test JSON
local test_json
test_json=$(cat <<EOF
{
"ctid": ${TEST_CTID},
"hostname": "sb-${TEST_CTID}",
"fqdn": "sb-${TEST_CTID}.userman.de",
"ip": "192.168.45.104",
"vlan": 90,
"urls": {
"n8n_internal": "http://192.168.45.104:5678/",
"n8n_external": "https://sb-${TEST_CTID}.userman.de",
"postgrest": "http://192.168.45.104:3000",
"chat_webhook": "https://sb-${TEST_CTID}.userman.de/webhook/rag-chat-webhook/chat",
"chat_internal": "http://192.168.45.104:5678/webhook/rag-chat-webhook/chat",
"upload_form": "https://sb-${TEST_CTID}.userman.de/form/rag-upload-form",
"upload_form_internal": "http://192.168.45.104:5678/form/rag-upload-form"
},
"postgres": {
"host": "postgres",
"port": 5432,
"db": "customer",
"user": "customer",
"password": "TEST_PASSWORD_SHOULD_NOT_BE_EXPOSED"
},
"supabase": {
"url": "http://postgrest:3000",
"url_external": "http://192.168.45.104:3000",
"anon_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.TEST",
"service_role_key": "TEST_SERVICE_ROLE_KEY_SHOULD_NOT_BE_EXPOSED",
"jwt_secret": "TEST_JWT_SECRET_SHOULD_NOT_BE_EXPOSED"
},
"ollama": {
"url": "http://192.168.45.3:11434",
"model": "ministral-3:3b",
"embedding_model": "nomic-embed-text:latest"
},
"n8n": {
"encryption_key": "TEST_ENCRYPTION_KEY_SHOULD_NOT_BE_EXPOSED",
"owner_email": "admin@userman.de",
"owner_password": "TEST_PASSWORD_SHOULD_NOT_BE_EXPOSED",
"secure_cookie": false
}
}
EOF
)
# Try to store
if store_installer_json_in_db "${TEST_CTID}" "${TEST_EMAIL}" "${TEST_POSTGREST_URL}" "${TEST_SERVICE_ROLE_KEY}" "${test_json}"; then
print_pass "Installer JSON stored successfully"
# Verify it was stored
sleep 1
local response
response=$(get_installer_json_by_email "${TEST_EMAIL}" "${TEST_POSTGREST_URL}" 2>/dev/null || echo "")
if [[ -n "$response" && "$response" != "[]" ]]; then
print_pass "Stored data can be retrieved"
# Verify secrets are NOT in the response
if echo "$response" | grep -q "TEST_PASSWORD_SHOULD_NOT_BE_EXPOSED"; then
print_fail "CRITICAL: Passwords are exposed in API response!"
elif echo "$response" | grep -q "TEST_SERVICE_ROLE_KEY_SHOULD_NOT_BE_EXPOSED"; then
print_fail "CRITICAL: Service role key is exposed in API response!"
elif echo "$response" | grep -q "TEST_JWT_SECRET_SHOULD_NOT_BE_EXPOSED"; then
print_fail "CRITICAL: JWT secret is exposed in API response!"
elif echo "$response" | grep -q "TEST_ENCRYPTION_KEY_SHOULD_NOT_BE_EXPOSED"; then
print_fail "CRITICAL: Encryption key is exposed in API response!"
else
print_pass "SECURITY: All secrets are properly filtered"
fi
else
print_fail "Stored data could not be retrieved"
fi
else
print_skip "Failed to store installer JSON (instance may not exist in database)"
fi
}
test_cors_headers() {
print_test "CORS Headers"
local response
response=$(curl -sS -I -X OPTIONS "${TEST_POSTGREST_URL}/rpc/get_public_config" \
-H "Origin: https://botkonzept.de" \
-H "Access-Control-Request-Method: POST" 2>&1 || echo "")
if echo "$response" | grep -qi "access-control-allow-origin"; then
print_pass "CORS headers are present"
else
print_skip "CORS headers not found (may need configuration)"
fi
}
test_rate_limiting() {
print_test "Rate Limiting (optional)"
print_skip "Rate limiting test not implemented (should be configured at nginx/gateway level)"
}
test_response_format() {
print_test "Response Format Validation"
local response
response=$(get_public_config "${TEST_POSTGREST_URL}" 2>/dev/null || echo "")
if [[ -n "$response" ]]; then
# Validate JSON format
if echo "$response" | python3 -m json.tool >/dev/null 2>&1; then
print_pass "Response is valid JSON"
else
print_fail "Response is not valid JSON"
fi
else
print_fail "No response received"
fi
}
# Main test execution
main() {
print_header "BotKonzept Installer JSON API Tests"
echo "Test Configuration:"
echo " CTID: ${TEST_CTID}"
echo " Email: ${TEST_EMAIL}"
echo " PostgREST URL: ${TEST_POSTGREST_URL}"
echo " Service Role Key: ${TEST_SERVICE_ROLE_KEY:+***provided***}"
echo ""
# Run tests
test_api_connectivity
test_public_config
test_response_format
test_cors_headers
test_get_instance_by_email
test_get_instance_by_ctid
test_store_installer_json
test_rate_limiting
# Print summary
print_header "Test Summary"
echo "Total Tests: ${TESTS_TOTAL}"
echo -e "${GREEN}Passed: ${TESTS_PASSED}${NC}"
echo -e "${RED}Failed: ${TESTS_FAILED}${NC}"
echo ""
if [[ $TESTS_FAILED -eq 0 ]]; then
echo -e "${GREEN}✓ All tests passed!${NC}"
exit 0
else
echo -e "${RED}✗ Some tests failed${NC}"
exit 1
fi
}
# Run main
main