Theme files are cached under a path that only changes with Keycloak's version, for 30 days, so returning players kept the grey stylesheet. It is renamed to login.css, and theme files are now cached for an hour.
94 lines
4.3 KiB
Markdown
94 lines
4.3 KiB
Markdown
# Mancala Keycloak
|
|
|
|
Keycloak is the only auth system for Mancala. Players can either log in with an account or play as a guest,
|
|
and both come back as normal Keycloak tokens from the `mancala` realm.
|
|
|
|
## Guest login
|
|
|
|
`extension/` adds a `mancala-guest-authenticator` to Keycloak. When an authorization request has `guest=true`,
|
|
it creates a new user named `guest-xxxxxxxx`, gives it the `guest` realm role and logs it in without showing a
|
|
form. Requests without the parameter fall through to the normal login form.
|
|
|
|
```
|
|
/realms/mancala/protocol/openid-connect/auth?client_id=mancala-web&response_type=code
|
|
&scope=openid%20offline_access&redirect_uri=...&code_challenge=...&code_challenge_method=S256
|
|
&guest=true
|
|
```
|
|
|
|
- Clients can tell guests apart by `"guest"` in the access token's `realm_access.roles`.
|
|
- Guests should request `offline_access` so they keep their identity after the SSO session ends
|
|
(offline sessions expire after 30 days without use).
|
|
- A scheduled task deletes guests that are older than a day and have no session or offline session left.
|
|
Its timing can be changed with server options such as
|
|
`KC_SPI_AUTHENTICATOR__MANCALA_GUEST_AUTHENTICATOR__CLEANUP_INTERVAL_SECONDS` (default 3600),
|
|
`..._CLEANUP_MIN_AGE_SECONDS` (default 86400) and `..._CLEANUP_MAX_DELETES_PER_RUN` (default 1000).
|
|
- Each guest login creates a user, so the auth endpoint is rate limited per IP in `config/nginx.conf`.
|
|
|
|
## Realm
|
|
|
|
`realm/mancala-realm.json` holds the realm: the `mancala-web` public client (PKCE S256), the
|
|
`browser with guest` flow, the `guest` role, and the required actions with "Verify Profile" turned off so guests
|
|
are not asked for an email or a name.
|
|
|
|
Keycloak imports the file only if the realm does not exist yet. After changing it, apply the change in the admin
|
|
console too, or delete the realm and restart Keycloak.
|
|
|
|
## Login theme
|
|
|
|
`themes/mancala/login` gives the login, registration and password reset pages the web app's look in its three themes
|
|
(Ceviz, Gece, Yeşim): its header, logo and name, font, cards, fields, pill buttons and a board with stones on top of
|
|
the card (`docs/specs/theme-polish`). It extends Keycloak's `keycloak.v2` theme and only adds
|
|
`resources/css/login.css` and `resources/js/theme.js`, so its templates and behaviour stay Keycloak's own and
|
|
upgrades need no template changes.
|
|
|
|
The script runs in the page's head and puts the theme's class (`t-ceviz`, `t-gece`, `t-yesim`) on `<html>`: the
|
|
theme the player chose in the web app, which the app keeps in the `mancala_theme` cookie (shared by `localhost`'s
|
|
ports, and set for `playmancala.app` so `auth.playmancala.app` gets it), or else Ceviz for a dark system color scheme
|
|
and Yeşim for a light one. Keycloak's own dark mode is off (`darkMode=false`); the script adds PatternFly's
|
|
`pf-v5-theme-dark` for the dark themes. The themes' colors are copied from `apps/frontend/src/styles/app.css`; the logo
|
|
and the board are masks (`img/*-mask.svg`) filled with them. The realm turns the theme on (`loginTheme`) and offers English and Turkish;
|
|
the web app passes its language as `ui_locales`.
|
|
|
|
To try a change without rebuilding the image, copy the theme into the running container, clear Keycloak's gzip cache
|
|
(it survives restarts) and restart:
|
|
|
|
```sh
|
|
docker cp apps/keycloak/themes/mancala apps-keycloak-1:/opt/keycloak/themes/
|
|
docker exec apps-keycloak-1 rm -rf /opt/keycloak/data/tmp/kc-gzip-cache
|
|
docker restart apps-keycloak-1
|
|
```
|
|
|
|
## Running
|
|
|
|
```sh
|
|
cd apps
|
|
cat > .env <<EOF
|
|
POSTGRES_PASSWORD=change-me
|
|
KEYCLOAK_DB_PASSWORD=change-me
|
|
KEYCLOAK_ADMIN_PASSWORD=change-me
|
|
MANCALA_DB_PASSWORD=change-me
|
|
EOF
|
|
docker compose up -d --build keycloak
|
|
```
|
|
|
|
Keycloak uses the `keycloak` database of the shared `postgres` service; `apps/postgres/init` creates it the first time
|
|
the Postgres volume is initialised.
|
|
|
|
Keycloak is then at http://localhost:8080 and the admin console at http://localhost:8080/admin.
|
|
In production set `KEYCLOAK_HOSTNAME=https://auth.playmancala.app`; nginx proxies that host to port 8080.
|
|
|
|
## Tests
|
|
|
|
```sh
|
|
cd apps/keycloak/extension
|
|
mvn test
|
|
```
|
|
|
|
The tests start Keycloak with the extension, the real realm file and the login theme in a container, so they need
|
|
Docker.
|
|
|
|
## Upgrading Keycloak
|
|
|
|
The extension uses Keycloak's authenticator SPI, which Keycloak marks as internal. When upgrading, change the
|
|
version in `extension/pom.xml` and in `Dockerfile` together and run the tests.
|