""" Django settings for core project. Generated by 'django-admin startproject' using Django 5.2.6. For more information on this file, see https://docs.djangoproject.com/en/5.2/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/5.2/ref/settings/ """ from pathlib import Path import os import logging.config # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-et2fv=%$5h(^!iyo+&v+hm!#52w6)%d!hx%!kvwvx9y_%*kjdj' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'rest_framework.authtoken', 'django_filters', 'corsheaders', 'security', 'incident_intelligence', 'automation_orchestration', 'sla_oncall', 'collaboration_war_rooms', 'compliance_governance', 'analytics_predictive_insights', 'knowledge_learning', 'monitoring', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'security.middleware.zero_trust.ZeroTrustMiddleware', 'security.middleware.zero_trust.DeviceRegistrationMiddleware', 'security.middleware.zero_trust.RiskBasedRateLimitMiddleware', 'incident_intelligence.security.IncidentSecurityMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'core.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'core.wsgi.application' # Database # https://docs.djangoproject.com/en/5.2/ref/settings/#databases # Production Database Configuration DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.getenv('DB_NAME', 'etb_incident_management'), 'USER': os.getenv('DB_USER', 'etb_user'), 'PASSWORD': os.getenv('DB_PASSWORD', 'secure_password'), 'HOST': os.getenv('DB_HOST', 'localhost'), 'PORT': os.getenv('DB_PORT', '5432'), 'OPTIONS': { 'sslmode': 'require', 'connect_timeout': 10, }, 'CONN_MAX_AGE': 600, 'CONN_HEALTH_CHECKS': True, 'ATOMIC_REQUESTS': True, } } # Development fallback to SQLite if DEBUG and not os.getenv('DB_HOST'): DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } } # Password validation # https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators 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', }, ] # Internationalization # https://docs.djangoproject.com/en/5.2/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.2/howto/static-files/ STATIC_URL = 'static/' # Default primary key field type # https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # Django REST Framework Configuration REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', 'security.authentication.SSOAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', ], 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 20, } # Security Settings SECURE_BROWSER_XSS_FILTER = True SECURE_CONTENT_TYPE_NOSNIFF = True X_FRAME_OPTIONS = 'DENY' # Session Security SESSION_COOKIE_SECURE = True SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_AGE = 3600 # 1 hour SESSION_EXPIRE_AT_BROWSER_CLOSE = True # CSRF Protection CSRF_COOKIE_SECURE = True CSRF_COOKIE_HTTPONLY = True # MFA Settings MFA_ISSUER_NAME = "ETB Incident Management" MFA_QR_CODE_SIZE = 200 # SSO Settings SSO_PROVIDERS = { 'saml': { 'enabled': True, 'entity_id': 'https://etb-incident-management.com/saml', 'sso_url': None, # To be configured per environment 'x509_cert': None, # To be configured per environment }, 'oauth2': { 'enabled': True, 'providers': { 'google': { 'client_id': None, # To be configured per environment 'client_secret': None, # To be configured per environment }, 'microsoft': { 'client_id': None, # To be configured per environment 'client_secret': None, # To be configured per environment }, } }, 'ldap': { 'enabled': True, 'server_uri': None, # To be configured per environment 'bind_dn': None, # To be configured per environment 'bind_password': None, # To be configured per environment 'user_search_base': None, # To be configured per environment } } # Data Classification Levels DATA_CLASSIFICATION_LEVELS = [ 'PUBLIC', 'INTERNAL', 'CONFIDENTIAL', 'RESTRICTED', 'TOP_SECRET', ] # Audit Trail Settings AUDIT_LOG_RETENTION_DAYS = 2555 # 7 years AUDIT_LOG_IMMUTABLE = True # Custom User Model AUTH_USER_MODEL = 'security.User' # Zero Trust Architecture Settings ZERO_TRUST_ENABLED = True ZERO_TRUST_STRICT_MODE = False # Set to True for maximum security # Geolocation API Settings GEO_API_KEY = None # Set your geolocation API key here GEO_API_PROVIDER = 'ipapi' # Options: 'ipapi', 'ipinfo', 'maxmind' # Device Posture Assessment DEVICE_POSTURE_ENABLED = True DEVICE_POSTURE_STRICT_MODE = False DEVICE_POSTURE_UPDATE_INTERVAL = 3600 # Update device posture every hour # Risk Assessment Settings RISK_ASSESSMENT_ENABLED = True RISK_ASSESSMENT_CACHE_TTL = 300 # Cache risk assessments for 5 minutes RISK_ASSESSMENT_ML_ENABLED = False # Enable ML-based risk assessment # Behavioral Analysis Settings BEHAVIORAL_ANALYSIS_ENABLED = True BEHAVIORAL_LEARNING_PERIOD = 30 # Days to learn user behavior BEHAVIORAL_ANOMALY_THRESHOLD = 0.7 # Threshold for behavioral anomalies # Adaptive Authentication Settings ADAPTIVE_AUTH_ENABLED = True ADAPTIVE_AUTH_FALLBACK_METHODS = ['PASSWORD', 'MFA_TOTP'] ADAPTIVE_AUTH_MAX_ATTEMPTS = 3 ADAPTIVE_AUTH_LOCKOUT_DURATION = 15 # minutes # Rate Limiting Settings RATE_LIMIT_ENABLED = True RATE_LIMIT_BACKEND = 'memory' # Options: 'memory', 'redis', 'database' # Zero Trust Logging ZERO_TRUST_LOG_LEVEL = 'INFO' # DEBUG, INFO, WARNING, ERROR ZERO_TRUST_LOG_AUDIT_EVENTS = True ZERO_TRUST_LOG_RISK_ASSESSMENTS = True # Monitoring Settings MONITORING_ENABLED = True MONITORING_HEALTH_CHECK_INTERVAL = 60 # seconds MONITORING_METRICS_COLLECTION_INTERVAL = 300 # seconds (5 minutes) MONITORING_ALERT_EVALUATION_INTERVAL = 60 # seconds MONITORING_DATA_RETENTION_DAYS = 90 MONITORING_CLEANUP_INTERVAL = 86400 # seconds (24 hours) # Health Check Settings HEALTH_CHECK_TIMEOUT = 30 # seconds HEALTH_CHECK_RETRY_COUNT = 3 HEALTH_CHECK_ENABLED_TARGETS = [ 'APPLICATION', 'DATABASE', 'CACHE', 'QUEUE', 'MODULE' ] # Metrics Collection Settings METRICS_COLLECTION_ENABLED = True METRICS_AGGREGATION_METHODS = ['AVERAGE', 'SUM', 'COUNT', 'MIN', 'MAX', 'PERCENTILE_95', 'PERCENTILE_99'] METRICS_DEFAULT_RETENTION_DAYS = 90 # Alerting Settings ALERTING_ENABLED = True ALERTING_DEFAULT_CHANNELS = ['EMAIL'] ALERTING_EMAIL_FROM = 'monitoring@etb-api.com' ALERTING_SLACK_WEBHOOK_URL = None # Set in environment ALERTING_WEBHOOK_URL = None # Set in environment # Dashboard Settings DASHBOARD_AUTO_REFRESH_ENABLED = True DASHBOARD_DEFAULT_REFRESH_INTERVAL = 30 # seconds DASHBOARD_MAX_WIDGETS_PER_DASHBOARD = 20 # System Status Settings SYSTEM_STATUS_ENABLED = True SYSTEM_STATUS_UPDATE_INTERVAL = 300 # seconds (5 minutes) SYSTEM_STATUS_NOTIFICATION_CHANNELS = ['EMAIL', 'SLACK'] # Performance Monitoring PERFORMANCE_MONITORING_ENABLED = True PERFORMANCE_SLOW_QUERY_THRESHOLD = 1000 # milliseconds PERFORMANCE_API_RESPONSE_THRESHOLD = 2000 # milliseconds PERFORMANCE_MEMORY_THRESHOLD = 80 # percentage PERFORMANCE_CPU_THRESHOLD = 80 # percentage PERFORMANCE_DISK_THRESHOLD = 80 # percentage # Redis Caching Configuration CACHES = { 'default': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': os.getenv('REDIS_URL', 'redis://localhost:6379/1'), 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', 'CONNECTION_POOL_KWARGS': { 'max_connections': 50, 'retry_on_timeout': True, 'socket_keepalive': True, 'socket_keepalive_options': {}, }, 'COMPRESSOR': 'django_redis.compressors.zlib.ZlibCompressor', 'IGNORE_EXCEPTIONS': True, } }, 'sessions': { 'BACKEND': 'django_redis.cache.RedisCache', 'LOCATION': os.getenv('REDIS_URL', 'redis://localhost:6379/2'), 'OPTIONS': { 'CLIENT_CLASS': 'django_redis.client.DefaultClient', } } } # Session Configuration SESSION_ENGINE = 'django.contrib.sessions.backends.cache' SESSION_CACHE_ALIAS = 'sessions' SESSION_COOKIE_AGE = 3600 # 1 hour SESSION_SAVE_EVERY_REQUEST = True SESSION_EXPIRE_AT_BROWSER_CLOSE = True # Celery Configuration CELERY_BROKER_URL = os.getenv('CELERY_BROKER_URL', 'redis://localhost:6379/0') CELERY_RESULT_BACKEND = os.getenv('CELERY_RESULT_BACKEND', 'redis://localhost:6379/0') CELERY_ACCEPT_CONTENT = ['json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' CELERY_TIMEZONE = 'UTC' CELERY_ENABLE_UTC = True CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' CELERY_WORKER_PREFETCH_MULTIPLIER = 1 CELERY_TASK_ACKS_LATE = True CELERY_WORKER_MAX_TASKS_PER_CHILD = 1000 # Email Configuration EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = os.getenv('EMAIL_HOST', 'smtp.gmail.com') EMAIL_PORT = int(os.getenv('EMAIL_PORT', '587')) EMAIL_USE_TLS = os.getenv('EMAIL_USE_TLS', 'True').lower() == 'true' EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', '') EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', '') DEFAULT_FROM_EMAIL = os.getenv('DEFAULT_FROM_EMAIL', 'noreply@etb-api.com') # Enhanced Security Settings SECURE_SSL_REDIRECT = not DEBUG SECURE_HSTS_SECONDS = 31536000 if not DEBUG else 0 # 1 year SECURE_HSTS_INCLUDE_SUBDOMAINS = True SECURE_HSTS_PRELOAD = True SECURE_CONTENT_TYPE_NOSNIFF = True SECURE_BROWSER_XSS_FILTER = True X_FRAME_OPTIONS = 'DENY' SECURE_REFERRER_POLICY = 'strict-origin-when-cross-origin' # API Rate Limiting REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', 'security.authentication.SSOAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', ], 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 20, 'DEFAULT_THROTTLE_CLASSES': [ 'rest_framework.throttling.AnonRateThrottle', 'rest_framework.throttling.UserRateThrottle', 'rest_framework.throttling.ScopedRateThrottle', ], 'DEFAULT_THROTTLE_RATES': { 'anon': '100/hour', 'user': '1000/hour', 'login': '5/min', 'register': '3/min', 'password_reset': '3/min', }, 'DEFAULT_FILTER_BACKENDS': [ 'django_filters.rest_framework.DjangoFilterBackend', 'rest_framework.filters.SearchFilter', 'rest_framework.filters.OrderingFilter', ], # 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', # 'ALLOWED_VERSIONS': ['v1', 'v2'], # 'DEFAULT_VERSION': 'v1', } # Comprehensive Logging Configuration LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'verbose': { 'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}', 'style': '{', }, 'simple': { 'format': '{levelname} {message}', 'style': '{', }, 'json': { 'format': '{"level": "%(levelname)s", "time": "%(asctime)s", "module": "%(module)s", "process": %(process)d, "thread": %(thread)d, "message": "%(message)s"}', }, 'security': { 'format': 'SECURITY: {levelname} {asctime} {module} {message}', 'style': '{', }, }, 'filters': { 'require_debug_false': { '()': 'django.utils.log.RequireDebugFalse', }, 'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', }, }, 'handlers': { 'console': { 'level': 'INFO', 'filters': ['require_debug_true'], 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'file': { 'level': 'INFO', 'filters': ['require_debug_false'], 'class': 'logging.handlers.RotatingFileHandler', 'filename': '/var/log/etb-api/application.log', 'maxBytes': 1024*1024*15, # 15MB 'backupCount': 10, 'formatter': 'verbose', }, 'json_file': { 'level': 'INFO', 'filters': ['require_debug_false'], 'class': 'logging.handlers.RotatingFileHandler', 'filename': '/var/log/etb-api/application.json', 'maxBytes': 1024*1024*15, 'backupCount': 10, 'formatter': 'json', }, 'security_file': { 'level': 'WARNING', 'class': 'logging.handlers.RotatingFileHandler', 'filename': '/var/log/etb-api/security.log', 'maxBytes': 1024*1024*15, 'backupCount': 10, 'formatter': 'security', }, 'error_file': { 'level': 'ERROR', 'class': 'logging.handlers.RotatingFileHandler', 'filename': '/var/log/etb-api/error.log', 'maxBytes': 1024*1024*15, 'backupCount': 10, 'formatter': 'verbose', }, 'mail_admins': { 'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler', 'formatter': 'verbose', }, }, 'loggers': { 'django': { 'handlers': ['console', 'file', 'json_file'], 'level': 'INFO', 'propagate': True, }, 'django.request': { 'handlers': ['error_file', 'mail_admins'], 'level': 'ERROR', 'propagate': True, }, 'django.security': { 'handlers': ['security_file', 'mail_admins'], 'level': 'WARNING', 'propagate': True, }, 'etb_api': { 'handlers': ['console', 'file', 'json_file'], 'level': 'INFO', 'propagate': True, }, 'security': { 'handlers': ['security_file', 'mail_admins'], 'level': 'WARNING', 'propagate': True, }, 'monitoring': { 'handlers': ['console', 'file', 'json_file'], 'level': 'INFO', 'propagate': True, }, }, } # Health Check Configuration HEALTH_CHECK_ENABLED = True HEALTH_CHECK_TIMEOUT = 30 HEALTH_CHECK_RETRY_COUNT = 3 HEALTH_CHECK_ENABLED_TARGETS = [ 'APPLICATION', 'DATABASE', 'CACHE', 'QUEUE', 'MODULE' ] # Backup Configuration BACKUP_ENABLED = True BACKUP_RETENTION_DAYS = 30 BACKUP_SCHEDULE = '0 2 * * *' # Daily at 2 AM BACKUP_LOCATION = '/backups/etb-api/' # API Documentation SPECTACULAR_SETTINGS = { 'TITLE': 'ETB Incident Management API', 'DESCRIPTION': 'Enterprise-grade incident management and response platform', 'VERSION': '1.0.0', 'SERVE_INCLUDE_SCHEMA': False, 'COMPONENT_SPLIT_REQUEST': True, 'SCHEMA_PATH_PREFIX': '/api/v1/', } # CORS Configuration CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "http://127.0.0.1:3000", ] CORS_ALLOW_CREDENTIALS = True CORS_ALLOW_ALL_ORIGINS = True # Only for development CORS_ALLOW_HEADERS = [ 'accept', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', ]