- Neue ldap_fileshare_mappings-Tabelle (AD-Gruppe -> Freigabe-UNC+Label), verwaltet in Einstellungen -> LDAP wie die bestehende App-Gruppenzuordnung (inkl. AD-Gruppen-Dropdown per "Gruppen laden", UNC-Backslash/Slash- Normalisierung). - Login-Gate: optionale "Erforderliche AD-Gruppe fuer Login" (Dropdown, gleiches Lade-Muster) -- ohne Mitgliedschaft scheitert der Login wie bei falschen Zugangsdaten, ohne Hinweis auf den eigentlichen Grund. - Sessionabhaengiges Mounten: beim LDAP-Login werden alle per AD-Gruppe zugeordneten Freigaben mit den eigenen (nie gespeicherten) Zugangsdaten per mount.cifs unter /mnt/tesm-shares/<session-token>/ gemountet, beim Logout wieder ausgehaengt. Passwort läuft ausschliesslich ueber die PASSWD-Umgebungsvariable von mount.cifs. Aufraeum-Sweep (30 Min-Takt, 12h-Schwelle) und Cleanup-on-Startup als Sicherheitsnetz. - Zwei unabhaengige Gates: TESM-Rechtesystem (fileshare.view/.create/.edit, neue PERMISSIONS-Gruppe fileshare_group) UND AD-Gruppenmitgliedschaft muessen beide zutreffen, sonst wird nicht gemountet und der Menuepunkt "Dateifreigaben" bleibt verborgen. - Neuer Dateibrowser (/fileshare, .../download, .../upload, .../mkdir, .../delete, .../rename) mit Breadcrumbs, Upload/Download, Anlegen/ Umbenennen/Loeschen -- Pfadaufloesung ausschliesslich ueber os.path.realpath-Vergleich gegen die eigene Mount-Root (Path-Traversal- Schutz), zusaetzlich secure_filename() fuer Datei-/Ordnernamen. - KRITISCHER Bugfix waehrend Live-Test gefunden: generate_ips.py importiert app.py als Hilfsmodul (u.a. aus poe.sh/tesm-check.service heraus, alle paar Sekunden) -- das fuehrte Modul-Level-Code erneut aus und hat aktive Fileshare-Mounts anderer Sitzungen sofort wieder ausgehaengt. Neues TESM_WEB_PROCESS-Env-Flag (nur in tesm.service gesetzt) schuetzt Cleanup-on-Startup und den Sweep-Thread davor, bei einem reinen Modul-Import erneut zu laufen. - install.sh: cifs-utils ergaenzt (liefert mount.cifs). - SCHEMA_VERSION 1 -> 2, VERSION 1.0.10 -> 1.1.0. Live auf Testbox (192.168.82.51) und POETEST (192.168.80.202) getestet: Login-Gate (erlauben/verbieten/reset), Rechte-Gate (Mount+Menuepunkt nur mit fileshare.view), vollstaendiger Datei-Workflow (Upload/Download/ Umbenennen/Anlegen/Loeschen) gegen eine echte SMB-Freigabe, Path-Traversal gegen alle 5 Routen (serverseitig verifiziert, kein Escape), sauberes Unmount bei /logout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
38 lines
1.7 KiB
Desktop File
38 lines
1.7 KiB
Desktop File
[Unit]
|
|
Description=TESM Web App
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=root
|
|
WorkingDirectory=/srv/tesm
|
|
# Markiert genau DIESEN Prozess als den echten Web-App-Dienst -- app.py
|
|
# wird nämlich NICHT nur hierüber gestartet, sondern auch von
|
|
# generate_ips.py (via "from app import ...") als reines Hilfsmodul
|
|
# importiert, z.B. aus poe.sh/tesm-check.service heraus, alle paar
|
|
# Sekunden. Ein einfacher Import führt JEDEN Modul-Level-Code in app.py
|
|
# erneut aus -- ohne dieses Flag würde jeder generate_ips.py-Aufruf
|
|
# _fileshare_cleanup_all_on_startup() erneut auslösen und damit gerade
|
|
# aktive Fileshare-Mounts anderer, echter Sitzungen sofort wieder
|
|
# aushängen. Siehe die Prüfung auf TESM_WEB_PROCESS in app.py.
|
|
Environment=TESM_WEB_PROCESS=1
|
|
# Produktiver WSGI-Server (gunicorn) statt Flasks eigenem app.run()-
|
|
# Entwicklungsserver -- siehe requirements.txt für die ausführliche
|
|
# Begründung von "--workers 1" (In-Memory-Zustand) und "--worker-class
|
|
# gthread" (blockierende WebSocket-Threads für das Browser-SSH-Terminal).
|
|
# "--timeout 0" deaktiviert Gunicorns Worker-Timeout: der greift sonst
|
|
# nach 30s auch bei einer offenen, aber gerade inaktiven SSH-Terminal-
|
|
# WebSocket-Verbindung und würde den Worker (und damit JEDE Verbindung,
|
|
# da nur ein Prozess läuft) killen.
|
|
# "--bind 127.0.0.1:5000" statt 0.0.0.0: Flask/Gunicorn soll ausschließlich
|
|
# über den nginx-Reverse-Proxy (siehe Einstellungen -> NGINX) erreichbar
|
|
# sein, nicht zusätzlich direkt und unverschlüsselt über Port 5000 aus dem
|
|
# Netz -- nginx selbst greift ohnehin nur über 127.0.0.1 zu.
|
|
ExecStart=/srv/tesm/venv/bin/gunicorn --workers 1 --worker-class gthread --threads 16 \
|
|
--timeout 0 --bind 127.0.0.1:5000 app:app
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|