fix(privacyidea): repair the resolver reconciliation script (NK-WP-0033)

reconcile-lldap-resolver-live.sh had never completed a run. Four defects,
found by running it on 2026-08-27:

1. request() set Content-Type: application/json on every call, including
   bodyless GETs. Werkzeug 3.x rejects those in front of privacyIDEA, so
   every GET returned an HTML 400 while POSTs succeeded — the resolver
   write landed and the lookup immediately after it did not.
   bootstrap-realm.sh already fixed this in pi_api and said why; this
   script was written later and did not inherit it.

2. GET /user/ returns result.value as a list of user objects, not a dict
   carrying "users". With the 400 fixed, the lookup finally reached the
   parse and raised AttributeError past the except clause, so the run
   died as a traceback instead of a receipt. Both shapes now accepted,
   and the except clause catches parse errors so a failed run still
   names the phase it died in.

3. A resolver write replaces the whole object, so TIMEOUT,
   CACHE_TIMEOUT and SIZELIMIT were dropped by every --apply. A resolver
   with them unset still resolves users, but the WebUI refuses to save
   or test it — so the script silently un-repaired a resolver an
   operator had fixed by hand. Now sent, defaulting to the verified
   5/120/500 and overridable per run. Same omission fixed in
   bootstrap-realm.sh, which created the resolver that way originally.

4. The predecessor prompt could not be left empty, so an operator who
   had lost the exposed credential had to type a placeholder — which
   also fails the bind and was recorded as a PASSING denial proof.
   --predecessor-unavailable skips the bind and records NOT-PROVEN.
   --note carries operator context into the receipt line itself, so the
   claim and its caveat travel together.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 3377672@bnt-lap001
Assistant-Session: 15463ccf-238f-4e13-b163-93aa25c6d166
This commit is contained in:
tegwick 2026-08-27 22:20:03 +02:00
parent 7ce02957b3
commit 4a38511d11
2 changed files with 117 additions and 17 deletions

View file

@ -35,6 +35,13 @@ REALM_NAME="coulomb"
LLDAP_URL="ldap://lldap.sso.svc.cluster.local:3890"
LLDAP_BASE_DN="dc=netkingdom,dc=local"
LLDAP_BIND_DN="uid=admin,ou=people,dc=netkingdom,dc=local"
# Numeric resolver parameters. A resolver with these unset still resolves
# users, but the WebUI refuses to save or test it until they are filled in by
# hand, and a write that omits them drops whatever was there (NK-WP-0033,
# 2026-08-27).
LDAP_TIMEOUT="${LDAP_TIMEOUT:-5}"
LDAP_CACHE_TIMEOUT="${LDAP_CACHE_TIMEOUT:-120}"
LDAP_SIZELIMIT="${LDAP_SIZELIMIT:-500}"
PASS_COUNT=0
FAIL_COUNT=0
@ -152,7 +159,10 @@ body = {
'USERINFO': json.dumps({\"username\": \"uid\", \"phone\": \"telephoneNumber\", \"mobile\": \"mobile\", \"email\": \"mail\", \"surname\": \"sn\", \"givenname\": \"givenName\"}),
'UIDTYPE': 'uid',
'NOREFERRALS': True,
'NOSCHEMAS': True
'NOSCHEMAS': True,
'TIMEOUT': int('$LDAP_TIMEOUT'),
'CACHE_TIMEOUT': int('$LDAP_CACHE_TIMEOUT'),
'SIZELIMIT': int('$LDAP_SIZELIMIT')
}
print(json.dumps(body))
")