feat(verzeichnis): LDAP-Abgleich, Zeitplan, CSV-Import und Log
Prüfung / pruefung (push) Canceled after 0s
Prüfung / pruefung (pull_request) Canceled after 0s
Prüfung / e2e (push) Canceled after 0s
Prüfung / e2e (pull_request) Canceled after 0s

Quelle anlegen, Verbindung testen, nach Zeitplan oder auf Knopfdruck
abgleichen. Gelesen wird seitenweise mit searchPaginated, objectGUID
kommt als Puffer und wird gemischt-endian zur GUID umsortiert. Wer im
Verzeichnis verschwindet, wird hier inaktiv und nie geloescht.

Drei Regeln verhindern, dass eine kaputte Eingabe wie "alle sind
gegangen" aussieht: laesst sich kein einziger Eintrag zuordnen, wird
niemand deaktiviert; uebersprungene Eintraege werden am dn erkannt und
ausgenommen; eine von Hand angelegte Person wird uebernommen statt
verdoppelt.

Der Zeitplan laeuft ueber node-cron im selben Prozess, gestartet aus
src/instrumentation.ts, und nimmt keine eigene Sperre - die liegt in der
Datenbank, damit zwei Instanzen sich einig sind.

Closes #16

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Florian Wilde
2026-09-26 02:21:08 +02:00
co-authored by Claude Opus 5
parent ab5777a57e
commit 16059e7846
57 changed files with 6834 additions and 61 deletions
+45 -2
View File
@@ -1,6 +1,4 @@
# Dienste fuer die Testsuite. Nicht fuer den Betrieb.
# Die LDAP-Quelle fuer den Verzeichnis-Abgleich kommt in #016 dazu, dort wird sie
# auch tatsaechlich benutzt und geprueft.
name: laufzettel-test
@@ -18,3 +16,48 @@ services:
interval: 5s
timeout: 5s
retries: 10
# Das Verzeichnis fuer den Abgleich (#016). OpenLDAP mit einem AD-aehnlichen
# Schema: sAMAccountName, userPrincipalName, binaeres objectGUID,
# userAccountControl, objectCategory und department bringt OpenLDAP nicht mit,
# sie stehen deshalb in tests/fixtures/ldap/schema/ad-fixture.ldif.
#
# LDAP_TLS ist aus, und das ist eine Einschraenkung mit Ansage: das Zertifikat,
# das osixia sonst selbst erzeugt, laeutet auf den Containernamen, waehrend der
# Test von aussen 127.0.0.1 anspricht -- die Pruefung des Hostnamens schlaege
# fehl. Ein Schalter, der sie abstellt, waere ein Schalter zu viel im
# Produktionscode. Der Container wird deshalb im Klartext angesprochen; die
# TLS-Optionen (ldaps, StartTLS, eigenes CA-Zertifikat, minVersion) sind als
# reine Funktion `tlsOptionenBauen` in tests/verzeichnis.test.ts geprueft.
ldap:
image: osixia/openldap:1.5.0
# Ohne `--copy-service` spielt der Startskript die Bootstrap-Dateien nicht
# ein, wenn sie nur eingehaengt sind.
command: ["--copy-service"]
environment:
LDAP_ORGANISATION: Firma Test
LDAP_DOMAIN: firma.test
LDAP_ADMIN_PASSWORD: ldap-test-geheim
LDAP_TLS: "false"
ports:
- "127.0.0.1:1389:389"
volumes:
# Schema und Daten liegen in getrennten Verzeichnissen, weil osixia die
# Daten-LDIFs mit `sed -i` nach Platzhaltern durchsucht. Eingehaengt wird
# deshalb das Verzeichnis und nicht die Datei: `sed -i` schreibt ueber eine
# Umbenennung, und die scheitert auf einer einzeln eingehaengten Datei --
# das Startskript laeuft mit `bash -e` und der Container waere tot.
- ./tests/fixtures/ldap/schema:/container/service/slapd/assets/config/bootstrap/schema/custom:ro
- ./tests/fixtures/ldap/daten:/container/service/slapd/assets/config/bootstrap/ldif/custom
healthcheck:
# Die Suche laeuft ueber den authentifizierten Bind, weil anonymes Lesen
# abgeschaltet ist. Gesund ist der Dienst erst, wenn die Fixture-Personen
# wirklich da sind -- sonst liest der Test gegen ein leeres Verzeichnis.
test:
[
"CMD-SHELL",
"ldapsearch -x -H ldap://localhost:389 -D cn=admin,dc=firma,dc=test -w ldap-test-geheim -b ou=Benutzer,dc=firma,dc=test -s sub '(sAMAccountName=mhuber)' dn | grep -q 'cn=Maria Huber'",
]
interval: 5s
timeout: 5s
retries: 20