|
|
|
@@ -266,6 +266,35 @@ def _bitte_bestaetigen(permission: str) -> Any:
|
|
|
|
|
return redirect(url_for("auth.reauth"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _heikel(permissions: tuple[str, ...], mode: str) -> str:
|
|
|
|
|
"""Welches Recht verlangt hier eine frische Bestaetigung? Sonst leer.
|
|
|
|
|
|
|
|
|
|
Bei ``mode="all"`` ist die Antwort einfach: jedes genannte Recht wird
|
|
|
|
|
gebraucht, also zaehlt jedes heikle darunter.
|
|
|
|
|
|
|
|
|
|
Bei ``mode="any"`` nicht. Diese Seiten nennen mehrere **unabhaengige**
|
|
|
|
|
Wege hinein, und welcher genommen wird, entscheidet das Konto. Der
|
|
|
|
|
Protokollverlauf etwa nennt "logs_history.read" und "logs_history.export":
|
|
|
|
|
lesen ist harmlos, mitnehmen nicht. Gezaehlt wurde aber ueber alle
|
|
|
|
|
genannten Rechte -- und so verlangte das blosse **Ansehen** des Verlaufs
|
|
|
|
|
nach fuenfzehn Minuten eine Passworteingabe, mit dem Hinweis, man greife
|
|
|
|
|
auf einen Datenexport zu. Das stimmte nicht, und wer es dreimal liest,
|
|
|
|
|
glaubt die Meldung beim vierten Mal auch dann nicht, wenn sie zutrifft.
|
|
|
|
|
|
|
|
|
|
Gefragt wird deshalb: haette dieses Konto die Seite auch ohne das heikle
|
|
|
|
|
Recht geoeffnet? Dann gibt es nichts zu bestaetigen. Die Ausfuhr selbst
|
|
|
|
|
haengt an ihrer eigenen Route, und die nennt nur ein Recht.
|
|
|
|
|
"""
|
|
|
|
|
heikle = [p for p in permissions if _verlangt_wiederanmeldung(p)]
|
|
|
|
|
if not heikle:
|
|
|
|
|
return ""
|
|
|
|
|
if mode == "any":
|
|
|
|
|
harmlos = [p for p in permissions if p not in heikle]
|
|
|
|
|
if any(current_user.has(p) for p in harmlos):
|
|
|
|
|
return ""
|
|
|
|
|
return heikle[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def permission_required(*permissions: str, mode: str = "all") -> Callable[..., Any]:
|
|
|
|
|
"""Erzwingt Rechte serverseitig.
|
|
|
|
|
|
|
|
|
@@ -289,9 +318,9 @@ def permission_required(*permissions: str, mode: str = "all") -> Callable[..., A
|
|
|
|
|
# in jeder Route einzeln. Vorher hing es daran, dass jemand an den
|
|
|
|
|
# Dekorator dachte: dieselbe Lizenz herunterzuladen fragte nach,
|
|
|
|
|
# sie per Mail zu verschicken nicht.
|
|
|
|
|
heikel = [p for p in permissions if _verlangt_wiederanmeldung(p)]
|
|
|
|
|
heikel = _heikel(permissions, mode)
|
|
|
|
|
if heikel and not _wiederanmeldung_frisch():
|
|
|
|
|
return _bitte_bestaetigen(heikel[0])
|
|
|
|
|
return _bitte_bestaetigen(heikel)
|
|
|
|
|
return view(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
wrapper._required_permissions = permissions # type: ignore[attr-defined]
|
|
|
|
|