Commit Graph
6 Commits
Author SHA1 Message Date
alientimandClaude Sonnet 5 7e39320c87 Ticket-System fuer Kunden-Self-Service + Fingerprint-Auto-Supersede (v1.1.0)
Konzept: Kunde kauft eine Lizenz -> Admin legt einen Kunden an (oder nutzt
einen bestehenden) und weist ihm ein TICKET fuer eine Lizenz mit festen
Eckdaten (Typ/Module/Laufzeit) zu -- das Ticket ist die dauerhafte,
dem Kunden gehoerende Berechtigung, unabhaengig von der konkreten
signierten Lizenzdatei darunter. Admin ODER Kunde (per Self-Service-Link,
kein Login noetig) koennen aus einem offenen Ticket jederzeit eine Lizenz
erstellen, widerrufen und erneut erstellen -- ein Kunde kann mehrere
Tickets haben (z.B. mehrere Systeme).

Neu:
- license_tickets-Tabelle (id = unerratbares Token, customer_id, Typ/
  Module/Laufzeit, status 'open'/'blocked'), licenses.ticket_id-Spalte.
  Rueckwirkende Migration erzeugt fuer jede bereits VOR diesem Feature
  direkt ausgestellte Lizenz automatisch ein passendes Ticket (sonst
  waeren z.B. POETESTs bereits aktivierte Produktivlizenz oder die
  Demo-Lizenzen im neuen, rein ticket-basierten Dashboard verschwunden) --
  gegen eine echte Kopie der Live-Datenbank getestet.
- /tickets/new (Ticket anlegen, admin), /tickets/<id> (Details, Lizenz
  aus Ticket erstellen -- reguraer laut Ticket-Typ ODER als Trial mit
  vollem Modulumfang unabhaengig vom Ticket-Typ --, Ticket sperren/
  entsperren).
- /self-service/<ticket_id>: oeffentlich erreichbar (kein Login), Zugriff
  ueber Besitz des unerratbaren Ticket-Tokens (192 Bit Zufall) als 'Magic
  Link' -- Kunde kann eigene Lizenz herunterladen, widerrufen und (mit den
  Ticket-Eckdaten) neu erstellen. Link wird auf der Ticket-Seite angezeigt
  und in die 'Lizenz per E-Mail senden'-Nachricht aufgenommen.
- /licenses/<id>/delete (admin): raeumt widerrufene oder nie aktivierte
  Lizenzen auf, OHNE das zugehoerige Ticket anzutasten -- der Kunde (oder
  Admin) kann sich ueber das Ticket jederzeit eine neue mit denselben
  Eckdaten erzeugen.
- Bugfix: wird fuer einen Fingerprint eine neue Lizenz aktiviert (z.B.
  Trial durch Enterprise ersetzt), werden jetzt automatisch alle ANDEREN
  fuer denselben Fingerprint noch 'active' vermerkten Lizenzen auf
  'deactivated' gesetzt -- vorher blieben beide faelschlich gleichzeitig
  aktiv in der Uebersicht stehen. Bewusst nach Fingerprint gefiltert (ein
  Kunde darf mehrere Systeme mit je eigener Lizenz betreiben).
- Dashboard zeigt jetzt Tickets statt roher Lizenzzeilen (inkl. aktueller
  Lizenz je Ticket), Kunden-Seite zeigt Ticket-Anzahl statt Lizenz-Anzahl
  mit Filter-Link aufs Dashboard.

SCHEMA_VERSION 1 -> 2 (neue Tabelle + Spalte, ueber install.sh-
Sicherheitsnetz mit Backup+Health-Check abgesichert).

Verifiziert: Migration gegen eine echte Kopie der Live-Datenbank
(POETESTs aktive Produktivlizenz + 3 Demo-Lizenzen) durchlaufen lassen --
alle 8 bestehenden Lizenzen haben danach ein Ticket, keine verwaist.
Anschliessend alle neuen Seiten (Dashboard, Ticket-Anlage, Ticket-Detail,
Self-Service) per Playwright gegen diese migrierte Kopie auf einem
isolierten Scratch-Port durchgeklickt, keine Fehler.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 11:41:51 +02:00
alientimandClaude Sonnet 5 b280cbf121 Version 1.0.1: update.sh-Fix fuer 'latest'-Aufloesung
Kein App-Code geaendert -- reiner Versions-/Release-Bump, damit 'latest'
auch als heruntergeladenes Paket das bereits korrigierte update.sh
enthaelt (siehe vorheriger Commit).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 10:50:48 +02:00
alientimandClaude Sonnet 5 5fa60ec3ef update.sh: 'latest' zuverlaessig ueber die Gitea-API aufloesen
Identischer Bug/Fix wie im TESM-Hauptrepo (siehe dortiger Commit fuer
Details): /releases/download/latest/tesm-license-latest.tar.gz liefert
HTTP 200, aber Giteas automatisch generiertes Quellcode-Archiv des
aktuellen Default-Branch-Stands statt des echten Release-Assets.
'latest' wird jetzt zuerst per Gitea-API auf den echten Tag aufgeloest.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 10:48:27 +02:00
alientimandClaude Sonnet 5 a9fc56ff47 Eigenstaendiges Repo: install.sh/update.sh auf tesm-license umgestellt, README + .gitignore
Ausgelagert aus dem TESM-Hauptrepo (srv/tesm-license/, install-license.sh,
update-license.sh, zugehoerige systemd-/nginx-Vorlagen) per
git-filter-repo, komplette bisherige Historie erhalten. install-license.sh
und update-license.sh wurden zu install.sh/update.sh (jetzt die einzigen
Skripte in diesem Repo, keine Namenskollision mit TESM mehr noetig).
update.sh zeigt jetzt auf dieses eigene Repo/Release-Paket
(tesm-license-vX.Y.Z.tar.gz) statt auf das gemeinsame TESM-Paket.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 10:34:53 +02:00
alientimandClaude Sonnet 5 3f5d85c7ee Lizenzserver-Deployment: install-license.sh/update-license.sh + systemd/nginx-Vorlagen
Fork von install.sh/update.sh/tesm.service/nginx-Site (TESM selbst),
beschraenkt auf /srv/tesm-license -- deployt ausschliesslich den in Phase 2
gebauten Master-Lizenzserver, laesst eine evtl. auf demselben Host
vorhandene TESM-Installation komplett unberuehrt (eigener Pfad-/Env-Var-
Namespace, siehe app.py). Gleiches Backup+Health-Check+Rueckroll-
Sicherheitsnetz wie bei TESMs eigenem Installer.

Teil von Phase 3 (Infrastruktur), siehe Plan toasty-twirling-hickey.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 10:15:02 +02:00
alientimandClaude Sonnet 5 83eb0be3b1 Master-Lizenzserver Phase 2: neue Schwester-Anwendung srv/tesm-license (v1.0.0)
Fork von TESM (srv/tesm), auf Kunden-/Lizenzverwaltung reduziert statt
Geraete-/PoE-Management. Wiederverwendet unveraendert: Login/Session/
Benutzer- und Gruppenverwaltung, LDAP/AD, NGINX- und Systemeinstellungen,
Live-Log/Verlauf/Auditlog, Im-/Export-Grundgeruest, das komplette
PERMISSIONS/NAV_ITEMS/inject_nav()-Rechtesystem sowie das in Phase 1
gebaute Lizenzsystem selbst sowohl fuer die MASTER-eigene Bootstrap-Lizenz
als auch fuer das exakt gleiche licensing.py (byte-identisch zu TESM --
Signieren/Verifizieren muss zwischen beiden Seiten kompatibel bleiben).

Entfernt: Clients/Switche/Zugangsdaten/DHCP/Fileshare/Wartung/Papierkorb/
manueller PoE-Neustart/SSH-Terminal inkl. aller zugehoerigen Tabellen,
Routen, Permissions, Nav-Eintraege und Abhaengigkeiten (paramiko/Flask-Sock/
simple-websocket/PyNaCl/pyasn1 aus requirements.txt). Benutzer-/Gruppen-
Loeschung von Soft- auf Hard-Delete umgestellt (kein Papierkorb mehr).
Eigener Pfad-/Env-Var-Namespace (TESM_LICENSE_* statt TESM_*, /var/log/
tesm-license statt /var/log/tesm usw.), damit Master und TESM testweise
sogar auf demselben Host nebeneinander laufen koennen, ohne sich Log-/
Config-Pfade streitig zu machen.

Neu -- der eigentliche Lizenzserver:
- license_customers/licenses-Tabellen, Master-Signaturschluessel
  (master_signing_key.json, einmalig erzeugt, NIE automatisch rotiert --
  jede Kundenlizenz traegt den zum Ausstellungszeitpunkt aktuellen
  master_pubkey fest eingebettet).
- Dashboard ('/') als Kunden-/Lizenzuebersicht (Typ, Module, Ablauf,
  Status, letzter Heartbeat), eigene Kunden-Verwaltungsseite.
- Lizenz-Ausstellung (Typ/Module/Laufzeit -> signierte Datei via
  licensing.issue_license), Detailseite, Download, Widerruf.
- /api/activate, /api/deactivate, /api/heartbeat (unauthentifiziert per
  Design -- die Signatur der Anfrage IST der Berechtigungsnachweis) sowie
  eine manuelle Offline-Code-Seite, die dieselben drei Verarbeitungs-
  funktionen (_process_activate/_process_deactivate/_process_heartbeat)
  nutzt wie die Online-API -- ein Protokoll, zwei Transportwege.
- E-Mail-Versand ausgestellter Lizenzen per Microsoft Graph
  (Client-Credentials-Flow, reine Standardbibliothek/urllib, keine neue
  Abhaengigkeit) inkl. Einrichtungsanleitung und Verbindungstest.
- create_master_license.py: lokales Bootstrap-/Erneuerungs-Skript fuer
  die eigene Lizenz des Masters (kein externer Super-Master noetig).

Verifiziert auf dem Testsystem (192.168.82.51): App laeuft parallel zu der
dort laufenden echten TESM-Instanz (Port 5001 vs. 80/5000, eigene
Log-/DB-Pfade, TESM unangetastet). Kompletter ECHTER End-to-End-Rundlauf
per Playwright durchgespielt -- kein simulierter Gegenpart: Kunde anlegen
-> Custom-Lizenz (dhcp+fileshare) ausstellen -> herunterladen -> auf der
echten TESM-Instanz hochladen -> ECHTE Online-Aktivierung (Master
verzeichnet Fingerprint, TESM zeigt 'Aktiviert') -> ECHTE Online-
Deaktivierung (TESM zeigt 'lizenzlos, Export bleibt moeglich', Master
zeigt Status 'Deaktiviert'). Lokale Syntax-/Templatepruefung (py_compile,
pyflakes, jinja2-Parse aller Templates) sauber.

Bewusst NICHT nach main gemergt/getaggt/ausgerollt -- folgt zusammen mit
Phase 3 (Infrastruktur-Umzug + POETEST-Enterprise-Lizenz), siehe Plan
toasty-twirling-hickey.md (Phase 2 von 3).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 02:07:30 +02:00