# ungleich account webapp This service runs on [account.ungleich.ch](https://account.ungleich.ch/). Customers use it to manage their ungleich LDAP account: register (with email confirmation), log in, change their name, email or password, reset a forgotten password, delete the account, and view their OTP seeds. It also offers a small API for creating accounts and fetching OTP seeds. Django 6.1 on Python 3.15. LDAP access goes through [ldap3](https://ldap3.readthedocs.io/) only, with no C extensions. ## Development You need Docker and [uv](https://docs.astral.sh/uv/) (or any Python 3.15). Only LDAP (and optionally PostgreSQL) runs in containers. The app runs natively. ```sh docker compose -f docker-compose.dev.yml up -d --build # OpenLDAP 2.6 on :3389, PostgreSQL on :5433 cp dev/env.dev .env # dev-only settings uv venv -p 3.15 .venv && uv pip install -r requirements.txt .venv/bin/python manage.py migrate .venv/bin/python manage.py runserver ``` The test LDAP mirrors the production layout (`dc=ungleich,dc=ch`, `ou=customer`, `ou=users`) and comes with `customer1` / `customerpass` and `staff1` / `staffpass`. To reset its data: `docker compose -f docker-compose.dev.yml up -d --force-recreate ldap`. ### Tests ```sh .venv/bin/python manage.py test dal ``` The tests in `dal/tests/` exercise every view over HTTP against the real test LDAP server, which must be running. Mail and the OTP server are mocked. Set `DATABASE_HOST=localhost DATABASE_PORT=5433 DATABASE_PASSWORD=dev-only` to run them on PostgreSQL instead of SQLite. ## Configuration Every setting is an environment variable (a `.env` file in development). [`.env.example`](.env.example) lists each one, with its default and whether it is a secret. ## Deployment The [`Dockerfile`](Dockerfile) builds a production image: gunicorn running as non-root, static files served by WhiteNoise, and logs on stdout. [`docker.md`](docker.md) explains how to deploy it with `docker run`, Docker Compose ([`compose.yaml`](compose.yaml)) or Helm, and which variables are needed. For the plain Kubernetes manifests, and testing locally with kind, see [`deploy/k8s/README.md`](deploy/k8s/README.md). ## Layout | Path | Contents | | --- | --- | | `dal/views.py` | All views | | `dal/ungleich_ldap.py` | LDAP writes and searches (`LdapManager`, server pool) | | `dal/backends.py` | LDAP login backend | | `dal/health.py` | `/healthz` and `/readyz` | | `dal/tests/` | End-to-end tests | | `dev/` | Dev settings and the test OpenLDAP image | | `deploy/k8s/` | Kubernetes manifests (base and kind dev overlay) |