Kumi
1e1b590803
Set up the initial Django project structure including custom user model, domain management app, and associated configurations. Added models for Domain, DNSRecord, LeaseAgreement, Payment, and Registrar. Configured serializers, views, and URLs for basic operations. Implemented JWT-based authentication and login via email link. Included necessary admin configurations and migrations. - Added .gitignore to exclude unnecessary files. - Added .vscode/launch.json for VSCode debug configuration. - Added LICENSE file with MIT license. - Created README.md and initialized project directories. - Configured settings for different environments and database support. - Configured basic Celery integration and REST framework settings.
243 lines
7 KiB
Python
243 lines
7 KiB
Python
from autosecretkey import AutoSecretKey
|
|
|
|
from pathlib import Path
|
|
|
|
from django.urls import reverse_lazy
|
|
|
|
import datetime
|
|
|
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
|
BASE_DIR = Path(__file__).resolve().parent
|
|
|
|
ASK = AutoSecretKey("settings.ini")
|
|
|
|
SECRET_KEY = ASK.secret_key
|
|
|
|
DEBUG = ASK.config.getboolean("CaffeinatedDomains", "Debug", fallback=False)
|
|
|
|
ALLOWED_HOSTS = [
|
|
host.strip()
|
|
for host in ASK.config.get("CaffeinatedDomains", "Host", fallback="*").split(",")
|
|
]
|
|
|
|
CSRF_TRUSTED_ORIGINS = [f"https://{host}" for host in ALLOWED_HOSTS]
|
|
FRONTEND_URL = CSRF_TRUSTED_ORIGINS[0]
|
|
|
|
USE_X_FORWARDED_HOST = True
|
|
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
|
|
|
# Application definition
|
|
|
|
INSTALLED_APPS = [
|
|
"django.contrib.admin",
|
|
"django.contrib.auth",
|
|
"django.contrib.contenttypes",
|
|
"django.contrib.sessions",
|
|
"django.contrib.messages",
|
|
"django.contrib.staticfiles",
|
|
"polymorphic",
|
|
"rest_framework",
|
|
"rest_framework_simplejwt",
|
|
"django_celery_beat",
|
|
"django_celery_results",
|
|
"drf_spectacular",
|
|
"drf_spectacular_sidecar",
|
|
"crispy_forms",
|
|
"crispy_bootstrap5",
|
|
"caffeinateddomains",
|
|
"caffeinateddomains.users",
|
|
"caffeinateddomains.domains",
|
|
]
|
|
|
|
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",
|
|
]
|
|
|
|
ROOT_URLCONF = "caffeinateddomains.urls"
|
|
|
|
TEMPLATES = [
|
|
{
|
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
"DIRS": [],
|
|
"APP_DIRS": True,
|
|
"OPTIONS": {
|
|
"context_processors": [
|
|
"django.template.context_processors.debug",
|
|
"django.template.context_processors.request",
|
|
"django.contrib.auth.context_processors.auth",
|
|
"django.contrib.messages.context_processors.messages",
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
WSGI_APPLICATION = "caffeinateddomains.wsgi.application"
|
|
|
|
|
|
# Database
|
|
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
|
|
|
|
if (dbtype := "MySQL") in ASK.config or (dbtype := "MariaDB") in ASK.config:
|
|
DATABASES = {
|
|
"default": {
|
|
"ENGINE": "django.db.backends.mysql",
|
|
"NAME": ASK.config.get(dbtype, "Database"),
|
|
"USER": ASK.config.get(dbtype, "Username"),
|
|
"PASSWORD": ASK.config.get(dbtype, "Password"),
|
|
"HOST": ASK.config.get(dbtype, "Host", fallback="localhost"),
|
|
"PORT": ASK.config.getint(dbtype, "Port", fallback=3306),
|
|
}
|
|
}
|
|
|
|
elif (dbtype := "Postgres") in ASK.config or (dbtype := "PostgreSQL") in ASK.config:
|
|
DATABASES = {
|
|
"default": {
|
|
"ENGINE": "django.db.backends.postgresql",
|
|
"NAME": ASK.config.get(dbtype, "Database"),
|
|
"USER": ASK.config.get(dbtype, "Username"),
|
|
"PASSWORD": ASK.config.get(dbtype, "Password"),
|
|
"HOST": ASK.config.get(dbtype, "Host", fallback="localhost"),
|
|
"PORT": ASK.config.getint(dbtype, "Port", fallback=5432),
|
|
}
|
|
}
|
|
|
|
else:
|
|
DATABASES = {
|
|
"default": {
|
|
"ENGINE": "django.db.backends.sqlite3",
|
|
"NAME": "db.sqlite3",
|
|
}
|
|
}
|
|
|
|
|
|
# Password validation
|
|
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
|
|
|
|
AUTH_USER_MODEL = "users.User"
|
|
|
|
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",
|
|
]
|
|
|
|
# Internationalization
|
|
# https://docs.djangoproject.com/en/5.0/topics/i18n/
|
|
|
|
LANGUAGE_CODE = "en-us"
|
|
|
|
TIME_ZONE = "UTC"
|
|
|
|
USE_I18N = True
|
|
|
|
USE_TZ = True
|
|
|
|
|
|
# Static files (CSS, JavaScript, Images)
|
|
# https://docs.djangoproject.com/en/5.0/howto/static-files/
|
|
|
|
STATIC_URL = "static/"
|
|
|
|
STATICFILES_DIRS = [
|
|
"static",
|
|
]
|
|
|
|
# Settings for uploaded files
|
|
|
|
MEDIA_URL = "/media/"
|
|
MEDIA_ROOT = ASK.config.get("CaffeinatedDomains", "MediaRoot", fallback="media")
|
|
|
|
if "S3" in ASK.config:
|
|
DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
|
|
|
|
if not ASK.config.getboolean("S3", "LocalStatic", fallback=False):
|
|
STATICFILES_STORAGE = "storages.backends.s3boto3.S3StaticStorage"
|
|
|
|
AWS_ACCESS_KEY_ID = ASK.config.get("S3", "AccessKey")
|
|
AWS_SECRET_ACCESS_KEY = ASK.config.get("S3", "SecretKey")
|
|
AWS_STORAGE_BUCKET_NAME = ASK.config.get("S3", "Bucket")
|
|
AWS_S3_ENDPOINT_URL = ASK.config.get("S3", "Endpoint")
|
|
|
|
# Default primary key field type
|
|
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
|
|
|
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|
|
|
# Django Rest Framework settings
|
|
|
|
SPECTACULAR_SETTINGS = {
|
|
"SWAGGER_UI_DIST": "SIDECAR",
|
|
"SWAGGER_UI_FAVICON_HREF": "SIDECAR",
|
|
"REDOC_DIST": "SIDECAR",
|
|
}
|
|
|
|
REST_FRAMEWORK = {
|
|
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
|
"DEFAULT_AUTHENTICATION_CLASSES": [
|
|
"rest_framework_simplejwt.authentication.JWTAuthentication",
|
|
],
|
|
}
|
|
|
|
SIMPLE_JWT = {
|
|
"ACCESS_TOKEN_LIFETIME": datetime.timedelta(minutes=5),
|
|
"REFRESH_TOKEN_LIFETIME": datetime.timedelta(days=1),
|
|
"ROTATE_REFRESH_TOKENS": True,
|
|
"AUTH_HEADER_TYPES": ("Bearer",),
|
|
}
|
|
|
|
# Celery settings
|
|
|
|
CELERY_BROKER_URL = ASK.config.get(
|
|
"CaffeinatedDomains", "Redis", fallback="redis://localhost:6379/0"
|
|
)
|
|
CELERY_RESULT_BACKEND = "django-db"
|
|
|
|
# TODO: CSP settings
|
|
|
|
# Authentication
|
|
|
|
LOGIN_URL = reverse_lazy("caffeinateddomains.users:login")
|
|
LOGIN_REDIRECT_URL = reverse_lazy("caffeinateddomains.users:categories")
|
|
LOGOUT_REDIRECT_URL = reverse_lazy("caffeinateddomains.users:login")
|
|
|
|
# Crispy forms settings
|
|
|
|
CRISPY_ALLOWED_TEMPLATE_PACKS = {"bootstrap5"}
|
|
CRISPY_TEMPLATE_PACK = "bootstrap5"
|
|
|
|
# Email settings
|
|
|
|
EMAIL_BACKEND = (
|
|
"django.core.mail.backends.smtp.EmailBackend"
|
|
if "SMTP" in ASK.config
|
|
else "django.core.mail.backends.console.EmailBackend"
|
|
)
|
|
EMAIL_HOST = ASK.config.get("Email", "Host")
|
|
EMAIL_USE_TLS = ASK.config.getboolean("Email", "TLS", fallback=True)
|
|
EMAIL_PORT = ASK.config.getint("Email", "Port", fallback=587 if EMAIL_USE_TLS else 25)
|
|
EMAIL_HOST_USER = ASK.config.get("Email", "Username")
|
|
EMAIL_HOST_PASSWORD = ASK.config.get("Email", "Password")
|
|
DEFAULT_FROM_EMAIL = ASK.config.get("Email", "From", fallback=EMAIL_HOST_USER)
|