servala-portal/src/servala/settings.py

212 lines
7.3 KiB
Python

"""
Django settings for servala project.
Servala is run using environment variables. Documentation:
- README.md for project information
- .env.example for environment variables in use
- Django settings guide: https://docs.djangoproject.com/en/5.2/topics/settings/
- Django settings reference: https://docs.djangoproject.com/en/5.2/ref/settings/
"""
import os
from pathlib import Path
from django.contrib import messages
SERVALA_ENVIRONMENT = os.environ.get("SERVALA_ENVIRONMENT", "development")
DEBUG = SERVALA_ENVIRONMENT == "development"
SECRET_KEY = os.environ.get("SERVALA_SECRET_KEY")
if previous_secret_key := os.environ.get("SERVALA_PREVIOUS_SECRET_KEY"):
SECRET_KEY_FALLBACKS = [previous_secret_key]
SALT_KEY = os.environ.get("SERVALA_SALT_KEY")
if previous_salt := os.environ.get("SERVALA_PREVIOUS_SALT_KEY"):
SALT_KEY = [SALT_KEY, previous_salt]
BASE_DIR = Path(__file__).resolve().parent.parent
ALLOWED_HOSTS = []
if allowed_hosts := os.environ.get("SERVALA_ALLOWED_HOSTS"):
ALLOWED_HOSTS = allowed_hosts.split(",")
CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in ALLOWED_HOSTS]
db_name = os.environ.get("SERVALA_DB_NAME", "")
if SERVALA_ENVIRONMENT == "development" and not db_name:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
"OPTIONS": {"timeout": 10},
}
}
else:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": db_name or "servala",
"USER": os.environ.get("SERVALA_DB_USER", "servala"),
"PASSWORD": os.environ.get("SERVALA_DB_PASSWORD"),
"HOST": os.environ.get("SERVALA_DB_HOST", "localhost"),
"PORT": os.environ.get("SERVALA_DB_PORT", "5432"),
"CONN_MAX_AGE": 120,
"CONN_HEALTH_CHECKS": True,
}
}
MEDIA_ROOT = os.environ.get("SERVALA_MEDIA_ROOT", "media")
if MEDIA_ROOT.startswith("/"):
MEDIA_ROOT = Path(MEDIA_ROOT)
else:
MEDIA_ROOT = BASE_DIR / MEDIA_ROOT
EMAIL_HOST = os.environ.get("SERVALA_EMAIL_HOST", "localhost")
EMAIL_PORT = int(os.environ.get("SERVALA_EMAIL_PORT", "25"))
EMAIL_HOST_USER = os.environ.get("SERVALA_EMAIL_USER", "")
EMAIL_HOST_PASSWORD = os.environ.get("SERVALA_EMAIL_PASSWORD", "")
EMAIL_USE_TLS = os.environ.get("SERVALA_EMAIL_TLS", "False") == "True"
EMAIL_USE_SSL = os.environ.get("SERVALA_EMAIL_SSL", "False") == "True"
SERVALA_DEFAULT_ORIGIN = int(os.environ.get("SERVALA_DEFAULT_ORIGIN", "1"))
SOCIALACCOUNT_PROVIDERS = {
"openid_connect": {
"APPS": [
{
"provider_id": "keycloak",
"name": "VSHN Account",
"client_id": os.environ.get("SERVALA_KEYCLOAK_CLIENT_ID"),
"secret": os.environ.get("SERVALA_KEYCLOAK_CLIENT_SECRET"),
"settings": {
"server_url": os.environ.get("SERVALA_KEYCLOAK_SERVER_URL"),
},
}
]
}
}
#######################################
# Non-configurable settings below #
#######################################
WSGI_APPLICATION = "servala.wsgi.application"
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.forms",
"template_partials",
"rules.apps.AutodiscoverRulesConfig",
# The frontend app is loaded early in order to supersede some allauth views/behaviour
"servala.frontend",
"allauth",
"allauth.account",
"allauth.socialaccount",
"allauth.socialaccount.providers.openid_connect",
"servala.core",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"allauth.account.middleware.AccountMiddleware",
"django.contrib.auth.middleware.LoginRequiredMiddleware",
"servala.core.middleware.OrganizationMiddleware",
]
LOGIN_URL = "account_login"
ROOT_URLCONF = "servala.urls"
STATIC_URL = "static/" # CSS, JavaScript, etc.
# Collected static files as provided by ``collectstatic`` management command are stored here ready to be served by a web server.
STATIC_ROOT = BASE_DIR / "static.dist"
MEDIA_URL = "media/" # User uploads, e.g. images
# Additional locations of static files
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
)
STATICFILES_DIRS = [BASE_DIR / "servala" / "static"]
template_loaders = (
"django.template.loaders.filesystem.Loader",
"django.template.loaders.app_directories.Loader",
)
if not DEBUG:
template_loaders = (("django.template.loaders.cached.Loader", template_loaders),)
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": False,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
"django.template.context_processors.static",
"servala.frontend.context_processors.add_organizations",
],
"loaders": template_loaders,
},
},
]
FORM_RENDERER = "servala.frontend.forms.renderers.VerticalFormRenderer"
MESSAGE_TAGS = {
messages.ERROR: "danger",
}
AUTH_USER_MODEL = "core.User"
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_LOGIN_METHODS = {"email"}
ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*", "password2*"]
ACCOUNT_SIGNUP_FORM_CLASS = "servala.frontend.forms.auth.ServalaSignupForm"
if ALLOWED_HOSTS or not DEBUG:
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
AUTHENTICATION_BACKENDS = [
"rules.permissions.ObjectPermissionBackend",
# Needed to login by username in Django admin, regardless of `allauth`
"django.contrib.auth.backends.ModelBackend",
"allauth.account.auth_backends.AuthenticationBackend",
]
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
PASSWORD_HASHERS = [
"django.contrib.auth.hashers.Argon2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
"django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
"django.contrib.auth.hashers.ScryptPasswordHasher",
]
CSRF_COOKIE_NAME = "servala_csrf"
LANGUAGE_COOKIE_NAME = "servala_lang"
SESSION_COOKIE_NAME = "servala_sess"
SESSION_COOKIE_SECURE = not DEBUG
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# TODO
TIME_ZONE = "UTC"
if SERVALA_ENVIRONMENT in ("staging", "production"):
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")