103 lines
4.2 KiB
Python
103 lines
4.2 KiB
Python
import os
|
|
from pathlib import Path
|
|
from urllib.parse import unquote, urlparse
|
|
|
|
from django.core.exceptions import ImproperlyConfigured
|
|
|
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
|
PRODUCTION = os.environ.get("APP_ENV") == "production"
|
|
SECRET_KEY = os.environ.get("SECRET_KEY", "development-only-not-for-production-traceiq")
|
|
if PRODUCTION and (len(SECRET_KEY) < 50 or SECRET_KEY.startswith("development")):
|
|
raise ImproperlyConfigured("Set a random SECRET_KEY of at least 50 characters")
|
|
DEBUG = not PRODUCTION
|
|
ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS", "localhost,127.0.0.1,testserver").split(",")
|
|
CSRF_TRUSTED_ORIGINS = [x for x in os.environ.get("CSRF_TRUSTED_ORIGINS", "").split(",") if x]
|
|
INSTALLED_APPS = [
|
|
"django.contrib.auth",
|
|
"django.contrib.contenttypes",
|
|
"django.contrib.sessions",
|
|
"django.contrib.staticfiles",
|
|
"finance",
|
|
]
|
|
MIDDLEWARE = [
|
|
"django.middleware.security.SecurityMiddleware",
|
|
"whitenoise.middleware.WhiteNoiseMiddleware",
|
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
"django.middleware.common.CommonMiddleware",
|
|
"django.middleware.csrf.CsrfViewMiddleware",
|
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
"finance.middleware.SecurityHeaders",
|
|
]
|
|
ROOT_URLCONF = "server.urls"
|
|
WSGI_APPLICATION = "server.wsgi.application"
|
|
url = os.environ.get("DATABASE_URL")
|
|
if url:
|
|
db = urlparse(url)
|
|
if db.scheme not in ("postgres", "postgresql"):
|
|
raise ImproperlyConfigured("DATABASE_URL must be PostgreSQL")
|
|
DATABASES = {
|
|
"default": {
|
|
"ENGINE": "django.db.backends.postgresql",
|
|
"NAME": db.path[1:],
|
|
"USER": unquote(db.username or ""),
|
|
"PASSWORD": unquote(db.password or ""),
|
|
"HOST": db.hostname,
|
|
"PORT": db.port or 5432,
|
|
"CONN_MAX_AGE": 60,
|
|
"OPTIONS": {"sslmode": os.environ.get("DB_SSLMODE", "prefer")},
|
|
}
|
|
}
|
|
else:
|
|
if PRODUCTION:
|
|
raise ImproperlyConfigured("Production requires DATABASE_URL")
|
|
DATABASES = {
|
|
"default": {
|
|
"ENGINE": "django.db.backends.sqlite3",
|
|
"NAME": os.environ.get("SQLITE_PATH", str(BASE_DIR / "var/db.sqlite3")),
|
|
"OPTIONS": {"timeout": 30},
|
|
}
|
|
}
|
|
AUTH_PASSWORD_VALIDATORS = [
|
|
{"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
|
|
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", "OPTIONS": {"min_length": 12}},
|
|
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
|
|
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
|
|
]
|
|
LANGUAGE_CODE = "zh-hans"
|
|
TIME_ZONE = "UTC"
|
|
USE_TZ = True
|
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|
SESSION_COOKIE_HTTPONLY = True
|
|
SESSION_COOKIE_SAMESITE = "Lax"
|
|
SESSION_COOKIE_AGE = 8 * 3600
|
|
SESSION_COOKIE_SECURE = PRODUCTION
|
|
CSRF_COOKIE_SECURE = PRODUCTION
|
|
SECURE_SSL_REDIRECT = PRODUCTION and os.environ.get("SECURE_SSL_REDIRECT", "1") == "1"
|
|
SECURE_HSTS_SECONDS = 31536000 if PRODUCTION else 0
|
|
SECURE_HSTS_INCLUDE_SUBDOMAINS = PRODUCTION
|
|
SECURE_HSTS_PRELOAD = PRODUCTION
|
|
# Enable only behind the private reverse proxy which overwrites this header.
|
|
TRUST_PROXY = os.environ.get("TRUST_PROXY", "0") == "1"
|
|
if TRUST_PROXY:
|
|
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
|
SECURE_CONTENT_TYPE_NOSNIFF = True
|
|
X_FRAME_OPTIONS = "DENY"
|
|
DATA_UPLOAD_MAX_MEMORY_SIZE = 2 * 1024 * 1024
|
|
FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024
|
|
MEDIA_ROOT = Path(os.environ.get("MEDIA_ROOT", BASE_DIR / "var/uploads"))
|
|
STATIC_URL = "/assets/"
|
|
STATIC_ROOT = BASE_DIR / "staticfiles"
|
|
STATICFILES_DIRS = [BASE_DIR / "frontend/dist/assets"] if (BASE_DIR / "frontend/dist/assets").exists() else []
|
|
MAX_UPLOAD_BYTES = int(os.environ.get("MAX_UPLOAD_BYTES", 64 * 1024 * 1024))
|
|
MAX_IMPORT_ROWS = int(os.environ.get("MAX_IMPORT_ROWS", 1000000))
|
|
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", "")
|
|
OPENAI_MODEL = os.environ.get("OPENAI_MODEL", "")
|
|
AI_ENABLED = os.environ.get("AI_ENABLED", "0") == "1"
|
|
LOGGING = {
|
|
"version": 1,
|
|
"disable_existing_loggers": False,
|
|
"handlers": {"console": {"class": "logging.StreamHandler"}},
|
|
"root": {"handlers": ["console"], "level": "INFO"},
|
|
}
|