The backend half of the sweep RD-18 did for the front end. git blame holds the provenance and stays correct when the code moves; the comment names a closed ticket and tells the reader nothing the sentence around it does not. public/letter.css and LetterHtml.golden.html change together, because the renderer inlines the CSS and the golden file snapshots the result. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
64 lines
2.7 KiB
Bash
Executable File
64 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Proves the "real write -> real webhook delivery" round-trip end-to-end: PATCHes the
|
|
# zaak bootstrap-catalogus.sh seeded (a notified ZRC resource), then polls the BFF's own audit
|
|
# trail for the resulting `zgw:notificatie` row. Requires bootstrap-catalogus.sh and
|
|
# bootstrap-notificaties.sh to have already run.
|
|
set -euo pipefail
|
|
cd "$(dirname "${BASH_SOURCE[0]}")"
|
|
|
|
[ -f seeded.env ] || { echo "seeded.env missing — run ./bootstrap-catalogus.sh first" >&2; exit 1; }
|
|
# Not `source`d: seeded.env's ZAAKTYPE_LABEL value contains an unquoted space (fine for the
|
|
# line-oriented C# reader it's written for, not valid as sourceable shell).
|
|
ZAAK_URL=$(grep '^ZAAK_URL=' seeded.env | cut -d= -f2-)
|
|
|
|
BFF_BASE="${BFF_BASE:-http://localhost:5000}"
|
|
CLIENT_ID="bigregister-test"
|
|
SECRET="bigregister-test-secret"
|
|
|
|
b64url() { openssl base64 -A | tr '+/' '-_' | tr -d '='; }
|
|
jwt() {
|
|
local header='{"alg":"HS256","typ":"JWT"}'
|
|
local payload
|
|
payload=$(printf '{"iss":"%s","iat":%d,"client_id":"%s","user_id":"%s","user_representation":"%s"}' \
|
|
"$CLIENT_ID" "$(date +%s)" "$CLIENT_ID" "$CLIENT_ID" "verify")
|
|
local h p signing_input sig
|
|
h=$(printf '%s' "$header" | b64url)
|
|
p=$(printf '%s' "$payload" | b64url)
|
|
signing_input="$h.$p"
|
|
sig=$(printf '%s' "$signing_input" | openssl dgst -sha256 -hmac "$SECRET" -binary | b64url)
|
|
printf '%s.%s' "$signing_input" "$sig"
|
|
}
|
|
|
|
echo "Triggering a real write: PATCH $ZAAK_URL (bijwerken — the client is granted zaken.aanmaken"
|
|
echo "for exactly ONE status, so a second status create 403s; a zaak update is the write this"
|
|
echo "client's narrowed scope can repeat)..."
|
|
response=$(curl -sS -X PATCH -H "Authorization: Bearer $(jwt)" -H 'Content-Type: application/json' \
|
|
-H 'Content-Crs: EPSG:4326' -H 'Accept-Crs: EPSG:4326' \
|
|
-d "$(printf '{"toelichting":"wp-58 verify %s"}' "$(date -u +%s)")" \
|
|
-w $'\n%{http_code}' "$ZAAK_URL")
|
|
http_code="${response##*$'\n'}"
|
|
if [[ ! "$http_code" =~ ^2 ]]; then
|
|
echo "FAILED: zaak PATCH -> $http_code: ${response%$'\n'*}" >&2
|
|
exit 1
|
|
fi
|
|
echo " updated"
|
|
|
|
echo "Waiting for the BFF's audit trail to show the delivered notification..."
|
|
for _ in $(seq 1 30); do
|
|
if curl -sS -H 'X-Role: admin' "$BFF_BASE/api/v1/admin/audit" \
|
|
| python3 -c "
|
|
import json, sys
|
|
rows = json.load(sys.stdin)
|
|
found = any(r['action'] == 'zgw:notificatie' and r['resource'] == '$ZAAK_URL' and r['decision'] == 'allow' for r in rows)
|
|
sys.exit(0 if found else 1)
|
|
"; then
|
|
echo " delivered: found a zgw:notificatie/allow row for $ZAAK_URL"
|
|
exit 0
|
|
fi
|
|
sleep 2
|
|
done
|
|
|
|
echo "FAILED: no delivered notification for $ZAAK_URL after 60s. Diagnostics:" >&2
|
|
docker compose -f docker-compose.openzaak.yml -f docker-compose.openzaak.notificaties.yml logs --tail=50 celery >&2
|
|
exit 1
|