Benachrichtigungen: Web Push und E-Mail als Kanaele der Automatiken
Neuer BenachrichtigungTransport hinter der Aktor-URL "Benachrichtigung": push schickt an alle angemeldeten Geraete (homeMesh.push_abos), mail ueber den SMTP-Zugang aus der config.ini. Ein Abo, das der Push-Dienst mit 404 oder 410 ablehnt, wird geloescht statt weiter angeschrieben. Daneben hoert der Runner auf benachrichtigung/# - darueber schickt die Probe aus den Einstellungen, ohne dass die Weboberflaeche verschluesseln muesste. Zugestellt wird im Haupttakt, nicht im MQTT-Faden. pywebpush, py_vapid und http_ece liegen wie die uebrigen Fremdpakete im Ordner, nicht in site-packages; transports.py haengt ihn an den Suchpfad. Das Schluesselpaar erzeugt vapid_erzeugen.py und bleibt ausserhalb des Git. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Einmalig: das VAPID-Schluesselpaar fuer Web Push erzeugen.
|
||||
|
||||
Der private Schluessel bleibt auf der NAS (der Runner unterschreibt damit
|
||||
jede Nachricht), der oeffentliche geht in den Browser - er steckt im Abo und
|
||||
laesst sich nicht missbrauchen. Beide landen in push_vapid.json neben
|
||||
skoda.conf: ausserhalb des Web-Roots, aber fuer die Weboberflaeche lesbar,
|
||||
die den oeffentlichen Teil braucht.
|
||||
|
||||
Vorhandene Schluessel werden NICHT ueberschrieben - alle bestehenden Abos
|
||||
haengen daran und waeren sonst wertlos.
|
||||
"""
|
||||
import base64
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
ORDNER = "/volume1/homes/wagner/SolarManager"
|
||||
ZIEL = os.path.join(ORDNER, "push_vapid.json")
|
||||
sys.path.insert(0, ORDNER)
|
||||
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec
|
||||
|
||||
|
||||
def b64(roh):
|
||||
return base64.urlsafe_b64encode(roh).rstrip(b"=").decode("ascii")
|
||||
|
||||
|
||||
if os.path.exists(ZIEL):
|
||||
with open(ZIEL) as f:
|
||||
vorhanden = json.load(f)
|
||||
print("existiert schon, unveraendert:", vorhanden.get("public_key", "")[:16] + "…")
|
||||
sys.exit(0)
|
||||
|
||||
schluessel = ec.generate_private_key(ec.SECP256R1())
|
||||
privat = schluessel.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.NoEncryption()).decode("ascii")
|
||||
oeffentlich = schluessel.public_key().public_bytes(
|
||||
encoding=serialization.Encoding.X962,
|
||||
format=serialization.PublicFormat.UncompressedPoint)
|
||||
|
||||
with open(ZIEL, "w") as f:
|
||||
json.dump({
|
||||
"public_key": b64(oeffentlich),
|
||||
"private_key_pem": privat,
|
||||
# Wen die Push-Dienste bei Problemen erreichen. Muss eine mailto- oder
|
||||
# https-Adresse sein, sonst lehnen manche Dienste ab.
|
||||
"subject": "mailto:m0w1337@gmail.com",
|
||||
}, f, indent=2)
|
||||
os.chmod(ZIEL, 0o644)
|
||||
print("neu erzeugt:", b64(oeffentlich))
|
||||
Reference in New Issue
Block a user