Compare commits

..

4 commits

Author SHA1 Message Date
Kevin Heyer
bfd1c081e9 add login_required to Risk Matrix 2025-09-22 07:43:34 +02:00
Kevin Heyer
f8d3062da6 change Login Style 2025-09-22 07:42:26 +02:00
Kevin Heyer
566d6aa096 cleanup 2025-09-22 07:42:17 +02:00
Kevin Heyer
d35ed7b292 cleanup 2025-09-22 07:34:49 +02:00
6 changed files with 53 additions and 78 deletions

16
TODO
View file

@ -1,16 +0,0 @@
✅Risiken
✅Eintrittswahrscheinlichkeiten
✅Schadenshöhen
✅Maßnahmen
✅Maßnahmenstatus
✅Restrisiko
✅Schutzziele (CIA)
✅Benutzer
✅Audit
✅Vorfälle
Benachrichtigungen
Workflow
Riskomatrix

View file

@ -45,15 +45,15 @@ INSTALLED_APPS = [
# Middleware # Middleware
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
MIDDLEWARE = [ MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware", "django.middleware.security.SecurityMiddleware", # CSRF protection
"django.contrib.sessions.middleware.SessionMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", # session management
"django.middleware.locale.LocaleMiddleware", "django.middleware.locale.LocaleMiddleware", # language settings
"django.middleware.common.CommonMiddleware", "django.middleware.common.CommonMiddleware", # common middleware
"django.middleware.csrf.CsrfViewMiddleware", "django.middleware.csrf.CsrfViewMiddleware", # CSRF protection
"django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", # authentication
"risks.middleware.AuditUserMiddleware", "risks.middleware.AuditUserMiddleware", # audit user
"django.contrib.messages.middleware.MessageMiddleware", "django.contrib.messages.middleware.MessageMiddleware", # messages
"django.middleware.clickjacking.XFrameOptionsMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", # clickjacking protection
] ]
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -72,11 +72,11 @@ TEMPLATES = [
"APP_DIRS": True, "APP_DIRS": True,
"OPTIONS": { "OPTIONS": {
"context_processors": [ "context_processors": [
"django.template.context_processors.debug", "django.template.context_processors.debug", # debug info
"django.template.context_processors.request", "django.template.context_processors.request", # request info
"django.contrib.auth.context_processors.auth", "django.contrib.auth.context_processors.auth", # auth info
"django.contrib.messages.context_processors.messages", "django.contrib.messages.context_processors.messages", # messages
"risks.context_processors.unread_notifications_count", "risks.context_processors.unread_notifications_count", # unread notifications
], ],
}, },
}, },
@ -118,7 +118,7 @@ else: # default: SQLite
DATABASES = { DATABASES = {
"default": { "default": {
"ENGINE": "django.db.backends.sqlite3", "ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3", # fixed filename for simplicity "NAME": BASE_DIR / "db.sqlite3",
} }
} }
@ -130,10 +130,10 @@ AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend", # local auth "django.contrib.auth.backends.ModelBackend", # local auth
] ]
AUTH_PASSWORD_VALIDATORS = [ AUTH_PASSWORD_VALIDATORS = [
{"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"}, {"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"}, # check for username similarity
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}, # min length
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"}, # check for common passwords
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}, # check for numeric passwords
] ]
# Login-Flow # Login-Flow

View file

@ -14,13 +14,18 @@ router.register(r"users", UserViewSet)
router.register(r"logs", AuditViewSet) router.register(r"logs", AuditViewSet)
urlpatterns = [ urlpatterns = [
path("admin/", admin.site.urls), # Risk Management
path("i18n/", include("django.conf.urls.i18n")), # Language Switch
path("api/ping/", ping), # Public healthcheck endpoint
path("api/secure-ping/", secure_ping), # Protected API endpoint
path("api/", include(router.urls)),
path("accounts/", include("django.contrib.auth.urls")),
path("", include("risks.urls", namespace="risks")), path("", include("risks.urls", namespace="risks")),
# Admin
path("admin/", admin.site.urls),
# Login/Logout
path("accounts/", include("django.contrib.auth.urls")),
# Language Switch
path("i18n/", include("django.conf.urls.i18n")),
# API
path("api/", include(router.urls)),
path("api/ping/", ping),
path("api/secure-ping/", secure_ping),
] ]
# Add OIDC routes only if Single Sign-On is enabled # Add OIDC routes only if Single Sign-On is enabled

View file

@ -410,8 +410,7 @@ msgstr "Sende an alle App-Mitarbeiter"
#: risks/models.py:438 #: risks/models.py:438
msgid "Extra recipients (emails, comma or newline separated)" msgid "Extra recipients (emails, comma or newline separated)"
msgstr "" msgstr "Zusätzliche Empfänger (E-Mails, durch Komma oder Zeilenumbruch getrennt)"
"Zusätzliche Empfänger (E-Mails, durch Komma oder Zeilenumbruch getrennt)"
#: risks/signals.py:71 #: risks/signals.py:71
#, python-brace-format #, python-brace-format
@ -459,8 +458,7 @@ msgstr "Maßnahme gelöscht: {t}"
#: risks/signals.py:218 #: risks/signals.py:218
#, python-brace-format #, python-brace-format
msgid "Residual review required for risk '{t}' due to control change" msgid "Residual review required for risk '{t}' due to control change"
msgstr "" msgstr "Restrisikoprüfung nötig für das Risiko: '{t}', da Maßnahmen geändert wurden"
"Restrisikoprüfung nötig für das Risiko: '{t}', da Maßnahmen geändert wurden"
#: risks/signals.py:245 #: risks/signals.py:245
#, python-brace-format #, python-brace-format
@ -508,9 +506,7 @@ msgstr "Das Risiko wurde geprüft und als geschlossen markiert"
#: risks/views.py:220 #: risks/views.py:220
msgid "Not all controls are completed. Risk cannot be closed yet." msgid "Not all controls are completed. Risk cannot be closed yet."
msgstr "" msgstr "Nicht alle Maßnhamen sind abgeschlossen, das Risiko kann nicht geschlossen werden."
"Nicht alle Maßnhamen sind abgeschlossen, das Risiko kann nicht geschlossen "
"werden."
#: risks/views.py:409 #: risks/views.py:409
msgid "Risk status updated." msgid "Risk status updated."

View file

@ -462,6 +462,7 @@ def update_residual_review(request, risk_id):
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Risk Matrix # Risk Matrix
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@login_required
def risk_matrix(request): def risk_matrix(request):
"""Show gross/net risk matrix.""" """Show gross/net risk matrix."""
risks = Risk.objects.select_related("owner", "residual_risk").all() risks = Risk.objects.select_related("owner", "residual_risk").all()

View file

@ -1,17 +1,12 @@
{% load static %} {% extends "base.html" %}
<!doctype html> {% load i18n %}
<html lang="de">
<head>
<meta charset="utf-8">
<title>Login</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Wenn Bulma bereits global geladen wird, diesen Link entfernen --> {% block title %}{% trans "Login" %}{% endblock %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@1.0.2/css/bulma.min.css">
</head>
<body class="has-background-light">
<section class="hero is-fullheight"> {% block breadcrumbs %}{% endblock %} {# Breadcrumbs bei Login-Seite ausblenden #}
{% block content %}
<section class="hero is-fullheight has-background-light">
<div class="hero-body"> <div class="hero-body">
<div class="container"> <div class="container">
<div class="columns is-centered"> <div class="columns is-centered">
@ -19,7 +14,7 @@
<div class="card"> <div class="card">
<header class="card-header"> <header class="card-header">
<p class="card-header-title">Bitte anmelden</p> <p class="card-header-title">{% trans "Bitte anmelden" %}</p>
</header> </header>
<div class="card-content"> <div class="card-content">
@ -36,7 +31,7 @@
<!-- Benutzername --> <!-- Benutzername -->
<div class="field"> <div class="field">
<label class="label" for="{{ form.username.id_for_label }}">Benutzername</label> <label class="label" for="{{ form.username.id_for_label }}">{% trans "Benutzername" %}</label>
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input
class="input{% if form.username.errors %} is-danger{% endif %}" class="input{% if form.username.errors %} is-danger{% endif %}"
@ -49,16 +44,14 @@
required> required>
<span class="icon is-left">👤</span> <span class="icon is-left">👤</span>
</div> </div>
{% if form.username.errors %} {% for error in form.username.errors %}
{% for error in form.username.errors %} <p class="help is-danger">{{ error }}</p>
<p class="help is-danger">{{ error }}</p> {% endfor %}
{% endfor %}
{% endif %}
</div> </div>
<!-- Passwort --> <!-- Passwort -->
<div class="field"> <div class="field">
<label class="label" for="{{ form.password.id_for_label }}">Passwort</label> <label class="label" for="{{ form.password.id_for_label }}">{% trans "Passwort" %}</label>
<div class="control has-icons-left"> <div class="control has-icons-left">
<input <input
class="input{% if form.password.errors %} is-danger{% endif %}" class="input{% if form.password.errors %} is-danger{% endif %}"
@ -70,11 +63,9 @@
required> required>
<span class="icon is-left">🔒</span> <span class="icon is-left">🔒</span>
</div> </div>
{% if form.password.errors %} {% for error in form.password.errors %}
{% for error in form.password.errors %} <p class="help is-danger">{{ error }}</p>
<p class="help is-danger">{{ error }}</p> {% endfor %}
{% endfor %}
{% endif %}
</div> </div>
<input type="hidden" name="next" value="{{ next }}"> <input type="hidden" name="next" value="{{ next }}">
@ -82,11 +73,11 @@
<div class="field is-grouped is-justify-content-space-between is-align-items-center"> <div class="field is-grouped is-justify-content-space-between is-align-items-center">
<div class="control"> <div class="control">
<button type="submit" class="button is-primary"> <button type="submit" class="button is-primary">
Anmelden {% trans "Anmelden" %}
</button> </button>
</div> </div>
<div class="control"> <div class="control">
<a class="button is-text" href="{% url 'password_reset' %}">Passwort vergessen?</a> <a class="button is-text" href="{% url 'password_reset' %}">{% trans "Passwort vergessen?" %}</a>
</div> </div>
</div> </div>
</form> </form>
@ -104,6 +95,4 @@
</div> </div>
</div> </div>
</section> </section>
{% endblock %}
</body>
</html>