- internal/notifyapi.Mount (POST /notify/enqueue), reiner Wrapper um notifyprefs.EnqueueIfAllowed (CFG-04) - Reuse von internal/policyapi.RequireServiceToken (RBAC-06), kein neues Provisorium, eigener Service-Token pro Endpunkt - Tests: 401 ohne Token, Aequivalenz HTTP vs. direkter Aufruf (aktiviert/deaktiviert), realer Fremd-Modul-Client mit echter notification_jobs-Zeile - real deployed auf 131 (notify-api, Port 8094), Grant-Nachverfolgung fuer nexarch_core auf notification_preferences/notification_jobs, end-zu-ende per curl nachgewiesen (401, job_id+skipped:false) Pruefungen siehe docs/CFG-05-PRUEFPROTOKOLL.md
88 lines
4.6 KiB
Markdown
88 lines
4.6 KiB
Markdown
# CFG-05 – Prüfprotokoll: Modulübergreifender HTTP-Endpunkt für Benachrichtigungs-Ereignisse
|
||
|
||
Voraussetzung CFG-04 – bereits Fertig (siehe eigenes Protokoll).
|
||
|
||
## Grundsatzentscheidung: Wrapper, keine zweite Benachrichtigungslogik
|
||
|
||
`internal/notifyapi.Mount` registriert `POST /notify/enqueue`, dessen
|
||
Handler AUSSCHLIESSLICH `notifyprefs.EnqueueIfAllowed` aufruft — dieselbe
|
||
Funktion, die auch core-interne Aufrufer nutzen (z. B. CFG-04s eigene
|
||
Handler). Die Übereinstimmung zwischen HTTP-Antwort und direktem
|
||
Aufruf ist dadurch strukturell garantiert — real bewiesen für
|
||
aktivierten UND deaktivierten Kanal (siehe Prüfungen).
|
||
|
||
**Endpunkt ist für externe Module aufrufbar, nicht nur Core-intern:**
|
||
real per HTTP von einem simulierten Fremd-Modul-Testclient
|
||
(`TestEnqueueHandler_RealForeignModuleClient`) und per `curl` von der
|
||
Kommandozeile aus aufgerufen, jeweils gegen den laufenden, über
|
||
systemd verwalteten `notify-api`-Prozess — nicht nur als Go-Funktion
|
||
innerhalb desselben Prozesses getestet.
|
||
|
||
## Service-Authentifizierung: Reuse von RBAC-06, kein neues Provisorium
|
||
|
||
`internal/policyapi.RequireServiceToken` (RBAC-06) direkt
|
||
wiederverwendet — kein zweiter, abweichender Service-Token-Mechanismus.
|
||
Beide liegen im selben Core-Go-Modul, ein echter Import statt
|
||
Duplikat. `notify-api` läuft als eigener systemd-Dienst (analog
|
||
`policy-api`), mit eigenem `NEXARCH_NOTIFY_SERVICE_TOKEN`
|
||
(unabhängiger Tokenwert von RBAC-06s Token — getrennte
|
||
Vertrauensgrenze pro Endpunkt, kein geteiltes Secret).
|
||
|
||
## Umsetzung
|
||
|
||
- `internal/notifyapi.Mount`/`enqueueHandler` — `POST /notify/enqueue`,
|
||
reiner Wrapper um `notifyprefs.EnqueueIfAllowed`.
|
||
- `cmd/notify-api` — eigenständiger HTTP-Dienst, Port 8094.
|
||
- `deploy/systemd/nexarch-notify-api.service.tmpl`.
|
||
|
||
## Prüfungen
|
||
|
||
| # | Prüfung | Ergebnis |
|
||
|---|---|---|
|
||
| 1 | Endpunkt-Antwort stimmt in mehreren Stichproben mit dem direkten EnqueueIfAllowed-Ergebnis überein | **bestanden** — `TestEnqueueHandler_MatchesDirectEnqueueIfAllowed`: aktivierter Kanal (Opt-out-Default) liefert echte Job-ID; deaktivierter Kanal wird real per `prefs.Set(...,false)` gesetzt, HTTP-Antwort (`skipped=true`) stimmt exakt mit dem parallel ausgeführten direkten Aufruf überein |
|
||
| 2 | Aufruf ohne Service-Token wird abgewiesen (401), Handler nie erreicht | **bestanden** — `TestEnqueueHandler_MissingTokenReturns401`; real auf 131: `curl` ohne `X-Service-Token` → 401 |
|
||
| 3 | Ein simulierter Fremd-Modul-Testclient löst real über den laufenden Endpunkt ein Ereignis aus | **bestanden** — `TestEnqueueHandler_RealForeignModuleClient`: echte `notification_jobs`-Zeile per SQL nachgewiesen; zusätzlich real auf 131 per `curl` reproduziert, resultierende `notification_jobs`-Zeile per `psql` bestätigt (`status=pending`), danach entfernt |
|
||
|
||
## Echte Verdrahtung auf 192.168.1.131
|
||
|
||
- `notify-api` gebaut nach `/opt/nexarch-core/bin/`
|
||
- `/etc/nexarch/notify-api.env` (0600)
|
||
- `nexarch-notify-api.service` installiert/aktiviert (dauerhaft,
|
||
`Restart=on-failure`)
|
||
- Reale Rechtevergabe-Lücke gefunden und behoben (gleiches Muster wie
|
||
RBAC-06): `notification_preferences`/`notification_jobs` gehörten
|
||
`postgres`, `nexarch_core` hatte keine Rechte — `GRANT` nachgezogen
|
||
und über `information_schema.role_table_grants` verifiziert (nicht
|
||
nur ausgeführt und angenommen), bevor der End-zu-Ende-Test erneut
|
||
lief.
|
||
- Realer End-zu-Ende-Test via `curl`: 401 ohne Token, `job_id` +
|
||
`skipped:false` nach echtem Aufruf, `notification_jobs`-Zeile per
|
||
`psql` bestätigt, danach entfernt.
|
||
|
||
## Build/Test-Ergebnis (192.168.1.131)
|
||
|
||
```
|
||
go build ./... -> clean
|
||
go vet ./... -> clean
|
||
golangci-lint run ./... -> 0 issues
|
||
go test ./internal/notifyapi/... ./internal/notifyprefs/... ./internal/policyapi/... -> alle bestanden
|
||
```
|
||
|
||
**Hinweis:** `go test ./... -p 1` auf diesem Branch zeigt Fehlschläge in
|
||
`internal/user` (`database "test_iam01_users" already exists`) — reale
|
||
Umgebungs-Altlast aus früheren IAM-01-Testläufen dieser Session,
|
||
NICHT durch CFG-05 verursacht. Alle von CFG-05 tatsächlich berührten
|
||
Pakete (`internal/notifyapi`, `internal/notifyprefs`, `internal/notify`,
|
||
`internal/policy`, `internal/policyapi`, `internal/rbac`,
|
||
`internal/auth`, `internal/cfgservice`, `internal/channels`,
|
||
`internal/tenant`) sind grün.
|
||
|
||
## Gesamtergebnis
|
||
|
||
**Bestanden.** Alle drei Akzeptanzkriterien und alle drei
|
||
Pflichtprüfungen real erfüllt — inklusive echtem systemd-Deploy und
|
||
curl-Nachweis. Schließt denselben "Go-Code ohne HTTP-Schnittstelle für
|
||
andere Module"-Befund für Benachrichtigungs-Ereignisse, den RBAC-06
|
||
für Policy-Entscheidungen geschlossen hat. RET-07 (Archive) kann sich
|
||
jetzt gegen diesen Endpunkt verdrahten.
|