Document WebUntis
docs/API.md gains the findings: the endpoint and its required version parameter, the one-time code and the two error codes worth naming, the Z that means local time, a substitution being two periods, the unused exam module that puts announced tests in the period notes, and a day without lessons that is not a holiday. Those cost an afternoon of probing to learn and nothing upstream states them. docs/AUTH.md sets the key against the Schulcloud token it sits beside: no password, nothing to keep alive, revocable on its own, and not read-only in itself — which is why the allowlist exists. PI.md and DEPLOYMENT.md add the four values, the container recreate a changed key needs, and the clock requirement; the Pi's troubleshooting table gains both failure messages. README and CLAUDE.md say what the server now is: Schulcloud for the material, WebUntis for the day. Smoke is 89 checks with the index and a key, 87 live-only, 9 fewer without one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
32
docs/AUTH.md
32
docs/AUTH.md
@@ -162,6 +162,38 @@ says so immediately:
|
||||
[schulcloud-mcp] keepalive: token rejected (401). The session is gone …
|
||||
```
|
||||
|
||||
## WebUntis: a second credential, of a different kind
|
||||
|
||||
The timetable is not in Schulcloud, so the server talks to WebUntis as well —
|
||||
and that side authenticates far more comfortably. In WebUntis, open **Profil →
|
||||
Freigaben → Untis Mobile → QR-Code**. The dialog shows four values, which go
|
||||
into `.env` as `UNTIS_SERVER` (its "Url"), `UNTIS_SCHOOL`, `UNTIS_USER` and
|
||||
`UNTIS_SECRET` (its "Schlüssel"). The school number shown there is not used.
|
||||
|
||||
Why this is the right credential for a server:
|
||||
|
||||
- **No password.** The key is what the Untis Mobile app is given, and it works
|
||||
even where the WebUntis login goes through the school's SSO.
|
||||
- **Nothing to keep alive.** Every request carries a fresh time-based code
|
||||
derived from the key, so there is no session to refresh and nothing that dies
|
||||
when the Pi is off for a day. Unlike the Schulcloud token, this needs no
|
||||
monthly chore: the key stays valid until you replace it.
|
||||
- **Revocable on its own.** Generating a new key in that dialog invalidates the
|
||||
old one, and it has nothing to do with your password.
|
||||
|
||||
Two things to know:
|
||||
|
||||
- **The host's clock matters.** A time-based code from a drifting clock is
|
||||
refused with `-8524 invalid client time`, which the tools report as such. Any
|
||||
Pi with working NTP is fine.
|
||||
- **The key is not read-only — the server is.** It can do what the app can, and
|
||||
on this account that includes reporting an absence (`W_OWN_ABSENCE`). Untis'
|
||||
API is JSON-RPC, where reads are POSTs too, so "GET only" cannot be the
|
||||
guarantee here as it is for Schulcloud. Instead `core/untis.ts` carries an
|
||||
allowlist of five read methods and refuses everything else; `test/untis.test.ts`
|
||||
holds it to that. Replacing `UNTIS_SECRET` needs a restart — there is no live
|
||||
swap for it, because it does not expire.
|
||||
|
||||
## Why not username + password
|
||||
|
||||
The instance's login redirects to Keycloak (realm `TIS`) with a `redirect_uri`
|
||||
|
||||
Reference in New Issue
Block a user