Rustelo/info/config_readme.md

841 lines
20 KiB
Markdown
Raw Normal View History

# Configuration System
This project uses a comprehensive TOML-based configuration system with environment variable overrides. The configuration system supports multiple environments, feature flags, and secure credential management.
## Quick Start
1. Copy one of the example configuration files to `config.toml`:
```bash
cp config.dev.toml config.toml
```
2. Set environment-specific variables:
```bash
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
export SESSION_SECRET="your-secret-key-here"
```
3. Run your application:
```bash
cargo run
```
## Configuration Files
### File Priority
The configuration system looks for files in this order:
1. `$CONFIG_FILE` (if environment variable is set)
2. `config.{environment}.toml` (e.g., `config.dev.toml`, `config.prod.toml`)
3. `config.toml` (default fallback)
### Environment Detection
The environment is determined by the `ENVIRONMENT` variable:
- `development` or `dev` → looks for `config.dev.toml`
- `production` or `prod` → looks for `config.prod.toml`
- Default → looks for `config.toml`
## Configuration Structure
### Server Configuration
```toml
[server]
protocol = "http" # "http" or "https"
host = "127.0.0.1" # Server bind address
port = 3030 # Server port
environment = "development" # "development" or "production"
log_level = "info" # "trace", "debug", "info", "warn", "error"
# TLS Configuration (required when protocol = "https")
[server.tls]
cert_path = "certs/server.crt"
key_path = "certs/server.key"
```
### Database Configuration
```toml
[database]
url = "postgresql://user:pass@localhost:5432/dbname"
max_connections = 10
min_connections = 1
connect_timeout = 30 # seconds
idle_timeout = 600 # seconds
max_lifetime = 1800 # seconds
```
### Session Configuration
```toml
[session]
secret = "your-session-secret-here"
cookie_name = "session_id"
cookie_secure = false # Set to true in production with HTTPS
cookie_http_only = true
cookie_same_site = "lax" # "strict", "lax", or "none"
max_age = 3600 # Session duration in seconds
```
### CORS Configuration
```toml
[cors]
allowed_origins = ["http://localhost:3030"]
allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allowed_headers = ["Content-Type", "Authorization"]
allow_credentials = true
max_age = 3600
```
### Security Configuration
```toml
[security]
enable_csrf = true
csrf_token_name = "csrf_token"
rate_limit_requests = 100 # Requests per window
rate_limit_window = 60 # Window size in seconds
bcrypt_cost = 12 # BCrypt hashing cost
```
### OAuth Configuration
```toml
[oauth]
enabled = true
[oauth.google]
client_id = "your-google-client-id"
client_secret = "your-google-client-secret"
redirect_uri = "http://localhost:3030/auth/google/callback"
[oauth.github]
client_id = "your-github-client-id"
client_secret = "your-github-client-secret"
redirect_uri = "http://localhost:3030/auth/github/callback"
```
### Email Configuration
```toml
[email]
# Enable/disable email functionality
enabled = true
# Email provider: "smtp", "sendgrid", or "console"
provider = "console"
# Default sender information
from_email = "noreply@yourapp.com"
from_name = "Your App Name"
# Template directory for internationalized email templates
template_dir = "templates/email"
# SMTP Configuration (when provider = "smtp")
smtp_host = "smtp.gmail.com"
smtp_port = 587
smtp_username = "your-email@gmail.com"
smtp_password = "your-app-password"
smtp_use_tls = false
smtp_use_starttls = true
# SendGrid Configuration (when provider = "sendgrid")
sendgrid_api_key = ""
sendgrid_endpoint = "https://api.sendgrid.com/v3/mail/send"
# Environment-specific email settings
[environments.development]
email.enabled = true
email.provider = "console"
[environments.production]
email.enabled = true
email.provider = "sendgrid"
email.sendgrid_api_key = "${SENDGRID_API_KEY}"
email.from_email = "noreply@yourdomain.com"
```
### Feature Flags
```toml
[features]
auth = true # Enable authentication
tls = false # Enable TLS support
content_db = true # Enable database content management
two_factor_auth = false # Enable 2FA
email = true # Enable email functionality
```
## Environment Variable Overrides
Environment variables take precedence over TOML file values. Use the following format:
### Server Overrides
- `SERVER_PROTOCOL``server.protocol`
- `SERVER_HOST``server.host`
- `SERVER_PORT``server.port`
- `ENVIRONMENT``server.environment`
- `LOG_LEVEL``server.log_level`
### TLS Overrides
- `TLS_CERT_PATH``server.tls.cert_path`
- `TLS_KEY_PATH``server.tls.key_path`
### Database Overrides
- `DATABASE_URL``database.url`
### Session Overrides
- `SESSION_SECRET``session.secret`
### Example Environment Variables
```bash
# Server configuration
export SERVER_HOST="0.0.0.0"
export SERVER_PORT="8080"
export ENVIRONMENT="production"
export SERVER_PROTOCOL="https"
# Database
export DATABASE_URL="postgresql://prod_user:${DB_PASSWORD}@db.example.com:5432/prod_db"
# Security
export SESSION_SECRET="super-secret-production-key"
export TLS_CERT_PATH="/etc/ssl/certs/server.crt"
export TLS_KEY_PATH="/etc/ssl/private/server.key"
# OAuth
export GOOGLE_CLIENT_ID="your-google-client-id"
export GOOGLE_CLIENT_SECRET="your-google-client-secret"
export GITHUB_CLIENT_ID="your-github-client-id"
export GITHUB_CLIENT_SECRET="your-github-client-secret"
# Email
export EMAIL_PROVIDER="sendgrid"
export EMAIL_FROM_ADDRESS="noreply@yourdomain.com"
export EMAIL_FROM_NAME="Your Production App"
export SENDGRID_API_KEY="your-sendgrid-api-key"
export SMTP_HOST="smtp.gmail.com"
export SMTP_USERNAME="your-email@gmail.com"
export SMTP_PASSWORD="your-app-password"
```
## Environment Variable Substitution
You can use environment variable substitution in TOML files:
```toml
[database]
url = "postgresql://user:${DATABASE_PASSWORD}@localhost:5432/db"
[session]
secret = "${SESSION_SECRET}"
[oauth.google]
client_id = "${GOOGLE_CLIENT_ID}"
client_secret = "${GOOGLE_CLIENT_SECRET}"
[email]
provider = "${EMAIL_PROVIDER}"
from_email = "${EMAIL_FROM_ADDRESS}"
sendgrid_api_key = "${SENDGRID_API_KEY}"
smtp_password = "${SMTP_PASSWORD}"
```
## Usage in Code
### Loading Configuration
```rust
use server::config::Config;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Load configuration
let config = Config::load()?;
// Use configuration
println!("Server: {}:{}", config.server.host, config.server.port);
println!("Database: {}", config.database.url);
Ok(())
}
```
### Configuration Methods
```rust
let config = Config::load()?;
// Helper methods
let server_addr = config.server_address(); // "127.0.0.1:3030"
let server_url = config.server_url(); // "http://127.0.0.1:3030"
let is_dev = config.is_development(); // true/false
let is_prod = config.is_production(); // true/false
let needs_tls = config.requires_tls(); // true/false
// Database pool configuration
let pool_config = config.database_pool_config();
// Email configuration
let email_enabled = config.email.enabled;
let email_provider = &config.email.provider;
let template_dir = &config.email.template_dir;
```
### Custom Configuration
```rust
let custom_config = Config {
server: ServerConfig {
protocol: Protocol::Http,
host: "localhost".to_string(),
port: 3000,
environment: Environment::Development,
log_level: "debug".to_string(),
tls: None,
},
app: AppConfig {
name: "My App".to_string(),
version: "1.0.0".to_string(),
debug: true,
..Default::default()
},
..Default::default()
};
```
## Best Practices
### Development
1. Use `config.dev.toml` for development settings
2. Enable debug logging and relaxed security
3. Use local database connections
4. Disable TLS for easier development
### Production
1. Use `config.prod.toml` for production settings
2. Enable all security features
3. Use environment variables for secrets
4. Enable TLS and secure cookies
5. Use restrictive CORS policies
### Security
1. **Never commit secrets to version control**
2. Use environment variables for sensitive data
3. Use strong session secrets (32+ characters)
4. Enable CSRF protection in production
5. Use secure cookies with HTTPS
6. Implement rate limiting
### Docker
```dockerfile
# Copy configuration files
COPY config.prod.toml /app/config.toml
# Set environment variables
ENV ENVIRONMENT=production
ENV DATABASE_URL=${DATABASE_URL}
ENV SESSION_SECRET=${SESSION_SECRET}
```
### Kubernetes
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
config.toml: |
[server]
protocol = "https"
host = "0.0.0.0"
port = 8080
environment = "production"
[database]
url = "postgresql://user:${DATABASE_PASSWORD}@postgres:5432/app"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
data:
DATABASE_PASSWORD: <base64-encoded-password>
SESSION_SECRET: <base64-encoded-secret>
```
## Configuration Examples
### Development Environment
```toml
[server]
protocol = "http"
host = "127.0.0.1"
port = 3030
environment = "development"
log_level = "debug"
[database]
url = "postgresql://dev:dev@localhost:5432/app_dev"
max_connections = 5
[security]
enable_csrf = false
rate_limit_requests = 1000
bcrypt_cost = 4
[session]
cookie_secure = false
max_age = 7200
[email]
enabled = true
provider = "console"
template_dir = "templates/email"
```
### Production Environment
```toml
[server]
protocol = "https"
host = "0.0.0.0"
port = 443
environment = "production"
log_level = "info"
[server.tls]
cert_path = "/etc/ssl/certs/app.crt"
key_path = "/etc/ssl/private/app.key"
[database]
url = "postgresql://app:${DATABASE_PASSWORD}@db.example.com:5432/app_prod"
max_connections = 20
[security]
enable_csrf = true
rate_limit_requests = 50
bcrypt_cost = 12
[session]
secret = "${SESSION_SECRET}"
cookie_secure = true
cookie_same_site = "strict"
max_age = 3600
[email]
enabled = true
provider = "sendgrid"
sendgrid_api_key = "${SENDGRID_API_KEY}"
from_email = "noreply@yourdomain.com"
from_name = "Your Production App"
template_dir = "templates/email"
```
## Troubleshooting
### Configuration Not Found
```
Error: Configuration file not found: config.toml
```
**Solution:** Create a configuration file or set the `CONFIG_FILE` environment variable.
### Environment Variable Not Found
```
Error: Environment variable 'DATABASE_PASSWORD' not found
```
**Solution:** Set the required environment variable or remove the substitution from the TOML file.
### TLS Configuration Error
```
Error: TLS certificate path is required when using HTTPS
```
**Solution:** Either set `protocol = "http"` or provide valid TLS certificate paths.
### Database Connection Error
```
Error: Failed to connect to database
```
**Solution:** Check the database URL and ensure the database is running and accessible.
## Migration from Environment-Only Configuration
If you're migrating from a purely environment-based configuration:
1. Create a `config.toml` file with your current settings
2. Move sensitive values to environment variables
3. Use environment variable substitution in TOML
4. Test the configuration loading
Example migration:
```bash
# Old way (environment only)
export SERVER_HOST="0.0.0.0"
export SERVER_PORT="3030"
export DATABASE_URL="postgresql://..."
# New way (TOML + environment)
# config.toml
[server]
host = "0.0.0.0"
port = 3030
[database]
url = "${DATABASE_URL}"
```
## Testing Configuration
Run the configuration example to test your setup:
```bash
cargo run --example config_example
```
This will show you how your configuration is being loaded and what values are being used.
## Email Template Configuration
The email system uses an internationalized template structure with automatic language fallback:
### Template Directory Structure
```
templates/email/
├── en_/ # English templates (default)
│ ├── html/ # HTML email templates
│ │ ├── contact.hbs # Contact form template
│ │ └── notification.hbs # Notification template
│ └── text/ # Plain text templates
│ ├── contact.hbs
│ └── notification.hbs
├── es_/ # Spanish templates
│ ├── html/
│ └── text/
└── README.md # Template documentation
```
### Template Naming Convention
Templates are registered with the pattern: `{language}_{template_name}_{format}`
Examples:
- `en_contact_html` - English contact form HTML template
- `es_notification_text` - Spanish notification text template
### Language Detection and Fallback
The system automatically detects language preferences from:
1. **User Profile**: Authenticated user's saved language preference
2. **Request Headers**: `Accept-Language` HTTP header
3. **Default Fallback**: English (`en`)
### Template Configuration
```toml
[email]
# Template directory (relative to project root)
template_dir = "templates/email"
# Default language for fallback
default_language = "en"
# Supported languages
supported_languages = ["en", "es", "fr", "de"]
```
### Creating New Templates
1. **Create language directory:**
```bash
mkdir -p templates/email/fr_/html
mkdir -p templates/email/fr_/text
```
2. **Add template files:**
```bash
# Create French contact template
touch templates/email/fr_/html/contact.hbs
touch templates/email/fr_/text/contact.hbs
```
3. **Template variables:**
```handlebars
{{name}} # User's name
{{email}} # User's email
{{subject}} # Message subject
{{message}} # Message content
{{submitted_at}} # Timestamp
```
### Available Handlebars Helpers
- `{{date_format submitted_at "%B %d, %Y at %I:%M %p UTC"}}`
- `{{capitalize form_type}}`
- `{{truncate user_agent 100}}`
- `{{default action_text "Click Here"}}`
- `{{url_encode email}}`
### Environment-Specific Email Settings
```toml
# Development - Print emails to console
[environments.development]
email.enabled = true
email.provider = "console"
# Staging - Use test SMTP server
[environments.staging]
email.enabled = true
email.provider = "smtp"
email.smtp_host = "smtp.mailtrap.io"
email.smtp_port = 2525
# Production - Use SendGrid
[environments.production]
email.enabled = true
email.provider = "sendgrid"
email.sendgrid_api_key = "${SENDGRID_API_KEY}"
```
For detailed email template documentation, see `templates/email/README.md`.
## Configuration Encryption System
The Rustelo framework includes a comprehensive encryption system for securing sensitive configuration values using AES-256-GCM encryption with automatic key management.
### Overview
The encryption system provides:
- **AES-256-GCM encryption** for sensitive configuration values
- **Automatic key generation** and management via `.k` file
- **Simple syntax** - encrypted values start with `@`
- **Automatic decryption** during configuration loading
- **CLI tools** for managing encrypted values
- **Environment variable compatibility** alongside encryption
### Quick Start
1. **Generate Encryption Key**:
```bash
cargo run --bin config_crypto_tool generate-key
```
2. **Encrypt Sensitive Values**:
```bash
cargo run --bin config_crypto_tool encrypt "my_secret_password"
# Output: @AbCdEf123456...
```
3. **Use in Configuration**:
```toml
[session]
secret = "@AbCdEf123456..."
[database]
url = "postgresql://user:@ZW5jcnlwdGVk@localhost:5432/db"
```
4. **Verify Setup**:
```bash
cargo run --bin config_crypto_tool verify
```
### Encryption Integration in Configuration
Configuration values starting with `@` are automatically decrypted during loading:
```toml
# config.prod.toml
[session]
secret = "@c2Vzc2lvbl9zZWNyZXRfZXhhbXBsZQ==" # Encrypted session secret
[database]
url = "postgresql://user:@ZW5jcnlwdGVkX3Bhc3N3b3Jk@localhost:5432/mydb"
[oauth.google]
client_id = "${GOOGLE_CLIENT_ID}" # Environment variable
client_secret = "@Z29vZ2xlX2NsaWVudF9zZWNyZXQ=" # Encrypted value
[email]
sendgrid_api_key = "@c2VuZGdyaWRfYXBpX2tleQ=="
smtp_password = "@c210cF9wYXNzd29yZA=="
```
### Mixed Configuration Approach
You can combine encrypted values with environment variables for maximum flexibility:
```toml
[database]
url = "${DATABASE_URL}" # Environment variable (highest priority)
[session]
secret = "@encrypted_session_secret" # Encrypted value
[oauth.google]
client_id = "${GOOGLE_CLIENT_ID}" # Environment variable
client_secret = "@encrypted_google_secret" # Encrypted value
[redis]
url = "@encrypted_redis_url" # Encrypted Redis URL with credentials
```
### Configuration Loading Order
1. **Environment variables** (highest priority)
2. **Encrypted values** (decrypted automatically)
3. **Plain text values** (lowest priority)
The framework includes a built-in encryption system for securing sensitive configuration values using AES-256-GCM encryption.
### How It Works
1. **Encryption Key**: A `.k` file in the project root contains the encryption key
2. **Encrypted Values**: Configuration values starting with `@` are automatically decrypted
3. **Automatic Management**: The system handles key generation and value decryption seamlessly
### Quick Start
```bash
# Generate encryption key
cargo run --bin config_crypto_tool generate-key
# Encrypt a sensitive value
cargo run --bin config_crypto_tool encrypt "your_secret_value"
# Output: @AbCdEf123456...
# Use in configuration
echo 'session.secret = "@AbCdEf123456..."' >> config.toml
# Verify encryption works
cargo run --bin config_crypto_tool verify
```
### Configuration Examples
```toml
# Example encrypted configuration
[session]
secret = "@encrypted_session_secret"
[database]
url = "postgresql://user:@encrypted_password@localhost:5432/db"
[oauth.google]
client_secret = "@encrypted_google_client_secret"
[email]
sendgrid_api_key = "@encrypted_sendgrid_api_key"
smtp_password = "@encrypted_smtp_password"
```
### CLI Commands
```bash
# Key management
cargo run --bin config_crypto_tool generate-key # Generate new key
cargo run --bin config_crypto_tool key-info # Show key information
cargo run --bin config_crypto_tool verify # Verify key works
cargo run --bin config_crypto_tool rotate-key --confirm # Rotate key
# Value encryption/decryption
cargo run --bin config_crypto_tool encrypt "value" # Encrypt a value
cargo run --bin config_crypto_tool decrypt "@..." # Decrypt a value
# Configuration management
cargo run --bin config_crypto_tool find-encrypted -c config.toml
cargo run --bin config_crypto_tool show-decrypted -c config.toml
cargo run --bin config_crypto_tool encrypt-config -c config.toml -k "secret,api_key"
# Interactive mode
cargo run --bin config_crypto_tool interactive
```
### Security Features
- **AES-256-GCM encryption** with authenticated encryption
- **Automatic key generation** using cryptographically secure random numbers
- **File permissions** set to 0600 (read/write for owner only)
- **Key rotation support** with backup creation
- **Environment variable compatibility** - can mix encrypted and environment values
### Best Practices
1. **Never commit `.k` files** to version control
2. **Use different keys** for different environments
3. **Backup encryption keys** securely
4. **Rotate keys regularly** in production
5. **Monitor key file integrity**
### Mixed Configuration Approach
You can combine encrypted values with environment variables:
```toml
[database]
url = "${DATABASE_URL}" # Environment variable
[session]
secret = "@encrypted_session_secret" # Encrypted value
[oauth.google]
client_id = "${GOOGLE_CLIENT_ID}" # Environment variable
client_secret = "@encrypted_google_secret" # Encrypted value
```
### Deployment Considerations
```bash
# Production deployment
# 1. Generate key on production server
cargo run --bin config_crypto_tool generate-key
# 2. Encrypt production secrets
PROD_SECRET=$(cargo run --bin config_crypto_tool encrypt "prod-secret-2024")
# 3. Update configuration with encrypted values
# 4. Ensure .k file is properly secured and backed up
```
### File Structure
```
project/
├── .k # Encryption key (DO NOT COMMIT)
├── config.prod.toml # Config with encrypted values
├── .gitignore # Must include .k
└── docs/
└── ENCRYPTION.md # Detailed encryption documentation
```
### Error Handling
Common issues and solutions:
- **Key not found**: Run `cargo run --bin config_crypto_tool generate-key`
- **Decryption failed**: Verify key with `cargo run --bin config_crypto_tool verify`
- **Permission denied**: Set proper permissions with `chmod 600 .k`
For comprehensive encryption documentation, see `docs/ENCRYPTION.md`.