#!/bin/bash # Fix script for MockAPI VPS deployment issues set -e echo "=== MockAPI VPS Issue Fixer ===" echo APP_DIR="/opt/mockapi" ENV_FILE="${APP_DIR}/.env" # Function to print colored output print_status() { echo -e "\033[0;32m[+]\033[0m $1" } print_warning() { echo -e "\033[1;33m[!]\033[0m $1" } print_error() { echo -e "\033[0;31m[!]\033[0m $1" } # Step 1: Check current .env file print_status "Step 1: Checking current .env file" if [[ ! -f "$ENV_FILE" ]]; then print_error ".env file not found at $ENV_FILE" exit 1 fi echo "Current .env file content:" echo "--------------------------" cat "$ENV_FILE" echo "--------------------------" echo # Step 2: Check for duplicate entries print_status "Step 2: Checking for duplicate entries in .env" DUPLICATES=$(grep -i "^OAUTH2_SUPPORTED_SCOPES=" "$ENV_FILE" | wc -l) if [[ $DUPLICATES -gt 1 ]]; then print_warning "Found $DUPLICATES entries for OAUTH2_SUPPORTED_SCOPES" # Keep only the first one FIRST_LINE=$(grep -i -n "^OAUTH2_SUPPORTED_SCOPES=" "$ENV_FILE" | head -1 | cut -d: -f1) print_status "Keeping only line $FIRST_LINE" # Create backup cp "$ENV_FILE" "${ENV_FILE}.backup.$(date +%s)" # Remove all OAUTH2_SUPPORTED_SCOPES lines, then add correct one grep -v -i "^OAUTH2_SUPPORTED_SCOPES=" "$ENV_FILE" > "${ENV_FILE}.tmp" # Add correct entry (from first line) CORRECT_LINE=$(grep -i "^OAUTH2_SUPPORTED_SCOPES=" "$ENV_FILE" | head -1) echo "$CORRECT_LINE" >> "${ENV_FILE}.tmp" mv "${ENV_FILE}.tmp" "$ENV_FILE" print_status "Removed duplicate entries" fi # Also check for OAUTH2_SUPPORTED_GRANT_TYPES duplicates DUPLICATES_GRANT=$(grep -i "^OAUTH2_SUPPORTED_GRANT_TYPES=" "$ENV_FILE" | wc -l) if [[ $DUPLICATES_GRANT -gt 1 ]]; then print_warning "Found $DUPLICATES_GRANT entries for OAUTH2_SUPPORTED_GRANT_TYPES" # Keep only the first one FIRST_LINE=$(grep -i -n "^OAUTH2_SUPPORTED_GRANT_TYPES=" "$ENV_FILE" | head -1 | cut -d: -f1) print_status "Keeping only line $FIRST_LINE" # Create backup if not already done if [[ ! -f "${ENV_FILE}.backup" ]]; then cp "$ENV_FILE" "${ENV_FILE}.backup" fi # Remove all OAUTH2_SUPPORTED_GRANT_TYPES lines, then add correct one grep -v -i "^OAUTH2_SUPPORTED_GRANT_TYPES=" "$ENV_FILE" > "${ENV_FILE}.tmp" # Add correct entry (from first line) CORRECT_LINE=$(grep -i "^OAUTH2_SUPPORTED_GRANT_TYPES=" "$ENV_FILE" | head -1) echo "$CORRECT_LINE" >> "${ENV_FILE}.tmp" mv "${ENV_FILE}.tmp" "$ENV_FILE" print_status "Removed duplicate grant types entries" fi # Step 3: Ensure proper JSON format for list fields print_status "Step 3: Ensuring proper JSON format for list fields" # Backup if not already done if [[ ! -f "${ENV_FILE}.backup" ]]; then cp "$ENV_FILE" "${ENV_FILE}.backup" fi # Fix OAUTH2_SUPPORTED_SCOPES if not in JSON format SCOPES_LINE=$(grep -i "^OAUTH2_SUPPORTED_SCOPES=" "$ENV_FILE" | head -1) if [[ -n "$SCOPES_LINE" ]]; then SCOPES_VALUE=$(echo "$SCOPES_LINE" | cut -d'=' -f2-) # Check if value is valid JSON array if ! python3 -c "import json; json.loads('$SCOPES_VALUE')" 2>/dev/null; then print_warning "OAUTH2_SUPPORTED_SCOPES value is not valid JSON: $SCOPES_VALUE" print_status "Converting to JSON array format" # Convert space-separated or comma-separated to JSON array # Remove quotes and split CLEAN_VALUE=$(echo "$SCOPES_VALUE" | sed 's/"//g' | sed "s/'//g") # Convert to JSON array JSON_ARRAY=$(echo "$CLEAN_VALUE" | python3 -c " import sys, json value = sys.stdin.read().strip() if ',' in value: items = [item.strip() for item in value.split(',')] else: items = [item.strip() for item in value.split()] print(json.dumps([item for item in items if item])) ") # Update .env file sed -i "s/^OAUTH2_SUPPORTED_SCOPES=.*$/OAUTH2_SUPPORTED_SCOPES=$JSON_ARRAY/" "$ENV_FILE" print_status "Updated OAUTH2_SUPPORTED_SCOPES to: $JSON_ARRAY" else print_status "OAUTH2_SUPPORTED_SCOPES already in valid JSON format" fi fi # Fix OAUTH2_SUPPORTED_GRANT_TYPES if not in JSON format GRANT_LINE=$(grep -i "^OAUTH2_SUPPORTED_GRANT_TYPES=" "$ENV_FILE" | head -1) if [[ -n "$GRANT_LINE" ]]; then GRANT_VALUE=$(echo "$GRANT_LINE" | cut -d'=' -f2-) # Check if value is valid JSON array if ! python3 -c "import json; json.loads('$GRANT_VALUE')" 2>/dev/null; then print_warning "OAUTH2_SUPPORTED_GRANT_TYPES value is not valid JSON: $GRANT_VALUE" print_status "Converting to JSON array format" # Convert space-separated or comma-separated to JSON array # Remove quotes and split CLEAN_VALUE=$(echo "$GRANT_VALUE" | sed 's/"//g' | sed "s/'//g") # Convert to JSON array JSON_ARRAY=$(echo "$CLEAN_VALUE" | python3 -c " import sys, json value = sys.stdin.read().strip() if ',' in value: items = [item.strip() for item in value.split(',')] else: items = [item.strip() for item in value.split()] print(json.dumps([item for item in items if item])) ") # Update .env file sed -i "s/^OAUTH2_SUPPORTED_GRANT_TYPES=.*$/OAUTH2_SUPPORTED_GRANT_TYPES=$JSON_ARRAY/" "$ENV_FILE" print_status "Updated OAUTH2_SUPPORTED_GRANT_TYPES to: $JSON_ARRAY" else print_status "OAUTH2_SUPPORTED_GRANT_TYPES already in valid JSON format" fi fi # Step 4: Add missing OAuth2 settings if not present print_status "Step 4: Adding missing OAuth2 settings" if ! grep -q "^OAUTH2_AUTHORIZATION_CODE_EXPIRE_MINUTES=" "$ENV_FILE"; then echo "OAUTH2_AUTHORIZATION_CODE_EXPIRE_MINUTES=10" >> "$ENV_FILE" print_status "Added OAUTH2_AUTHORIZATION_CODE_EXPIRE_MINUTES=10" fi if ! grep -q "^OAUTH2_PKCE_REQUIRED=" "$ENV_FILE"; then echo "OAUTH2_PKCE_REQUIRED=false" >> "$ENV_FILE" print_status "Added OAUTH2_PKCE_REQUIRED=false" fi # Step 5: Test config import print_status "Step 5: Testing configuration import" cd "$APP_DIR" # Create test script cat > test_config.py << 'EOF' import os import sys import json # Add app directory to path sys.path.insert(0, os.getcwd()) try: print("Attempting to import config...") from app.core.config import settings print("✓ Config import successful!") print(f" DEBUG: {settings.debug}") print(f" OAUTH2_SUPPORTED_SCOPES: {settings.oauth2_supported_scopes}") print(f" OAUTH2_SUPPORTED_GRANT_TYPES: {settings.oauth2_supported_grant_types}") print(f" Type of scopes: {type(settings.oauth2_supported_scopes)}") print(f" Type of grant types: {type(settings.oauth2_supported_grant_types)}") # Also test JSON serialization print(f" Scopes as JSON: {json.dumps(settings.oauth2_supported_scopes)}") except Exception as e: print(f"✗ Config import failed: {e}") import traceback traceback.print_exc() sys.exit(1) EOF # Run test if python3 test_config.py; then print_status "Configuration test passed!" rm test_config.py else print_error "Configuration test failed" print_warning "Check the error above. The .env file may still have issues." exit 1 fi # Step 6: Check for environment variables that might interfere print_status "Step 6: Checking for interfering environment variables" ENV_VARS=$(env | grep -i oauth) if [[ -n "$ENV_VARS" ]]; then print_warning "Found OAuth-related environment variables that might override .env:" echo "$ENV_VARS" print_warning "These may cause conflicts with .env file settings." fi # Step 7: Restart service print_status "Step 7: Restarting MockAPI service" sudo systemctl restart mockapi sleep 3 if sudo systemctl is-active --quiet mockapi; then print_status "✓ Service is running successfully!" echo echo "Service status:" sudo systemctl status mockapi --no-pager -l echo print_status "Testing API endpoints..." if curl -f http://localhost:8000/health > /dev/null 2>&1; then print_status "✓ Health check passed: http://localhost:8000/health" else print_warning "Health check failed. Checking logs..." sudo journalctl -u mockapi -n 10 --no-pager fi else print_error "Service failed to start" echo print_warning "Checking service logs..." sudo journalctl -u mockapi -n 30 --no-pager exit 1 fi echo print_status "=== Fix completed successfully! ===" echo echo "Access your MockAPI:" echo " Admin UI: http://localhost:8000/admin/login" echo " API Docs: http://localhost:8000/docs" echo " Health check: http://localhost:8000/health" echo echo "Credentials are in: $ENV_FILE" echo "Backup created at: ${ENV_FILE}.backup"