forked from ungleich-public/ungleich-user
Replace the v2 notes and the broken setup steps with what the app does, how to develop and test against the dev LDAP, where configuration is documented, how to deploy, and a map of the code.
65 lines
2.4 KiB
Markdown
65 lines
2.4 KiB
Markdown
# 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=customers`, `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.sample`](env.sample) 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. To
|
|
deploy on Kubernetes, and to test 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) |
|