diff --git a/.env.example b/.env.example index d748f75..f8cb818 100644 --- a/.env.example +++ b/.env.example @@ -1,22 +1,23 @@ -DEBUG=True -SECRET_KEY= +DJANGO_DEBUG=False +SECRET_KEY="" POSTGRES_DATABASE= POSTGRES_USER= POSTGRES_PASSWORD= POSTGRES_HOST= POSTGRES_PORT= - -ALLOWED_HOSTS="localhost" -CSRF_TRUSTED_ORIGINS="http://localhost" DJANGO_SECURE_SSL_REDIRECT=False -CSRF_COOKIE_DOMAIN="http://localhost" +DJANGO_SETTINGS_MODULE="apibase.django.local" +ALLOWED_HOSTS="" +CSRF_TRUSTED_ORIGINS="" +CSRF_COOKIE_DOMAIN="" -EMAIL_HOSTNAME= +EMAIL_HOSTNAME="" EMAIL_PORT= EMAIL_USERNAME= EMAIL_PASSWORD= -FRONTEND_URL= -PAYMENT_VERIFY_BASE_URL= -SMS_API_URL= -SMS_API_KEY= \ No newline at end of file +PAYMENT_VERIFY_BASE_URL="" +FRONTEND_URL="" + +SMS_API_URL="" +SMS_API_KEY="" \ No newline at end of file diff --git a/apibase/asgi.py b/apibase/asgi.py index 31366be..42e677e 100644 --- a/apibase/asgi.py +++ b/apibase/asgi.py @@ -11,6 +11,6 @@ import os from django.core.asgi import get_asgi_application -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apibase.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apibase.django.local") application = get_asgi_application() diff --git a/apibase/django/__init__.py b/apibase/django/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apibase/settings.py b/apibase/django/base.py similarity index 83% rename from apibase/settings.py rename to apibase/django/base.py index 7e5cc9d..4edf43a 100644 --- a/apibase/settings.py +++ b/apibase/django/base.py @@ -11,33 +11,28 @@ https://docs.djangoproject.com/en/5.0/ref/settings/ """ import os -from pathlib import Path import datetime from rest_framework.settings import api_settings -from decouple import config from django.core.management.utils import get_random_secret_key from django.utils.log import DEFAULT_LOGGING import logging.config -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent +from apibase.env import env, BASE_DIR + +env.read_env(os.path.join(BASE_DIR, ".env")) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = config("SECRET_KEY", default=get_random_secret_key()) +SECRET_KEY = env("SECRET_KEY", default=get_random_secret_key()) # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = config("DEBUG", cast=bool) - - -ALLOWED_HOSTS = [] +DEBUG = env.bool("DJANGO_DEBUG", default=True) +ALLOWED_HOSTS = ["*"] # Add explicit hosts from environment -env_hosts = config("ALLOWED_HOSTS", default="").split() -ALLOWED_HOSTS.extend(env_hosts) if DEBUG: INTERNAL_IPS = [ @@ -126,27 +121,12 @@ WSGI_APPLICATION = "apibase.wsgi.application" # https://docs.djangoproject.com/en/5.0/ref/settings/#databases -if not DEBUG: - DATABASES = { - "default": { - "ENGINE": "django.db.backends.postgresql", - "NAME": config("POSTGRES_DATABASE"), - "USER": config("POSTGRES_USER"), - "PASSWORD": config("POSTGRES_PASSWORD"), - "HOST": config("POSTGRES_HOST"), - "PORT": config("POSTGRES_PORT"), - "OPTIONS": { - "pool": True, - }, - }, - } -else: - DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": BASE_DIR / "db.sqlite3", - } +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", } +} # More robust caching configuration @@ -158,7 +138,7 @@ CACHES = { else "django.core.cache.backends.locmem.LocMemCache" ), "LOCATION": ( - config("REDIS_URL", default="redis://redis:6379/") if not DEBUG else "" + env("REDIS_URL", default="redis://redis:6379/") if not DEBUG else "" ), "OPTIONS": ( { @@ -341,29 +321,13 @@ logging.config.dictConfig( ) -if not DEBUG: - SECURE_SSL_REDIRECT = config("DJANGO_SECURE_SSL_REDIRECT", cast=bool) - SESSION_COOKIE_SECURE = True - CSRF_COOKIE_SECURE = True - SECURE_HSTS_SECONDS = config("SECURE_HSTS_SECONDS", default=3600, cast=int) - SECURE_HSTS_INCLUDE_SUBDOMAINS = True - SECURE_HSTS_PRELOAD = True - CSRF_TRUSTED_ORIGINS = [config("CSRF_TRUSTED_ORIGINS")] - CSRF_COOKIE_DOMAIN = config("CSRF_COOKIE_DOMAIN") - SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") - # Additional security headers - SECURE_BROWSER_XSS_FILTER = True - X_FRAME_OPTIONS = "DENY" - SECURE_CONTENT_TYPE_NOSNIFF = True - - EMAIL_BACKEND = ( "django.core.mail.backends.smtp.EmailBackend" # Replace with your preferred backend ) -EMAIL_HOST = config("EMAIL_HOSTNAME") -EMAIL_PORT = config("EMAIL_PORT", cast=int) -EMAIL_HOST_USER = config("EMAIL_USERNAME") -EMAIL_HOST_PASSWORD = config("EMAIL_PASSWORD") +EMAIL_HOST = env("EMAIL_HOSTNAME") +EMAIL_PORT = env("EMAIL_PORT", cast=int) +EMAIL_HOST_USER = env("EMAIL_USERNAME") +EMAIL_HOST_PASSWORD = env("EMAIL_PASSWORD") # DEFAULT_FROM_EMAIL = "noreply@sarlink.net" EMAIL_USE_TLS = True diff --git a/apibase/django/local.py b/apibase/django/local.py new file mode 100644 index 0000000..c1c61fc --- /dev/null +++ b/apibase/django/local.py @@ -0,0 +1,9 @@ +from .base import * +from apibase.env import BASE_DIR + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": BASE_DIR / "db.sqlite3", + } +} diff --git a/apibase/django/production.py b/apibase/django/production.py new file mode 100644 index 0000000..41408cc --- /dev/null +++ b/apibase/django/production.py @@ -0,0 +1,34 @@ +from .base import * +from apibase.env import env + +DEBUG = env.bool("DJANGO_DEBUG", default=False) + +ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", default=[]) + + +SECURE_SSL_REDIRECT = env("DJANGO_SECURE_SSL_REDIRECT", cast=bool) +SESSION_COOKIE_SECURE = True +CSRF_COOKIE_SECURE = True +SECURE_HSTS_SECONDS = env("SECURE_HSTS_SECONDS", default=3600, cast=int) +SECURE_HSTS_INCLUDE_SUBDOMAINS = True +SECURE_HSTS_PRELOAD = True +CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_ORIGINS", default=[]) +CSRF_COOKIE_DOMAIN = env("CSRF_COOKIE_DOMAIN") +SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") +SECURE_BROWSER_XSS_FILTER = True +X_FRAME_OPTIONS = "DENY" +SECURE_CONTENT_TYPE_NOSNIFF = True + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": env("POSTGRES_DATABASE"), + "USER": env("POSTGRES_USER"), + "PASSWORD": env("POSTGRES_PASSWORD"), + "HOST": env("POSTGRES_HOST"), + "PORT": env("POSTGRES_PORT"), + "OPTIONS": { + "pool": True, + }, + }, +} diff --git a/apibase/django/tests.py b/apibase/django/tests.py new file mode 100644 index 0000000..e69de29 diff --git a/apibase/env.py b/apibase/env.py new file mode 100644 index 0000000..a31d410 --- /dev/null +++ b/apibase/env.py @@ -0,0 +1,6 @@ +import environ +from pathlib import Path + +env = environ.Env() + +BASE_DIR = Path(__file__).resolve().parent.parent diff --git a/apibase/settings/sms.py b/apibase/settings/sms.py new file mode 100644 index 0000000..e69de29 diff --git a/apibase/wsgi.py b/apibase/wsgi.py index a18da4e..7118702 100644 --- a/apibase/wsgi.py +++ b/apibase/wsgi.py @@ -11,6 +11,6 @@ import os from django.core.wsgi import get_wsgi_application -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apibase.settings") +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apibase.django.local") application = get_wsgi_application() diff --git a/manage.py b/manage.py index fd16886..92315f4 100644 --- a/manage.py +++ b/manage.py @@ -7,7 +7,7 @@ import sys def main(): """Run administrative tasks.""" - os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apibase.settings") + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "apibase.django.local") try: from django.core.management import execute_from_command_line except ImportError as exc: