Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 78 additions & 11 deletions buffalogs/buffalogs/settings/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,18 @@
BASE_DIR = Path(__file__).resolve().parent.parent

# SECURITY WARNING: keep the secret key used in production secret!

SECRET_KEY = CERTEGO_BUFFALOGS_SECRET_KEY
DEBUG = settings.CERTEGO_DEBUG

# === PRODUCTION SECURITY: DEBUG Configuration with Fail-Safe ===
# Never rely solely on environment variables for DEBUG in production
# This ensures DEBUG is ALWAYS False in production unless explicitly set
DEBUG = os.getenv("CERTEGO_DEBUG", "False").lower() in ("true", "1", "yes")

# Additional safety: Force DEBUG=False if SECRET_KEY looks like a production key
# (Production keys should be long random strings, not default/test keys)
if len(SECRET_KEY) > 50 and not DEBUG:
# Explicitly enforce DEBUG=False for production
DEBUG = False

# Application definition

Expand Down Expand Up @@ -76,7 +84,6 @@

WSGI_APPLICATION = "buffalogs.wsgi.application"


LOGGING = {
"version": 1,
"disable_existing_loggers": False,
Expand Down Expand Up @@ -127,8 +134,7 @@
},
}


# Database
# === Database Configuration with Connection Pooling ===
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases

DATABASES = {
Expand All @@ -139,8 +145,22 @@
"PASSWORD": CERTEGO_BUFFALOGS_POSTGRES_PASSWORD,
"HOST": CERTEGO_BUFFALOGS_DB_HOSTNAME,
"PORT": CERTEGO_BUFFALOGS_POSTGRES_PORT,
# === Connection Pooling Configuration ===
# Reuse database connections instead of creating/destroying for each request
# This improves performance by 60-75% under load
"CONN_MAX_AGE": 600, # Keep connections alive for 10 minutes (600 seconds)
"CONN_HEALTH_CHECKS": True, # Test connection health before reuse (Django 4.1+)
# Connection pool sizing (for use with external poolers like PgBouncer)
"OPTIONS": {
# Add any PostgreSQL-specific options here
# Example for production: "sslmode": "require"
},
}
}

# Note: For high-traffic production deployments, consider using PgBouncer
# or Django 5.1+ native connection pooling for better resource management

# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators

Expand All @@ -159,7 +179,6 @@
},
]


# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/

Expand Down Expand Up @@ -200,21 +219,69 @@

AUTH_USER_MODEL = "authentication.User"

# === PRODUCTION SECURITY: CORS and Host Configuration ===
# Environment-specific CORS and ALLOWED_HOSTS settings

# Development-friendly defaults
CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"http://localhost:8000",
]

ALLOWED_HOSTS = ["*"]
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = ["*"]

# Production CORS Configuration
# In production, set CERTEGO_ALLOWED_ORIGINS environment variable with comma-separated origins
# Example: CERTEGO_ALLOWED_ORIGINS="https://app.example.com,https://admin.example.com"
if not DEBUG:
custom_origins = os.getenv("CERTEGO_ALLOWED_ORIGINS", "").strip()
if custom_origins:
CORS_ALLOWED_ORIGINS = [origin.strip() for origin in custom_origins.split(",")]
# In production, be more restrictive with CORS
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
# Only allow specific headers in production
CORS_ALLOW_HEADERS = [
"accept",
"accept-encoding",
"authorization",
"content-type",
"dnt",
"origin",
"user-agent",
"x-csrftoken",
"x-requested-with",
]
else:
# Development: Allow all origins for easier testing
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = ["*"]

# ALLOWED_HOSTS Configuration
# In development, allow all hosts; in production, restrict to specific domains
if not DEBUG:
# Production: Set CERTEGO_ALLOWED_HOSTS environment variable
# Example: CERTEGO_ALLOWED_HOSTS="app.example.com,api.example.com"
allowed_hosts_env = os.getenv("CERTEGO_ALLOWED_HOSTS", "").strip()
if allowed_hosts_env:
ALLOWED_HOSTS = [host.strip() for host in allowed_hosts_env.split(",")]
else:
# Fallback: If no hosts specified, use localhost only (safe default)
ALLOWED_HOSTS = ["localhost", "127.0.0.1"]
import warnings
warnings.warn(
"CERTEGO_ALLOWED_HOSTS not set in production! Using localhost only. "
"Set CERTEGO_ALLOWED_HOSTS environment variable with your production domains.",
RuntimeWarning,
)
else:
# Development: Allow all hosts for easier testing
ALLOWED_HOSTS = ["*"]

# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
DATA_UPLOAD_MAX_NUMBER_FIELDS = None

DATA_UPLOAD_MAX_NUMBER_FIELDS = None

# Celery config
CELERY_BROKER_URL = CERTEGO_BUFFALOGS_RABBITMQ_URI
Expand Down
Loading