fix: Gitea Traefik routing and connection pool optimization
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
- Remove middleware reference from Gitea Traefik labels (caused routing issues) - Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s) - Add explicit service reference in Traefik labels - Fix intermittent 504 timeouts by improving PostgreSQL connection handling Fixes Gitea unreachability via git.michaelschiemer.de
This commit is contained in:
290
scripts/test/test-deployment-secrets.sh
Executable file
290
scripts/test/test-deployment-secrets.sh
Executable file
@@ -0,0 +1,290 @@
|
||||
#!/bin/bash
|
||||
set -uo pipefail
|
||||
|
||||
# Test script for deployment with new docker-compose files and secret management
|
||||
# This script validates the deployment configuration and tests secret loading
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
SECRETS_DIR="$PROJECT_ROOT/secrets"
|
||||
|
||||
# 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 results
|
||||
TESTS_PASSED=0
|
||||
TESTS_FAILED=0
|
||||
TESTS_TOTAL=0
|
||||
|
||||
print_header() {
|
||||
echo ""
|
||||
echo -e "${BLUE}????????????????????????????????????????????????????????????????????${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}????????????????????????????????????????????????????????????????????${NC}"
|
||||
}
|
||||
|
||||
print_test() {
|
||||
echo -e "${YELLOW}[TEST]${NC} $1"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}[?]${NC} $1"
|
||||
((TESTS_PASSED++))
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}[?]${NC} $1"
|
||||
((TESTS_FAILED++))
|
||||
}
|
||||
|
||||
run_test() {
|
||||
((TESTS_TOTAL++))
|
||||
local test_name="$1"
|
||||
shift
|
||||
print_test "$test_name"
|
||||
|
||||
if "$@" 2>/dev/null; then
|
||||
print_success "$test_name"
|
||||
return 0
|
||||
else
|
||||
print_error "$test_name"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
echo ""
|
||||
echo -e "${YELLOW}Cleaning up test artifacts...${NC}"
|
||||
|
||||
# Remove test secrets directory
|
||||
if [ -d "$SECRETS_DIR" ] && [ -f "$SECRETS_DIR/.test-marker" ]; then
|
||||
rm -rf "$SECRETS_DIR"
|
||||
print_success "Test secrets directory removed"
|
||||
fi
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
print_header "?? Testing Deployment with New Docker Compose Files & Secret Management"
|
||||
|
||||
# ============================================================================
|
||||
# Phase 1: Validate Docker Compose Files
|
||||
# ============================================================================
|
||||
print_header "Phase 1: Validating Docker Compose Files"
|
||||
|
||||
run_test "docker-compose.base.yml exists" test -f "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "docker-compose.local.yml exists" test -f "$PROJECT_ROOT/docker-compose.local.yml"
|
||||
run_test "docker-compose.staging.yml exists" test -f "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
run_test "docker-compose.production.yml exists" test -f "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
|
||||
# Validate docker-compose syntax
|
||||
if command -v docker-compose &> /dev/null || command -v docker &> /dev/null; then
|
||||
run_test "docker-compose.base.yml syntax valid" bash -c "cd '$PROJECT_ROOT' && docker-compose -f docker-compose.base.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml config > /dev/null 2>&1"
|
||||
run_test "docker-compose.local.yml syntax valid" bash -c "cd '$PROJECT_ROOT' && docker-compose -f docker-compose.base.yml -f docker-compose.local.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.local.yml config > /dev/null 2>&1"
|
||||
run_test "docker-compose.staging.yml syntax valid" bash -c "cd '$PROJECT_ROOT' && docker-compose -f docker-compose.base.yml -f docker-compose.staging.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.staging.yml config > /dev/null 2>&1"
|
||||
run_test "docker-compose.production.yml syntax valid" bash -c "cd '$PROJECT_ROOT' && docker-compose -f docker-compose.base.yml -f docker-compose.production.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.production.yml config > /dev/null 2>&1"
|
||||
else
|
||||
print_error "docker-compose or docker not available, skipping syntax validation"
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# Phase 2: Validate Secret Configuration
|
||||
# ============================================================================
|
||||
print_header "Phase 2: Validating Secret Configuration"
|
||||
|
||||
# Check that secrets are defined in docker-compose.base.yml
|
||||
run_test "secrets section exists in docker-compose.base.yml" grep -q "^secrets:" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "db_root_password secret defined" grep -q "db_root_password:" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "db_user_password secret defined" grep -q "db_user_password:" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "redis_password secret defined" grep -q "redis_password:" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "app_key secret defined" grep -q "app_key:" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "vault_encryption_key secret defined" grep -q "vault_encryption_key:" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "git_token secret defined" grep -q "git_token:" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
|
||||
# Check that production uses secrets
|
||||
run_test "production uses db_user_password secret" grep -q "db_user_password" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
run_test "production uses redis_password secret" grep -q "redis_password" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
run_test "production uses app_key secret" grep -q "app_key" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
run_test "production uses vault_encryption_key secret" grep -q "vault_encryption_key" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
|
||||
# Check that staging uses secrets
|
||||
run_test "staging uses db_user_password secret" grep -q "db_user_password" "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
run_test "staging uses redis_password secret" grep -q "redis_password" "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
run_test "staging uses app_key secret" grep -q "app_key" "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
run_test "staging uses vault_encryption_key secret" grep -q "vault_encryption_key" "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
|
||||
# ============================================================================
|
||||
# Phase 3: Create Test Secrets
|
||||
# ============================================================================
|
||||
print_header "Phase 3: Creating Test Secrets"
|
||||
|
||||
# Create test secrets directory
|
||||
mkdir -p "$SECRETS_DIR"
|
||||
echo "test-marker" > "$SECRETS_DIR/.test-marker"
|
||||
|
||||
# Create test secret files
|
||||
echo "test-db-root-password-12345" > "$SECRETS_DIR/db_root_password.txt"
|
||||
echo "test-db-user-password-67890" > "$SECRETS_DIR/db_user_password.txt"
|
||||
echo "test-redis-password-abcde" > "$SECRETS_DIR/redis_password.txt"
|
||||
echo "test-app-key-base64encoded123456789012345678901234567890" > "$SECRETS_DIR/app_key.txt"
|
||||
echo "test-vault-encryption-key-32charslong12345678" > "$SECRETS_DIR/vault_encryption_key.txt"
|
||||
echo "test-git-token-ghp_test12345678901234567890" > "$SECRETS_DIR/git_token.txt"
|
||||
|
||||
# Set secure permissions
|
||||
chmod 600 "$SECRETS_DIR"/*.txt 2>/dev/null || true
|
||||
|
||||
run_test "Test secrets directory created" test -d "$SECRETS_DIR"
|
||||
run_test "db_root_password.txt created" test -f "$SECRETS_DIR/db_root_password.txt"
|
||||
run_test "db_user_password.txt created" test -f "$SECRETS_DIR/db_user_password.txt"
|
||||
run_test "redis_password.txt created" test -f "$SECRETS_DIR/redis_password.txt"
|
||||
run_test "app_key.txt created" test -f "$SECRETS_DIR/app_key.txt"
|
||||
run_test "vault_encryption_key.txt created" test -f "$SECRETS_DIR/vault_encryption_key.txt"
|
||||
run_test "git_token.txt created" test -f "$SECRETS_DIR/git_token.txt"
|
||||
|
||||
# ============================================================================
|
||||
# Phase 4: Test Secret File References
|
||||
# ============================================================================
|
||||
print_header "Phase 4: Validating Secret File References"
|
||||
|
||||
# Check that docker-compose files reference correct secret file paths
|
||||
run_test "base.yml references ./secrets/db_root_password.txt" grep -q "./secrets/db_root_password.txt" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "base.yml references ./secrets/db_user_password.txt" grep -q "./secrets/db_user_password.txt" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "base.yml references ./secrets/redis_password.txt" grep -q "./secrets/redis_password.txt" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "base.yml references ./secrets/app_key.txt" grep -q "./secrets/app_key.txt" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "base.yml references ./secrets/vault_encryption_key.txt" grep -q "./secrets/vault_encryption_key.txt" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
run_test "base.yml references ./secrets/git_token.txt" grep -q "./secrets/git_token.txt" "$PROJECT_ROOT/docker-compose.base.yml"
|
||||
|
||||
# ============================================================================
|
||||
# Phase 5: Test *_FILE Pattern Support
|
||||
# ============================================================================
|
||||
print_header "Phase 5: Testing *_FILE Pattern Support"
|
||||
|
||||
# Check that docker-compose files use *_FILE pattern
|
||||
run_test "production uses DB_PASSWORD_FILE pattern" grep -q "DB_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.production.yml" || grep -q "db_user_password" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
run_test "production uses REDIS_PASSWORD_FILE pattern" grep -q "REDIS_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.production.yml" || grep -q "redis_password" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
run_test "production uses APP_KEY_FILE pattern" grep -q "APP_KEY_FILE" "$PROJECT_ROOT/docker-compose.production.yml" || grep -q "app_key" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
run_test "production uses VAULT_ENCRYPTION_KEY_FILE pattern" grep -q "VAULT_ENCRYPTION_KEY_FILE" "$PROJECT_ROOT/docker-compose.production.yml" || grep -q "vault_encryption_key" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
|
||||
run_test "staging uses DB_PASSWORD_FILE pattern" grep -q "DB_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.staging.yml" || grep -q "db_user_password" "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
run_test "staging uses APP_KEY_FILE pattern" grep -q "APP_KEY_FILE" "$PROJECT_ROOT/docker-compose.staging.yml" || grep -q "app_key" "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
run_test "staging uses VAULT_ENCRYPTION_KEY_FILE pattern" grep -q "VAULT_ENCRYPTION_KEY_FILE" "$PROJECT_ROOT/docker-compose.staging.yml" || grep -q "vault_encryption_key" "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
run_test "staging uses GIT_TOKEN_FILE pattern" grep -q "GIT_TOKEN_FILE" "$PROJECT_ROOT/docker-compose.staging.yml" || grep -q "git_token" "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
|
||||
# ============================================================================
|
||||
# Phase 6: Test DockerSecretsResolver Integration
|
||||
# ============================================================================
|
||||
print_header "Phase 6: Testing DockerSecretsResolver Integration"
|
||||
|
||||
# Check that DockerSecretsResolver exists
|
||||
run_test "DockerSecretsResolver.php exists" test -f "$PROJECT_ROOT/src/Framework/Config/DockerSecretsResolver.php"
|
||||
|
||||
# Check that Environment.php uses DockerSecretsResolver
|
||||
run_test "Environment.php imports DockerSecretsResolver" grep -q "DockerSecretsResolver" "$PROJECT_ROOT/src/Framework/Config/Environment.php"
|
||||
run_test "Environment.php resolves secrets via *_FILE pattern" grep -q "secretsResolver->resolve" "$PROJECT_ROOT/src/Framework/Config/Environment.php"
|
||||
|
||||
# Test secret resolution logic
|
||||
if command -v php &> /dev/null; then
|
||||
PHP_TEST_SCRIPT=$(cat <<'PHPEOF'
|
||||
<?php
|
||||
require_once __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use App\Framework\Config\DockerSecretsResolver;
|
||||
|
||||
$resolver = new DockerSecretsResolver();
|
||||
|
||||
// Test 1: Resolve secret from file
|
||||
$variables = [
|
||||
'DB_PASSWORD_FILE' => __DIR__ . '/secrets/db_user_password.txt',
|
||||
];
|
||||
|
||||
$result = $resolver->resolve('DB_PASSWORD', $variables);
|
||||
if ($result === 'test-db-user-password-67890') {
|
||||
echo "? Secret resolution works\n";
|
||||
exit(0);
|
||||
} else {
|
||||
echo "? Secret resolution failed: got '$result'\n";
|
||||
exit(1);
|
||||
}
|
||||
PHPEOF
|
||||
)
|
||||
|
||||
echo "$PHP_TEST_SCRIPT" > "$PROJECT_ROOT/test_secret_resolver.php"
|
||||
|
||||
run_test "DockerSecretsResolver resolves secrets correctly" bash -c "cd '$PROJECT_ROOT' && php test_secret_resolver.php > /dev/null 2>&1"
|
||||
|
||||
# Cleanup
|
||||
rm -f "$PROJECT_ROOT/test_secret_resolver.php"
|
||||
else
|
||||
print_error "PHP not available, skipping DockerSecretsResolver test"
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# Phase 7: Test EncryptedEnvLoader Integration
|
||||
# ============================================================================
|
||||
print_header "Phase 7: Testing EncryptedEnvLoader Integration"
|
||||
|
||||
run_test "EncryptedEnvLoader.php exists" test -f "$PROJECT_ROOT/src/Framework/Config/EncryptedEnvLoader.php"
|
||||
run_test "EncryptedEnvLoader loads system environment" grep -q "loadSystemEnvironment" "$PROJECT_ROOT/src/Framework/Config/EncryptedEnvLoader.php"
|
||||
run_test "EncryptedEnvLoader supports encryption key" grep -q "ENCRYPTION_KEY" "$PROJECT_ROOT/src/Framework/Config/EncryptedEnvLoader.php"
|
||||
|
||||
# ============================================================================
|
||||
# Phase 8: Test Entrypoint Script
|
||||
# ============================================================================
|
||||
print_header "Phase 8: Testing Entrypoint Script"
|
||||
|
||||
run_test "entrypoint.sh exists" test -f "$PROJECT_ROOT/docker/entrypoint.sh"
|
||||
run_test "entrypoint.sh loads secrets from *_FILE pattern" grep -q "_FILE" "$PROJECT_ROOT/docker/entrypoint.sh" || grep -q "DockerSecretsResolver" "$PROJECT_ROOT/docker/entrypoint.sh"
|
||||
run_test "entrypoint.sh is executable" test -x "$PROJECT_ROOT/docker/entrypoint.sh" || [ -f "$PROJECT_ROOT/docker/entrypoint.sh" ]
|
||||
|
||||
# ============================================================================
|
||||
# Phase 9: Validate Service Configuration
|
||||
# ============================================================================
|
||||
print_header "Phase 9: Validating Service Configuration"
|
||||
|
||||
# Check that services reference secrets correctly
|
||||
run_test "production php service uses secrets" grep -A 5 "php:" "$PROJECT_ROOT/docker-compose.production.yml" | grep -q "secrets:" || grep -q "APP_KEY_FILE" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
run_test "production queue-worker uses secrets" grep -A 10 "queue-worker:" "$PROJECT_ROOT/docker-compose.production.yml" | grep -q "secrets:" || grep -q "DB_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.production.yml"
|
||||
run_test "staging-app uses secrets" grep -A 10 "staging-app:" "$PROJECT_ROOT/docker-compose.staging.yml" | grep -q "secrets:" || grep -q "DB_PASSWORD_FILE" "$PROJECT_ROOT/docker-compose.staging.yml"
|
||||
|
||||
# ============================================================================
|
||||
# Phase 10: Test Docker Compose Override Chain
|
||||
# ============================================================================
|
||||
print_header "Phase 10: Testing Docker Compose Override Chain"
|
||||
|
||||
# Test that override chain works correctly
|
||||
if command -v docker-compose &> /dev/null || command -v docker &> /dev/null; then
|
||||
run_test "local override combines with base" bash -c "cd '$PROJECT_ROOT' && (docker-compose -f docker-compose.base.yml -f docker-compose.local.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.local.yml config > /dev/null 2>&1)"
|
||||
run_test "staging override combines with base" bash -c "cd '$PROJECT_ROOT' && (docker-compose -f docker-compose.base.yml -f docker-compose.staging.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.staging.yml config > /dev/null 2>&1)"
|
||||
run_test "production override combines with base" bash -c "cd '$PROJECT_ROOT' && (docker-compose -f docker-compose.base.yml -f docker-compose.production.yml config > /dev/null 2>&1 || docker compose -f docker-compose.base.yml -f docker-compose.production.yml config > /dev/null 2>&1)"
|
||||
else
|
||||
print_error "docker-compose not available, skipping override chain test"
|
||||
fi
|
||||
|
||||
# ============================================================================
|
||||
# Summary
|
||||
# ============================================================================
|
||||
print_header "Test Summary"
|
||||
|
||||
echo ""
|
||||
echo -e "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}"
|
||||
echo ""
|
||||
echo -e "${BLUE}Next steps:${NC}"
|
||||
echo " 1. Deploy secrets to your server using Ansible Vault"
|
||||
echo " 2. Run: docker-compose -f docker-compose.base.yml -f docker-compose.production.yml up -d"
|
||||
echo " 3. Verify secrets are loaded correctly in containers"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}? Some tests failed. Please review the errors above.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
328
scripts/test/test-registry-credentials.sh
Executable file
328
scripts/test/test-registry-credentials.sh
Executable file
@@ -0,0 +1,328 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Script zum Testen der Docker Registry Credentials
|
||||
# Testet sowohl HTTP als auch HTTPS Zugriff auf die Registry
|
||||
#
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Farben für Output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default-Werte
|
||||
REGISTRY_USER="${REGISTRY_USER:-admin}"
|
||||
REGISTRY_PASSWORD="${REGISTRY_PASSWORD:-}"
|
||||
REGISTRY_DOMAIN="${REGISTRY_DOMAIN:-registry.michaelschiemer.de}"
|
||||
REGISTRY_HOST="${REGISTRY_HOST:-94.16.110.151}"
|
||||
REGISTRY_PORT="${REGISTRY_PORT:-5000}"
|
||||
|
||||
# Funktionen
|
||||
print_header() {
|
||||
echo ""
|
||||
echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${BLUE}$1${NC}"
|
||||
echo -e "${BLUE}════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
# Prüfe ob Docker verfügbar ist
|
||||
check_docker() {
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
print_error "Docker ist nicht installiert oder nicht im PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker info >/dev/null 2>&1; then
|
||||
print_error "Docker daemon läuft nicht oder keine Berechtigung"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_success "Docker ist verfügbar"
|
||||
}
|
||||
|
||||
# Prüfe ob curl verfügbar ist
|
||||
check_curl() {
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
print_warning "curl ist nicht verfügbar, installiere..."
|
||||
if command -v apk >/dev/null 2>&1; then
|
||||
apk add --no-cache curl ca-certificates >/dev/null 2>&1
|
||||
elif command -v apt-get >/dev/null 2>&1; then
|
||||
apt-get update >/dev/null 2>&1 && apt-get install -y curl ca-certificates >/dev/null 2>&1
|
||||
else
|
||||
print_error "curl kann nicht automatisch installiert werden"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
print_success "curl ist verfügbar"
|
||||
}
|
||||
|
||||
# Teste HTTP-Zugriff auf Registry
|
||||
test_http_connectivity() {
|
||||
local test_url="$1"
|
||||
print_info "Teste HTTP-Zugriff auf $test_url..."
|
||||
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://${test_url}/v2/" 2>&1 || echo "000")
|
||||
|
||||
if [ "$HTTP_CODE" = "401" ]; then
|
||||
print_success "Registry erreichbar über HTTP (Status: 401 - Auth erforderlich, das ist gut!)"
|
||||
return 0
|
||||
elif [ "$HTTP_CODE" = "200" ]; then
|
||||
print_success "Registry erreichbar über HTTP (Status: 200 - keine Auth erforderlich)"
|
||||
return 0
|
||||
elif [ "$HTTP_CODE" = "000" ]; then
|
||||
print_error "Registry nicht erreichbar über HTTP (curl Fehler)"
|
||||
return 1
|
||||
else
|
||||
print_warning "Registry antwortet über HTTP (Status: $HTTP_CODE)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Teste HTTPS-Zugriff auf Registry
|
||||
test_https_connectivity() {
|
||||
local test_url="$1"
|
||||
print_info "Teste HTTPS-Zugriff auf $test_url..."
|
||||
|
||||
HTTPS_CODE=$(curl -k -s -o /dev/null -w "%{http_code}" "https://${test_url}/v2/" 2>&1 || echo "000")
|
||||
|
||||
if [ "$HTTPS_CODE" = "401" ]; then
|
||||
print_success "Registry erreichbar über HTTPS (Status: 401 - Auth erforderlich, das ist gut!)"
|
||||
return 0
|
||||
elif [ "$HTTPS_CODE" = "200" ]; then
|
||||
print_success "Registry erreichbar über HTTPS (Status: 200 - keine Auth erforderlich)"
|
||||
return 0
|
||||
elif [ "$HTTPS_CODE" = "404" ]; then
|
||||
print_warning "Registry Route nicht gefunden über HTTPS (Status: 404)"
|
||||
print_info "Möglicherweise ist Traefik-Routing nicht richtig konfiguriert"
|
||||
return 1
|
||||
elif [ "$HTTPS_CODE" = "000" ]; then
|
||||
print_error "Registry nicht erreichbar über HTTPS (curl Fehler)"
|
||||
return 1
|
||||
else
|
||||
print_warning "Registry antwortet über HTTPS (Status: $HTTPS_CODE)"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Teste Docker Login
|
||||
test_docker_login() {
|
||||
local registry_url="$1"
|
||||
local use_http="${2:-false}"
|
||||
|
||||
print_info "Teste Docker Login bei $registry_url..."
|
||||
|
||||
if [ -z "$REGISTRY_PASSWORD" ]; then
|
||||
print_error "REGISTRY_PASSWORD ist nicht gesetzt!"
|
||||
print_info "Setze es mit: export REGISTRY_PASSWORD='dein-passwort'"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Docker Login versuchen
|
||||
set +e
|
||||
LOGIN_OUTPUT=$(echo "$REGISTRY_PASSWORD" | docker login "$registry_url" -u "$REGISTRY_USER" --password-stdin 2>&1)
|
||||
LOGIN_EXIT_CODE=$?
|
||||
set -e
|
||||
|
||||
if [ $LOGIN_EXIT_CODE -eq 0 ]; then
|
||||
print_success "Docker Login erfolgreich!"
|
||||
echo "$LOGIN_OUTPUT" | grep -i "Login Succeeded" || true
|
||||
return 0
|
||||
else
|
||||
print_error "Docker Login fehlgeschlagen (Exit Code: $LOGIN_EXIT_CODE)"
|
||||
|
||||
if echo "$LOGIN_OUTPUT" | grep -qi "unauthorized\|401"; then
|
||||
print_warning "Fehler: Unauthorized (401)"
|
||||
print_info "Die Credentials sind falsch:"
|
||||
print_info " - Username: $REGISTRY_USER"
|
||||
print_info " - Password Länge: ${#REGISTRY_PASSWORD} Zeichen"
|
||||
print_info ""
|
||||
print_info "Mögliche Lösungen:"
|
||||
print_info " 1. Prüfe REGISTRY_USER in Gitea Secrets (sollte 'admin' sein)"
|
||||
print_info " 2. Prüfe REGISTRY_PASSWORD in Gitea Secrets"
|
||||
print_info " 3. Prüfe das Passwort in deployment/stacks/registry/auth/htpasswd auf dem Server"
|
||||
fi
|
||||
|
||||
if echo "$LOGIN_OUTPUT" | grep -qi "HTTP response to HTTPS client"; then
|
||||
print_warning "Fehler: Docker versucht HTTPS, aber Registry läuft auf HTTP"
|
||||
print_info "Lösung: Docker-daemon muss mit --insecure-registry=$registry_url konfiguriert werden"
|
||||
fi
|
||||
|
||||
if echo "$LOGIN_OUTPUT" | grep -qi "certificate\|tls"; then
|
||||
print_warning "Fehler: SSL/TLS Problem"
|
||||
print_info "Lösung: Prüfe SSL-Zertifikat-Konfiguration"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Vollständiger Fehler-Output:"
|
||||
echo "$LOGIN_OUTPUT" | while IFS= read -r line; do
|
||||
echo " $line"
|
||||
done
|
||||
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Teste Registry API Zugriff
|
||||
test_registry_api() {
|
||||
local registry_url="$1"
|
||||
local protocol="${2:-http}"
|
||||
|
||||
print_info "Teste Registry API Zugriff über $protocol..."
|
||||
|
||||
API_URL="${protocol}://${registry_url}/v2/_catalog"
|
||||
|
||||
if [ "$protocol" = "https" ]; then
|
||||
API_RESPONSE=$(curl -k -u "${REGISTRY_USER}:${REGISTRY_PASSWORD}" -s "$API_URL" 2>&1)
|
||||
else
|
||||
API_RESPONSE=$(curl -u "${REGISTRY_USER}:${REGISTRY_PASSWORD}" -s "$API_URL" 2>&1)
|
||||
fi
|
||||
|
||||
if echo "$API_RESPONSE" | grep -qi "repositories"; then
|
||||
print_success "Registry API Zugriff erfolgreich!"
|
||||
echo "$API_RESPONSE" | jq '.' 2>/dev/null || echo "$API_RESPONSE"
|
||||
return 0
|
||||
elif echo "$API_RESPONSE" | grep -qi "unauthorized\|401"; then
|
||||
print_error "Registry API Zugriff fehlgeschlagen: Unauthorized"
|
||||
return 1
|
||||
else
|
||||
print_warning "Registry API Antwort: $API_RESPONSE"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Hauptfunktion
|
||||
main() {
|
||||
print_header "Docker Registry Credentials Test"
|
||||
|
||||
# Prüfungen
|
||||
check_docker
|
||||
check_curl
|
||||
|
||||
# Zeige Konfiguration
|
||||
print_info "Verwendete Konfiguration:"
|
||||
echo " REGISTRY_USER: $REGISTRY_USER"
|
||||
echo " REGISTRY_PASSWORD: ${REGISTRY_PASSWORD:+*** (${#REGISTRY_PASSWORD} Zeichen)}"
|
||||
echo " REGISTRY_DOMAIN: $REGISTRY_DOMAIN"
|
||||
echo " REGISTRY_HOST: $REGISTRY_HOST"
|
||||
echo " REGISTRY_PORT: $REGISTRY_PORT"
|
||||
|
||||
if [ -z "$REGISTRY_PASSWORD" ]; then
|
||||
print_error ""
|
||||
print_error "REGISTRY_PASSWORD ist nicht gesetzt!"
|
||||
print_info ""
|
||||
print_info "Verwendung:"
|
||||
echo " export REGISTRY_PASSWORD='dein-passwort'"
|
||||
echo " ./scripts/test-registry-credentials.sh"
|
||||
echo ""
|
||||
print_info "Oder in CI/CD:"
|
||||
echo " REGISTRY_PASSWORD=\"\${{ secrets.REGISTRY_PASSWORD }}\" ./scripts/test-registry-credentials.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Test-Ergebnisse
|
||||
HTTP_AVAILABLE=false
|
||||
HTTPS_AVAILABLE=false
|
||||
HTTP_LOGIN_SUCCESS=false
|
||||
HTTPS_LOGIN_SUCCESS=false
|
||||
|
||||
# Test 1: HTTP Connectivity
|
||||
print_header "Test 1: HTTP Connectivity"
|
||||
if test_http_connectivity "${REGISTRY_HOST}:${REGISTRY_PORT}"; then
|
||||
HTTP_AVAILABLE=true
|
||||
fi
|
||||
|
||||
# Test 2: HTTPS Connectivity
|
||||
print_header "Test 2: HTTPS Connectivity"
|
||||
if test_https_connectivity "$REGISTRY_DOMAIN"; then
|
||||
HTTPS_AVAILABLE=true
|
||||
fi
|
||||
|
||||
# Test 3: Docker Login über HTTP
|
||||
if [ "$HTTP_AVAILABLE" = true ]; then
|
||||
print_header "Test 3: Docker Login über HTTP"
|
||||
if test_docker_login "${REGISTRY_HOST}:${REGISTRY_PORT}" "http"; then
|
||||
HTTP_LOGIN_SUCCESS=true
|
||||
fi
|
||||
else
|
||||
print_warning "Überspringe HTTP Login Test (Registry nicht erreichbar)"
|
||||
fi
|
||||
|
||||
# Test 4: Docker Login über HTTPS
|
||||
if [ "$HTTPS_AVAILABLE" = true ]; then
|
||||
print_header "Test 4: Docker Login über HTTPS"
|
||||
if test_docker_login "$REGISTRY_DOMAIN" "https"; then
|
||||
HTTPS_LOGIN_SUCCESS=true
|
||||
fi
|
||||
else
|
||||
print_warning "Überspringe HTTPS Login Test (Registry nicht erreichbar)"
|
||||
fi
|
||||
|
||||
# Test 5: Registry API (nur wenn Login erfolgreich)
|
||||
if [ "$HTTP_LOGIN_SUCCESS" = true ] || [ "$HTTPS_LOGIN_SUCCESS" = true ]; then
|
||||
print_header "Test 5: Registry API Zugriff"
|
||||
|
||||
if [ "$HTTP_LOGIN_SUCCESS" = true ]; then
|
||||
test_registry_api "${REGISTRY_HOST}:${REGISTRY_PORT}" "http" || true
|
||||
fi
|
||||
|
||||
if [ "$HTTPS_LOGIN_SUCCESS" = true ]; then
|
||||
test_registry_api "$REGISTRY_DOMAIN" "https" || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Zusammenfassung
|
||||
print_header "Zusammenfassung"
|
||||
|
||||
if [ "$HTTP_LOGIN_SUCCESS" = true ] || [ "$HTTPS_LOGIN_SUCCESS" = true ]; then
|
||||
print_success "✅ Credentials sind korrekt und funktionieren!"
|
||||
|
||||
if [ "$HTTPS_LOGIN_SUCCESS" = true ]; then
|
||||
print_success "✅ HTTPS Login funktioniert (empfohlen)"
|
||||
print_info "Verwende in Workflows: registry.michaelschiemer.de"
|
||||
fi
|
||||
|
||||
if [ "$HTTP_LOGIN_SUCCESS" = true ]; then
|
||||
print_warning "⚠️ HTTP Login funktioniert (Fallback)"
|
||||
print_info "Verwende in Workflows: ${REGISTRY_HOST}:${REGISTRY_PORT}"
|
||||
print_info "HINWEIS: Benötigt insecure-registry Konfiguration im Docker-daemon"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
else
|
||||
print_error "❌ Credentials funktionieren nicht!"
|
||||
print_info ""
|
||||
print_info "Nächste Schritte:"
|
||||
print_info "1. Prüfe REGISTRY_USER in Gitea Secrets"
|
||||
print_info "2. Prüfe REGISTRY_PASSWORD in Gitea Secrets"
|
||||
print_info "3. Prüfe das Passwort in deployment/stacks/registry/auth/htpasswd auf dem Server"
|
||||
print_info "4. Prüfe ob die Registry läuft: docker ps | grep registry"
|
||||
print_info "5. Prüfe Registry-Logs: docker logs registry"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Script ausführen
|
||||
main "$@"
|
||||
74
scripts/test/test-security.sh
Executable file
74
scripts/test/test-security.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Security Configuration Test Script
|
||||
# Tests production security configuration
|
||||
|
||||
GREEN="\e[32m"
|
||||
YELLOW="\e[33m"
|
||||
RED="\e[31m"
|
||||
RESET="\e[0m"
|
||||
|
||||
BASE_URL="https://localhost"
|
||||
USER_AGENT="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
|
||||
|
||||
echo -e "${YELLOW}Testing Production Security Configuration${RESET}"
|
||||
echo "================================================"
|
||||
|
||||
# Function to test HTTP endpoint
|
||||
test_endpoint() {
|
||||
local path=$1
|
||||
local expected_status=$2
|
||||
local description=$3
|
||||
|
||||
echo -e "\n${YELLOW}Testing: ${description}${RESET}"
|
||||
echo "Endpoint: ${path}"
|
||||
|
||||
response=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-H "User-Agent: $USER_AGENT" \
|
||||
"${BASE_URL}${path}" 2>/dev/null)
|
||||
|
||||
if [ "$response" = "$expected_status" ]; then
|
||||
echo -e "${GREEN}✓ PASS${RESET} - Got expected status: $response"
|
||||
else
|
||||
echo -e "${RED}✗ FAIL${RESET} - Expected: $expected_status, Got: $response"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test blocked routes in production (should return 404)
|
||||
echo -e "\n${YELLOW}=== Testing Blocked Routes ===${RESET}"
|
||||
test_endpoint "/admin/discovery" "404" "Admin Discovery Route (blocked in production)"
|
||||
test_endpoint "/admin/routes" "404" "Admin Routes Route (blocked in production)"
|
||||
test_endpoint "/admin/performance" "404" "Admin Performance Route (blocked in production)"
|
||||
test_endpoint "/debug" "404" "Debug Route (blocked in production)"
|
||||
|
||||
# Test IP-restricted routes (should return 403 from external IPs, but might be 200 from localhost)
|
||||
echo -e "\n${YELLOW}=== Testing IP-Restricted Routes ===${RESET}"
|
||||
test_endpoint "/admin" "200" "Admin Route (IP-restricted, should work from localhost)"
|
||||
test_endpoint "/health" "200" "Health Route (IP-restricted, should work from localhost)"
|
||||
|
||||
# Test normal routes (should work)
|
||||
echo -e "\n${YELLOW}=== Testing Normal Routes ===${RESET}"
|
||||
test_endpoint "/" "200" "Home Route (should work)"
|
||||
test_endpoint "/api/version" "200" "API Version Route (should work)"
|
||||
|
||||
echo -e "\n${YELLOW}=== Environment Configuration Test ===${RESET}"
|
||||
|
||||
# Check if APP_ENV is set correctly
|
||||
if [ -f .env ]; then
|
||||
APP_ENV=$(grep "^APP_ENV=" .env | cut -d'=' -f2)
|
||||
APP_DEBUG=$(grep "^APP_DEBUG=" .env | cut -d'=' -f2)
|
||||
|
||||
echo "APP_ENV: $APP_ENV"
|
||||
echo "APP_DEBUG: $APP_DEBUG"
|
||||
|
||||
if [ "$APP_ENV" = "production" ] && [ "$APP_DEBUG" = "false" ]; then
|
||||
echo -e "${GREEN}✓ PASS${RESET} - Production environment correctly configured"
|
||||
else
|
||||
echo -e "${RED}✗ FAIL${RESET} - Environment not configured for production"
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}✗ FAIL${RESET} - .env file not found"
|
||||
fi
|
||||
|
||||
echo -e "\n${YELLOW}Security test completed.${RESET}"
|
||||
echo -e "\n${YELLOW}Note: For full production testing, deploy to production server and test from external IP.${RESET}"
|
||||
37
scripts/test/test-simple.sh
Normal file
37
scripts/test/test-simple.sh
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "🧪 Testing Upload System with CSRF Protection"
|
||||
echo "=============================================="
|
||||
|
||||
BASE_URL="https://localhost"
|
||||
USER_AGENT="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
|
||||
|
||||
echo ""
|
||||
echo "📋 Test 1: CSRF Token Generation"
|
||||
echo "--------------------------------"
|
||||
|
||||
CSRF_RESPONSE=$(curl -k -s -H "User-Agent: $USER_AGENT" -H "Accept: application/json" "$BASE_URL/api/csrf/token?action=/api/images&method=post")
|
||||
|
||||
if [ $? -eq 0 ] && [[ $CSRF_RESPONSE == *"form_id"* ]]; then
|
||||
echo "✅ CSRF API working"
|
||||
echo "Response: $CSRF_RESPONSE"
|
||||
else
|
||||
echo "❌ CSRF API failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🌐 Test 2: Test Page Check"
|
||||
echo "-------------------------"
|
||||
|
||||
HTTP_STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -H "User-Agent: $USER_AGENT" "$BASE_URL/admin/test/upload")
|
||||
|
||||
if [ "$HTTP_STATUS" = "200" ]; then
|
||||
echo "✅ Test page accessible: $BASE_URL/admin/test/upload"
|
||||
else
|
||||
echo "❌ Test page not accessible (HTTP $HTTP_STATUS)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📊 Summary: System ready for browser testing!"
|
||||
echo "Open: $BASE_URL/admin/test/upload"
|
||||
140
scripts/test/test-ssl.sh
Executable file
140
scripts/test/test-ssl.sh
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# SSL Test Script for michaelschiemer.de
|
||||
# Quick verification of SSL certificate and HTTPS connectivity
|
||||
#
|
||||
|
||||
DOMAIN="michaelschiemer.de"
|
||||
SERVER_IP="94.16.110.151"
|
||||
|
||||
# Colors
|
||||
GREEN="\e[32m"
|
||||
YELLOW="\e[33m"
|
||||
RED="\e[31m"
|
||||
BLUE="\e[34m"
|
||||
RESET="\e[0m"
|
||||
|
||||
log_info() { echo -e "${BLUE}[INFO]${RESET} $1"; }
|
||||
log_success() { echo -e "${GREEN}[SUCCESS]${RESET} $1"; }
|
||||
log_warning() { echo -e "${YELLOW}[WARNING]${RESET} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${RESET} $1"; }
|
||||
|
||||
echo "=== SSL Test for $DOMAIN ==="
|
||||
echo
|
||||
|
||||
# Test 1: DNS Resolution
|
||||
log_info "Testing DNS resolution..."
|
||||
resolved_ip=$(dig +short "$DOMAIN" | head -1)
|
||||
if [[ "$resolved_ip" == "$SERVER_IP" ]]; then
|
||||
log_success "DNS: $DOMAIN → $resolved_ip ✓"
|
||||
else
|
||||
log_warning "DNS: $DOMAIN → $resolved_ip (expected: $SERVER_IP)"
|
||||
fi
|
||||
echo
|
||||
|
||||
# Test 2: Port Connectivity
|
||||
log_info "Testing port connectivity..."
|
||||
if nc -z "$DOMAIN" 443 2>/dev/null; then
|
||||
log_success "Port 443: Accessible ✓"
|
||||
else
|
||||
log_error "Port 443: Not accessible ✗"
|
||||
fi
|
||||
|
||||
if nc -z "$DOMAIN" 80 2>/dev/null; then
|
||||
log_success "Port 80: Accessible ✓"
|
||||
else
|
||||
log_error "Port 80: Not accessible ✗"
|
||||
fi
|
||||
echo
|
||||
|
||||
# Test 3: HTTP to HTTPS Redirect
|
||||
log_info "Testing HTTP to HTTPS redirect..."
|
||||
http_response=$(curl -I -s "http://$DOMAIN" | head -1)
|
||||
if echo "$http_response" | grep -q "301\|302"; then
|
||||
log_success "HTTP Redirect: Working ✓"
|
||||
curl -I -s "http://$DOMAIN" | grep -i "location:" || true
|
||||
else
|
||||
log_warning "HTTP Redirect: $http_response"
|
||||
fi
|
||||
echo
|
||||
|
||||
# Test 4: HTTPS Connection
|
||||
log_info "Testing HTTPS connection..."
|
||||
if curl -sSf "https://$DOMAIN" > /dev/null 2>&1; then
|
||||
log_success "HTTPS Connection: Working ✓"
|
||||
else
|
||||
log_error "HTTPS Connection: Failed ✗"
|
||||
log_info "Trying with --insecure flag..."
|
||||
if curl -sSf --insecure "https://$DOMAIN" > /dev/null 2>&1; then
|
||||
log_warning "HTTPS works with --insecure (certificate issue)"
|
||||
else
|
||||
log_error "HTTPS completely broken"
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
|
||||
# Test 5: SSL Certificate Details
|
||||
log_info "Checking SSL certificate..."
|
||||
cert_info=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -text 2>/dev/null)
|
||||
|
||||
if [[ -n "$cert_info" ]]; then
|
||||
echo "Certificate Details:"
|
||||
echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -dates 2>/dev/null
|
||||
|
||||
# Check if Let's Encrypt
|
||||
if echo "$cert_info" | grep -q "Let's Encrypt"; then
|
||||
log_success "Certificate: Let's Encrypt ✓"
|
||||
else
|
||||
log_warning "Certificate: Not Let's Encrypt (might be self-signed)"
|
||||
fi
|
||||
|
||||
# Check expiration
|
||||
exp_date=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
|
||||
if [[ -n "$exp_date" ]]; then
|
||||
exp_timestamp=$(date -d "$exp_date" +%s 2>/dev/null || echo "")
|
||||
current_timestamp=$(date +%s)
|
||||
if [[ -n "$exp_timestamp" ]] && [[ $exp_timestamp -gt $current_timestamp ]]; then
|
||||
days_left=$(( (exp_timestamp - current_timestamp) / 86400 ))
|
||||
if [[ $days_left -gt 30 ]]; then
|
||||
log_success "Certificate Expiry: $days_left days remaining ✓"
|
||||
else
|
||||
log_warning "Certificate Expiry: $days_left days remaining (renew soon)"
|
||||
fi
|
||||
else
|
||||
log_error "Certificate: Expired or invalid ✗"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_error "Could not retrieve certificate information"
|
||||
fi
|
||||
echo
|
||||
|
||||
# Test 6: SSL Labs Grade (optional, requires internet)
|
||||
log_info "SSL Labs test available at:"
|
||||
echo "https://www.ssllabs.com/ssltest/analyze.html?d=$DOMAIN"
|
||||
echo
|
||||
|
||||
# Test 7: Framework Health Check
|
||||
log_info "Testing framework health endpoint..."
|
||||
health_status=$(curl -s -o /dev/null -w "%{http_code}" "https://$DOMAIN/ping" 2>/dev/null)
|
||||
if [[ "$health_status" == "200" ]]; then
|
||||
log_success "Framework Health: OK ✓"
|
||||
elif [[ "$health_status" == "404" ]]; then
|
||||
log_warning "Framework Health: Endpoint not found (might be disabled)"
|
||||
else
|
||||
log_error "Framework Health: HTTP $health_status ✗"
|
||||
fi
|
||||
|
||||
# Summary
|
||||
echo
|
||||
echo "=== Test Summary ==="
|
||||
echo "Domain: $DOMAIN"
|
||||
echo "Target IP: $SERVER_IP"
|
||||
echo
|
||||
echo "Next steps if issues found:"
|
||||
echo "1. Check DNS: dig +short $DOMAIN"
|
||||
echo "2. Check firewall: nmap -p 80,443 $DOMAIN"
|
||||
echo "3. Check containers: ssh deploy@$SERVER_IP 'docker compose ps'"
|
||||
echo "4. Check nginx logs: ssh deploy@$SERVER_IP 'docker compose logs web'"
|
||||
echo "5. Regenerate SSL: ./setup-production-ssl.sh"
|
||||
111
scripts/test/test-upload-system.sh
Executable file
111
scripts/test/test-upload-system.sh
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Upload System Test Script
|
||||
# Tests the complete JavaScript upload system with CSRF protection
|
||||
|
||||
echo "🧪 Testing Upload System with CSRF Protection"
|
||||
echo "================================================"
|
||||
|
||||
BASE_URL="https://localhost"
|
||||
USER_AGENT="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
|
||||
|
||||
# Test 1: CSRF Token Generation
|
||||
echo ""
|
||||
echo "📋 Test 1: CSRF Token Generation"
|
||||
echo "--------------------------------"
|
||||
|
||||
CSRF_RESPONSE=$(curl -k -s -H "User-Agent: $USER_AGENT" -H "Accept: application/json" \
|
||||
"$BASE_URL/api/csrf/token?action=/api/images&method=post")
|
||||
|
||||
if [ $? -eq 0 ] && [[ $CSRF_RESPONSE == *"form_id"* ]]; then
|
||||
echo "✅ CSRF API reachable and returns tokens"
|
||||
echo "Response: $CSRF_RESPONSE"
|
||||
|
||||
# Extract tokens using simple text manipulation
|
||||
FORM_ID=$(echo "$CSRF_RESPONSE" | sed -n 's/.*"form_id":"\([^"]*\)".*/\1/p')
|
||||
TOKEN=$(echo "$CSRF_RESPONSE" | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')
|
||||
|
||||
echo "Form ID: $FORM_ID"
|
||||
echo "Token: ${TOKEN:0:20}..."
|
||||
else
|
||||
echo "❌ CSRF API test failed"
|
||||
echo "Response: $CSRF_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test 2: Test Page Accessibility
|
||||
echo ""
|
||||
echo "🌐 Test 2: Test Page Accessibility"
|
||||
echo "----------------------------------"
|
||||
|
||||
HTTP_STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -H "User-Agent: $USER_AGENT" \
|
||||
"$BASE_URL/admin/test/upload")
|
||||
|
||||
if [ "$HTTP_STATUS" = "200" ]; then
|
||||
echo "✅ Test page accessible at /admin/test/upload"
|
||||
else
|
||||
echo "❌ Test page not accessible (HTTP $HTTP_STATUS)"
|
||||
fi
|
||||
|
||||
# Test 3: Upload API Endpoint Check
|
||||
echo ""
|
||||
echo "📤 Test 3: Upload API Endpoint Check"
|
||||
echo "------------------------------------"
|
||||
|
||||
# Test without file (should return error about missing file)
|
||||
UPLOAD_RESPONSE=$(curl -k -s -H "User-Agent: $USER_AGENT" -H "Accept: application/json" \
|
||||
-H "X-CSRF-Form-ID: $FORM_ID" -H "X-CSRF-Token: $TOKEN" \
|
||||
-X POST "$BASE_URL/api/images")
|
||||
|
||||
if [[ $UPLOAD_RESPONSE == *"No image file uploaded"* ]]; then
|
||||
echo "✅ Upload API reachable and CSRF validation working"
|
||||
echo "Expected error: No image file uploaded"
|
||||
else
|
||||
echo "❌ Upload API test failed"
|
||||
echo "Response: $UPLOAD_RESPONSE"
|
||||
fi
|
||||
|
||||
# Test 4: JavaScript Files Accessibility
|
||||
echo ""
|
||||
echo "📜 Test 4: JavaScript Files Accessibility"
|
||||
echo "-----------------------------------------"
|
||||
|
||||
JS_STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -H "User-Agent: $USER_AGENT" \
|
||||
"$BASE_URL/js/test-upload.js")
|
||||
|
||||
if [ "$JS_STATUS" = "200" ]; then
|
||||
echo "✅ JavaScript test file accessible"
|
||||
else
|
||||
echo "❌ JavaScript test file not accessible (HTTP $JS_STATUS)"
|
||||
fi
|
||||
|
||||
UPLOAD_JS_STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -H "User-Agent: $USER_AGENT" \
|
||||
"$BASE_URL/js/utils/upload.js")
|
||||
|
||||
if [ "$UPLOAD_JS_STATUS" = "200" ]; then
|
||||
echo "✅ Upload utility accessible"
|
||||
else
|
||||
echo "❌ Upload utility not accessible (HTTP $UPLOAD_JS_STATUS)"
|
||||
fi
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
echo "📊 Test Summary"
|
||||
echo "==============="
|
||||
echo "✅ CSRF token generation: Working"
|
||||
echo "✅ Test page: Available at $BASE_URL/admin/test/upload"
|
||||
echo "✅ Upload API: Ready for file uploads"
|
||||
echo "✅ JavaScript modules: Accessible"
|
||||
echo ""
|
||||
echo "🎯 Next Steps:"
|
||||
echo "1. Open browser: $BASE_URL/admin/test/upload"
|
||||
echo "2. Select image files and test upload"
|
||||
echo "3. Check browser console for debug info"
|
||||
echo "4. Test console commands: await testCsrfTokens()"
|
||||
echo ""
|
||||
echo "🔧 Manual Browser Tests:"
|
||||
echo "- Open DevTools Console"
|
||||
echo "- Run: await uploadManager.getCsrfTokens('/api/images', 'post')"
|
||||
echo "- Select image files in the form"
|
||||
echo "- Click Upload Files button"
|
||||
echo "- Watch progress and results"
|
||||
9
scripts/test/test-workflow.sh
Executable file
9
scripts/test/test-workflow.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
# Script to test Gitea workflows locally with act
|
||||
# Maps custom runner labels to Docker images
|
||||
|
||||
act -P php-ci=php-ci:latest \
|
||||
-P docker-build=docker:latest \
|
||||
-P ubuntu-latest=ubuntu:latest \
|
||||
-P ubuntu-22.04=ubuntu:22.04 \
|
||||
"$@"
|
||||
Reference in New Issue
Block a user