Files
tessera-ctl/.planning/quick/260707-csw-ldap-ad-anbindung-zugangsdaten-aus-xwiki/260707-csw-SUMMARY.md
T

4.0 KiB

status
status
complete

Quick Task 260707-csw: LDAP AD Anbindung — Zugangsdaten aus XWiki vorbefuellen und Import-Filter fuer Benutzer/Gruppen

What shipped

  1. AD connection prefill — admin/ldap page now defaults a brand-new config form to the CTL Active Directory values extracted from user-files/xwiki.cfg (server balios.ctl.local:3268, base DN dc=ctl,dc=local, AD person search filter, down-level bind-DN hint). Password stays blank. Editing an existing config still shows its real saved values (unchanged behavior).
  2. Selective group/OU import filter — new groupFilterDns String[] column on LdapConfig (additive migration, empty array = current "import everyone" behavior). GET /ldap/groups discovers AD groups/OUs under the base DN; admin can select from the discovered list or add DNs manually; selection persists via PATCH /ldap/config and is editable any time post-setup. syncUsersForTenant now restricts its directory search to members of selected groups (via escaped memberOf clauses) or users under selected OUs (extra search bases), for both manual sync and the scheduled cron sync.
  3. Bugfix caught during manual testing (not in original plan): CreateLdapConfigDto's optional fields (searchFilter, syncIntervalMin, isActive, groupFilterDns) had TS class-field default initializers. NestJS's ValidationPipe applies those defaults via plainToInstance even when the field is absent from the request body, so any partial PATCH silently reset the other fields to hardcoded defaults. Caught live: saving the group filter alone reset searchFilter back to (objectClass=person), clobbering the AD-specific filter. Fixed by removing the initializers — the service layer's own ?? default fallback already covers create-time defaults.
  4. Pre-existing i18n gap fixed (user-approved scope addition): the admin.ldap message block referenced by the page (t('title'), t('connectionTitle'), t('serverUrl'), etc.) did not exist in de.json/en.json at all, so the whole page rendered raw translation keys instead of text. Backfilled the full set of keys the page actually uses, in addition to the new group-filter keys.

Verification performed

  • prisma validate, prisma generate, API type-check, API build — all green.
  • Web type-check green; both message JSON files parse.
  • Migration applied live via container restart (Applying migration 20260707090000_add_ldap_group_filter), confirmed idempotent entrypoint (prisma migrate deploy).
  • End-to-end manual test via Playwright against the running dev stack:
    • Fresh /admin/ldap page load shows AD-prefilled connection form, password blank.
    • Created a config (test bind DN/password — dev environment, no live AD reachable from this sandbox), confirmed default field mappings (displayName, mail, sAMAccountName) are AD-correct.
    • Added a group DN manually, saved the filter, reloaded the page — filter persisted.
    • Verified via direct DB query (SELECT ... FROM "LdapConfig") that groupFilterDns persisted correctly and, after the DTO fix, that searchFilter/syncIntervalMin/isActive are no longer clobbered by a groupFilterDns-only PATCH.

Known limitations / follow-ups for the user

  • Not tested against a live AD server — balios.ctl.local is not reachable from this environment. GET /ldap/groups discovery and the memberOf-filtered sync are implemented per the plan's design and pass all static checks, but have not been exercised against real Active Directory data. Recommend testing testConnection, Gruppen/OUs suchen, and a real sync once this is deployed somewhere with network access to the CTL AD.
  • The dev database now has one LdapConfig test row (server/base DN are the real CTL AD values; bind DN/password are placeholders ctl\testservice / testpassword) with one filter DN saved. Replace the bind credentials with the real service-account before relying on this in a real environment.
  • The i18n backfill only covers keys this page actually calls — it does not audit the rest of the app for similar gaps.