Commit Graph

17 Commits

Author SHA1 Message Date
Serreau Jovann
b6dde137b4 Drop custom Caddy log file, fall back to journald
Caddy failed to start because the caddy user could not open
/var/log/caddy/auth.e-cosplay.fr.log. Rather than manage a
dedicated log directory + permissions, remove the custom `log`
block from the vhost so Caddy logs to stderr, which systemd
captures via journald (read with `journalctl -u caddy -f`).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 16:07:18 +02:00
Serreau Jovann
74aec1f1c9 Fix Caddy sites directory path (sites, not site)
The target server uses /etc/caddy/sites/ (plural) for per-site
config files, not /etc/caddy/site/.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:52:47 +02:00
Serreau Jovann
88723b5e5f Add Ansible playbook for on-server deploy
Self-contained playbook intended to be run locally on the target
server, where this repo is already cloned (typically at
/var/www/e-auth). No SSH / inventory needed — hosts: localhost
with connection: local.

What it does:
- Installs Docker Engine + compose plugin from the official repo
  (idempotent, no-op if already present).
- Ensures /etc/caddy/site exists and templates the vhost file at
  /etc/caddy/site/e-auth.conf with the Cloudflare DNS-01 token for
  caddy-dns/cloudflare, reverse-proxying to 127.0.0.1:9450.
- Validates the Caddy config and reloads the service on change.
- Runs `docker compose pull` and `docker compose up -d` from the
  repo root.

Assumes Caddy is already installed with the caddy-dns/cloudflare
plugin and loads per-site files from /etc/caddy/site/*.conf.

Usage (on the server):
  cd /var/www/e-auth/ansible && ansible-playbook deploy.yml

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 15:45:15 +02:00
Serreau Jovann
16d9b3fd35 Add E-Cosplay logo to login, account, and email themes
- Bundle logo.jpg in the repo root as the source asset and copy it
  into themes/ecosplay/login/resources/img and
  themes/ecosplay/account/resources/img so Keycloak serves it under
  ${url.resourcesPath}/img/logo.jpg.
- Login: render the logo above the auth card in a brutalist white
  frame (black border, offset hard shadow), 160x160.
- Account console: inject a 64x64 brand mark in the masthead via
  a ::before pseudo-element on .pf-v5-c-masthead__brand using the
  theme's resources/img/logo.jpg as background.
- Email: inline the logo as a base64 data URI (resized to 400x400
  JPEG @ q82 ~14KB) directly in html/template.ftl, so external image
  blocking in mail clients does not hide it. Rendered as a 160x160
  framed brand mark above the message body.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 14:45:31 +02:00
Serreau Jovann
d7c62b15f1 Add eticket OIDC client for ticket.e-cosplay.fr
- Declare a new confidential client 'eticket' (PKCE S256, standard
  flow only) in the realm import JSON for fresh installs.
- Add a generic ensure_client helper to sync.sh that creates a
  client with sane defaults if missing, then applies the URIs via
  set_client_uris on every run for idempotent reconciliation.
- Wire the new client up with its four redirect URIs:
    https://ticket.e-cosplay.fr/api/auth/login/sso/validate
    https://cos.local/api/auth/login/sso/validate
    https://ticket.e-cosplay.fr/connection/sso/check
    https://cos.local/connection/sso/check
  and matching webOrigins / post-logout URIs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 12:02:22 +02:00
Serreau Jovann
c52ff85b98 Capitalize admin first name (Jovann)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:59:33 +02:00
Serreau Jovann
8069fce9e3 Rename ecosplay client, fix redirect URIs, set admin user real name
- Rename OIDC client ecosplay-web -> ecosplay_web in the realm import
  JSON. The client is used by the internal e-cosplay site for OAuth.
- Replace wildcard redirect URIs with the two exact callbacks:
  https://www.e-cosplay.fr/oauth/keycloak and
  https://cos.local/oauth/keycloak. webOrigins and post-logout URIs
  follow the same hosts.
- Add helpers to sync.sh (client_internal_id, rename_client,
  set_client_uris) and a reconciliation step that renames any legacy
  ecosplay-web -> ecosplay_web and idempotently re-applies the URIs
  on every run, so live installs are migrated automatically.
- Set the bootstrap admin user's real first/last name (jovann Serreau)
  in both the env vars and the realm import JSON.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:59:06 +02:00
Serreau Jovann
6176a4fad9 Extract init logic to versioned sync script + bootstrap admin user
- Move the inline keycloak-init bash block out of docker-compose.yml
  into init/sync.sh, mounted into the init container at /opt/init.
  The script is fully idempotent and is the new entry point for any
  future role/group/user/realm configuration changes — re-run with
  `docker compose up -d keycloak-init --force-recreate`.
- Add reusable helper functions (ensure_user, ensure_group,
  ensure_user_in_group, ensure_user_realm_role, ensure_user_client_role)
  on top of kcadm.sh, with safe parsing of user/group IDs.
- Bootstrap admin identity jovann@siteconseil.fr (password Shoko1997@)
  in both realms:
    * master realm: granted the global `admin` role.
    * ecosplay realm: granted realm-management/realm-admin and added
      to groups super_admin_asso and superadmin.
  Both users have CONFIGURE_TOTP as a required action so OTP enrollment
  is forced at first login.
- Mirror the ecosplay user in the realm import JSON for fresh installs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:57:50 +02:00
Serreau Jovann
0716484360 Add fixed group set on ecosplay realm
- Declare the 10 application groups (gp_asso, gp_contest, gp_mail,
  gp_mailling, gp_member, gp_ndd, gp_sign, gp_ticket, super_admin_asso,
  superadmin) in the realm import JSON for fresh installs.
- Extend keycloak-init to idempotently create them via kcadm on every
  boot, so existing installs (where the realm is already imported and
  --import-realm is a no-op) also get them in sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:36:40 +02:00
Serreau Jovann
581d6a0929 Go-live, ecosplay realm-as-code, and full theme coverage
Go-live:
- Switch keycloak from start-dev to start --import-realm (production
  mode with auto-build at boot, no Dockerfile needed yet).
- Set KC_HOSTNAME=https://auth.e-cosplay.fr and KC_PROXY_HEADERS=
  xforwarded so Keycloak emits correct issuer URLs and trusts
  Caddy's X-Forwarded-* headers.
- Replace deprecated KEYCLOAK_ADMIN env vars with KC_BOOTSTRAP_ADMIN_*.
- Bind the public port to 127.0.0.1 only (Caddy is colocated).
- Add a Keycloak healthcheck against /health/ready on the management
  port (9000) using bash /dev/tcp; init container now waits on
  service_healthy instead of service_started.

Architecture:
- New realms/ecosplay-realm.json mounted into /opt/keycloak/data/import
  and imported on first boot. Defines the dedicated 'ecosplay' realm
  (separate from master) with French i18n, brute-force protection,
  strong password policy, SES SMTP, and an OIDC client 'ecosplay-web'
  pointing at e-cosplay.fr (confidential + PKCE S256).

Theme coverage:
- themes/ecosplay/account: PatternFly v5 overlay (parent=keycloak.v2)
  bringing the neo-brutalist colors, thick borders, italic uppercase
  typography, and offset hard shadows to the user account console.
- themes/ecosplay/email: branded HTML wrapper template (table layout
  with inline styles for email-client safety) plus a matching plain
  text wrapper. All Keycloak emails now ship with the E-Cosplay
  identity without needing per-template overrides.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:22:40 +02:00
Serreau Jovann
fb62e7f942 Force French locale on master and rebrand header tag
- keycloak-init now enables i18n on master with French as the only
  supported locale and the default, so all login pages render in fr.
- Replace dynamic realm.displayName tag (which showed 'Keycloak') with
  hardcoded '// Connexion sécurisée' in the theme header.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 10:13:20 +02:00
Serreau Jovann
d7f904c183 Fix FTL crash when realm has i18n disabled
Guard locale references with null-safe defaults — the master realm
ships with internationalization off, so locale is undefined and
${locale.currentLanguageTag} threw InvalidReferenceException.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 10:11:49 +02:00
Serreau Jovann
f1b98fe8d7 Add neo-brutalist Keycloak login theme 'ecosplay'
- Custom theme under themes/ecosplay/login (extends keycloak parent)
  with template.ftl and login.ftl matching the e-cosplay.fr style:
  thick black borders, hard offset shadows, italic uppercase, indigo
  accent, hover translate effect, marquee header, watermark.
- Tailwind via Play CDN for utility classes (no build step).
- Mount the theme dir read-only into the Keycloak container.
- Init container now also sets loginTheme=ecosplay on master realm
  alongside the SMTP config; service renamed keycloak-init.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 09:17:49 +02:00
Serreau Jovann
59f60b4c5c Revert hostname to localhost, drop proxy-headers config
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 09:10:20 +02:00
Serreau Jovann
be17955712 Configure SMTP via init container and set public hostname
- Add keycloak-smtp-init service that uses kcadm.sh to apply SES SMTP
  settings to the master realm at startup (idempotent, env-driven).
- Set KC_HOSTNAME to https://auth.e-cosplay.fr and trust X-Forwarded-*
  headers for the upcoming Caddy reverse proxy in front.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:38:08 +02:00
Serreau Jovann
9f83c5aa02 Expose Keycloak on public port 9450
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:34:19 +02:00
Serreau Jovann
1c64d001cc Initial commit: Keycloak + Postgres docker-compose setup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 08:34:09 +02:00