#!/bin/bash # Configuration Setup Script # This script helps initialize the configuration system for your Rust application set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_status() { echo -e "${GREEN}[INFO]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARN]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_header() { echo -e "${BLUE}$1${NC}" } # Function to check if a command exists command_exists() { command -v "$1" >/dev/null 2>&1 } # Function to prompt for user input prompt_user() { local prompt="$1" local default="$2" local result if [ -n "$default" ]; then echo -n "$prompt [$default]: " else echo -n "$prompt: " fi read -r result if [ -z "$result" ] && [ -n "$default" ]; then result="$default" fi echo "$result" } # Function to generate a random secret generate_secret() { openssl rand -base64 32 2>/dev/null || echo "change-this-to-a-secure-random-string-$(date +%s)" } # Main setup function setup_config() { print_header "=== Rust Application Configuration Setup ===" echo # Check dependencies print_status "Checking dependencies..." if ! command_exists "cargo"; then print_error "Cargo is required but not installed. Please install Rust first." exit 1 fi # Determine environment print_status "Configuring environment..." ENVIRONMENT=$(prompt_user "Enter environment (dev/prod)" "dev") case "$ENVIRONMENT" in "dev"|"development") ENVIRONMENT="dev" CONFIG_FILE="config.dev.toml" ;; "prod"|"production") ENVIRONMENT="prod" CONFIG_FILE="config.prod.toml" ;; *) print_warning "Unknown environment '$ENVIRONMENT', using 'dev'" ENVIRONMENT="dev" CONFIG_FILE="config.dev.toml" ;; esac print_status "Environment: $ENVIRONMENT" print_status "Config file: $CONFIG_FILE" # Check if config file already exists if [ -f "$CONFIG_FILE" ]; then print_warning "Configuration file $CONFIG_FILE already exists." OVERWRITE=$(prompt_user "Overwrite existing file? (y/N)" "n") if [[ ! "$OVERWRITE" =~ ^[Yy]$ ]]; then print_status "Keeping existing configuration file." CONFIG_EXISTS=true else CONFIG_EXISTS=false fi else CONFIG_EXISTS=false fi # Create configuration file if it doesn't exist or should be overwritten if [ "$CONFIG_EXISTS" != true ]; then print_status "Creating configuration file..." # Get configuration values from user APP_NAME=$(prompt_user "Application name" "My Rust App") APP_VERSION=$(prompt_user "Application version" "0.1.0") if [ "$ENVIRONMENT" = "dev" ]; then SERVER_HOST=$(prompt_user "Server host" "127.0.0.1") SERVER_PORT=$(prompt_user "Server port" "3030") SERVER_PROTOCOL=$(prompt_user "Server protocol (http/https)" "http") LOG_LEVEL=$(prompt_user "Log level (debug/info/warn/error)" "debug") DATABASE_URL=$(prompt_user "Database URL" "postgresql://dev:dev@localhost:5432/${APP_NAME,,}_dev") else SERVER_HOST=$(prompt_user "Server host" "0.0.0.0") SERVER_PORT=$(prompt_user "Server port" "443") SERVER_PROTOCOL=$(prompt_user "Server protocol (http/https)" "https") LOG_LEVEL=$(prompt_user "Log level (debug/info/warn/error)" "info") DATABASE_URL=$(prompt_user "Database URL" "postgresql://prod:\${DATABASE_PASSWORD}@db.example.com:5432/${APP_NAME,,}_prod") fi # Create the configuration file cat > "$CONFIG_FILE" << EOF # ${APP_NAME} Configuration - ${ENVIRONMENT^} Environment [server] protocol = "${SERVER_PROTOCOL}" host = "${SERVER_HOST}" port = ${SERVER_PORT} environment = "${ENVIRONMENT}" log_level = "${LOG_LEVEL}" EOF # Add TLS configuration if HTTPS if [ "$SERVER_PROTOCOL" = "https" ]; then if [ "$ENVIRONMENT" = "dev" ]; then TLS_CERT_PATH=$(prompt_user "TLS certificate path" "certs/server.crt") TLS_KEY_PATH=$(prompt_user "TLS private key path" "certs/server.key") else TLS_CERT_PATH=$(prompt_user "TLS certificate path" "/etc/ssl/certs/server.crt") TLS_KEY_PATH=$(prompt_user "TLS private key path" "/etc/ssl/private/server.key") fi cat >> "$CONFIG_FILE" << EOF # TLS Configuration [server.tls] cert_path = "${TLS_CERT_PATH}" key_path = "${TLS_KEY_PATH}" EOF fi # Add database configuration cat >> "$CONFIG_FILE" << EOF # Database Configuration [database] url = "${DATABASE_URL}" max_connections = $([ "$ENVIRONMENT" = "dev" ] && echo "5" || echo "20") min_connections = 1 connect_timeout = 30 idle_timeout = 600 max_lifetime = 1800 EOF # Add session configuration cat >> "$CONFIG_FILE" << EOF # Session Configuration [session] secret = $([ "$ENVIRONMENT" = "dev" ] && echo "\"dev-secret-not-for-production\"" || echo "\"\${SESSION_SECRET}\"") cookie_name = "session_id" cookie_secure = $([ "$SERVER_PROTOCOL" = "https" ] && echo "true" || echo "false") cookie_http_only = true cookie_same_site = $([ "$ENVIRONMENT" = "dev" ] && echo "\"lax\"" || echo "\"strict\"") max_age = $([ "$ENVIRONMENT" = "dev" ] && echo "7200" || echo "3600") EOF # Add remaining configuration sections cat >> "$CONFIG_FILE" << EOF # CORS Configuration [cors] allowed_origins = [$([ "$ENVIRONMENT" = "dev" ] && echo "\"http://localhost:3030\", \"http://127.0.0.1:3030\"" || echo "\"https://yourdomain.com\"")] allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"] allowed_headers = ["Content-Type", "Authorization", "X-Requested-With"] allow_credentials = true max_age = 3600 # Static Files Configuration [static] assets_dir = "public" site_root = "target/site" site_pkg_dir = "pkg" # Server Directories Configuration [server_dirs] public_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"public\"" || echo "\"/var/www/public\"") uploads_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"uploads\"" || echo "\"/var/www/uploads\"") logs_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"logs\"" || echo "\"/var/log/app\"") temp_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"tmp\"" || echo "\"/tmp/app\"") cache_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"cache\"" || echo "\"/var/cache/app\"") config_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"config\"" || echo "\"/etc/app\"") data_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"data\"" || echo "\"/var/lib/app\"") backup_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"backups\"" || echo "\"/var/backups/app\"") # Security Configuration [security] enable_csrf = $([ "$ENVIRONMENT" = "dev" ] && echo "false" || echo "true") csrf_token_name = "csrf_token" rate_limit_requests = $([ "$ENVIRONMENT" = "dev" ] && echo "1000" || echo "50") rate_limit_window = 60 bcrypt_cost = $([ "$ENVIRONMENT" = "dev" ] && echo "4" || echo "12") # OAuth Configuration [oauth] enabled = false [oauth.google] client_id = "\${GOOGLE_CLIENT_ID}" client_secret = "\${GOOGLE_CLIENT_SECRET}" redirect_uri = "${SERVER_PROTOCOL}://${SERVER_HOST}:${SERVER_PORT}/auth/google/callback" [oauth.github] client_id = "\${GITHUB_CLIENT_ID}" client_secret = "\${GITHUB_CLIENT_SECRET}" redirect_uri = "${SERVER_PROTOCOL}://${SERVER_HOST}:${SERVER_PORT}/auth/github/callback" # Email Configuration [email] enabled = false smtp_host = "smtp.gmail.com" smtp_port = 587 smtp_username = "\${SMTP_USERNAME}" smtp_password = "\${SMTP_PASSWORD}" from_email = "noreply@example.com" from_name = "${APP_NAME}" # Redis Configuration [redis] enabled = false url = "redis://localhost:6379" pool_size = 10 connection_timeout = 5 command_timeout = 5 # Application Settings [app] name = "${APP_NAME}" version = "${APP_VERSION}" debug = $([ "$ENVIRONMENT" = "dev" ] && echo "true" || echo "false") enable_metrics = $([ "$ENVIRONMENT" = "dev" ] && echo "true" || echo "true") enable_health_check = true enable_compression = $([ "$ENVIRONMENT" = "dev" ] && echo "false" || echo "true") max_request_size = $([ "$ENVIRONMENT" = "dev" ] && echo "52428800" || echo "5242880") # Logging Configuration [logging] format = $([ "$ENVIRONMENT" = "dev" ] && echo "\"text\"" || echo "\"json\"") level = "${LOG_LEVEL}" file_path = "logs/app.log" max_file_size = 10485760 max_files = 5 enable_console = true enable_file = $([ "$ENVIRONMENT" = "dev" ] && echo "true" || echo "true") # Content Management [content] enabled = false content_dir = "content" cache_enabled = $([ "$ENVIRONMENT" = "dev" ] && echo "false" || echo "true") cache_ttl = 3600 max_file_size = 5242880 # Feature Flags [features] auth = true tls = $([ "$SERVER_PROTOCOL" = "https" ] && echo "true" || echo "false") content_db = true two_factor_auth = false EOF print_status "Configuration file created: $CONFIG_FILE" fi # Create .env file ENV_FILE=".env" if [ "$ENVIRONMENT" = "dev" ]; then ENV_FILE=".env.development" elif [ "$ENVIRONMENT" = "prod" ]; then ENV_FILE=".env.production" fi if [ -f "$ENV_FILE" ]; then print_warning "Environment file $ENV_FILE already exists." OVERWRITE_ENV=$(prompt_user "Overwrite existing environment file? (y/N)" "n") if [[ ! "$OVERWRITE_ENV" =~ ^[Yy]$ ]]; then print_status "Keeping existing environment file." ENV_EXISTS=true else ENV_EXISTS=false fi else ENV_EXISTS=false fi if [ "$ENV_EXISTS" != true ]; then print_status "Creating environment file..." cat > "$ENV_FILE" << EOF # Environment Configuration for ${ENVIRONMENT^} ENVIRONMENT=${ENVIRONMENT} # Database Configuration EOF if [ "$ENVIRONMENT" = "dev" ]; then cat >> "$ENV_FILE" << EOF DATABASE_URL=postgresql://dev:dev@localhost:5432/myapp_dev # Session Configuration SESSION_SECRET=dev-secret-not-for-production EOF else cat >> "$ENV_FILE" << EOF DATABASE_PASSWORD=your-production-database-password # Session Configuration SESSION_SECRET=$(generate_secret) EOF fi cat >> "$ENV_FILE" << EOF # OAuth Configuration (optional) # GOOGLE_CLIENT_ID=your-google-client-id # GOOGLE_CLIENT_SECRET=your-google-client-secret # GITHUB_CLIENT_ID=your-github-client-id # GITHUB_CLIENT_SECRET=your-github-client-secret # Email Configuration (optional) # SMTP_USERNAME=your-smtp-username # SMTP_PASSWORD=your-smtp-password # Server Overrides (optional) # SERVER_HOST=0.0.0.0 # SERVER_PORT=8080 # LOG_LEVEL=debug EOF print_status "Environment file created: $ENV_FILE" fi # Create directories print_status "Creating directories..." # Create basic directories mkdir -p logs mkdir -p content/public # Create server directories based on environment if [ "$ENVIRONMENT" = "dev" ]; then mkdir -p public uploads tmp cache config data backups print_status "Created development directories: public, uploads, logs, tmp, cache, config, data, backups" else print_status "Production directories should be created by system administrator with proper permissions" print_warning "Required directories: /var/www/public, /var/www/uploads, /var/log/app, /tmp/app, /var/cache/app, /etc/app, /var/lib/app, /var/backups/app" fi if [ "$SERVER_PROTOCOL" = "https" ]; then mkdir -p certs print_warning "HTTPS is enabled. You'll need to provide TLS certificates in the certs/ directory." fi # Create a default config.toml symlink if it doesn't exist if [ ! -f "config.toml" ]; then ln -sf "$CONFIG_FILE" config.toml print_status "Created config.toml symlink to $CONFIG_FILE" fi # Validate configuration print_status "Validating configuration..." if command_exists "cargo"; then if cargo run --bin config_tool -- validate 2>/dev/null; then print_status "Configuration validation passed!" else print_warning "Configuration validation failed. Please check your settings." fi else print_warning "Could not validate configuration (cargo not found)." fi # Display next steps print_header "=== Setup Complete ===" echo print_status "Configuration has been set up successfully!" echo print_status "Next steps:" echo "1. Review and customize your configuration file: $CONFIG_FILE" echo "2. Set up your environment variables: $ENV_FILE" echo "3. If using HTTPS, place your TLS certificates in the certs/ directory" echo "4. Set up your database and update the connection string" echo "5. Configure OAuth providers if needed" echo "6. Run 'cargo run --bin config_tool -- show' to view your configuration" echo "7. Start your application with 'cargo run'" echo if [ "$ENVIRONMENT" = "prod" ]; then print_warning "Production environment detected!" echo "- Make sure to set secure values for SESSION_SECRET and DATABASE_PASSWORD" echo "- Review all security settings in your configuration" echo "- Use proper secrets management in production" echo "- Enable HTTPS with valid TLS certificates" fi print_status "For more information, see CONFIG_README.md" } # Function to show usage show_usage() { echo "Usage: $0 [OPTIONS]" echo echo "Options:" echo " -h, --help Show this help message" echo " -e, --env ENV Set environment (dev/prod)" echo " -f, --force Overwrite existing files without prompting" echo echo "Examples:" echo " $0 # Interactive setup" echo " $0 -e dev # Setup for development" echo " $0 -e prod # Setup for production" echo " $0 -f # Force overwrite existing files" } # Parse command line arguments FORCE=false ENV_ARG="" while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_usage exit 0 ;; -e|--env) ENV_ARG="$2" shift 2 ;; -f|--force) FORCE=true shift ;; *) print_error "Unknown option: $1" show_usage exit 1 ;; esac done # Set environment if provided if [ -n "$ENV_ARG" ]; then ENVIRONMENT="$ENV_ARG" fi # Set force mode if [ "$FORCE" = true ]; then export FORCE_OVERWRITE=true fi # Run setup setup_config