Version 2.8.7: drei Standardgruppen, Module abschaltbar

This commit is contained in:
alientim committed 2026-09-13 00:19:55 +02:00
1 parent 294d47684b
commit 48ce56fe7d
9 files changed
+243 -66

No files matched your search

+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "tesm-license"
version = "2.8.2"
version = "2.8.3"
description = "TESM-Lizenzserver -- Kunden, Tickets, Lizenzen, Aktivierung"
requires-python = ">=3.11"
dependencies = [
@@ -68,7 +68,11 @@ def system():
else ""
),
timezones=_timezone_choices(),
nav_items=extension.nav.items,
# Nicht ``nav_items``: dieser Name gehoert dem Seitenrahmen. Wer ihn hier
# belegt, ueberschreibt die gefilterte Navigation aus dem Kontext --
# und die Seitenleiste zeigte dann jeden Punkt, auch den, den dieser
# Benutzer nicht darf und den die Lizenz nicht freischaltet.
nav_baum=extension.nav.items,
nav_order=extension.settings.get(conn, "nav_order") or extension.nav.default_order(),
nav_child_order=extension.settings.get(conn, "nav_child_order") or {},
sysops_available=bool(sysops and sysops.available),
@@ -183,6 +183,14 @@ FUNKTIONEN_VOLLZUGRIFF = RolePreset(
)
#: Wie in TESM: drei Gruppen ab Werk, nicht sechs.
#:
#: Auch "Vertrieb" ist hier entfallen, obwohl es die Rolle ist, die den
#: Lizenzserver taeglich benutzt -- gerade deshalb: wer Lizenzen ausstellt,
#: schneidet die Gruppe ohnehin auf sein Haus zu (darf Vertrieb widerrufen?
#: Tickets loeschen? in die Protokolle sehen?). Eine mitgelieferte Antwort auf
#: diese Frage wird entweder uebernommen, ohne sie zu pruefen, oder sie wird
#: umgebaut. "Funktionen (Vollzugriff)" ist der ehrlichere Startpunkt.
ROLE_PRESETS: tuple[RolePreset, ...] = (
RolePreset(
key="viewer",
@@ -191,52 +199,6 @@ ROLE_PRESETS: tuple[RolePreset, ...] = (
grants=(("logs_live", (A.READ,)),),
is_default=True,
),
RolePreset(
key="sales",
name="Vertrieb",
description="Kunden und Tickets pflegen, Lizenzen ausstellen und versenden.",
grants=(
("customers", "*"),
("tickets", "*"),
("licenses", (A.READ, A.EXPORT)),
("license_issue", "*"),
("license_renew", "*"),
("license_revoke", "*"),
("portal", "*"),
("logs_live", (A.READ,)),
("logs_audit", (A.READ,)),
),
),
RolePreset(
key="support",
name="Support",
description="Lesen und Offline-Aktivierungen verarbeiten.",
grants=(
("customers", (A.READ,)),
("tickets", (A.READ,)),
("licenses", (A.READ,)),
("license_activation", "*"),
("reports", (A.READ,)),
("logs_live", (A.READ,)),
),
),
RolePreset(
key="auditor",
name="Revision",
description="Nur lesen – inklusive Änderungsprotokoll und Diagnose.",
grants=(
("customers", (A.READ,)),
("tickets", (A.READ,)),
("licenses", (A.READ,)),
("reports", (A.READ,)),
("users", (A.READ,)),
("groups", (A.READ,)),
("logs_live", (A.READ,)),
("logs_history", (A.READ, A.EXPORT)),
("logs_audit", (A.READ, A.EXPORT)),
("diagnostics", (A.READ,)),
),
),
RolePreset(
key="administration",
name="Administration",
@@ -27,6 +27,8 @@ Aenderungen gegenueber dem Vorgaenger:
from __future__ import annotations
from typing import Any
from tesm_core.migrations import Migration
V1 = """
@@ -223,8 +225,79 @@ def uebergang_funktionsgruppe(conn) -> None: # type: ignore[no-untyped-def]
rbac.funktionsgruppe_fuer_administratoren(conn, PERMISSIONS, FUNKTIONEN_VOLLZUGRIFF)
#: Die drei Vorlagen, die es bis 2.8.2 gab -- eingefrorene Kopie, siehe TESM.
ABGELEGTE_VORLAGEN: tuple[tuple[str, str, tuple[tuple[str, Any], ...]], ...] = (
(
"sales",
"Vertrieb",
(
("customers", "*"),
("tickets", "*"),
("licenses", ("read", "export")),
("license_issue", "*"),
("license_renew", "*"),
("license_revoke", "*"),
("portal", "*"),
("logs_live", ("read",)),
("logs_audit", ("read",)),
),
),
(
"support",
"Support",
(
("customers", ("read",)),
("tickets", ("read",)),
("licenses", ("read",)),
("license_activation", "*"),
("reports", ("read",)),
("logs_live", ("read",)),
),
),
(
"auditor",
"Revision",
(
("customers", ("read",)),
("tickets", ("read",)),
("licenses", ("read",)),
("reports", ("read",)),
("users", ("read",)),
("groups", ("read",)),
("logs_live", ("read",)),
("logs_history", ("read", "export")),
("logs_audit", ("read", "export")),
("diagnostics", ("read",)),
),
),
)
def uebergang_standardgruppen(conn) -> None: # type: ignore[no-untyped-def]
"""Wie in TESM: unberuehrte Vorlagen in den Papierkorb, benutzte bleiben."""
from tesm_core.rbac import service as rbac
from tesm_core.rbac.model import Action, RolePreset
from .permissions import PERMISSIONS
vorlagen = [
RolePreset(
key=key,
name=name,
description="",
grants=tuple(
(ressource, a if a == "*" else tuple(Action(x) for x in a))
for ressource, a in grants
),
)
for key, name, grants in ABGELEGTE_VORLAGEN
]
rbac.unberuehrte_vorlagen_entfernen(conn, PERMISSIONS, vorlagen)
LICENSE_MIGRATIONS: tuple[Migration, ...] = (
Migration(version=1, name="baseline", sql=V1, allow_integrity_error=True),
Migration(version=2, name="revision-timestamp", sql=V2),
Migration(version=3, name="funktionsgruppe-fuer-admins", fn=uebergang_funktionsgruppe),
Migration(version=4, name="standardgruppen-aufraeumen", fn=uebergang_standardgruppen),
)
@@ -129,7 +129,7 @@
</section>
{% if current_user.is_admin %}
{{ nav_order_card(nav_items, nav_order, nav_child_order,
{{ nav_order_card(nav_baum, nav_order, nav_child_order,
url_for('admin.nav_order'), csrf_field_name, csrf_token(),
sub='Gilt für alle Benutzer') }}
{% endif %}