From 07ae69e3b7f6c593631b7a3c6e5c6e7a5a35ba07 Mon Sep 17 00:00:00 2001 From: Tim Eertmoed Date: Fri, 11 Sep 2026 20:16:37 +0200 Subject: [PATCH] Version 2.5.2: Wartung ist auch in der Rechtematrix ein eigener Bereich --- apps/tesm/pyproject.toml | 2 +- apps/tesm/src/tesm/permissions.py | 21 ++++++++++++++++--- apps/tesm/src/tesm/schema.py | 20 ++++++++++++++++++ packages/tesm-core/pyproject.toml | 2 +- .../tesm-core/src/tesm_core/app_factory.py | 2 +- packages/tesm-licensing/pyproject.toml | 2 +- 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/apps/tesm/pyproject.toml b/apps/tesm/pyproject.toml index 0703961..648c9d7 100644 --- a/apps/tesm/pyproject.toml +++ b/apps/tesm/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm" -version = "2.5.1" +version = "2.5.2" description = "TESM -- Verwaltung und Ueberwachung von PoE-Endgeraeten und Aruba-Switchen" requires-python = ">=3.11" dependencies = [ diff --git a/apps/tesm/src/tesm/permissions.py b/apps/tesm/src/tesm/permissions.py index d201546..c860c01 100644 --- a/apps/tesm/src/tesm/permissions.py +++ b/apps/tesm/src/tesm/permissions.py @@ -65,7 +65,8 @@ CREDENTIALS = Resource( MAINTENANCE = Resource( key="maintenance", - label="Wartung", + # Nicht "Wartung": so heisst der Bereich. Die Zeile sagt, was sie erlaubt. + label="Aktualisierung und Neustart", actions=(A.VIEW, A.EXECUTE), hint="Paketaktualisierung und Neustart per SSH (lizenzpflichtiges Modul)", action_hints={A.EXECUTE: "Aktualisierung oder Neustart auf ausgewaehlten Geraeten starten."}, @@ -128,9 +129,22 @@ MONITORING_AREA = Area( key="monitoring", label="Überwachung", icon="cpu", - hint="Geraete, Switche, Zugangsdaten und Wartung. Ohne diesen Zugang bleibt der " + hint="Geraete, Switche und Zugangsdaten. Ohne diesen Zugang bleibt der " "gesamte Bereich verborgen.", - resources=(DEVICES, SWITCHES, CREDENTIALS, MAINTENANCE), + resources=(DEVICES, SWITCHES, CREDENTIALS), +) + +#: Wartung ueberwacht nichts, sie greift ein -- und sie steht seit 2.5.0 als +#: eigener Punkt im Menue. Der Bereichsschluessel heisst ``servicing``, weil +#: ``maintenance`` schon die Ressource ist und Bereiche und Ressourcen sich +#: einen Namensraum teilen. Nach aussen heisst beides "Wartung". +MAINTENANCE_AREA = Area( + key="servicing", + label="Wartung", + icon="wrench", + hint="Paketpflege und Neustarts. Ohne diesen Zugang bleibt der Bereich " + "verborgen -- auch wenn einzelne Rechte darunter gesetzt sind.", + resources=(MAINTENANCE,), ) NETWORK_AREA = Area( @@ -150,6 +164,7 @@ FILES_AREA = Area( PERMISSIONS = PermissionTree( [ MONITORING_AREA, + MAINTENANCE_AREA, NETWORK_AREA, FILES_AREA, observability_area(LOGS_DHCP), diff --git a/apps/tesm/src/tesm/schema.py b/apps/tesm/src/tesm/schema.py index 6524da5..6277d45 100644 --- a/apps/tesm/src/tesm/schema.py +++ b/apps/tesm/src/tesm/schema.py @@ -289,10 +289,30 @@ DELETE FROM settings WHERE key = 'terminal_enabled'; """ +# Wartung ist ein eigener Bereich geworden und hat damit einen eigenen +# Kill-Switch. Ohne diesen Schritt waere sie nach dem Update bei allen weg: +# das neue Bereichsrecht ist bei niemandem gesetzt, und ohne Bereichsrecht +# greift kein Recht darunter. +# +# Bewusst nicht "alle, die ein Wartungsrecht haben": wer den Bereich +# Ueberwachung nicht hatte, kam auch vorher nicht an die Wartung. Ein Update +# darf Zugang erhalten, aber keinen neuen schaffen. +V6 = """ +INSERT OR IGNORE INTO group_permissions (group_id, permission) + SELECT DISTINCT group_id, 'servicing.view' + FROM group_permissions + WHERE permission IN ('maintenance.view', 'maintenance.execute') + AND group_id IN ( + SELECT group_id FROM group_permissions WHERE permission = 'monitoring.view' + ); +""" + + TESM_MIGRATIONS: tuple[Migration, ...] = ( Migration(version=1, name="baseline", sql=V1), Migration(version=2, name="seed-dhcp-options", fn=seed_dhcp_options), Migration(version=3, name="restart-events", sql=V3), Migration(version=4, name="fileshare-pdf-rechte", sql=V4), Migration(version=5, name="terminal-getrennt", sql=V5), + Migration(version=6, name="wartung-eigener-bereich", sql=V6), ) diff --git a/packages/tesm-core/pyproject.toml b/packages/tesm-core/pyproject.toml index fd5176e..d57d785 100644 --- a/packages/tesm-core/pyproject.toml +++ b/packages/tesm-core/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm-core" -version = "2.5.1" +version = "2.5.2" description = "Gemeinsames Anwendungsgeruest (Auth, RBAC, Navigation, Design-System, Migrationen) fuer TESM und TESM-Lizenzserver" requires-python = ">=3.11" dependencies = [ diff --git a/packages/tesm-core/src/tesm_core/app_factory.py b/packages/tesm-core/src/tesm_core/app_factory.py index df3fcbc..c7e3efa 100644 --- a/packages/tesm-core/src/tesm_core/app_factory.py +++ b/packages/tesm-core/src/tesm_core/app_factory.py @@ -148,7 +148,7 @@ def create_base_app( #: Wortmarke, ohne Zeile darunter; die Marke selbst zeigen beide #: Anwendungen. auth_tagline: str = "", - app_version: str = "2.5.1", + app_version: str = "2.5.2", built_in_trusted_keys: tuple[str, ...] = (), enable_license: bool = True, template_folder: str | None = None, diff --git a/packages/tesm-licensing/pyproject.toml b/packages/tesm-licensing/pyproject.toml index cdc6fd4..a6d6562 100644 --- a/packages/tesm-licensing/pyproject.toml +++ b/packages/tesm-licensing/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm-licensing" -version = "2.5.1" +version = "2.5.2" description = "Ed25519-basiertes Lizenz- und Aktivierungsprotokoll fuer TESM und TESM-Lizenzserver" requires-python = ">=3.11" dependencies = ["cryptography>=42"]