Sample entries from production show:
- customers live in ou=customer (singular), not ou=customers
- customers have gidNumber 10004 and staff 10002; uidNumbers are in
the 10000s
- staff entries list organizationalPerson and person explicitly
- the servers serve ldaps:// on port 636
The app reads all of these from settings, so its behaviour is
unchanged; the customer entry it creates already matches production
attribute for attribute. The defaults and test setups were wrong:
env.sample, the Kubernetes ConfigMap (now ldaps:// without StartTLS,
gid 10004, start uid 10000), dev/env.dev and the dev LDAP seed now
mirror production. The made-up ou=groups is gone. The tests take the
customer DN and gidNumber from settings instead of hardcoding them.
Production and the client's test server use ldaps://, so the dev server
now offers TLS as well: ldaps on 636 (localhost:3636) and StartTLS on
389, with both ports also published on [::1].
A throwaway CA and server certificate are generated on every start, with
the full CA extensions that Python 3.13+ strict verification requires.
The CA certificate is copied to dev/ldap/export/ca.crt (gitignored).
The server certificate covers localhost, the service names and ::1, but
not 127.0.0.1, so tests can show that hostname mismatches are
rejected.
Sessions, password reset tokens and pending registrations live in the
database, so running more than one replica needs a shared one. With
DATABASE_HOST set the app uses PostgreSQL (psycopg 3 binary wheels, no
system libraries) with persistent, health-checked connections.
Otherwise SQLite is used, at a path configurable with SQLITE_PATH so a
single replica can keep it on a volume.
docker-compose.dev.yml gains a PostgreSQL 18 service on
localhost:5433. The full test suite passes on SQLite and PostgreSQL.
The OTP server variables were read straight from the environment in
views.py. They are now OTP_* settings next to everything else, under
the same environment variable names, so existing deployments are
unaffected.
Remove LDAP_SERVER and LDAP_USERS_DN, which nothing used.
env.sample moves to the repository root (where .env is read from) and
lists every variable settings.py reads, including defaults and which
values are secrets.
Alpine 3.24 based slapd with the production directory layout
(dc=ungleich,dc=ch, ou=customers, ou=users) and the openssh-lpk schema.
The app runs natively against it on ldap://localhost:3389.
Includes dev/env.dev with dev-only settings (cp dev/env.dev .env).