diff --git a/CHANGELOG.md b/CHANGELOG.md index 500ca0b..5458f70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,15 @@ ## 2026-07-03 ### Ajouté +- **Thème de connexion Keycloak à l'identité Alliance Boréale.** Thème de login `alliance-boreale` + (`roles/serveur_keycloak/files/themes/`, `parent=keycloak` + overlay CSS) reprenant l'identité du + site de l'Alliance (extraite de `site-alliance-boreale`) : **ciel nocturne aurore** (`#05060f`/ + `#0a0d24` + dégradés), **carte glassmorphism**, **logo étoile aurore** (le `favicon.svg` du site), + **bouton dégradé aurore** (teal→cyan, pilule), liens cyan, **police système** (souveraineté, zéro + dépendance externe). Déployé dans `{{ keycloak_home }}/themes/`, appliqué au realm via + `kcadm ... -s loginTheme` (var `serveur_keycloak_login_theme`, idempotent), Keycloak rechargé + (`flush_handlers` avant la config realm). **Prouvé** : la page de login charge `alliance.css` + (HTTP 200) + le `logo.svg` (200), `loginTheme=alliance-boreale` actif sur `chezlepro`. - **Soumission courriel `:587` interne (authentifiée) — la boucle souveraine est bouclée.** Postfix (`edge-mta`) sert la **soumission `:587`** (bloc `master.cf` : STARTTLS requis, `SMTP AUTH`, seuls les authentifiés relaient) ; l'auth SASL est **déléguée à Dovecot** (`infra-mail`, passdb LDAP diff --git a/roles/serveur_keycloak/defaults/main.yml b/roles/serveur_keycloak/defaults/main.yml index 6bedeab..a3fa8f1 100644 --- a/roles/serveur_keycloak/defaults/main.yml +++ b/roles/serveur_keycloak/defaults/main.yml @@ -25,6 +25,8 @@ serveur_keycloak_admin_password: "{{ vault_keycloak_admin | default('') }}" # r # Requiert client_pki sur ce nœud (racine step_ca dans le bundle système pour LDAPS). serveur_keycloak_ldap_federation: true serveur_keycloak_realm: "chezlepro" +# Thème de login du realm (déployé depuis files/themes/). Vide = thème Keycloak par défaut. +serveur_keycloak_login_theme: "" serveur_keycloak_ldap_nom: "openldap" # Connexion à l'annuaire (url, users_dn, bind_dn, bind_password) : fournie par le rôle # partagé resoudre_annuaire (voir tasks/main.yml « Adopter la connexion annuaire »). diff --git a/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/css/alliance.css b/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/css/alliance.css new file mode 100644 index 0000000..6719d43 --- /dev/null +++ b/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/css/alliance.css @@ -0,0 +1,121 @@ +/* ========================================================================= + Alliance Boréale — thème de connexion Keycloak + Identité : aurore boréale · étoiles · constellation · ciel nocturne souverain. + Police système (souveraineté, aucune dépendance externe). + ========================================================================= */ +:root { + --bg: #05060f; + --bg-2: #0a0d24; + --ink: #e9ecff; + --ink-dim: #99a1c9; + --border: rgba(255, 255, 255, 0.10); + --panel: rgba(255, 255, 255, 0.05); + --aurora-teal: #4fe3c1; + --aurora-cyan: #56c2ff; + --aurora-violet: #a98bff; + --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, + Ubuntu, Cantarell, "Noto Sans", "Helvetica Neue", Arial, sans-serif; +} + +/* ---------- Ciel nocturne : aurore en fond ---------- */ +html { height: 100%; } +body.login-pf, +body { + height: 100%; + font-family: var(--font); + color: var(--ink); + background: + radial-gradient(1200px 700px at 80% -10%, #131a44 0%, transparent 60%), + radial-gradient(900px 600px at 10% 0%, #0e1640 0%, transparent 55%), + linear-gradient(180deg, var(--bg-2) 0%, var(--bg) 70%) fixed; +} +.login-pf-page { padding-top: 40px; } + +/* ---------- En-tête + logo étoile aurore ---------- */ +#kc-header, +#kc-header-wrapper { + color: var(--ink); + font-size: 1.6rem; + font-weight: 600; + letter-spacing: 0.5px; + text-transform: none; +} +.login-pf-page .login-pf-header { + text-align: center; +} +.login-pf-page .login-pf-header::before { + content: ""; + display: block; + width: 84px; + height: 84px; + margin: 0 auto 18px; + background: url("../img/logo.svg") center / contain no-repeat; + filter: drop-shadow(0 0 22px rgba(86, 194, 255, 0.5)); +} + +/* ---------- Carte de connexion (glassmorphism) ---------- */ +.card-pf { + background: var(--panel); + border: 1px solid var(--border); + border-radius: 16px; + box-shadow: 0 18px 50px rgba(0, 0, 0, 0.45); + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); + padding: 2rem 2.2rem 2.4rem; +} + +/* ---------- Titres, libellés, texte ---------- */ +#kc-page-title, +.login-pf-page .login-pf-signup a, +label, +.control-label, +#kc-form-options, +.login-pf-page label { color: var(--ink); } +.login-pf-page .login-pf-header h1 { color: var(--ink); } +p, .instruction, #kc-info-message { color: var(--ink-dim); } + +/* ---------- Champs ---------- */ +input.form-control, +.pf-c-form-control, +.form-control { + background: rgba(255, 255, 255, 0.06); + border: 1px solid rgba(255, 255, 255, 0.14); + color: var(--ink); + border-radius: 10px; +} +input.form-control:focus, +.form-control:focus { + border-color: var(--aurora-cyan); + box-shadow: 0 0 0 3px rgba(86, 194, 255, 0.25); + background: rgba(255, 255, 255, 0.09); +} +input.form-control::placeholder { color: var(--ink-dim); } + +/* ---------- Bouton primaire : ruban d'aurore ---------- */ +.btn-primary, +input.btn-primary, +.pf-c-button.pf-m-primary, +#kc-login { + background: linear-gradient(100deg, var(--aurora-teal), var(--aurora-cyan)) !important; + color: #04121a !important; + border: none !important; + border-radius: 999px !important; + font-weight: 600 !important; + box-shadow: 0 10px 30px rgba(79, 227, 193, 0.28); + transition: transform 0.15s ease, box-shadow 0.2s ease; +} +.btn-primary:hover, +#kc-login:hover { + transform: translateY(-2px); + box-shadow: 0 14px 38px rgba(86, 194, 255, 0.4); +} + +/* ---------- Liens ---------- */ +a, a:visited { color: var(--aurora-cyan); } +a:hover { color: var(--aurora-violet); } + +/* ---------- Alertes ---------- */ +.alert { border-radius: 12px; border: 1px solid var(--border); } + +/* ---------- Bas de page ---------- */ +#kc-info, #kc-info-wrapper { color: var(--ink-dim); } diff --git a/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/img/logo.svg b/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/img/logo.svg new file mode 100644 index 0000000..057b7e0 --- /dev/null +++ b/roles/serveur_keycloak/files/themes/alliance-boreale/login/resources/img/logo.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/roles/serveur_keycloak/files/themes/alliance-boreale/login/theme.properties b/roles/serveur_keycloak/files/themes/alliance-boreale/login/theme.properties new file mode 100644 index 0000000..eb8f547 --- /dev/null +++ b/roles/serveur_keycloak/files/themes/alliance-boreale/login/theme.properties @@ -0,0 +1,3 @@ +parent=keycloak +import=common/keycloak +styles=css/login.css css/alliance.css diff --git a/roles/serveur_keycloak/tasks/main.yml b/roles/serveur_keycloak/tasks/main.yml index 73b05c4..662372b 100644 --- a/roles/serveur_keycloak/tasks/main.yml +++ b/roles/serveur_keycloak/tasks/main.yml @@ -117,6 +117,16 @@ mode: "0644" notify: Redemarrer keycloak +- name: Deployer les themes Set-OPS (identite Alliance Boreale) + ansible.builtin.copy: + src: themes/ + dest: "{{ serveur_keycloak_home }}/themes/" + owner: "{{ serveur_keycloak_utilisateur }}" + group: "{{ serveur_keycloak_utilisateur }}" + mode: "0644" + directory_mode: "0755" + notify: Redemarrer keycloak + - name: Activer et demarrer keycloak when: not ansible_check_mode ansible.builtin.systemd: @@ -125,6 +135,9 @@ state: started daemon_reload: true +- name: Appliquer le theme (recharger Keycloak avant la config du realm) + ansible.builtin.meta: flush_handlers + - name: Configurer la federation LDAP (realm + provider OpenLDAP) ansible.builtin.include_tasks: federation-ldap.yml when: serveur_keycloak_ldap_federation | bool @@ -132,3 +145,27 @@ - name: Enregistrer les clients OIDC applicatifs ansible.builtin.include_tasks: clients-oidc.yml when: serveur_keycloak_clients | length > 0 + +- name: Definir le theme de login du realm (identite Alliance Boreale) + ansible.builtin.shell: + executable: /bin/bash + cmd: | + set -euo pipefail + KC={{ serveur_keycloak_home }}/bin/kcadm.sh + "$KC" config credentials --server http://localhost:8080 --realm master \ + --user {{ serveur_keycloak_admin_user }} --password "$KC_ADMIN_PW" >/dev/null + if "$KC" get realms/{{ serveur_keycloak_realm }} --fields loginTheme 2>/dev/null \ + | grep -q '"{{ serveur_keycloak_login_theme }}"'; then + echo SETOPS_OK + else + "$KC" update realms/{{ serveur_keycloak_realm }} \ + -s loginTheme={{ serveur_keycloak_login_theme }} >/dev/null + echo SETOPS_CHANGED + fi + environment: + KC_ADMIN_PW: "{{ serveur_keycloak_admin_password }}" + register: serveur_keycloak_theme_res + changed_when: "'SETOPS_CHANGED' in serveur_keycloak_theme_res.stdout" + when: + - serveur_keycloak_login_theme | length > 0 + - not ansible_check_mode