ISO-27001-Risk-Management/config/settings.py
Kevin Heyer ab01841cf2 Add risk status and notification preferences
- Introduced a new `status` field to the `Risk` model with choices for "open", "in_progress", "closed", and "review_required".
- Created a `NotificationPreference` model to manage user notification settings for various events related to risks, controls, residual risks, reviews, users, and incidents.
- Updated the admin interface to include `NotificationPreference` inline with the `User` admin.
- Enhanced signal handlers to send notifications based on user preferences for created, updated, and deleted events for users, risks, controls, and incidents.
- Modified the `check_risk_followups` utility function to update risk status and create notifications for follow-ups.
- Updated serializers and views to accommodate the new `status` field and improved risk listing functionality.
- Added a new section in the risk detail template to display related incidents.
- Removed the unused statistics view from URLs.
2025-09-10 11:54:08 +02:00

220 lines
No EOL
7.8 KiB
Python

import os
from pathlib import Path
import environ
# ---------------------------------------------------------------------------
# Base project paths
# ---------------------------------------------------------------------------
BASE_DIR = Path(__file__).resolve().parent.parent
# ---------------------------------------------------------------------------
# Environment configuration
# ---------------------------------------------------------------------------
env = environ.Env()
environ.Env.read_env(os.path.join(BASE_DIR, ".env"))
# ---------------------------------------------------------------------------
# Security settings
# ---------------------------------------------------------------------------
SECRET_KEY = env(
"SECRET_KEY",
default="django-insecure-lbfv*h@=mjj#xq^!k@-5f2oiq@u6ms9t6=3&nr+!#itih%jh^l" # fallback only for development
)
DEBUG = env.bool("DEBUG", default=False)
ALLOWED_HOSTS = ["localhost", "127.0.0.1"]
# ---------------------------------------------------------------------------
# Installed apps
# ---------------------------------------------------------------------------
INSTALLED_APPS = [
# Django built-in apps
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django_crontab",
# Third-party apps
"rest_framework",
"risks",
]
# ---------------------------------------------------------------------------
# Middleware
# ---------------------------------------------------------------------------
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"risks.middleware.AuditUserMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
# ---------------------------------------------------------------------------
# URL & WSGI configuration
# ---------------------------------------------------------------------------
ROOT_URLCONF = "config.urls"
WSGI_APPLICATION = "config.wsgi.application"
# ---------------------------------------------------------------------------
# Templates
# ---------------------------------------------------------------------------
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"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",
],
},
},
]
# ---------------------------------------------------------------------------
# Database configuration
# ---------------------------------------------------------------------------
DB_ENGINE = env("DB_ENGINE", default="sqlite").lower()
if DB_ENGINE == "postgres":
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": env("DB_NAME", default="postgres"),
"USER": env("DB_USER", default="postgres"),
"PASSWORD": env("DB_PASSWORD", default=""),
"HOST": env("DB_HOST", default="localhost"),
"PORT": env("DB_PORT", default="5432"),
}
}
elif DB_ENGINE == "mysql":
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": env("DB_NAME", default="mysql"),
"USER": env("DB_USER", default="root"),
"PASSWORD": env("DB_PASSWORD", default=""),
"HOST": env("DB_HOST", default="localhost"),
"PORT": env("DB_PORT", default="3306"),
"OPTIONS": {
"charset": "utf8mb4", # recommended for full Unicode support
},
}
}
else: # default: SQLite
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3", # fixed filename for simplicity
}
}
# ---------------------------------------------------------------------------
# Authentication & password validation
# ---------------------------------------------------------------------------
AUTH_USER_MODEL = "risks.User"
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend", # local auth
]
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"},
]
# Login-Flow
LOGIN_URL = "login"
LOGIN_REDIRECT_URL = "risks:dashboard"
LOGOUT_REDIRECT_URL = "login"
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
# ---------------------------------------------------------------------------
# Internationalization
# ---------------------------------------------------------------------------
LANGUAGE_CODE = "de"
TIME_ZONE = "Europe/Berlin"
USE_I18N = True
USE_TZ = True
LANGUAGES = [
("de", "Deutsch"),
("en", "English"),
]
LOCALE_PATHS = [BASE_DIR / "locale"]
# ---------------------------------------------------------------------------
# Static files
# ---------------------------------------------------------------------------
STATIC_URL = "static/"
STATICFILES_DIRS = [
BASE_DIR / "static",
]
# ---------------------------------------------------------------------------
# Default primary key field type
# ---------------------------------------------------------------------------
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# ---------------------------------------------------------------------------
# Django REST framework configuration
# ---------------------------------------------------------------------------
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated", # all endpoints protected by default
],
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.SessionAuthentication", # required for OIDC/session login
"rest_framework.authentication.BasicAuthentication", # allows Basic Auth for API clients
],
}
# ---------------------------------------------------------------------------
# OpenID Connect (SSO) configuration
# ---------------------------------------------------------------------------
SSO_ENABLED = env.bool("SSO_ENABLED", default=False)
if SSO_ENABLED:
INSTALLED_APPS += ["mozilla_django_oidc"]
MIDDLEWARE += ["mozilla_django_oidc.middleware.SessionRefresh"]
AUTHENTICATION_BACKENDS.append(
"config.auth_backends.CustomOIDCBackend",
)
LOGIN_URL = "/oidc/authenticate/"
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/"
OIDC_RP_CLIENT_ID = env("OIDC_RP_CLIENT_ID", default="django-app")
OIDC_RP_CLIENT_SECRET = env("OIDC_RP_CLIENT_SECRET", default="changeme")
OIDC_OP_DISCOVERY_ENDPOINT = env(
"OIDC_OP_DISCOVERY_ENDPOINT",
default="http://localhost:9091/.well-known/openid-configuration",
)
OIDC_RP_SIGN_ALGO = "RS256"
OIDC_STORE_ID_TOKEN = True
OIDC_STORE_ACCESS_TOKEN = True
# ---------------------------------------------------------------------------
# Crojabs via Djnago-Crontabs
# ---------------------------------------------------------------------------
CRONJOBS = [
("0 8 * * *", "risks.utils.check_risk_followups", ">> /var/log/wira_followups.log 2>&1"),
]