2026-10-14 01:46:48 +03:00
|
|
|
# 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.
|
|
|
|
|
|
2026-10-16 01:13:20 +03:00
|
|
|
## Login theme
|
|
|
|
|
|
|
|
|
|
`themes/mancala/login` gives the login, registration and password reset pages the game's look: its app bar and logo,
|
|
|
|
|
the board's colors and a board with stones on top of the card. It extends Keycloak's `keycloak.v2` theme and only
|
|
|
|
|
adds `resources/css/mancala.css`, so its templates and behaviour stay Keycloak's own and upgrades need no template
|
|
|
|
|
changes. The colors come from `LightTheme` and `DarkTheme` in `packages/core/src/theme`; the dark ones are used when
|
|
|
|
|
the system prefers a dark color scheme. 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
|
|
|
|
|
```
|
|
|
|
|
|
2026-10-14 01:46:48 +03:00
|
|
|
## Running
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
cd apps
|
|
|
|
|
cat > .env <<EOF
|
2026-10-16 00:05:21 +03:00
|
|
|
POSTGRES_PASSWORD=change-me
|
2026-10-14 01:46:48 +03:00
|
|
|
KEYCLOAK_DB_PASSWORD=change-me
|
|
|
|
|
KEYCLOAK_ADMIN_PASSWORD=change-me
|
2026-10-16 00:05:21 +03:00
|
|
|
MANCALA_DB_PASSWORD=change-me
|
2026-10-14 01:46:48 +03:00
|
|
|
EOF
|
|
|
|
|
docker compose up -d --build keycloak
|
|
|
|
|
```
|
|
|
|
|
|
2026-10-16 00:05:21 +03:00
|
|
|
Keycloak uses the `keycloak` database of the shared `postgres` service; `apps/postgres/init` creates it the first time
|
|
|
|
|
the Postgres volume is initialised.
|
|
|
|
|
|
2026-10-14 01:46:48 +03:00
|
|
|
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
|
|
|
|
|
```
|
|
|
|
|
|
2026-10-16 01:13:20 +03:00
|
|
|
The tests start Keycloak with the extension, the real realm file and the login theme in a container, so they need
|
|
|
|
|
Docker.
|
2026-10-14 01:46:48 +03:00
|
|
|
|
|
|
|
|
## 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.
|