test(infra): verify-notifications smoke + CI job for the OZ→NRC path (refs #56)
make verify-notifications brings the stack up, seeds a published BIG zaaktype, and asserts a zaak-create notification is delivered to a webhook-sink abonnement. The sink + driver run as containers inside the compose network and reach OpenZaak/NRC by container IP (the runner can't reach published ports, and a single-label host isn't URL-valid). The sink enforces a bearer token because NRC refuses an unauthenticated callback. New 'notifications' Gitea Actions job runs it (Docker-only). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
39
infra/notification-sink.py
Executable file
39
infra/notification-sink.py
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
"""A throwaway webhook sink for verifying the OpenZaak → NRC notification path.
|
||||
|
||||
NRC delivers abonnement callbacks here as POSTs; each body is printed to stdout
|
||||
(prefixed `NOTIFICATION `) so the verify harness can assert on `docker logs`.
|
||||
|
||||
NRC refuses to register an abonnement whose callback is unauthenticated
|
||||
(`no-auth-on-callback`): when validating it sends a probe and expects the callback
|
||||
to reject a request without the configured `Authorization` value. So this sink
|
||||
enforces that header (EXPECTED_AUTH env) — 401 without it, 204 with it.
|
||||
|
||||
Stdlib only. Listens on :9000. See infra/verify-notifications.sh / S-01-c (#56).
|
||||
"""
|
||||
import http.server
|
||||
import os
|
||||
import sys
|
||||
|
||||
EXPECTED_AUTH = os.environ.get("EXPECTED_AUTH", "Bearer notification-sink-token")
|
||||
|
||||
|
||||
class Handler(http.server.BaseHTTPRequestHandler):
|
||||
def do_POST(self):
|
||||
length = int(self.headers.get("content-length", 0))
|
||||
body = self.rfile.read(length).decode("utf-8", "replace")
|
||||
if self.headers.get("Authorization") != EXPECTED_AUTH:
|
||||
self.send_response(401)
|
||||
self.end_headers()
|
||||
return
|
||||
print("NOTIFICATION " + body, flush=True)
|
||||
self.send_response(204)
|
||||
self.end_headers()
|
||||
|
||||
def log_message(self, *args): # silence default request logging
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
http.server.HTTPServer(("0.0.0.0", 9000), Handler).serve_forever()
|
||||
sys.exit(0)
|
||||
Reference in New Issue
Block a user