From 3f47532e2ddaeae7527224c8feb703db11480f3c Mon Sep 17 00:00:00 2001 From: Bkolb Date: Thu, 9 Apr 2026 16:37:36 +0200 Subject: [PATCH] impressum und Texte --- app/flask-postgres/app/app.py | 52 +++--- app/flask-postgres/app/security.py | 2 + app/flask-postgres/app/templates/base.html | 16 ++ .../app/templates/datenschutz.html | 164 ++++++++++++++++++ .../app/templates/impressum.html | 164 ++++++++++++++++++ app/flask-postgres/app/templates/index.html | 56 +----- .../app/templates/partials/home_content.html | 118 ++++++++++++- .../templates/partials/home_content_old.html | 6 + app/flask-postgres/deploy_flask.sh | 22 ++- app/flask-postgres/styles/site.css | 118 +++++++++++++ 10 files changed, 632 insertions(+), 86 deletions(-) create mode 100644 app/flask-postgres/app/templates/datenschutz.html create mode 100644 app/flask-postgres/app/templates/impressum.html create mode 100644 app/flask-postgres/app/templates/partials/home_content_old.html diff --git a/app/flask-postgres/app/app.py b/app/flask-postgres/app/app.py index 5ce30a9..5e3b045 100644 --- a/app/flask-postgres/app/app.py +++ b/app/flask-postgres/app/app.py @@ -30,6 +30,7 @@ from security import ( contentmanager_required ) from logging_config import setup_logging +from datetime import datetime app = Flask(__name__) @@ -497,6 +498,7 @@ def admin_mandanten(): name = request.form.get("name", "").strip() kontakt_email = request.form.get("kontakt_email", "").strip() level = request.form.get("level", "0").strip() + selected_groups = request.form.getlist("groups") admin_name = request.form.get("admin_name", "").strip() admin_email = request.form.get("admin_email", "").strip().lower() @@ -530,6 +532,8 @@ def admin_mandanten(): error_message = "Die beiden Admin-Passwörter stimmen nicht überein." elif len(admin_password) < 8: error_message = "Das Admin Passwort muss mindestens 8 Zeichen lang sein." + elif not selected_groups: + error_message = "Mindestens die Admin Gruppe muss ausgewählt werden." if error_message: cur.execute(""" @@ -560,6 +564,7 @@ def admin_mandanten(): "level": level, "admin_name": admin_name, "admin_email": admin_email, + "groups": selected_groups, } **get_current_user() @@ -583,19 +588,16 @@ def admin_mandanten(): new_mandant_id = cur.fetchone()[0] # Standardgruppen für den neuen Mandanten - cur.execute(""" - INSERT INTO app_group (mandant_id, group_name) - VALUES (%s, %s) - RETURNING id - """, (new_mandant_id, "Useradministration")) - useradmin_group_id = cur.fetchone()[0] + group_ids = {} - cur.execute(""" - INSERT INTO app_group (mandant_id, group_name) - VALUES (%s, %s) - RETURNING id - """, (new_mandant_id, "Contentmanager")) - contentmanager_group_id = cur.fetchone()[0] + for group_name in selected_groups: + cur.execute(""" + INSERT INTO app_group (mandant_id, group_name) + VALUES (%s, %s) + RETURNING id + """, (new_mandant_id, group_name)) + + group_ids[group_name] = cur.fetchone()[0] # erster Admin-User admin_password_hash = generate_password_hash(admin_password) @@ -607,16 +609,12 @@ def admin_mandanten(): """, (admin_email, admin_name, new_mandant_id, admin_password_hash, 1)) new_admin_user_id = cur.fetchone()[0] - # User beiden Gruppen zuordnen - cur.execute(""" - INSERT INTO user_group (user_id, group_id, mandant_id) - VALUES (%s, %s, %s) - """, (new_admin_user_id, useradmin_group_id, new_mandant_id)) - - cur.execute(""" - INSERT INTO user_group (user_id, group_id, mandant_id) - VALUES (%s, %s, %s) - """, (new_admin_user_id, contentmanager_group_id, new_mandant_id)) + # User den gewählten Gruppen zuordnen + for group_id in group_ids.values(): + cur.execute(""" + INSERT INTO user_group (user_id, group_id, mandant_id) + VALUES (%s, %s, %s) + """, (new_admin_user_id, group_id, new_mandant_id)) conn.commit() @@ -1605,4 +1603,12 @@ def admin_courses(): form_error=form_error, form_values=form_values, **get_current_user() - ) \ No newline at end of file + ) + +@app.route("/impressum") +def impressum(): + return render_template("impressum.html", **get_current_user()) + +@app.route("/datenschutz") +def datenschutz(): + return render_template("datenschutz.html", **get_current_user()) diff --git a/app/flask-postgres/app/security.py b/app/flask-postgres/app/security.py index f42d024..3e09bcd 100644 --- a/app/flask-postgres/app/security.py +++ b/app/flask-postgres/app/security.py @@ -1,5 +1,6 @@ from functools import wraps from flask import session, redirect, url_for, request, abort +from datetime import datetime from db import get_connection @@ -71,6 +72,7 @@ def get_current_user(): "is_user_admin": user_is_user_admin() if session.get("user_id") else False, "is_contentmanager": user_is_contentmanager() if session.get("user_id") else False, "country": country, + "current_year": datetime.now().year, } diff --git a/app/flask-postgres/app/templates/base.html b/app/flask-postgres/app/templates/base.html index 55a91cf..e0d0793 100644 --- a/app/flask-postgres/app/templates/base.html +++ b/app/flask-postgres/app/templates/base.html @@ -77,5 +77,21 @@ + + \ No newline at end of file diff --git a/app/flask-postgres/app/templates/datenschutz.html b/app/flask-postgres/app/templates/datenschutz.html new file mode 100644 index 0000000..e548ad8 --- /dev/null +++ b/app/flask-postgres/app/templates/datenschutz.html @@ -0,0 +1,164 @@ +{% extends "base.html" %} + +{% block content %} + +
+ +

Impressum & Datenschutz

+ +
+ + + + + + + +
+ + + +
+ +{% endblock %} \ No newline at end of file diff --git a/app/flask-postgres/app/templates/impressum.html b/app/flask-postgres/app/templates/impressum.html new file mode 100644 index 0000000..e548ad8 --- /dev/null +++ b/app/flask-postgres/app/templates/impressum.html @@ -0,0 +1,164 @@ +{% extends "base.html" %} + +{% block content %} + +
+ +

Impressum & Datenschutz

+ +
+ + + + + + + +
+ + + +
+ +{% endblock %} \ No newline at end of file diff --git a/app/flask-postgres/app/templates/index.html b/app/flask-postgres/app/templates/index.html index 43bf40a..88e88db 100644 --- a/app/flask-postgres/app/templates/index.html +++ b/app/flask-postgres/app/templates/index.html @@ -1,53 +1,5 @@ - - - - - - {{ page_title }} - - - - - -
-
- {% if active_page == "home" %} - {% include "partials/home_content.html" %} - {% elif active_page == "preise" %} - {% include "partials/preise_content.html" %} - {% elif active_page == "allgemein" %} - {% include "partials/allgemein_content.html" %} - {% endif %} -
-
- - \ No newline at end of file +{% block content %} + {% include "partials/home_content.html" %} +{% endblock %} \ No newline at end of file diff --git a/app/flask-postgres/app/templates/partials/home_content.html b/app/flask-postgres/app/templates/partials/home_content.html index bf7755b..bdef026 100644 --- a/app/flask-postgres/app/templates/partials/home_content.html +++ b/app/flask-postgres/app/templates/partials/home_content.html @@ -1,6 +1,112 @@ -
-

Compliance Verification

-

Willkommen auf Ihrem Portal zur geregelten Nutzung von KI in Ihrem Unternehmen.

-

Besuche insgesamt: {{ visit_count }}

-

Für die Seiten Preise und Allgemein ist eine Anmeldung erforderlich.

-
\ No newline at end of file + +
+

Compliance. Digitalisierung. Zukunftssicher.

+

+ Wir unterstützen Unternehmen dabei, regulatorische Anforderungen effizient umzusetzen + und gleichzeitig die Chancen moderner Technologien optimal zu nutzen. +

+ +
+ + +
+

Unsere Leistungen

+ +
+
+

Compliance & Regulierung

+

+ Umsetzung gesetzlicher Anforderungen wie EU AI Act, Datenschutz und Governance. +

+
+ +
+

KI & Digitalisierung

+

+ Strukturierte Einführung von KI-Systemen mit klaren Prozessen und Richtlinien. +

+
+ +
+

Schulung

+

+ Aufbau von Wissen im Unternehmen mit Trainings und nachvollziehbarer Dokumentation. +

+
+
+
+ + +
+
+
+

Warum Compliance Verification?

+
    +
  • Rechtssicherheit für Ihr Unternehmen
  • +
  • Klare Dokumentation und Nachweise
  • +
  • Strukturierte Umsetzung von KI-Richtlinien
  • +
  • Effiziente Schulung Ihrer Mitarbeitenden
  • +
+
+ +
+ Schulung +
+
+
+ + +
+

Unsere Module

+ +
+
+

Modul A – Basis

+

Grundlagen für alle Mitarbeitenden zur sicheren Nutzung von KI.

+
+ +
+

Modul B – Compliance

+

Erweiterte Anforderungen für Fachbereiche und Organisation.

+
+ +
+

Modul C – Governance

+

Ganzheitliche Steuerung und Absicherung im Unternehmen.

+
+
+
+ + +
+

So funktioniert es

+ +
+
+

Analyse

+

Wir analysieren Ihre aktuelle Situation und Anforderungen.

+
+ +
+

Umsetzung

+

Einführung von Prozessen, Richtlinien und Schulungen.

+
+ +
+

Verifikation

+

Nachweisbare Compliance und nachhaltige Absicherung.

+
+
+
+ + +
+

Bereit für den nächsten Schritt?

+

+ Starten Sie jetzt mit der strukturierten Umsetzung Ihrer KI-Compliance. +

+ Jetzt starten +
\ No newline at end of file diff --git a/app/flask-postgres/app/templates/partials/home_content_old.html b/app/flask-postgres/app/templates/partials/home_content_old.html new file mode 100644 index 0000000..bf7755b --- /dev/null +++ b/app/flask-postgres/app/templates/partials/home_content_old.html @@ -0,0 +1,6 @@ +
+

Compliance Verification

+

Willkommen auf Ihrem Portal zur geregelten Nutzung von KI in Ihrem Unternehmen.

+

Besuche insgesamt: {{ visit_count }}

+

Für die Seiten Preise und Allgemein ist eine Anmeldung erforderlich.

+
\ No newline at end of file diff --git a/app/flask-postgres/deploy_flask.sh b/app/flask-postgres/deploy_flask.sh index 2e6121f..2396e95 100644 --- a/app/flask-postgres/deploy_flask.sh +++ b/app/flask-postgres/deploy_flask.sh @@ -4,20 +4,25 @@ set -euo pipefail SRC_ROOT="/Volumes/MacBook SD/Projekte/compliance-verification/app/flask-postgres" DST_ROOT="/Volumes/docker/flask-postgres" -NAS_USER="BKolb" -NAS_HOST="192.168.0.10" CONTAINER_NAME="flask_web" -echo "Starte Deployment..." +echo "Starte Deployment für compliance-verification ..." +# Quellen prüfen [ -d "$SRC_ROOT/app" ] || { echo "Quelle app fehlt: $SRC_ROOT/app"; exit 1; } [ -d "$SRC_ROOT/images" ] || { echo "Quelle images fehlt: $SRC_ROOT/images"; exit 1; } [ -d "$SRC_ROOT/styles" ] || { echo "Quelle styles fehlt: $SRC_ROOT/styles"; exit 1; } +# Ziele prüfen [ -d "$DST_ROOT/app" ] || { echo "Ziel app fehlt: $DST_ROOT/app"; exit 1; } [ -d "$DST_ROOT/images" ] || { echo "Ziel images fehlt: $DST_ROOT/images"; exit 1; } [ -d "$DST_ROOT/styles" ] || { echo "Ziel styles fehlt: $DST_ROOT/styles"; exit 1; } +# Schutz: andere Projekte / DB dürfen nicht angefasst werden +[ -d "$DST_ROOT/app-unternehmen" ] && echo "Schutz aktiv: $DST_ROOT/app-unternehmen wird nicht angerührt." +[ -d "$DST_ROOT/unternehmen" ] && echo "Schutz aktiv: $DST_ROOT/unternehmen wird nicht angerührt." +[ -d "$DST_ROOT/db" ] && echo "Schutz aktiv: $DST_ROOT/db wird nicht angerührt." + echo "Synchronisiere app/ ..." rsync -av --delete \ --exclude '.DS_Store' \ @@ -28,6 +33,9 @@ rsync -av --delete \ --exclude 'styles/' \ --exclude 'files/' \ --exclude 'Dockerfile.txt' \ + --exclude 'app-unternehmen/' \ + --exclude 'unternehmen/' \ + --exclude 'db/' \ "$SRC_ROOT/app/" "$DST_ROOT/app/" echo "Synchronisiere images/ ..." @@ -43,9 +51,13 @@ rsync -av --delete \ --exclude '._*' \ "$SRC_ROOT/styles/" "$DST_ROOT/styles/" -echo "files/ wird bewusst nicht angefasst." +echo "Diese Pfade werden bewusst NICHT angefasst:" +echo " - $DST_ROOT/files" +echo " - $DST_ROOT/app-unternehmen" +echo " - $DST_ROOT/unternehmen" +echo " - $DST_ROOT/db" echo "Starte Container manuell neu ..." -#ssh "${NAS_USER}@${NAS_HOST}" "/usr/bin/docker restart ${CONTAINER_NAME}" +# docker restart "${CONTAINER_NAME}" echo "Deployment abgeschlossen." \ No newline at end of file diff --git a/app/flask-postgres/styles/site.css b/app/flask-postgres/styles/site.css index f8f290b..79a8a4b 100644 --- a/app/flask-postgres/styles/site.css +++ b/app/flask-postgres/styles/site.css @@ -816,4 +816,122 @@ button { .progress-green { background: #2e7d32; +} + +/* =============================== + Home + =============================== */ +.section { + margin: 40px 0; +} + +.section.alt { + background: #f6f8fb; + padding: 30px; + border-radius: 16px; +} + +.card-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 20px; +} + +.card { + background: #fff; + padding: 20px; + border-radius: 14px; + border: 1px solid #e3e8ef; +} + +.hero-actions { + margin-top: 20px; + display: flex; + gap: 12px; +} + +.cta-section { + text-align: center; +} + +.checkbox-group { + display: flex; + gap: 20px; + margin-top: 8px; +} + +.checkbox-group label { + display: flex; + align-items: center; + gap: 6px; + font-weight: normal; +} + +/* =============================== + Footer + =============================== */ + +.site-footer { + margin-top: 60px; + padding: 20px 30px; + background: #0f172a; + color: #cbd5e1; + font-size: 14px; +} + +.footer-inner { + max-width: 1200px; + margin: 0 auto; + display: flex; + justify-content: space-between; + align-items: center; +} + +.footer-links { + display: flex; + gap: 20px; +} + +.footer-links a { + color: #cbd5e1; + text-decoration: none; +} + +.footer-links a:hover { + text-decoration: underline; +} + +/* =============================== + Impressum / Legal + =============================== */ + +.legal-section { + padding: 10px 20px; +} + +.legal-section h2 { + margin-top: 0; +} + +.legal-section ul { + padding-left: 18px; +} + +.legal-footer { + margin-top: 40px; + text-align: center; + font-size: 14px; + color: #64748b; +} + +.responsive-stack { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 30px; +} + +@media (max-width: 768px) { + .responsive-stack { + grid-template-columns: 1fr; + } } \ No newline at end of file