chore: nettoyage racine - suppression docs/scripts obsoletes, mise a jour pom.xml et .gitignore
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -28,7 +28,8 @@
|
||||
"Bash(find:*)",
|
||||
"Bash(powershell -ExecutionPolicy Bypass -File verify-keycloak-config.ps1)",
|
||||
"Bash(powershell.exe -ExecutionPolicy Bypass -File verify-keycloak-config.ps1)",
|
||||
"Bash(mvn clean install:*)"
|
||||
"Bash(mvn clean install:*)",
|
||||
"Bash(mvn test:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
||||
244
.gitignore
vendored
244
.gitignore
vendored
@@ -1,4 +1,10 @@
|
||||
# ============================================================================
|
||||
# Lions User Manager - .gitignore
|
||||
# ============================================================================
|
||||
|
||||
# ==========================
|
||||
# Maven
|
||||
# ==========================
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
@@ -10,22 +16,31 @@ buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
# Eclipse
|
||||
# ==========================
|
||||
# Build artifacts
|
||||
# ==========================
|
||||
*.class
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
*.idx
|
||||
|
||||
# ==========================
|
||||
# IDE - Eclipse
|
||||
# ==========================
|
||||
.project
|
||||
.classpath
|
||||
.settings/
|
||||
.metadata/
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.loadpath
|
||||
.recommenders
|
||||
|
||||
# IntelliJ IDEA
|
||||
# ==========================
|
||||
# IDE - IntelliJ IDEA
|
||||
# ==========================
|
||||
.idea/
|
||||
*.iws
|
||||
*.iml
|
||||
@@ -33,7 +48,9 @@ local.properties
|
||||
out/
|
||||
.idea_modules/
|
||||
|
||||
# NetBeans
|
||||
# ==========================
|
||||
# IDE - NetBeans
|
||||
# ==========================
|
||||
nbproject/private/
|
||||
build/
|
||||
nbbuild/
|
||||
@@ -41,12 +58,22 @@ dist/
|
||||
nbdist/
|
||||
.nb-gradle/
|
||||
|
||||
# VS Code
|
||||
# ==========================
|
||||
# IDE - VS Code
|
||||
# ==========================
|
||||
.vscode/
|
||||
*.code-workspace
|
||||
.history/
|
||||
|
||||
# ==========================
|
||||
# IDE - Other
|
||||
# ==========================
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# ==========================
|
||||
# OS Files
|
||||
# ==========================
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
@@ -57,35 +84,54 @@ Thumbs.db
|
||||
Desktop.ini
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Logs
|
||||
# ==========================
|
||||
# JVM Logs & Crashes
|
||||
# ==========================
|
||||
*.log
|
||||
logs/
|
||||
*.log.*
|
||||
quarkus.log
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
*~
|
||||
.cache/
|
||||
|
||||
# Build artifacts
|
||||
*.class
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# JVM crash logs
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
||||
# Quarkus
|
||||
.quarkus/
|
||||
# ==========================
|
||||
# Test Output
|
||||
# ==========================
|
||||
test_output*.txt
|
||||
surefire-reports/
|
||||
failsafe-reports/
|
||||
*.dump
|
||||
*.dumpstream
|
||||
coverage/
|
||||
.nyc_output/
|
||||
test-results/
|
||||
junit.xml
|
||||
.jacoco/
|
||||
jacoco.exec
|
||||
|
||||
# Node (si utilisé pour le build frontend)
|
||||
# ==========================
|
||||
# Temporary Files
|
||||
# ==========================
|
||||
*.tmp
|
||||
*.temp
|
||||
*.bak
|
||||
*.swp
|
||||
*.orig
|
||||
*~
|
||||
.cache/
|
||||
|
||||
# ==========================
|
||||
# Quarkus
|
||||
# ==========================
|
||||
.quarkus/
|
||||
quarkus-app/
|
||||
quarkus-run.jar
|
||||
quarkus-*.dat
|
||||
.devservices/
|
||||
|
||||
# ==========================
|
||||
# Node.js (si build frontend)
|
||||
# ==========================
|
||||
node_modules/
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
@@ -93,103 +139,55 @@ yarn-error.log*
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
||||
# Documentation générée
|
||||
docs/generated/
|
||||
site/
|
||||
|
||||
# Fichiers de configuration locaux
|
||||
*.local
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Fichiers de test
|
||||
coverage/
|
||||
.nyc_output/
|
||||
test-results/
|
||||
junit.xml
|
||||
|
||||
# Fichiers de backup
|
||||
*.backup
|
||||
*.old
|
||||
|
||||
# Credentials et tokens (IMPORTANT!)
|
||||
# ==========================
|
||||
# Credentials & Secrets
|
||||
# ==========================
|
||||
token.json
|
||||
token.txt
|
||||
*.token
|
||||
|
||||
# Database
|
||||
*.db
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
|
||||
# IDE specific
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
|
||||
# Test coverage
|
||||
*.cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
|
||||
# Sass
|
||||
.sass-cache/
|
||||
*.css.map
|
||||
|
||||
# Scripts de configuration sensibles
|
||||
*.local.json
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
*-credentials.ps1
|
||||
*-secrets.ps1
|
||||
*-password.ps1
|
||||
|
||||
# Documentation de développement/session (garder uniquement README.md)
|
||||
*_HANDOFF_*.md
|
||||
*_COMPLETE*.md
|
||||
*_GUIDE*.md
|
||||
*_REPORT*.md
|
||||
*_SUMMARY*.md
|
||||
*_AUDIT*.md
|
||||
*_DEBUG*.md
|
||||
*_FINAL*.md
|
||||
*_MIGRATION*.md
|
||||
*_OPTIMISATION*.md
|
||||
*_SESSION*.md
|
||||
*_DEMARRAGE*.md
|
||||
*_DEPLOYMENT*.md
|
||||
*_DIAGNOSTIC*.md
|
||||
*_IMPLEMENTATION*.md
|
||||
*_INTEGRATION*.md
|
||||
*_INSTRUCTIONS*.md
|
||||
*_KEYCLOAK*.md
|
||||
*_OIDC*.md
|
||||
*_PREPARATION*.md
|
||||
*_PROGRESS*.md
|
||||
*_REFACTORING*.md
|
||||
*_RESTRUCTURATION*.md
|
||||
*_RESUME*.md
|
||||
*_SOLUTION*.md
|
||||
*_TESTS*.md
|
||||
*_CORRECTIONS*.md
|
||||
*_ETAT*.md
|
||||
*_EXPLICATION*.md
|
||||
*_ORGANISATION*.md
|
||||
*_PAGES*.md
|
||||
ANALYSE_*.md
|
||||
BOUTONS_*.md
|
||||
COMPOSANTS_*.md
|
||||
CONFIGURATION_*.md
|
||||
CORRECTIFS_*.md
|
||||
CORRECTION_*.md
|
||||
COVERAGE_*.md
|
||||
FREYA_*.md
|
||||
LANCEMENT_*.md
|
||||
PAGE_*.md
|
||||
PHASE_*.md
|
||||
README_DEMARRAGE.md
|
||||
README_PORTS.md
|
||||
REST_*.md
|
||||
UI_*.md
|
||||
# ==========================
|
||||
# Application Local Config
|
||||
# ==========================
|
||||
application-local.properties
|
||||
application-*.local.properties
|
||||
|
||||
# Fichiers de test et de démonstration
|
||||
**/FreyaShowcaseBean.java
|
||||
**/freya-showcase.xhtml
|
||||
# ==========================
|
||||
# Database
|
||||
# ==========================
|
||||
*.db
|
||||
*.sqlite
|
||||
*.sqlite3
|
||||
|
||||
# ==========================
|
||||
# Generated
|
||||
# ==========================
|
||||
generated-sources/
|
||||
generated-test-sources/
|
||||
maven-status/
|
||||
build-metrics.json
|
||||
docs/generated/
|
||||
site/
|
||||
|
||||
# ==========================
|
||||
# Sass
|
||||
# ==========================
|
||||
.sass-cache/
|
||||
*.css.map
|
||||
|
||||
# ==========================
|
||||
# Cleanup Script (auto)
|
||||
# ==========================
|
||||
cleanup.ps1
|
||||
|
||||
# ==========================
|
||||
# AI Agent
|
||||
# ==========================
|
||||
.claude/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,505 +0,0 @@
|
||||
# 📊 Analyse et Plan d'Optimisation - lions-user-manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
**Objectif**: Optimiser lions-user-manager pour en faire un module réutilisable intégré à l'écosystème lionsdev et unionflow
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Résumé Exécutif
|
||||
|
||||
Le projet **lions-user-manager** est un module de gestion centralisée des utilisateurs Keycloak qui doit être:
|
||||
- ✅ **Réutilisable** par tous les modules nécessitant la gestion des utilisateurs
|
||||
- ✅ **Intégré** à l'écosystème lionsdev
|
||||
- ✅ **Intégré** à unionflow et son menu "Gestion des Membres"
|
||||
- ✅ **Optimisé** avec composants réutilisables à l'instar de unionflow
|
||||
|
||||
**Statut actuel**: 🟡 40% complété - Backend API fonctionnel, client UI à développer
|
||||
|
||||
---
|
||||
|
||||
## 📋 État Actuel du Projet
|
||||
|
||||
### ✅ Points Forts
|
||||
|
||||
1. **Architecture Multi-Modules Solide**
|
||||
- `lions-user-manager-server-api` (100% ✅)
|
||||
- `lions-user-manager-server-impl-quarkus` (60% 🔄)
|
||||
- `lions-user-manager-client-quarkus-primefaces-freya` (0% ⏳)
|
||||
|
||||
2. **Backend API Complet**
|
||||
- UserService avec 25+ méthodes
|
||||
- Keycloak Admin Client avec résilience (Circuit Breaker, Retry)
|
||||
- Health checks et métriques Prometheus
|
||||
- Configuration dev/prod séparée
|
||||
|
||||
3. **Sécurité et Compliance**
|
||||
- ZÉRO accès direct DB Keycloak (Admin API uniquement)
|
||||
- OIDC avec Keycloak
|
||||
- @RolesAllowed sur tous les endpoints
|
||||
- Audit trail complet
|
||||
|
||||
### ⚠️ Points à Améliorer
|
||||
|
||||
1. **Module Client Inexistant** (0%)
|
||||
- Pas de pages XHTML
|
||||
- Pas de composants réutilisables
|
||||
- Pas d'intégration avec unionflow
|
||||
|
||||
2. **Manque de Réutilisabilité**
|
||||
- Pas de composants UI réutilisables
|
||||
- Pas de patterns WOU/DRY comme unionflow
|
||||
- Pas d'intégration avec d'autres modules
|
||||
|
||||
3. **Intégration Écosystème**
|
||||
- Pas de dépendance Maven vers unionflow
|
||||
- Pas d'intégration au menu unionflow
|
||||
- Pas de partage de composants communs
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Analyse Comparative avec UnionFlow
|
||||
|
||||
### Patterns Réutilisables Identifiés dans UnionFlow
|
||||
|
||||
#### 1. **Composants UI Réutilisables** (`templates/components/`)
|
||||
|
||||
UnionFlow utilise une architecture de composants modulaires:
|
||||
|
||||
```
|
||||
templates/components/
|
||||
├── buttons/ # Boutons réutilisables (primary, secondary, info, etc.)
|
||||
├── cards/ # Cartes (kpi-card, stat-card, etc.)
|
||||
├── columns/ # Colonnes de tableaux (actions, logo, tag, etc.)
|
||||
├── dialogs/ # Dialogs (confirm, form)
|
||||
├── forms/ # Champs de formulaire réutilisables
|
||||
├── layout/ # Layout (menu, topbar, footer)
|
||||
└── tables/ # Composants de tableaux
|
||||
```
|
||||
|
||||
**Pattern WOU/DRY** (Write Once Use / Don't Repeat Yourself):
|
||||
- Chaque composant est paramétrable via `<ui:param>`
|
||||
- Documentation inline dans chaque composant
|
||||
- Réutilisation maximale
|
||||
|
||||
#### 2. **Structure des Beans**
|
||||
|
||||
UnionFlow utilise des patterns constants:
|
||||
- Constantes de navigation outcomes (WOU/DRY)
|
||||
- Injection de services REST Client
|
||||
- Beans @ViewScoped ou @SessionScoped
|
||||
- Logging structuré
|
||||
|
||||
#### 3. **Menu Intégré**
|
||||
|
||||
Le menu unionflow (`menu.xhtml`) contient:
|
||||
- Section "Gestion des Membres" (lignes 44-52)
|
||||
- Structure modulaire avec `<p:submenu>`
|
||||
- Navigation via `outcome` vers les pages
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Plan d'Optimisation
|
||||
|
||||
### Phase 1: Création de Composants Réutilisables (PRIORITÉ 1)
|
||||
|
||||
#### 1.1 Structure de Composants UI
|
||||
|
||||
Créer la structure suivante dans `lions-user-manager-client-quarkus-primefaces-freya`:
|
||||
|
||||
```
|
||||
src/main/resources/META-INF/resources/templates/components/
|
||||
├── user-management/
|
||||
│ ├── user-card.xhtml # Carte utilisateur réutilisable
|
||||
│ ├── user-form.xhtml # Formulaire utilisateur
|
||||
│ ├── user-search-bar.xhtml # Barre de recherche
|
||||
│ ├── user-actions.xhtml # Actions utilisateur (activate, delete, etc.)
|
||||
│ └── user-role-badge.xhtml # Badge de rôle
|
||||
├── role-management/
|
||||
│ ├── role-card.xhtml
|
||||
│ ├── role-form.xhtml
|
||||
│ └── role-assignment.xhtml
|
||||
└── audit/
|
||||
├── audit-log-row.xhtml
|
||||
└── audit-stats-card.xhtml
|
||||
```
|
||||
|
||||
#### 1.2 Composants Génériques Réutilisables
|
||||
|
||||
Créer des composants génériques inspirés de unionflow:
|
||||
|
||||
```
|
||||
templates/components/
|
||||
├── buttons/
|
||||
│ ├── button-user-action.xhtml # Bouton action utilisateur
|
||||
│ └── button-role-action.xhtml # Bouton action rôle
|
||||
├── cards/
|
||||
│ ├── user-stat-card.xhtml # Carte statistique utilisateur
|
||||
│ └── role-stat-card.xhtml # Carte statistique rôle
|
||||
├── forms/
|
||||
│ ├── user-form-field.xhtml # Champ formulaire utilisateur
|
||||
│ └── role-form-field.xhtml # Champ formulaire rôle
|
||||
└── tables/
|
||||
├── user-data-table.xhtml # Tableau utilisateurs
|
||||
└── role-data-table.xhtml # Tableau rôles
|
||||
```
|
||||
|
||||
### Phase 2: Intégration avec UnionFlow (PRIORITÉ 2)
|
||||
|
||||
#### 2.1 Dépendance Maven
|
||||
|
||||
Ajouter `lions-user-manager-server-api` comme dépendance dans unionflow:
|
||||
|
||||
**Dans `unionflow/pom.xml`**:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>dev.lions.user.manager</groupId>
|
||||
<artifactId>lions-user-manager-server-api</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
**Dans `unionflow-client-quarkus-primefaces-freya/pom.xml`**:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>dev.lions.user.manager</groupId>
|
||||
<artifactId>lions-user-manager-client-quarkus-primefaces-freya</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
#### 2.2 Intégration au Menu UnionFlow
|
||||
|
||||
Modifier `unionflow/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/layout/menu.xhtml`:
|
||||
|
||||
**Section "Gestion des Membres" (lignes 44-52)** - À ENRICHIR:
|
||||
|
||||
```xhtml
|
||||
<!-- Gestion des Membres -->
|
||||
<p:submenu id="m_membres" label="Gestion des Membres" icon="pi pi-users">
|
||||
<!-- Pages UnionFlow existantes -->
|
||||
<p:menuitem id="m_inscription" value="Nouvelle Inscription" icon="pi pi-user-plus" outcome="/pages/secure/membre/inscription" />
|
||||
<p:menuitem id="m_liste_membres" value="Liste des Membres" icon="pi pi-list" outcome="/pages/secure/membre/liste" />
|
||||
<p:menuitem id="m_recherche_membres" value="Recherche Avancée" icon="pi pi-search" outcome="/pages/secure/membre/recherche" />
|
||||
<p:menuitem id="m_profil_membre" value="Mon Profil" icon="pi pi-user" outcome="/pages/secure/membre/profil" />
|
||||
|
||||
<!-- NOUVEAU: Sous-menu Gestion Utilisateurs Keycloak (lions-user-manager) -->
|
||||
<p:separator />
|
||||
<p:menuitem id="m_gestion_utilisateurs" value="Gestion Utilisateurs" icon="pi pi-users-cog" outcome="/pages/user-manager/users/list" />
|
||||
<p:menuitem id="m_gestion_roles" value="Gestion Rôles" icon="pi pi-shield" outcome="/pages/user-manager/roles/list" />
|
||||
<p:menuitem id="m_audit_utilisateurs" value="Audit Utilisateurs" icon="pi pi-history" outcome="/pages/user-manager/audit/logs" />
|
||||
<p:menuitem id="m_sync_keycloak" value="Synchronisation Keycloak" icon="pi pi-sync" outcome="/pages/user-manager/sync/dashboard" />
|
||||
|
||||
<!-- Pages UnionFlow existantes -->
|
||||
<p:separator />
|
||||
<p:menuitem id="m_import_membres" value="Import en Masse" icon="pi pi-upload" url="#" />
|
||||
<p:menuitem id="m_export_membres" value="Export Membres" icon="pi pi-download" url="#" />
|
||||
</p:submenu>
|
||||
```
|
||||
|
||||
#### 2.3 Pages d'Intégration
|
||||
|
||||
Créer des pages dans unionflow qui utilisent les composants de lions-user-manager:
|
||||
|
||||
```
|
||||
unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/user-manager/
|
||||
├── users/
|
||||
│ ├── list.xhtml # Liste utilisateurs (utilise user-data-table.xhtml)
|
||||
│ ├── search.xhtml # Recherche (utilise user-search-bar.xhtml)
|
||||
│ ├── create.xhtml # Création (utilise user-form.xhtml)
|
||||
│ └── profile.xhtml # Profil (utilise user-card.xhtml)
|
||||
├── roles/
|
||||
│ ├── list.xhtml
|
||||
│ ├── create.xhtml
|
||||
│ └── assign.xhtml
|
||||
└── audit/
|
||||
├── logs.xhtml
|
||||
└── stats.xhtml
|
||||
```
|
||||
|
||||
### Phase 3: Module Réutilisable pour Écosystème LionsDev (PRIORITÉ 3)
|
||||
|
||||
#### 3.1 Publication Maven
|
||||
|
||||
Publier les modules dans le repository Maven lionsdev:
|
||||
|
||||
```xml
|
||||
<!-- Configuration dans pom.xml parent -->
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>lions-maven-repo</id>
|
||||
<url>https://git.lions.dev/lionsdev/btpxpress-maven-repo/raw/branch/main</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
```
|
||||
|
||||
#### 3.2 Documentation d'Intégration
|
||||
|
||||
Créer `docs/INTEGRATION_GUIDE.md` avec:
|
||||
- Guide d'ajout de la dépendance
|
||||
- Exemples d'utilisation des composants
|
||||
- Configuration requise
|
||||
- Exemples d'intégration avec unionflow, btpxpress, etc.
|
||||
|
||||
#### 3.3 API Publique Documentée
|
||||
|
||||
S'assurer que:
|
||||
- Toutes les interfaces de services sont publiques
|
||||
- Documentation OpenAPI complète
|
||||
- Exemples d'utilisation dans la documentation
|
||||
|
||||
### Phase 4: Optimisation des Composants (PRIORITÉ 4)
|
||||
|
||||
#### 4.1 Pattern de Composants Réutilisables
|
||||
|
||||
Chaque composant doit suivre le pattern unionflow:
|
||||
|
||||
**Exemple: `user-card.xhtml`**
|
||||
```xhtml
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!--
|
||||
Composant réutilisable: Carte Utilisateur
|
||||
|
||||
Paramètres:
|
||||
- user: UserDTO (requis)
|
||||
- showActions: Boolean (défaut: true)
|
||||
- showRoles: Boolean (défaut: true)
|
||||
- clickable: Boolean (défaut: true)
|
||||
- outcome: String (optionnel, page de destination)
|
||||
|
||||
Exemple:
|
||||
<ui:include src="/templates/components/user-management/user-card.xhtml">
|
||||
<ui:param name="user" value="#{userBean.selectedUser}" />
|
||||
<ui:param name="showActions" value="true" />
|
||||
<ui:param name="outcome" value="/pages/user-manager/users/profile" />
|
||||
</ui:include>
|
||||
-->
|
||||
|
||||
<p:card>
|
||||
<!-- Contenu de la carte -->
|
||||
</p:card>
|
||||
</ui:composition>
|
||||
```
|
||||
|
||||
#### 4.2 Beans Réutilisables
|
||||
|
||||
Créer des beans de base réutilisables:
|
||||
|
||||
```java
|
||||
@Named("userManagerBaseBean")
|
||||
@ApplicationScoped
|
||||
public class UserManagerBaseBean {
|
||||
// Constantes communes
|
||||
// Méthodes utilitaires
|
||||
// Gestion d'erreurs
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📐 Architecture Cible
|
||||
|
||||
### Structure Modulaire
|
||||
|
||||
```
|
||||
lions-user-manager/
|
||||
├── lions-user-manager-server-api/ # Module API (JAR réutilisable)
|
||||
├── lions-user-manager-server-impl-quarkus/ # Implémentation serveur
|
||||
├── lions-user-manager-client-quarkus-primefaces-freya/ # Client UI avec composants
|
||||
│ └── src/main/resources/META-INF/resources/
|
||||
│ └── templates/components/
|
||||
│ ├── user-management/ # Composants spécifiques utilisateurs
|
||||
│ ├── role-management/ # Composants spécifiques rôles
|
||||
│ ├── audit/ # Composants audit
|
||||
│ └── shared/ # Composants partagés (buttons, cards, etc.)
|
||||
└── docs/
|
||||
└── INTEGRATION_GUIDE.md # Guide d'intégration
|
||||
```
|
||||
|
||||
### Intégration avec UnionFlow
|
||||
|
||||
```
|
||||
unionflow/
|
||||
└── unionflow-client-quarkus-primefaces-freya/
|
||||
├── pom.xml # Dépendance vers lions-user-manager-client
|
||||
└── src/main/resources/META-INF/resources/
|
||||
├── templates/components/layout/
|
||||
│ └── menu.xhtml # Menu enrichi avec gestion utilisateurs
|
||||
└── pages/user-manager/ # Pages utilisant les composants lions-user-manager
|
||||
├── users/
|
||||
├── roles/
|
||||
└── audit/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Plan d'Implémentation
|
||||
|
||||
### Étape 1: Création des Composants Réutilisables (2-3 jours)
|
||||
|
||||
**Tâches**:
|
||||
1. Créer la structure `templates/components/`
|
||||
2. Implémenter les composants user-management (5 composants)
|
||||
3. Implémenter les composants role-management (3 composants)
|
||||
4. Implémenter les composants audit (2 composants)
|
||||
5. Implémenter les composants shared (buttons, cards, forms, tables)
|
||||
|
||||
**Livrables**:
|
||||
- 15+ composants XHTML réutilisables
|
||||
- Documentation inline de chaque composant
|
||||
- Exemples d'utilisation
|
||||
|
||||
### Étape 2: Développement du Module Client (3-4 jours)
|
||||
|
||||
**Tâches**:
|
||||
1. Compléter le POM.xml avec Freya Theme
|
||||
2. Créer les REST Clients
|
||||
3. Créer les Beans JSF (10+ beans)
|
||||
4. Créer les pages XHTML utilisant les composants (15+ pages)
|
||||
5. Implémenter le layout avec menu
|
||||
|
||||
**Livrables**:
|
||||
- Module client fonctionnel
|
||||
- Interface utilisateur complète
|
||||
- Intégration OIDC
|
||||
|
||||
### Étape 3: Intégration avec UnionFlow (1-2 jours)
|
||||
|
||||
**Tâches**:
|
||||
1. Ajouter dépendance Maven dans unionflow
|
||||
2. Enrichir le menu unionflow
|
||||
3. Créer les pages d'intégration dans unionflow
|
||||
4. Tester l'intégration
|
||||
|
||||
**Livrables**:
|
||||
- Menu unionflow enrichi
|
||||
- Pages d'intégration fonctionnelles
|
||||
- Documentation d'intégration
|
||||
|
||||
### Étape 4: Publication et Documentation (1 jour)
|
||||
|
||||
**Tâches**:
|
||||
1. Publier les modules dans le repository Maven
|
||||
2. Créer le guide d'intégration
|
||||
3. Documenter les composants réutilisables
|
||||
4. Créer des exemples d'utilisation
|
||||
|
||||
**Livrables**:
|
||||
- Modules publiés dans Maven
|
||||
- Documentation complète
|
||||
- Guide d'intégration
|
||||
|
||||
---
|
||||
|
||||
## 📊 Métriques de Succès
|
||||
|
||||
### Réutilisabilité
|
||||
- ✅ Composants réutilisables dans au moins 2 projets (unionflow, btpxpress)
|
||||
- ✅ Réduction de 50%+ du code dupliqué
|
||||
- ✅ Temps de développement réduit de 30%+ pour nouveaux projets
|
||||
|
||||
### Intégration
|
||||
- ✅ Menu unionflow enrichi avec gestion utilisateurs
|
||||
- ✅ Pages d'intégration fonctionnelles
|
||||
- ✅ Pas de conflits de dépendances
|
||||
|
||||
### Qualité
|
||||
- ✅ Documentation complète de tous les composants
|
||||
- ✅ Exemples d'utilisation pour chaque composant
|
||||
- ✅ Tests d'intégration passants
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration Technique
|
||||
|
||||
### Dépendances Maven Requises
|
||||
|
||||
**Pour utiliser lions-user-manager dans un projet**:
|
||||
|
||||
```xml
|
||||
<!-- Dans le pom.xml du projet -->
|
||||
<dependency>
|
||||
<groupId>dev.lions.user.manager</groupId>
|
||||
<artifactId>lions-user-manager-server-api</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Pour l'UI (si PrimeFaces) -->
|
||||
<dependency>
|
||||
<groupId>dev.lions.user.manager</groupId>
|
||||
<artifactId>lions-user-manager-client-quarkus-primefaces-freya</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### Configuration Application
|
||||
|
||||
**Dans `application.properties`**:
|
||||
```properties
|
||||
# URL du serveur lions-user-manager
|
||||
lions.user.manager.backend.url=http://localhost:8080
|
||||
|
||||
# Configuration Keycloak
|
||||
lions.user.manager.keycloak.server-url=${KEYCLOAK_SERVER_URL}
|
||||
lions.user.manager.keycloak.realm=${KEYCLOAK_REALM}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Checklist d'Optimisation
|
||||
|
||||
### Composants Réutilisables
|
||||
- [ ] Structure `templates/components/` créée
|
||||
- [ ] Composants user-management (5 composants)
|
||||
- [ ] Composants role-management (3 composants)
|
||||
- [ ] Composants audit (2 composants)
|
||||
- [ ] Composants shared (buttons, cards, forms, tables)
|
||||
- [ ] Documentation inline de chaque composant
|
||||
|
||||
### Module Client
|
||||
- [ ] POM.xml complété avec Freya Theme
|
||||
- [ ] REST Clients créés
|
||||
- [ ] Beans JSF créés (10+)
|
||||
- [ ] Pages XHTML créées (15+)
|
||||
- [ ] Layout et menu implémentés
|
||||
|
||||
### Intégration UnionFlow
|
||||
- [ ] Dépendance Maven ajoutée
|
||||
- [ ] Menu unionflow enrichi
|
||||
- [ ] Pages d'intégration créées
|
||||
- [ ] Tests d'intégration passants
|
||||
|
||||
### Publication
|
||||
- [ ] Modules publiés dans Maven
|
||||
- [ ] Guide d'intégration créé
|
||||
- [ ] Documentation complète
|
||||
- [ ] Exemples d'utilisation
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Prochaines Actions Immédiates
|
||||
|
||||
1. **Créer la structure des composants réutilisables**
|
||||
- Dossier `templates/components/`
|
||||
- Premier composant: `user-card.xhtml`
|
||||
|
||||
2. **Compléter le module client**
|
||||
- REST Clients
|
||||
- Beans JSF
|
||||
- Pages XHTML
|
||||
|
||||
3. **Intégrer avec unionflow**
|
||||
- Ajouter dépendance
|
||||
- Enrichir menu
|
||||
- Créer pages d'intégration
|
||||
|
||||
---
|
||||
|
||||
**Document créé le**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
**Auteur**: Auto (Cursor AI)
|
||||
|
||||
@@ -1,500 +0,0 @@
|
||||
# 🔍 Audit Production - Lions User Manager
|
||||
|
||||
**Date**: 2025-01-15
|
||||
**Version**: 1.0.0
|
||||
**Statut**: ⚠️ **Configuration pré-déploiement requise** (voir `PREPARATION_PRODUCTION.md`)
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table des Matières
|
||||
|
||||
1. [Vue d'ensemble](#vue-densemble)
|
||||
2. [Sécurité](#sécurité)
|
||||
3. [Configuration](#configuration)
|
||||
4. [Performance](#performance)
|
||||
5. [Observabilité](#observabilité)
|
||||
6. [Résilience](#résilience)
|
||||
7. [Documentation](#documentation)
|
||||
8. [Checklist de Déploiement](#checklist-de-déploiement)
|
||||
9. [Recommandations](#recommandations)
|
||||
|
||||
---
|
||||
|
||||
## 1. Vue d'ensemble
|
||||
|
||||
### ✅ Points Forts
|
||||
|
||||
- ✅ Architecture multi-modules bien structurée
|
||||
- ✅ Authentification OIDC complète et sécurisée
|
||||
- ✅ Gestion des rôles avec `@RolesAllowed` fonctionnelle
|
||||
- ✅ Health checks et métriques Prometheus configurés
|
||||
- ✅ Gestion d'erreurs avec `RestClientExceptionMapper`
|
||||
- ✅ Configuration séparée dev/prod
|
||||
- ✅ Navigation JSF centralisée dans `faces-config.xml`
|
||||
|
||||
### ⚠️ Points d'Attention
|
||||
|
||||
- ✅ Dockerfiles de production créés (basés sur btpxpress)
|
||||
- ⚠️ Helm charts à finaliser pour Kubernetes
|
||||
- ⚠️ Tests unitaires et d'intégration manquants
|
||||
- ✅ Documentation de déploiement mise à jour
|
||||
|
||||
---
|
||||
|
||||
## 2. Sécurité
|
||||
|
||||
### ✅ Authentification & Autorisation
|
||||
|
||||
#### Frontend (Client)
|
||||
- ✅ **OIDC configuré** avec Keycloak
|
||||
- ✅ **Rôles extraits** depuis `realm_access/roles` (access token)
|
||||
- ✅ **Propagation du token** au backend via `bearer-token-propagation=true`
|
||||
- ✅ **Chemins protégés** : `/pages/user-manager/*`
|
||||
- ✅ **Chemins publics** : `/`, `/index.xhtml`, `/auth/*`, `/resources/*`
|
||||
|
||||
**Configuration** (`application.properties`):
|
||||
```properties
|
||||
quarkus.oidc.roles.role-claim-path=realm_access/roles
|
||||
quarkus.oidc.roles.source=accesstoken
|
||||
quarkus.rest-client."lions-user-manager-api".bearer-token-propagation=true
|
||||
```
|
||||
|
||||
#### Backend (Server)
|
||||
- ✅ **OIDC Service Account** configuré
|
||||
- ✅ **`@RolesAllowed`** sur tous les endpoints REST
|
||||
- ✅ **Rôles vérifiés** : `admin`, `user_manager`, `user_viewer`, `auditor`, `sync_manager`, `role_manager`
|
||||
- ✅ **Sécurité proactive** activée en production
|
||||
|
||||
**Endpoints protégés** :
|
||||
- `/api/users/*` : `admin`, `user_manager`, `user_viewer`
|
||||
- `/api/roles/*` : `admin`, `role_manager`, `role_viewer`
|
||||
- `/api/audit/*` : `admin`, `auditor`
|
||||
- `/api/sync/*` : `admin`, `sync_manager`
|
||||
|
||||
### ✅ Secrets & Configuration
|
||||
|
||||
#### Variables d'Environnement Requises (PROD)
|
||||
|
||||
**Frontend** :
|
||||
```bash
|
||||
KEYCLOAK_AUTH_SERVER_URL=https://security.lions.dev/realms/master
|
||||
KEYCLOAK_CLIENT_ID=lions-user-manager-client
|
||||
KEYCLOAK_CLIENT_SECRET=<secret-from-keycloak>
|
||||
OIDC_ENCRYPTION_SECRET=<32-char-secret>
|
||||
LIONS_USER_MANAGER_BACKEND_URL=https://lions-user-manager-api.lions.dev
|
||||
```
|
||||
|
||||
**Backend** :
|
||||
```bash
|
||||
KEYCLOAK_SERVER_URL=https://security.lions.dev
|
||||
KEYCLOAK_ADMIN_USERNAME=<admin-username>
|
||||
KEYCLOAK_ADMIN_PASSWORD=<admin-password>
|
||||
KEYCLOAK_CLIENT_SECRET=<service-account-secret>
|
||||
DB_USERNAME=<audit-db-user>
|
||||
DB_PASSWORD=<audit-db-password>
|
||||
DB_HOST=lions-db.lions.svc.cluster.local
|
||||
DB_PORT=5432
|
||||
DB_NAME=lions_audit
|
||||
SSL_KEYSTORE_FILE=/etc/ssl/keystore.p12
|
||||
SSL_KEYSTORE_PASSWORD=<keystore-password>
|
||||
```
|
||||
|
||||
### ✅ Dockerfiles de Production
|
||||
|
||||
**Frontend** (`lions-user-manager-client-quarkus-primefaces-freya/Dockerfile.prod`) :
|
||||
- ✅ Multi-stage build optimisé
|
||||
- ✅ Image UBI8 OpenJDK 17 (Red Hat)
|
||||
- ✅ Utilisateur non-root (185:185)
|
||||
- ✅ Health checks configurés
|
||||
- ✅ JVM optimisé (G1GC, heap dumps)
|
||||
- ✅ Variables d'environnement pour production
|
||||
|
||||
**Backend** (`lions-user-manager-server-impl-quarkus/Dockerfile.prod`) :
|
||||
- ✅ Multi-stage build optimisé
|
||||
- ✅ Image UBI8 OpenJDK 17 (Red Hat)
|
||||
- ✅ Utilisateur non-root (185:185)
|
||||
- ✅ Health checks configurés
|
||||
- ✅ JVM optimisé (G1GC, heap dumps)
|
||||
- ✅ Configuration Keycloak Admin Client
|
||||
|
||||
### ⚠️ Recommandations Sécurité
|
||||
|
||||
1. **Rotation des secrets** : Implémenter une rotation automatique des secrets Keycloak
|
||||
2. **Rate limiting** : Ajouter rate limiting sur les endpoints sensibles (création utilisateur, reset password)
|
||||
3. **CSRF Protection** : Vérifier que PrimeFaces gère correctement les tokens CSRF
|
||||
4. **Audit des accès** : S'assurer que tous les accès sont loggés (déjà fait via `AuditService`)
|
||||
5. **HTTPS obligatoire** : Vérifier que tous les endpoints sont accessibles uniquement via HTTPS en production
|
||||
6. **Headers de sécurité** : Ajouter un filtre pour les headers de sécurité HTTP (HSTS, CSP, etc.) comme dans btpxpress
|
||||
|
||||
---
|
||||
|
||||
## 3. Configuration
|
||||
|
||||
### ✅ Configuration Production
|
||||
|
||||
#### Frontend (`application-prod.properties`)
|
||||
- ✅ Configuration OIDC avec variables d'environnement
|
||||
- ✅ TLS verification activée (`quarkus.oidc.tls.verification=required`)
|
||||
- ✅ Cookie same-site strict (`quarkus.oidc.authentication.cookie-same-site=strict`)
|
||||
- ✅ PKCE désactivé en prod (non nécessaire avec service account)
|
||||
- ✅ Logging configuré (INFO par défaut)
|
||||
|
||||
#### Backend (`application-prod.properties`)
|
||||
- ✅ Configuration Keycloak Admin Client
|
||||
- ✅ Circuit Breaker activé
|
||||
- ✅ Retry configuré (5 tentatives, 3s délai)
|
||||
- ✅ Database PostgreSQL pour audit
|
||||
- ✅ Flyway migrations activées
|
||||
- ✅ Logging JSON activé
|
||||
- ✅ File logging avec rotation (50M, 30 backups)
|
||||
- ✅ Swagger UI désactivé par défaut
|
||||
- ✅ SSL/TLS configuré
|
||||
|
||||
### ✅ Navigation JSF
|
||||
|
||||
**Fichier** : `faces-config.xml`
|
||||
|
||||
Toutes les navigation-cases sont configurées :
|
||||
- ✅ Dashboard : `/pages/user-manager/dashboard`
|
||||
- ✅ Utilisateurs : list, create, profile, edit
|
||||
- ✅ Rôles : list, assign
|
||||
- ✅ Audit : logs
|
||||
- ✅ Synchronisation : dashboard
|
||||
- ✅ Paramètres : settings
|
||||
|
||||
**Format** : Navigation par outcome ET par chemin direct (ex: `/pages/user-manager/users/list`)
|
||||
|
||||
### ✅ Configuration Production Complète
|
||||
|
||||
**Dockerfiles** :
|
||||
- ✅ `Dockerfile.prod` pour le client (frontend)
|
||||
- ✅ `Dockerfile.prod` pour le serveur (backend)
|
||||
- ✅ Basés sur la structure de btpxpress (UBI8, multi-stage, sécurité)
|
||||
|
||||
**Configuration Kubernetes** :
|
||||
- ⚠️ **Helm Charts** : Structure existe mais templates à finaliser
|
||||
- ⚠️ **ConfigMaps/Secrets** : À définir (voir section Variables d'Environnement)
|
||||
- ⚠️ **Ingress Configuration** : À configurer pour exposition externe (basé sur btpxpress-production.yaml)
|
||||
|
||||
**Référence** : Voir `btpxpress/scripts/kubernetes/btpxpress-production.yaml` pour la structure complète
|
||||
|
||||
---
|
||||
|
||||
## 4. Performance
|
||||
|
||||
### ✅ Optimisations Actuelles
|
||||
|
||||
- ✅ **Connection Pooling** : Keycloak Admin Client (pool size: 20 en prod)
|
||||
- ✅ **Timeouts** : Connect (5s), Read (30s), Keycloak (60s)
|
||||
- ✅ **Thread Pool** : Core (2), Max (16), Queue (100)
|
||||
- ✅ **Caching** : PrimeFaces cache provider configuré
|
||||
- ✅ **Compression** : À vérifier au niveau reverse proxy (Nginx/Ingress)
|
||||
|
||||
### ⚠️ Recommandations Performance
|
||||
|
||||
1. **Cache Keycloak** : Implémenter un cache pour les appels Keycloak Admin API (rôles, realms)
|
||||
2. **Pagination** : Vérifier que toutes les listes utilisent la pagination efficace
|
||||
3. **Lazy Loading** : Implémenter lazy loading pour les grandes listes (utilisateurs, rôles)
|
||||
4. **CDN** : Utiliser un CDN pour les ressources statiques (CSS, JS, images)
|
||||
5. **Database Indexing** : Vérifier les index sur la table d'audit PostgreSQL
|
||||
|
||||
---
|
||||
|
||||
## 5. Observabilité
|
||||
|
||||
### ✅ Health Checks
|
||||
|
||||
**Endpoints** :
|
||||
- ✅ `/health` : Health check global
|
||||
- ✅ `/health/live` : Liveness probe
|
||||
- ✅ `/health/ready` : Readiness probe
|
||||
- ✅ `/api/health/keycloak` : Health check Keycloak (backend uniquement)
|
||||
|
||||
### ✅ Métriques Prometheus
|
||||
|
||||
**Endpoints** :
|
||||
- ✅ `/metrics` : Métriques Prometheus (frontend + backend)
|
||||
|
||||
**Métriques disponibles** :
|
||||
- `http_server_requests_total` : Nombre de requêtes HTTP
|
||||
- `http_server_request_duration_seconds` : Durée des requêtes
|
||||
- Métriques Quarkus standard (JVM, mémoire, threads)
|
||||
|
||||
### ✅ Logging
|
||||
|
||||
**Configuration** :
|
||||
- ✅ **Console** : Activé (format JSON en prod)
|
||||
- ✅ **File** : Activé avec rotation (50M, 30 backups)
|
||||
- ✅ **Niveaux** : INFO (prod), DEBUG (dev)
|
||||
- ✅ **Catégories** : Logging spécifique par package
|
||||
|
||||
**Fichiers de logs** :
|
||||
- Frontend : `/var/log/lions/lions-user-manager-client.log`
|
||||
- Backend : `/var/log/lions/lions-user-manager-server.log`
|
||||
|
||||
### ⚠️ Recommandations Observabilité
|
||||
|
||||
1. **Distributed Tracing** : Ajouter OpenTelemetry/Jaeger pour le tracing distribué
|
||||
2. **Log Aggregation** : Configurer l'envoi des logs vers Graylog/ELK
|
||||
3. **Alerting** : Configurer des alertes Prometheus (erreurs 5xx, latence élevée)
|
||||
4. **Dashboards** : Créer des dashboards Grafana pour monitoring
|
||||
|
||||
---
|
||||
|
||||
## 6. Résilience
|
||||
|
||||
### ✅ Fault Tolerance
|
||||
|
||||
**Circuit Breaker** :
|
||||
- ✅ Activé (`quarkus.smallrye-fault-tolerance.enabled=true`)
|
||||
- ⚠️ Configuration par défaut (à personnaliser)
|
||||
|
||||
**Retry** :
|
||||
- ✅ Configuré pour Keycloak Admin Client
|
||||
- ✅ Max attempts: 5 (prod), 3 (dev)
|
||||
- ✅ Delay: 3s (prod), 2s (dev)
|
||||
|
||||
**Timeout** :
|
||||
- ✅ Connect timeout: 5s
|
||||
- ✅ Read timeout: 30s
|
||||
- ✅ Keycloak timeout: 60s (prod)
|
||||
|
||||
### ✅ Gestion d'Erreurs
|
||||
|
||||
**Frontend** :
|
||||
- ✅ `RestClientExceptionMapper` : Mappe les erreurs HTTP en exceptions
|
||||
- ✅ Gestion des erreurs dans les beans JSF avec messages utilisateur
|
||||
|
||||
**Backend** :
|
||||
- ✅ `NotFoundException` : Gestion 404
|
||||
- ✅ `IllegalArgumentException` : Validation des paramètres
|
||||
- ✅ `RuntimeException` : Erreurs génériques avec logging
|
||||
|
||||
### ⚠️ Recommandations Résilience
|
||||
|
||||
1. **Circuit Breaker Configuration** : Configurer les seuils (failure ratio, timeout)
|
||||
2. **Bulkhead** : Isoler les appels Keycloak dans un pool de threads séparé
|
||||
3. **Fallback** : Implémenter des fallbacks pour les opérations non critiques
|
||||
4. **Graceful Degradation** : Gérer la dégradation gracieuse si Keycloak est indisponible
|
||||
|
||||
---
|
||||
|
||||
## 7. Documentation
|
||||
|
||||
### ✅ Documentation Existante
|
||||
|
||||
- ✅ `README.md` : Documentation principale
|
||||
- ✅ `README_DEMARRAGE.md` : Guide de démarrage
|
||||
- ✅ `README_PORTS.md` : Configuration des ports
|
||||
- ✅ `ETAT_FINAL.md` : État actuel du projet
|
||||
- ✅ `AUDIT_PRODUCTION.md` : Ce document
|
||||
|
||||
### ⚠️ Documentation Manquante
|
||||
|
||||
1. **Guide de Déploiement** : Procédure complète de déploiement Kubernetes
|
||||
2. **Guide d'Intégration** : Comment intégrer `lions-user-manager` dans d'autres applications
|
||||
3. **Runbook Opérationnel** : Procédures de maintenance, troubleshooting
|
||||
4. **Architecture Détaillée** : Diagrammes d'architecture, flux de données
|
||||
5. **Guide Utilisateur** : Documentation pour les utilisateurs finaux
|
||||
|
||||
---
|
||||
|
||||
## 8. Checklist de Déploiement
|
||||
|
||||
### ⚠️ PRÉ-DÉPLOIEMENT (OBLIGATOIRE)
|
||||
|
||||
**IMPORTANT** : Ne pas déployer avant d'avoir complété toutes ces étapes !
|
||||
|
||||
- [ ] **Configuration Keycloak** :
|
||||
- [ ] Clients OIDC créés (frontend + backend)
|
||||
- [ ] Rôles realm créés (admin, user_manager, user_viewer, auditor, sync_manager, role_manager, role_viewer)
|
||||
- [ ] Service account backend configuré avec rôles assignés
|
||||
- [ ] Protocol mapper `roles` configuré pour `realm_access.roles`
|
||||
- [ ] Secrets récupérés (frontend + backend)
|
||||
- [ ] Test de connexion Keycloak réussi
|
||||
|
||||
- [ ] **Configuration Base de Données** :
|
||||
- [ ] Base de données `lions_audit` créée
|
||||
- [ ] Utilisateur `lions_audit_user` créé
|
||||
- [ ] Privilèges accordés
|
||||
- [ ] Test de connexion réussi
|
||||
- [ ] Migrations Flyway prêtes
|
||||
|
||||
- [ ] **Secrets Kubernetes** :
|
||||
- [ ] Secret frontend créé (KEYCLOAK_CLIENT_SECRET, OIDC_ENCRYPTION_SECRET)
|
||||
- [ ] Secret backend créé (KEYCLOAK_CLIENT_SECRET, KEYCLOAK_ADMIN_PASSWORD, DB_PASSWORD)
|
||||
- [ ] Secrets vérifiés (sans afficher les valeurs)
|
||||
|
||||
- [ ] **Infrastructure** :
|
||||
- [ ] Namespace Kubernetes créé
|
||||
- [ ] SSL/TLS : Certificats préparés (si nécessaire)
|
||||
- [ ] Variables d'environnement documentées
|
||||
|
||||
**Guide complet** : Voir `PREPARATION_PRODUCTION.md`
|
||||
|
||||
### Déploiement (APRÈS Configuration)
|
||||
|
||||
- [ ] **Images Docker** : Build et push des images vers le registry
|
||||
- [ ] **Helm Charts** : Finaliser les templates et values.yaml (optionnel si lionsctl)
|
||||
- [ ] **ConfigMaps** : Créer les ConfigMaps pour la configuration
|
||||
|
||||
### Déploiement
|
||||
|
||||
- [ ] **Namespace** : Créer le namespace Kubernetes
|
||||
- [ ] **Secrets Kubernetes** : Créer les secrets pour Keycloak, DB, SSL
|
||||
- [ ] **ConfigMaps** : Créer les ConfigMaps pour la configuration
|
||||
- [ ] **Backend** : Déployer le backend (Deployment, Service)
|
||||
- [ ] **Frontend** : Déployer le frontend (Deployment, Service)
|
||||
- [ ] **Ingress** : Configurer l'Ingress pour exposition externe
|
||||
- [ ] **Health Checks** : Vérifier que les health checks répondent
|
||||
|
||||
### Post-déploiement
|
||||
|
||||
- [ ] **Tests Fonctionnels** : Tester toutes les fonctionnalités principales
|
||||
- [ ] **Tests de Charge** : Vérifier les performances sous charge
|
||||
- [ ] **Monitoring** : Vérifier que les métriques et logs sont collectés
|
||||
- [ ] **Alerting** : Configurer les alertes Prometheus
|
||||
- [ ] **Documentation** : Mettre à jour la documentation avec les URLs de production
|
||||
|
||||
---
|
||||
|
||||
## 9. Recommandations
|
||||
|
||||
### Priorité Haute 🔴
|
||||
|
||||
1. ✅ **Créer les Dockerfiles** : Multi-stage builds optimisés (FAIT)
|
||||
2. **Finaliser Helm Charts** : Templates complets avec ConfigMaps/Secrets (basés sur btpxpress)
|
||||
3. **Tests** : Ajouter tests unitaires et d'intégration (minimum 80% couverture)
|
||||
4. **Documentation Déploiement** : Guide complet de déploiement Kubernetes
|
||||
5. **Créer dépôts Git** : Créer les dépôts sur git.lions.dev pour chaque module
|
||||
|
||||
### Priorité Moyenne 🟡
|
||||
|
||||
1. **Cache Keycloak** : Implémenter cache pour réduire les appels API
|
||||
2. **Rate Limiting** : Ajouter rate limiting sur endpoints sensibles
|
||||
3. **Distributed Tracing** : Ajouter OpenTelemetry pour tracing
|
||||
4. **Dashboards Grafana** : Créer dashboards de monitoring
|
||||
|
||||
### Priorité Basse 🟢
|
||||
|
||||
1. **CDN** : Configurer CDN pour ressources statiques
|
||||
2. **Optimisation Queries** : Optimiser les requêtes Keycloak (pagination, filtres)
|
||||
3. **Documentation Utilisateur** : Guide utilisateur final
|
||||
4. **CI/CD** : Pipeline CI/CD complet (build, test, déploiement)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Score Global
|
||||
|
||||
| Catégorie | Score | Statut |
|
||||
|-----------|-------|--------|
|
||||
| Sécurité | 85% | ✅ Bon |
|
||||
| Configuration | 85% | ✅ Bon (Dockerfiles ajoutés) |
|
||||
| Performance | 70% | 🟡 Acceptable |
|
||||
| Observabilité | 75% | ✅ Bon |
|
||||
| Résilience | 70% | 🟡 Acceptable |
|
||||
| Documentation | 70% | ✅ Bon (audit mis à jour) |
|
||||
| Infrastructure | 90% | ✅ Excellent (Dockerfiles, scripts Git, push réussi) |
|
||||
| **TOTAL** | **79%** | **✅ Prêt pour production (avec recommandations)** |
|
||||
|
||||
---
|
||||
|
||||
## ✅ Conclusion
|
||||
|
||||
Le projet **Lions User Manager** est **prêt pour le déploiement en production** avec les recommandations suivantes :
|
||||
|
||||
1. ✅ **Sécurité** : Configuration OIDC complète, rôles bien gérés
|
||||
2. ✅ **Configuration** : Séparation dev/prod, variables d'environnement
|
||||
3. ✅ **Infrastructure** : Dockerfiles créés (basés sur btpxpress), code poussé sur git.lions.dev
|
||||
4. ⚠️ **Tests** : Tests unitaires et d'intégration à ajouter
|
||||
5. ✅ **Documentation** : Audit production complet, guide de déploiement avec lionsctl
|
||||
|
||||
**Recommandation finale** :
|
||||
|
||||
1. ⚠️ **OBLIGATOIRE** : Compléter toutes les étapes de `PREPARATION_PRODUCTION.md` avant tout déploiement
|
||||
2. ✅ Déployer en **environnement de staging** d'abord pour valider toutes les configurations
|
||||
3. ✅ Tester complètement en staging avant la production
|
||||
|
||||
---
|
||||
|
||||
## 10. Dépôts Git
|
||||
|
||||
### ✅ Dépôts Créés et Code Poussé
|
||||
|
||||
**Fichier** : `scripts/push-to-git-lions.ps1`
|
||||
|
||||
**Statut** : ✅ **TOUS LES MODULES ONT ÉTÉ POUSSÉS AVEC SUCCÈS**
|
||||
|
||||
Les 3 dépôts existent sur git.lions.dev et le code a été poussé :
|
||||
- ✅ `lions-user-manager-server-api` : Module API (DTOs, interfaces)
|
||||
- URL: https://git.lions.dev/lionsdev/lions-user-manager-server-api
|
||||
- Statut: ✅ Poussé avec succès
|
||||
|
||||
- ✅ `lions-user-manager-server-impl-quarkus` : Module serveur (implémentation Quarkus)
|
||||
- URL: https://git.lions.dev/lionsdev/lions-user-manager-server-impl-quarkus
|
||||
- Statut: ✅ Poussé avec succès
|
||||
|
||||
- ✅ `lions-user-manager-client-quarkus-primefaces-freya` : Module client (PrimeFaces Freya)
|
||||
- URL: https://git.lions.dev/lionsdev/lions-user-manager-client-quarkus-primefaces-freya
|
||||
- Statut: ✅ Poussé avec succès
|
||||
|
||||
### ✅ Commandes de Push
|
||||
|
||||
Pour mettre à jour les dépôts :
|
||||
```powershell
|
||||
cd lions-user-manager
|
||||
pwsh -File scripts/push-to-git-lions.ps1 -Component all
|
||||
```
|
||||
|
||||
Ou pour un module spécifique :
|
||||
```powershell
|
||||
pwsh -File scripts/push-to-git-lions.ps1 -Component api
|
||||
pwsh -File scripts/push-to-git-lions.ps1 -Component server
|
||||
pwsh -File scripts/push-to-git-lions.ps1 -Component client
|
||||
```
|
||||
|
||||
**Identifiants** : `lionsdev` / `lions@2025`
|
||||
|
||||
### ✅ Commandes de Déploiement avec lionsctl
|
||||
|
||||
**Server (Backend)** :
|
||||
```bash
|
||||
# Développement (cluster k1)
|
||||
cd ../lions-infrastructure-2025/lionsctl
|
||||
./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/lions-user-manager-server-impl-quarkus -b main -j 17 -e dev -c k1 -m gbanedahoud@gmail.com
|
||||
|
||||
# Production (cluster k2)
|
||||
cd ../lions-infrastructure-2025/lionsctl
|
||||
./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/lions-user-manager-server-impl-quarkus -b main -j 17 -e production -c k2 -m gbanedahoud@gmail.com
|
||||
```
|
||||
|
||||
**Client (Frontend)** :
|
||||
```bash
|
||||
# Développement (cluster k1)
|
||||
cd ../lions-infrastructure-2025/lionsctl
|
||||
./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/lions-user-manager-client-quarkus-primefaces-freya -b main -j 17 -e dev -c k1 -m gbanedahoud@gmail.com
|
||||
|
||||
# Production (cluster k2)
|
||||
cd ../lions-infrastructure-2025/lionsctl
|
||||
./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/lions-user-manager-client-quarkus-primefaces-freya -b main -j 17 -e production -c k2 -m gbanedahoud@gmail.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Document généré le** : 2025-01-15
|
||||
**Dernière mise à jour** : 2025-01-15
|
||||
**Changements** :
|
||||
- ✅ Dockerfiles de production créés (basés sur btpxpress)
|
||||
- ✅ Script de push Git créé et testé
|
||||
- ✅ Tous les modules poussés vers git.lions.dev avec succès
|
||||
- ✅ Audit mis à jour avec les bonnes pratiques de btpxpress
|
||||
- ✅ Navigation JSF centralisée dans faces-config.xml
|
||||
- ✅ Guide de préparation production créé (`PREPARATION_PRODUCTION.md`)
|
||||
- ✅ Scripts de configuration Keycloak et Database créés
|
||||
|
||||
**⚠️ IMPORTANT** :
|
||||
- **NE PAS DÉPLOYER** avant d'avoir complété `PREPARATION_PRODUCTION.md`
|
||||
- Configuration Keycloak et Database sont **OBLIGATOIRES** avant déploiement
|
||||
|
||||
**Prochaine révision** : Après déploiement staging
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
# Backend Démarré avec Succès
|
||||
|
||||
## Résumé
|
||||
|
||||
Le backend **Lions User Manager** démarre maintenant correctement sur le **port 8081**.
|
||||
|
||||
## Problèmes Résolus
|
||||
|
||||
### 1. Conflit RESTEasy / Keycloak Admin Client
|
||||
**Problème**: Utilisation de `keycloak-admin-client` (version standalone) avec `quarkus-rest` (RESTEasy Reactive) créait un conflit.
|
||||
|
||||
**Solution**: Remplacement par `quarkus-keycloak-admin-rest-client` dans le `pom.xml`:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-keycloak-admin-rest-client</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 2. Annotations de Validation sur Méthodes Privées
|
||||
**Problème**: Les méthodes privées dans `RoleServiceImpl` avaient des annotations `@NotBlank`, `@NotNull` ce qui est interdit par Quarkus.
|
||||
|
||||
**Erreur**:
|
||||
```
|
||||
@io.quarkus.hibernate.validator.runtime.interceptor.MethodValidated will have no effect on method
|
||||
dev.lions.user.manager.service.impl.RoleServiceImpl.assignClientRolesToUser()
|
||||
because the method is private
|
||||
```
|
||||
|
||||
**Solution**: Suppression des annotations de validation sur toutes les méthodes privées :
|
||||
- `assignClientRolesToUser()`
|
||||
- `assignRealmRolesToUser()`
|
||||
- `revokeClientRolesFromUser()`
|
||||
- `revokeRealmRolesFromUser()`
|
||||
- `getRealmRoleById()`
|
||||
- `getRealmRoleByName()`
|
||||
- `getClientRoleByName()`
|
||||
- `userHasRealmRole()`
|
||||
- `userHasClientRole()`
|
||||
|
||||
### 3. Continuous Testing Bloquant le Démarrage
|
||||
**Problème**: Le backend restait bloqué sur "Tests paused" et ne démarrait pas complètement.
|
||||
|
||||
**Solution**: Ajout dans `application-dev.properties`:
|
||||
```properties
|
||||
quarkus.test.continuous-testing=disabled
|
||||
```
|
||||
|
||||
### 4. Port de Debug Occupé
|
||||
**Problème**: Le port 5005 (debug) était déjà utilisé par un processus zombie.
|
||||
|
||||
**Solution**: Tuer le processus occupant le port 5005.
|
||||
|
||||
## État Actuel
|
||||
|
||||
### Backend (Port 8081)
|
||||
✅ **DÉMARRÉ** - Le backend fonctionne correctement sur http://localhost:8081
|
||||
|
||||
**Endpoints disponibles**:
|
||||
- **Swagger UI**: http://localhost:8081/q/swagger-ui
|
||||
- **Dev UI**: http://localhost:8081/q/dev-ui
|
||||
- **Health Check**: http://localhost:8081/q/health
|
||||
- **OpenAPI**: http://localhost:8081/q/openapi
|
||||
- **Metrics**: http://localhost:8081/metrics
|
||||
|
||||
**API Endpoints**:
|
||||
- Users: `GET/POST/PUT/DELETE /api/users`
|
||||
- Roles: `GET/POST/PUT/DELETE /api/roles/*`
|
||||
- Health: `GET /api/health/keycloak`, `GET /api/health/status`
|
||||
- Audit: `/api/audit/*`
|
||||
- Sync: `/api/sync/*`
|
||||
|
||||
### Keycloak (Port 8180)
|
||||
✅ **EN MARCHE** - Keycloak fonctionne sur http://localhost:8180
|
||||
|
||||
**Configuration**:
|
||||
- Realm: `lions-user-manager`
|
||||
- Client: `lions-user-manager-client`
|
||||
- Client Secret: `client-secret-lions-2025`
|
||||
- Test User: `testuser` / `test123`
|
||||
- Admin: `admin` / `admin`
|
||||
|
||||
### Frontend (Port 8080)
|
||||
⚠️ **À DÉMARRER** - Le frontend n'est pas encore lancé
|
||||
|
||||
## Problème Restant
|
||||
|
||||
### Connexion Keycloak
|
||||
Le backend ne parvient pas à se connecter à Keycloak :
|
||||
```json
|
||||
{"connected":false,"status":"DOWN"}
|
||||
```
|
||||
|
||||
**Cause probable**: Configuration dans `application-dev.properties` utilise des credentials ou URL incorrects.
|
||||
|
||||
**Vérification nécessaire**:
|
||||
```properties
|
||||
lions.keycloak.server-url=http://localhost:8180
|
||||
lions.keycloak.admin-realm=master
|
||||
lions.keycloak.admin-client-id=admin-cli
|
||||
lions.keycloak.admin-username=admin
|
||||
lions.keycloak.admin-password=admin
|
||||
```
|
||||
|
||||
## Prochaines Étapes
|
||||
|
||||
1. ✅ Backend démarré sur port 8081
|
||||
2. ⚠️ Corriger la connexion Keycloak du backend
|
||||
3. ⏳ Démarrer le frontend sur port 8080
|
||||
4. ⏳ Tester l'authentification complète
|
||||
5. ⏳ Tester les endpoints API
|
||||
|
||||
## Commande de Démarrage
|
||||
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\lions-user-manager\lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev -Ddebug=false
|
||||
```
|
||||
|
||||
## Warnings à Ignorer
|
||||
|
||||
Ces warnings sont normaux et n'empêchent pas le fonctionnement :
|
||||
- `Hibernate ORM is disabled because no JPA entities were found` - Normal, pas de DB configurée
|
||||
- `Unable to properly register the hierarchy...for reflection` - Les DTOs fonctionnent malgré tout
|
||||
- `Unrecognized configuration key "quarkus.smallrye-fault-tolerance.enabled"` - Propriété obsolète mais sans impact
|
||||
- `Unrecognized configuration key "quarkus.oidc.dev-ui.enabled"` - Propriété obsolète mais sans impact
|
||||
- `Unrecognized configuration key "quarkus.security.auth.proactive"` - Propriété obsolète mais sans impact
|
||||
@@ -1,166 +0,0 @@
|
||||
# État des Boutons dans Lions User Manager
|
||||
|
||||
## Pages Vérifiées et Corrigées
|
||||
|
||||
### ✅ 1. users/list.xhtml
|
||||
**État:** CORRIGÉ
|
||||
**Corrections apportées:**
|
||||
- ✅ Boutons de navigation (Voir Profil, Modifier, Gérer Rôles) : Utilisent `p:commandButton` avec `outcome`
|
||||
- ✅ Boutons d'actions AJAX (Activer, Désactiver, Supprimer) : Ajout de `process="@this"`
|
||||
- ✅ Suppression de l'option "master" du sélecteur de realm
|
||||
- ✅ Pattern Freya respecté : boutons icon-only avec `p-button-rounded`
|
||||
|
||||
**Boutons fonctionnels:**
|
||||
- 👁️ Voir le profil → `/pages/user-manager/users/profile`
|
||||
- ✏️ Modifier → `/pages/user-manager/users/edit`
|
||||
- 🔑 Gérer les rôles → `/pages/user-manager/roles/assign`
|
||||
- ✓ Activer / 🚫 Désactiver (AJAX avec confirmation)
|
||||
- 🗑️ Supprimer (AJAX avec confirmation)
|
||||
|
||||
### ✅ 2. users/create.xhtml
|
||||
**État:** OPTIMISÉ
|
||||
**Boutons fonctionnels:**
|
||||
- ✅ Créer l'utilisateur → `action="#{userCreationBean.createUser}"`
|
||||
- ✅ Réinitialiser → `action="#{userCreationBean.resetForm}"` avec confirmation
|
||||
- ✅ Annuler → `outcome="/pages/user-manager/users/list"`
|
||||
- ✅ Aide (Dialog) → `onclick="PF('helpDialog').show()"`
|
||||
|
||||
### ✅ 3. dashboard.xhtml
|
||||
**État:** OPTIMISÉ
|
||||
**Boutons fonctionnels:**
|
||||
- ✅ Rafraîchir → `action="#{dashboardBean.refreshStatistics}"`
|
||||
- ✅ KPI Cards cliquables → `outcome="/pages/user-manager/..."` avec effet hover
|
||||
- ✅ Actions Rapides:
|
||||
- Nouvel Utilisateur → `/pages/user-manager/users/create`
|
||||
- Liste des Utilisateurs → `/pages/user-manager/users/list`
|
||||
- Gestion des Rôles → `/pages/user-manager/roles/list`
|
||||
- Journal d'Audit → `/pages/user-manager/audit/logs`
|
||||
- ✅ Voir tout (Audit) → `/pages/user-manager/audit/logs`
|
||||
|
||||
### ✅ 4. audit/logs.xhtml
|
||||
**État:** OPTIMISÉ
|
||||
**Boutons fonctionnels:**
|
||||
- ✅ Exporter CSV → `action="#{auditConsultationBean.exportToCSV}" ajax="false"`
|
||||
- ✅ Rechercher → `action="#{auditConsultationBean.searchLogs}"`
|
||||
- ✅ Réinitialiser → `action="#{auditConsultationBean.resetFilters}"`
|
||||
- ✅ Voir détails (par log) → `onclick="PF('auditLogDetailsDialog').show()"`
|
||||
- ✅ Fermer (Dialog) → `onclick="PF('auditLogDetailsDialog').hide()"`
|
||||
|
||||
### ✅ 5. roles/list.xhtml
|
||||
**État:** VÉRIFIÉ - DÉJÀ FONCTIONNEL
|
||||
**Boutons fonctionnels:**
|
||||
- ✅ Nouveau Rôle Realm → `onclick="PF('createRealmRoleDialog').show()"`
|
||||
- ✅ Nouveau Rôle Client → `onclick="PF('createClientRoleDialog').show()"`
|
||||
- ✅ Rafraîchir (Realm) → `action="#{roleGestionBean.loadRealmRoles}"`
|
||||
- ✅ Rafraîchir (Client) → `action="#{roleGestionBean.loadClientRoles}"`
|
||||
- ✅ Supprimer Rôle Realm → `action="#{roleGestionBean.deleteRealmRole(role.name)}"` avec confirmation
|
||||
- ✅ Supprimer Rôle Client → `action="#{roleGestionBean.deleteClientRole(role.name)}"` avec confirmation
|
||||
- ✅ Créer (Dialog Realm) → `action="#{roleGestionBean.createRealmRole}"`
|
||||
- ✅ Créer (Dialog Client) → `action="#{roleGestionBean.createClientRole}"`
|
||||
|
||||
### ✅ 6. roles/assign.xhtml
|
||||
**État:** VÉRIFIÉ - DÉJÀ FONCTIONNEL
|
||||
**Boutons fonctionnels:**
|
||||
- ✅ Retour à la liste → `outcome="/pages/user-manager/users/list"`
|
||||
- ✅ Rafraîchir → `action="#{userProfilBean.loadUser}"`
|
||||
- ✅ Retirer rôle → `action="#{roleGestionBean.revokeRoleFromUser(...)}"` avec confirmation
|
||||
- ✅ Assigner rôle → `action="#{roleGestionBean.assignRoleToUser(...)}"`
|
||||
- ✅ Actions de navigation:
|
||||
- Voir le Profil → `/pages/user-manager/users/profile`
|
||||
- Modifier l'Utilisateur → `/pages/user-manager/users/edit`
|
||||
- Liste des Utilisateurs → `/pages/user-manager/users/list`
|
||||
- Gérer les Rôles → `/pages/user-manager/roles/list`
|
||||
|
||||
### ⚠️ 7. users/edit.xhtml
|
||||
**État:** UTILISE UN COMPOSANT D'INCLUSION
|
||||
**Note:** Cette page utilise `/templates/components/user-management/user-form.xhtml` qui n'existe peut-être pas.
|
||||
**À vérifier:** Ce composant doit être créé ou la page doit être réécrite.
|
||||
|
||||
### ⚠️ 8. users/profile.xhtml
|
||||
**État:** NON COMPLÈTEMENT VÉRIFIÉ
|
||||
**À vérifier:** Boutons d'actions dans cette page.
|
||||
|
||||
## Patterns Utilisés pour les Boutons
|
||||
|
||||
### Navigation Simple
|
||||
```xml
|
||||
<p:commandButton value="Texte" icon="pi pi-icon" outcome="/pages/..." />
|
||||
```
|
||||
ou
|
||||
```xml
|
||||
<h:link outcome="/pages/..." styleClass="p-button">
|
||||
<i class="pi pi-icon"></i> Texte
|
||||
</h:link>
|
||||
```
|
||||
|
||||
### Actions AJAX
|
||||
```xml
|
||||
<p:commandButton icon="pi pi-icon"
|
||||
action="#{bean.method}"
|
||||
update=":formId"
|
||||
process="@this" />
|
||||
```
|
||||
|
||||
### Dialogs
|
||||
```xml
|
||||
<p:commandButton icon="pi pi-icon"
|
||||
type="button"
|
||||
onclick="PF('dialogWidgetVar').show();" />
|
||||
```
|
||||
|
||||
### Boutons Icon-Only (Pattern Freya)
|
||||
```xml
|
||||
<p:commandButton icon="pi pi-icon"
|
||||
styleClass="p-button-rounded p-button-text p-button-sm"
|
||||
title="Description" />
|
||||
```
|
||||
|
||||
## Problèmes Identifiés et Résolus
|
||||
|
||||
### ❌ Problème 1: p:commandButton avec outcome dans DataTable
|
||||
**Symptôme:** Boutons ne réagissent pas dans les tableaux de données
|
||||
**Solution:** Utiliser p:commandButton avec outcome (fonctionne en dehors des complex containers)
|
||||
**Status:** ✅ RÉSOLU dans list.xhtml
|
||||
|
||||
### ❌ Problème 2: Boutons AJAX sans process="@this"
|
||||
**Symptôme:** Validation sur tout le formulaire même pour une action simple
|
||||
**Solution:** Ajout de `process="@this"` pour traiter uniquement le bouton
|
||||
**Status:** ✅ RÉSOLU dans list.xhtml
|
||||
|
||||
### ❌ Problème 3: Realm "master" inexistant
|
||||
**Symptôme:** Erreur 404 lors de la sélection du realm
|
||||
**Solution:** Suppression de l'option "master", seul "lions-user-manager" existe
|
||||
**Status:** ✅ RÉSOLU dans list.xhtml et create.xhtml
|
||||
|
||||
## Recommandations
|
||||
|
||||
1. ✅ Tous les boutons de navigation utilisent `outcome` ou `onclick` approprié
|
||||
2. ✅ Tous les boutons d'actions AJAX ont `process="@this"`
|
||||
3. ✅ Pattern Freya respecté partout
|
||||
4. ⚠️ Vérifier users/edit.xhtml et créer le composant manquant
|
||||
5. ⚠️ Vérifier users/profile.xhtml complètement
|
||||
|
||||
## Test des Boutons
|
||||
|
||||
Pour tester si un bouton est fonctionnel:
|
||||
1. Ouvrir la page dans le navigateur
|
||||
2. Ouvrir la console développeur (F12)
|
||||
3. Cliquer sur le bouton
|
||||
4. Vérifier:
|
||||
- Aucune erreur JavaScript
|
||||
- Requête AJAX envoyée (si bouton AJAX)
|
||||
- Navigation effectuée (si bouton de navigation)
|
||||
|
||||
## Conclusion
|
||||
|
||||
**Pages 100% fonctionnelles:**
|
||||
- ✅ users/list.xhtml
|
||||
- ✅ users/create.xhtml
|
||||
- ✅ dashboard.xhtml
|
||||
- ✅ audit/logs.xhtml
|
||||
- ✅ roles/list.xhtml
|
||||
- ✅ roles/assign.xhtml
|
||||
|
||||
**Pages à vérifier:**
|
||||
- ⚠️ users/edit.xhtml
|
||||
- ⚠️ users/profile.xhtml
|
||||
@@ -1,179 +0,0 @@
|
||||
# ✅ Composants Réutilisables Créés - Lions User Manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Statut**: ✅ **TOUS LES COMPOSANTS CRÉÉS** (14 composants)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Résumé
|
||||
|
||||
**Total**: 14 composants réutilisables créés
|
||||
- ✅ **User Management**: 5 composants
|
||||
- ✅ **Role Management**: 3 composants
|
||||
- ✅ **Audit**: 2 composants
|
||||
- ✅ **Shared**: 4 composants
|
||||
|
||||
---
|
||||
|
||||
## 📦 Liste Complète des Composants
|
||||
|
||||
### 👤 User Management (5/5 ✅)
|
||||
|
||||
1. ✅ **user-card.xhtml**
|
||||
- Carte utilisateur avec informations principales
|
||||
- Actions configurables
|
||||
- Affichage des rôles
|
||||
|
||||
2. ✅ **user-form.xhtml**
|
||||
- Formulaire complet création/modification
|
||||
- Validation intégrée
|
||||
- Support multi-realm
|
||||
|
||||
3. ✅ **user-search-bar.xhtml**
|
||||
- Recherche simple et avancée
|
||||
- Filtres configurables
|
||||
- Options avancées en dialog
|
||||
|
||||
4. ✅ **user-actions.xhtml**
|
||||
- Boutons d'action utilisateur
|
||||
- Layouts multiples (horizontal, vertical, dropdown)
|
||||
- Dialogs de confirmation
|
||||
|
||||
5. ✅ **user-role-badge.xhtml**
|
||||
- Badge de rôle avec icône
|
||||
- Couleurs selon type de rôle
|
||||
- Mode cliquable optionnel
|
||||
|
||||
---
|
||||
|
||||
### 🛡️ Role Management (3/3 ✅)
|
||||
|
||||
6. ✅ **role-card.xhtml**
|
||||
- Carte rôle avec informations
|
||||
- Affichage type de rôle
|
||||
- Actions configurables
|
||||
|
||||
7. ✅ **role-form.xhtml**
|
||||
- Formulaire création/modification rôle
|
||||
- Support Realm et Client roles
|
||||
- Options composite
|
||||
|
||||
8. ✅ **role-assignment.xhtml**
|
||||
- Interface attribution/révocation
|
||||
- Séparation Realm/Client roles
|
||||
- Recherche de rôles
|
||||
|
||||
---
|
||||
|
||||
### 📊 Audit (2/2 ✅)
|
||||
|
||||
9. ✅ **audit-log-row.xhtml**
|
||||
- Ligne de log d'audit
|
||||
- Affichage succès/échec
|
||||
- Détails optionnels
|
||||
|
||||
10. ✅ **audit-stats-card.xhtml**
|
||||
- Carte statistiques audit
|
||||
- Tendance optionnelle
|
||||
- Mode cliquable
|
||||
|
||||
---
|
||||
|
||||
### 🔧 Shared Components (4/4 ✅)
|
||||
|
||||
11. ✅ **button-user-action.xhtml**
|
||||
- Bouton générique actions
|
||||
- Severity configurables
|
||||
- Tailles multiples
|
||||
|
||||
12. ✅ **user-stat-card.xhtml**
|
||||
- Carte statistique utilisateur
|
||||
- Icône et couleur configurables
|
||||
- Tendance optionnelle
|
||||
|
||||
13. ✅ **user-form-field.xhtml**
|
||||
- Champ formulaire générique
|
||||
- Types multiples (text, email, password, select, etc.)
|
||||
- Validation intégrée
|
||||
|
||||
14. ✅ **user-data-table.xhtml**
|
||||
- Tableau de données utilisateurs
|
||||
- Pagination intégrée
|
||||
- Colonnes configurables
|
||||
- Sélection optionnelle
|
||||
|
||||
---
|
||||
|
||||
## 📂 Structure des Fichiers
|
||||
|
||||
```
|
||||
templates/components/
|
||||
├── user-management/
|
||||
│ ├── user-card.xhtml ✅
|
||||
│ ├── user-form.xhtml ✅
|
||||
│ ├── user-search-bar.xhtml ✅
|
||||
│ ├── user-actions.xhtml ✅
|
||||
│ └── user-role-badge.xhtml ✅
|
||||
├── role-management/
|
||||
│ ├── role-card.xhtml ✅
|
||||
│ ├── role-form.xhtml ✅
|
||||
│ └── role-assignment.xhtml ✅
|
||||
├── audit/
|
||||
│ ├── audit-log-row.xhtml ✅
|
||||
│ └── audit-stats-card.xhtml ✅
|
||||
└── shared/
|
||||
├── buttons/
|
||||
│ └── button-user-action.xhtml ✅
|
||||
├── cards/
|
||||
│ └── user-stat-card.xhtml ✅
|
||||
├── forms/
|
||||
│ └── user-form-field.xhtml ✅
|
||||
└── tables/
|
||||
└── user-data-table.xhtml ✅
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✨ Caractéristiques
|
||||
|
||||
### Documentation
|
||||
- ✅ Documentation inline complète dans chaque composant
|
||||
- ✅ Exemples d'utilisation pour chaque composant
|
||||
- ✅ Liste des paramètres avec types et valeurs par défaut
|
||||
|
||||
### Patterns
|
||||
- ✅ Pattern WOU/DRY (Write Once Use / Don't Repeat Yourself)
|
||||
- ✅ Paramètres configurables avec valeurs par défaut
|
||||
- ✅ Compatible avec unionflow
|
||||
|
||||
### Qualité
|
||||
- ✅ Validation JSF intégrée
|
||||
- ✅ Accessibilité respectée
|
||||
- ✅ Responsive design
|
||||
- ✅ Thème Freya compatible
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Prochaines Étapes
|
||||
|
||||
1. ✅ **Composants créés** - TERMINÉ
|
||||
2. ⏳ **REST Clients** - À créer
|
||||
3. ⏳ **Beans JSF** - À créer
|
||||
4. ⏳ **Pages XHTML** - À créer
|
||||
5. ⏳ **Intégration unionflow** - À faire
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- Tous les composants suivent les conventions de nommage
|
||||
- Documentation complète dans chaque fichier
|
||||
- Compatible avec PrimeFaces 14.0.5+
|
||||
- Utilise le thème Freya
|
||||
|
||||
---
|
||||
|
||||
**Statut**: ✅ **100% COMPLÉTÉ**
|
||||
**Date**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
# ✅ Configuration Complète - Lions User Manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Statut**: ✅ **CONFIGURATION COMPLÉTÉE**
|
||||
|
||||
---
|
||||
|
||||
## 📊 Résumé
|
||||
|
||||
Tous les fichiers de configuration nécessaires ont été créés pour **lions-user-manager**.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Fichiers de Configuration Créés
|
||||
|
||||
### 1. ✅ application.properties
|
||||
|
||||
**Localisation**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/application.properties`
|
||||
|
||||
**Contenu**:
|
||||
- ✅ Configuration HTTP (port 8081)
|
||||
- ✅ Configuration MyFaces
|
||||
- ✅ Configuration PrimeFaces (thème Freya)
|
||||
- ✅ Configuration REST Client (`lions-user-manager-api`)
|
||||
- ✅ Configuration Keycloak OIDC
|
||||
- ✅ Configuration sécurité (chemins publics/protégés)
|
||||
- ✅ Configuration CORS
|
||||
- ✅ Health checks et métriques
|
||||
|
||||
**Statut**: ✅ Créé
|
||||
|
||||
---
|
||||
|
||||
### 2. ✅ application-dev.properties
|
||||
|
||||
**Localisation**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/application-dev.properties`
|
||||
|
||||
**Contenu**:
|
||||
- ✅ Logging DEBUG/TRACE
|
||||
- ✅ Backend local (localhost:8080)
|
||||
- ✅ Keycloak local (si disponible)
|
||||
- ✅ CORS permissif
|
||||
|
||||
**Statut**: ✅ Créé
|
||||
|
||||
---
|
||||
|
||||
### 3. ✅ application-prod.properties
|
||||
|
||||
**Localisation**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/application-prod.properties`
|
||||
|
||||
**Contenu**:
|
||||
- ✅ Logging INFO
|
||||
- ✅ Backend production (variable d'environnement)
|
||||
- ✅ Keycloak production
|
||||
- ✅ CORS restrictif
|
||||
- ✅ Sécurité renforcée
|
||||
|
||||
**Statut**: ✅ Créé
|
||||
|
||||
---
|
||||
|
||||
### 4. ✅ faces-config.xml
|
||||
|
||||
**Localisation**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/META-INF/faces-config.xml`
|
||||
|
||||
**Contenu**:
|
||||
- ✅ Configuration locale (fr par défaut)
|
||||
- ✅ Règles de navigation pour toutes les pages:
|
||||
- Dashboard
|
||||
- Users (list, create, profile, edit)
|
||||
- Roles (list, assign)
|
||||
- Audit (logs)
|
||||
- Sync (dashboard)
|
||||
|
||||
**Statut**: ✅ Créé
|
||||
|
||||
---
|
||||
|
||||
### 5. ✅ pom.xml (Mise à jour)
|
||||
|
||||
**Localisation**: `lions-user-manager-client-quarkus-primefaces-freya/pom.xml`
|
||||
|
||||
**Ajouts**:
|
||||
- ✅ `freya-theme-jakarta` (version 5.0.0)
|
||||
- ✅ `quarkus-omnifaces` (version 4.4.1)
|
||||
- ✅ `quarkus-undertow`
|
||||
|
||||
**Statut**: ✅ Mis à jour
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration REST Client
|
||||
|
||||
### Clé de Configuration
|
||||
|
||||
```properties
|
||||
quarkus.rest-client."lions-user-manager-api".url=${lions.user.manager.backend.url}
|
||||
```
|
||||
|
||||
**Utilisation dans les Beans**:
|
||||
```java
|
||||
@RestClient(configKey = "lions-user-manager-api")
|
||||
UserServiceClient userServiceClient;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Configuration Keycloak
|
||||
|
||||
### Variables d'Environnement
|
||||
|
||||
```bash
|
||||
# Backend URL
|
||||
LIONS_USER_MANAGER_BACKEND_URL=http://localhost:8080
|
||||
|
||||
# Keycloak
|
||||
KEYCLOAK_AUTH_SERVER_URL=https://security.lions.dev/realms/master
|
||||
KEYCLOAK_CLIENT_ID=lions-user-manager-client
|
||||
KEYCLOAK_CLIENT_SECRET=<secret>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📂 Structure Complète
|
||||
|
||||
```
|
||||
lions-user-manager-client-quarkus-primefaces-freya/
|
||||
├── pom.xml ✅ (mis à jour avec Freya)
|
||||
└── src/main/resources/
|
||||
├── application.properties ✅
|
||||
├── application-dev.properties ✅
|
||||
├── application-prod.properties ✅
|
||||
└── META-INF/
|
||||
└── faces-config.xml ✅
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Utilisation
|
||||
|
||||
### Développement
|
||||
|
||||
```bash
|
||||
# Activer le profil dev
|
||||
mvn quarkus:dev -Dquarkus.profile=dev
|
||||
```
|
||||
|
||||
### Production
|
||||
|
||||
```bash
|
||||
# Activer le profil prod
|
||||
mvn quarkus:dev -Dquarkus.profile=prod
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist
|
||||
|
||||
- [x] `application.properties` créé
|
||||
- [x] `application-dev.properties` créé
|
||||
- [x] `application-prod.properties` créé
|
||||
- [x] `faces-config.xml` créé
|
||||
- [x] `pom.xml` mis à jour (Freya Theme)
|
||||
- [x] Configuration REST Client
|
||||
- [x] Configuration Keycloak OIDC
|
||||
- [x] Configuration sécurité
|
||||
- [x] Configuration CORS
|
||||
- [x] Health checks
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines Étapes
|
||||
|
||||
1. ✅ **Configuration complétée** - TERMINÉ
|
||||
2. ⏳ **Tests** - À faire
|
||||
3. ⏳ **Déploiement** - À faire
|
||||
|
||||
---
|
||||
|
||||
**Statut**: ✅ **CONFIGURATION 100% COMPLÉTÉE**
|
||||
**Date**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
|
||||
@@ -1,325 +0,0 @@
|
||||
# Guide de Configuration - Lions User Manager
|
||||
|
||||
## 📋 Structure des fichiers de configuration
|
||||
|
||||
Les fichiers de configuration ont été restructurés selon les **best practices Quarkus** :
|
||||
|
||||
```
|
||||
lions-user-manager/
|
||||
├── lions-user-manager-client-quarkus-primefaces-freya/
|
||||
│ └── src/main/resources/
|
||||
│ ├── application.properties # Configuration commune
|
||||
│ ├── application-dev.properties # Configuration DEV
|
||||
│ └── application-prod.properties # Configuration PROD
|
||||
│
|
||||
├── lions-user-manager-server-impl-quarkus/
|
||||
│ └── src/main/resources/
|
||||
│ ├── application.properties # Configuration commune
|
||||
│ ├── application-dev.properties # Configuration DEV
|
||||
│ └── application-prod.properties # Configuration PROD
|
||||
│
|
||||
└── lions-user-manager-server-api/
|
||||
└── (pas de configuration - module DTOs uniquement)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Principe de séparation
|
||||
|
||||
### ✅ Avant (ancien système avec préfixes)
|
||||
```properties
|
||||
# application.properties
|
||||
quarkus.http.port=8080
|
||||
%dev.quarkus.http.port=8082
|
||||
%prod.quarkus.http.port=8080
|
||||
```
|
||||
|
||||
### ✅ Après (nouveau système avec fichiers séparés)
|
||||
|
||||
**application.properties** (commun)
|
||||
```properties
|
||||
quarkus.http.host=0.0.0.0
|
||||
```
|
||||
|
||||
**application-dev.properties**
|
||||
```properties
|
||||
quarkus.http.port=8082
|
||||
```
|
||||
|
||||
**application-prod.properties**
|
||||
```properties
|
||||
quarkus.http.port=8080
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 Détail des configurations
|
||||
|
||||
### 1️⃣ lions-user-manager-client-quarkus-primefaces-freya
|
||||
|
||||
#### `application.properties` - Configuration commune
|
||||
Contient :
|
||||
- Configuration HTTP de base (host, session, cookies)
|
||||
- Configuration MyFaces (JSF)
|
||||
- Configuration PrimeFaces (thème, options)
|
||||
- Configuration REST Client (timeouts, scope)
|
||||
- Configuration OIDC de base (redirect path, scopes, rôles)
|
||||
- Chemins publics/protégés
|
||||
- Health checks et Metrics
|
||||
|
||||
#### `application-dev.properties` - Développement
|
||||
Contient :
|
||||
- **Port** : `8082`
|
||||
- **Debug port** : `5006`
|
||||
- **Logging** : DEBUG/TRACE
|
||||
- **OIDC** : Keycloak local `http://localhost:8180/realms/lions-user-manager`
|
||||
- **Backend URL** : `http://localhost:8081`
|
||||
- **CORS** : Permissif (`localhost:8080,8081,8082`)
|
||||
- **Cookies** : Non sécurisés (HTTP autorisé)
|
||||
|
||||
#### `application-prod.properties` - Production
|
||||
Contient :
|
||||
- **Port** : `8080`
|
||||
- **Logging** : WARN/INFO
|
||||
- **OIDC** : Keycloak production `https://security.lions.dev/realms/master`
|
||||
- **Backend URL** : Variable d'environnement `${LIONS_USER_MANAGER_BACKEND_URL}`
|
||||
- **CORS** : Restrictif (via `${CORS_ORIGINS}`)
|
||||
- **Cookies** : Sécurisés (HTTPS uniquement)
|
||||
- **TLS** : Vérification requise
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ lions-user-manager-server-impl-quarkus
|
||||
|
||||
#### `application.properties` - Configuration commune
|
||||
Contient :
|
||||
- Configuration HTTP de base (CORS headers, methods)
|
||||
- Type d'application OIDC : `service`
|
||||
- Configuration Keycloak Admin (pool, timeouts, retry)
|
||||
- Configuration Audit
|
||||
- Configuration Logging (format, rotation)
|
||||
- OpenAPI/Swagger metadata
|
||||
- Health checks et Metrics
|
||||
- Jackson (JSON)
|
||||
|
||||
#### `application-dev.properties` - Développement
|
||||
|
||||
**🔑 Point important : OIDC DÉSACTIVÉ en DEV**
|
||||
|
||||
Contient :
|
||||
- **Port** : `8081`
|
||||
- **Logging** : DEBUG/TRACE
|
||||
- **OIDC** : `quarkus.oidc.enabled=false` ⚠️
|
||||
- Simplifie le développement
|
||||
- Le client JSF reste sécurisé
|
||||
- Commentaires fournis pour réactiver si nécessaire
|
||||
- **Security** : Désactivée (`quarkus.security.auth.enabled=false`)
|
||||
- **Keycloak Admin** : Local `http://localhost:8180/realms/lions-user-manager`
|
||||
- **CORS** : Permissif (`*`)
|
||||
- **Realms autorisés** : `lions-user-manager,btpxpress,master,unionflow`
|
||||
|
||||
#### `application-prod.properties` - Production
|
||||
|
||||
**🔐 Point important : OIDC OBLIGATOIRE en PROD**
|
||||
|
||||
Contient :
|
||||
- **Port** : `8080`
|
||||
- **Logging** : INFO/WARN
|
||||
- **OIDC** : `quarkus.oidc.enabled=true` ✅
|
||||
- Vérification TLS requise
|
||||
- Token validation stricte
|
||||
- Extraction des rôles
|
||||
- **Security** : Activée et stricte
|
||||
- `quarkus.security.auth.enabled=true`
|
||||
- `quarkus.security.jaxrs.deny-unannotated-endpoints=true`
|
||||
- **Keycloak Admin** : Production `https://security.lions.dev/realms/master`
|
||||
- **Database** : PostgreSQL pour audit
|
||||
- **Swagger** : Désactivé
|
||||
- **Performance** : Thread pool optimisé (4-32 threads)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Utilisation
|
||||
|
||||
### Démarrage en mode DEV
|
||||
|
||||
```bash
|
||||
# Backend (port 8081, OIDC désactivé)
|
||||
cd lions-user-manager/lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev
|
||||
|
||||
# Client (port 8082, OIDC activé vers Keycloak local)
|
||||
cd lions-user-manager/lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
**Accès** : http://localhost:8082
|
||||
|
||||
### Démarrage en mode PROD
|
||||
|
||||
```bash
|
||||
# Backend
|
||||
mvn clean package -Pprod
|
||||
java -jar target/quarkus-app/quarkus-run.jar
|
||||
|
||||
# Client
|
||||
mvn clean package -Pprod
|
||||
java -jar target/quarkus-app/quarkus-run.jar
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Architecture de sécurité
|
||||
|
||||
### Mode DEV (simplifié)
|
||||
```
|
||||
[Navigateur] → [Client JSF:8082] → [Backend API:8081]
|
||||
↓ OIDC ✗ Pas d'OIDC
|
||||
[Keycloak local]
|
||||
```
|
||||
|
||||
**Avantages** :
|
||||
- ✅ Développement rapide sans configuration Keycloak backend
|
||||
- ✅ Client reste sécurisé (authentification utilisateur)
|
||||
- ✅ Pas de conflit de realms
|
||||
|
||||
**Inconvénients** :
|
||||
- ⚠️ Backend non sécurisé (localhost uniquement)
|
||||
- ⚠️ Différent de la production
|
||||
|
||||
---
|
||||
|
||||
### Mode PROD (sécurisé)
|
||||
```
|
||||
[Navigateur] → [Client JSF:8080] → [Backend API:8080]
|
||||
↓ OIDC ↓ OIDC
|
||||
[Keycloak Production]
|
||||
```
|
||||
|
||||
**Avantages** :
|
||||
- ✅ Défense en profondeur (double validation)
|
||||
- ✅ Traçabilité (qui a fait quoi)
|
||||
- ✅ Zero-trust (backend ne fait confiance à personne)
|
||||
- ✅ Best practice microservices
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Variables d'environnement requises en PROD
|
||||
|
||||
### Client
|
||||
|
||||
```bash
|
||||
LIONS_USER_MANAGER_BACKEND_URL=https://api.lions.dev/user-manager
|
||||
KEYCLOAK_AUTH_SERVER_URL=https://security.lions.dev/realms/master
|
||||
KEYCLOAK_CLIENT_ID=lions-user-manager-client
|
||||
KEYCLOAK_CLIENT_SECRET=<secret-du-client>
|
||||
OIDC_ENCRYPTION_SECRET=<secret-32-chars-minimum>
|
||||
CORS_ORIGINS=https://lions.dev,https://app.lions.dev
|
||||
```
|
||||
|
||||
### Serveur
|
||||
|
||||
```bash
|
||||
KEYCLOAK_CLIENT_SECRET=<secret-du-backend>
|
||||
KEYCLOAK_ADMIN_USERNAME=admin
|
||||
KEYCLOAK_ADMIN_PASSWORD=<mot-de-passe-admin>
|
||||
KEYCLOAK_AUTHORIZED_REALMS=btpxpress,master,unionflow
|
||||
DB_USERNAME=audit_user
|
||||
DB_PASSWORD=<mot-de-passe-db>
|
||||
DB_HOST=lions-db.lions.svc.cluster.local
|
||||
DB_NAME=lions_audit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Réactiver OIDC en DEV (optionnel)
|
||||
|
||||
Si vous voulez tester le flow complet en développement :
|
||||
|
||||
### Étape 1 : Modifier `application-dev.properties` du serveur
|
||||
|
||||
```properties
|
||||
# Commenter cette ligne:
|
||||
# quarkus.oidc.enabled=false
|
||||
|
||||
# Décommenter ces lignes:
|
||||
quarkus.oidc.enabled=true
|
||||
quarkus.oidc.auth-server-url=http://localhost:8180/realms/lions-user-manager
|
||||
quarkus.oidc.tls.verification=none
|
||||
quarkus.oidc.token.issuer=http://localhost:8180/realms/lions-user-manager
|
||||
quarkus.oidc.discovery-enabled=true
|
||||
quarkus.oidc.token.audience=account
|
||||
quarkus.oidc.verify-access-token=true
|
||||
quarkus.oidc.roles.role-claim-path=realm_access/roles
|
||||
quarkus.security.auth.enabled=true
|
||||
```
|
||||
|
||||
### Étape 2 : Configurer Keycloak
|
||||
|
||||
Suivre le guide : `KEYCLOAK_DEV_SETUP.md`
|
||||
|
||||
---
|
||||
|
||||
## ✅ Vérification de la configuration
|
||||
|
||||
### Compilationdes modules
|
||||
|
||||
```bash
|
||||
# Client
|
||||
cd lions-user-manager/lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn compile -DskipTests
|
||||
|
||||
# Serveur
|
||||
cd lions-user-manager/lions-user-manager-server-impl-quarkus
|
||||
mvn compile -DskipTests
|
||||
```
|
||||
|
||||
### Test rapide
|
||||
|
||||
```bash
|
||||
# Backend health check
|
||||
curl http://localhost:8081/health
|
||||
|
||||
# Client (via navigateur)
|
||||
http://localhost:8082
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Résumé des ports
|
||||
|
||||
| Module | DEV | PROD |
|
||||
|--------|-----|------|
|
||||
| **Client** | 8082 | 8080 |
|
||||
| **Serveur** | 8081 | 8080 |
|
||||
| **Keycloak** | 8180 | 443 |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Erreur : "Propriété non trouvée"
|
||||
✅ Vérifier que le profil est correct : `-Dquarkus.profile=dev` ou `-Pprod`
|
||||
|
||||
### Erreur : "Port already in use"
|
||||
✅ Vérifier qu'un seul module tourne sur chaque port
|
||||
|
||||
### Erreur HTTP 405 en DEV
|
||||
✅ Vérifier que OIDC est désactivé sur le backend DEV
|
||||
|
||||
### Erreur 401 en PROD
|
||||
✅ Vérifier que les secrets Keycloak sont corrects
|
||||
✅ Vérifier que les realms correspondent (client et serveur)
|
||||
|
||||
---
|
||||
|
||||
## 📖 Documentation complémentaire
|
||||
|
||||
- `KEYCLOAK_DEV_SETUP.md` - Configuration Keycloak pour DEV
|
||||
- `test-keycloak-config.sh` - Script de vérification (Linux/Mac)
|
||||
- `test-keycloak-config.ps1` - Script de vérification (Windows)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour** : 2025-12-25
|
||||
**Version** : 1.0.0
|
||||
@@ -1,139 +0,0 @@
|
||||
# Configuration Keycloak - Utilisateur de Test
|
||||
|
||||
Ce document explique comment configurer un utilisateur de test dans Keycloak avec les rôles nécessaires pour utiliser `lions-user-manager`.
|
||||
|
||||
## Prérequis
|
||||
|
||||
- Keycloak accessible sur `http://localhost:8180`
|
||||
- Accès admin : `admin` / `admin`
|
||||
- Realm `lions-user-manager` créé
|
||||
|
||||
## Étapes de Configuration
|
||||
|
||||
### 1. Créer l'utilisateur de test
|
||||
|
||||
1. Connectez-vous à Keycloak Admin Console : `http://localhost:8180`
|
||||
2. Sélectionnez le realm `lions-user-manager`
|
||||
3. Allez dans **Users** → **Add user**
|
||||
4. Remplissez les informations :
|
||||
- **Username** : `test-user` (ou le nom de votre choix)
|
||||
- **Email** : `test@lions.dev`
|
||||
- **First name** : `Test`
|
||||
- **Last name** : `User`
|
||||
- **Email verified** : `ON`
|
||||
- **Enabled** : `ON`
|
||||
5. Cliquez sur **Create**
|
||||
|
||||
### 2. Définir le mot de passe
|
||||
|
||||
1. Dans la page de l'utilisateur, allez dans l'onglet **Credentials**
|
||||
2. Cliquez sur **Set password**
|
||||
3. Définissez un mot de passe (ex: `test123`)
|
||||
4. **Temporary** : `OFF` (pour éviter de changer le mot de passe à la première connexion)
|
||||
5. Cliquez sur **Save**
|
||||
6. Confirmez dans la popup
|
||||
|
||||
### 3. Créer les rôles Realm nécessaires
|
||||
|
||||
Les rôles suivants doivent exister dans le realm `lions-user-manager` :
|
||||
|
||||
#### Rôles requis pour les endpoints Users :
|
||||
- `admin` - Accès complet
|
||||
- `user_manager` - Gestion des utilisateurs
|
||||
- `user_viewer` - Consultation des utilisateurs
|
||||
|
||||
#### Rôles requis pour les endpoints Roles :
|
||||
- `role_manager` - Gestion des rôles
|
||||
- `role_viewer` - Consultation des rôles
|
||||
|
||||
#### Rôles requis pour les endpoints Audit :
|
||||
- `auditor` - Accès aux logs d'audit
|
||||
|
||||
#### Rôles requis pour les endpoints Sync :
|
||||
- `sync_manager` - Gestion de la synchronisation
|
||||
|
||||
**Création des rôles :**
|
||||
|
||||
1. Allez dans **Realm roles** → **Create role**
|
||||
2. Créez chaque rôle un par un :
|
||||
- `admin`
|
||||
- `user_manager`
|
||||
- `user_viewer`
|
||||
- `role_manager`
|
||||
- `role_viewer`
|
||||
- `auditor`
|
||||
- `sync_manager`
|
||||
|
||||
### 4. Assigner les rôles à l'utilisateur
|
||||
|
||||
1. Retournez dans **Users** → Sélectionnez votre utilisateur de test
|
||||
2. Allez dans l'onglet **Role mapping**
|
||||
3. Cliquez sur **Assign role**
|
||||
4. Sélectionnez **Filter by realm roles**
|
||||
5. Cochez les rôles nécessaires :
|
||||
- Pour un accès complet : `admin`
|
||||
- Pour un accès limité : `user_manager`, `user_viewer`, `role_manager`, `role_viewer`
|
||||
6. Cliquez sur **Assign**
|
||||
|
||||
### 5. Configurer le Client pour les rôles
|
||||
|
||||
1. Allez dans **Clients** → Sélectionnez `lions-user-manager-client`
|
||||
2. Allez dans l'onglet **Mappers**
|
||||
3. Vérifiez qu'il existe un mapper pour les rôles realm :
|
||||
- **Name** : `realm roles`
|
||||
- **Mapper Type** : `Realm Role`
|
||||
- **Token Claim Name** : `realm_access.roles`
|
||||
- **Add to access token** : `ON`
|
||||
- **Add to ID token** : `ON`
|
||||
- **Add to userinfo** : `ON`
|
||||
|
||||
Si le mapper n'existe pas, créez-le :
|
||||
- Cliquez sur **Create**
|
||||
- **Name** : `realm roles`
|
||||
- **Mapper Type** : `Realm Role`
|
||||
- **Token Claim Name** : `realm_access.roles`
|
||||
- **Add to access token** : `ON`
|
||||
- **Add to ID token** : `ON`
|
||||
- **Add to userinfo** : `ON`
|
||||
- Cliquez sur **Save**
|
||||
|
||||
### 6. Vérifier la configuration
|
||||
|
||||
1. Connectez-vous au client avec l'utilisateur de test
|
||||
2. Ouvrez les DevTools du navigateur (F12)
|
||||
3. Allez dans **Application** → **Cookies**
|
||||
4. Trouvez le cookie de session
|
||||
5. Décodez le token JWT (utilisez https://jwt.io)
|
||||
6. Vérifiez que le claim `realm_access.roles` contient les rôles assignés
|
||||
|
||||
## Configuration rapide via script
|
||||
|
||||
Un script de configuration automatique sera créé prochainement.
|
||||
|
||||
## Rôles par endpoint
|
||||
|
||||
### `/api/users/*`
|
||||
- `admin` - Accès complet
|
||||
- `user_manager` - Création, modification, suppression
|
||||
- `user_viewer` - Consultation uniquement
|
||||
|
||||
### `/api/roles/*`
|
||||
- `admin` - Accès complet
|
||||
- `role_manager` - Création, modification, suppression
|
||||
- `role_viewer` - Consultation uniquement
|
||||
|
||||
### `/api/audit/*`
|
||||
- `admin` - Accès complet
|
||||
- `auditor` - Consultation des logs
|
||||
|
||||
### `/api/sync/*`
|
||||
- `admin` - Accès complet
|
||||
- `sync_manager` - Gestion de la synchronisation
|
||||
|
||||
## Notes importantes
|
||||
|
||||
- Les rôles sont vérifiés côté backend via `@RolesAllowed`
|
||||
- Le token JWT doit contenir les rôles dans `realm_access.roles`
|
||||
- Le client propage automatiquement le token au backend via `bearer-token-propagation=true`
|
||||
- En production, utilisez des rôles plus granulaires selon les besoins
|
||||
|
||||
@@ -1,313 +0,0 @@
|
||||
# Corrections Finales - Lions User Manager
|
||||
|
||||
**Date**: 2025-12-05
|
||||
**Statut**: ✅ Corrections complètes
|
||||
|
||||
## 🎯 Problèmes Identifiés et Corrigés
|
||||
|
||||
### 1. ❌ Rôles Keycloak Manquants
|
||||
**Problème**: Aucun rôle métier n'existait dans le realm `lions-user-manager`, seulement les rôles par défaut Keycloak.
|
||||
|
||||
**Impact**:
|
||||
- Token JWT ne contenait aucun rôle métier
|
||||
- Frontend affichait: `No claim exists at the path 'realm_access/roles'`
|
||||
- Impossible de gérer les autorisations
|
||||
|
||||
**Solution**: ✅
|
||||
- Créé les 5 rôles métier via script `create-roles-and-assign.sh`:
|
||||
- `admin` - Administrateur système
|
||||
- `user_manager` - Gestionnaire d'utilisateurs
|
||||
- `user_viewer` - Visualiseur d'utilisateurs
|
||||
- `auditor` - Auditeur
|
||||
- `sync_manager` - Gestionnaire de synchronisation
|
||||
- Assigné tous les rôles à l'utilisateur `testuser`
|
||||
|
||||
**Fichier**: `create-roles-and-assign.sh`
|
||||
|
||||
---
|
||||
|
||||
### 2. ❌ KeycloakTestUserConfig - Erreur bruteForceStrategy
|
||||
**Problème**: La classe `KeycloakTestUserConfig` tentait de lire la représentation du realm au démarrage, causant une erreur de désérialisation JSON avec le champ `bruteForceStrategy` non reconnu par la version Keycloak Admin Client.
|
||||
|
||||
**Impact**:
|
||||
- Erreur au démarrage du backend
|
||||
- Logs pollués avec des stack traces
|
||||
|
||||
**Solution**: ✅
|
||||
- Désactivé complètement `KeycloakTestUserConfig.onStart()`
|
||||
- Ajouté commentaires expliquant la désactivation
|
||||
- Configuration manuelle via script recommandée
|
||||
|
||||
**Fichier**: `lions-user-manager-server-impl-quarkus/src/main/java/dev/lions/user/manager/config/KeycloakTestUserConfig.java:62-68`
|
||||
|
||||
---
|
||||
|
||||
### 3. ❌ Extraction des Rôles depuis ID Token
|
||||
**Problème**: Le frontend Quarkus OIDC extrayait les rôles depuis l'`id_token` par défaut, mais Keycloak ne met `realm_access.roles` QUE dans l'`access_token`.
|
||||
|
||||
**Impact**:
|
||||
- Logs: `No claim exists at the path 'realm_access/roles' at the path segment 'realm_access'`
|
||||
- Aucun rôle disponible dans le contexte de sécurité
|
||||
|
||||
**Solution**: ✅
|
||||
- Configuré `quarkus.oidc.roles.source=accesstoken`
|
||||
- Les rôles sont maintenant extraits de l'access token qui contient bien `realm_access.roles`
|
||||
|
||||
**Fichier**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/application.properties:64`
|
||||
|
||||
---
|
||||
|
||||
### 4. ❌ Propagation du Token JWT - bearer-token-propagation Insuffisant
|
||||
**Problème**: La configuration `bearer-token-propagation=true` ne suffit pas pour propager le token depuis les managed beans JSF vers le backend. Cette configuration ne fonctionne QUE pour les appels backend-to-backend, PAS pour les appels JSF-to-backend.
|
||||
|
||||
**Impact**:
|
||||
- Backend logs: `Bearer access token is not available`
|
||||
- Frontend: `Received: 'Unauthorized, status code 401'`
|
||||
- Token JWT n'était pas envoyé au backend malgré l'authentification réussie
|
||||
|
||||
**Solution**: ✅
|
||||
- Créé `AuthHeaderFactory` - un `ClientHeadersFactory` qui injecte le JWT et l'ajoute au header Authorization
|
||||
- Enregistré le factory sur tous les REST Clients avec `@RegisterClientHeaders(AuthHeaderFactory.class)`
|
||||
- Le token est maintenant automatiquement propagé à chaque appel REST Client
|
||||
|
||||
**Fichiers**:
|
||||
- `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/filter/AuthHeaderFactory.java` (nouveau)
|
||||
- `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/service/UserServiceClient.java:20`
|
||||
- `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/service/RoleServiceClient.java:19`
|
||||
- `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/service/AuditServiceClient.java:20`
|
||||
- `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/service/SyncServiceClient.java:16`
|
||||
|
||||
---
|
||||
|
||||
### 5. ❌ Vérification de l'Audience JWT - Backend Rejetait les Tokens
|
||||
**Problème**: Après avoir résolu la propagation du token, le backend rejetait toujours les requêtes avec une erreur d'audience (aud) mismatch.
|
||||
|
||||
**Impact**:
|
||||
- Backend logs: `Audience (aud) claim [account] doesn't contain an acceptable identifier. Expected optional as an aud value.`
|
||||
- Token contient `"aud": "account"` (audience par défaut Keycloak)
|
||||
- Backend attendait `"optional"` (interprétation incorrecte de la config)
|
||||
|
||||
**Solution**: ✅
|
||||
- Changé `quarkus.oidc.token.audience=optional` vers `quarkus.oidc.token.audience=account`
|
||||
- Le backend accepte maintenant les tokens avec audience "account"
|
||||
- Pas besoin de modifier la configuration Keycloak
|
||||
|
||||
**Fichier**: `lions-user-manager-server-impl-quarkus/src/main/resources/application-dev.properties:25`
|
||||
|
||||
**Explication technique**:
|
||||
- Keycloak ajoute automatiquement `"aud": "account"` aux access tokens
|
||||
- `audience=optional` ne désactive PAS la vérification, mais attend littéralement "optional"
|
||||
- `audience=account` accepte les tokens avec cette audience standard
|
||||
|
||||
---
|
||||
|
||||
### 6. ❌ DataTable rowKey Manquant - Erreur JSF
|
||||
**Problème**: Le composant PrimeFaces DataTable dans `user-data-table.xhtml` n'avait pas l'attribut `rowKey` requis.
|
||||
|
||||
**Impact**:
|
||||
- Erreur JSF: `DataTable#rowKey must be defined for component formUsers:userTable`
|
||||
- Page `/pages/user-manager/users/list.xhtml` ne se chargeait pas
|
||||
- Exception lors du rendu de la vue
|
||||
|
||||
**Solution**: ✅
|
||||
- Ajouté `rowKey="#{user.id}"` au p:dataTable
|
||||
- Identifie de manière unique chaque ligne par l'ID utilisateur
|
||||
- PrimeFaces utilise cette clé pour la sélection, pagination, et tri
|
||||
|
||||
**Fichier**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/shared/tables/user-data-table.xhtml:61`
|
||||
|
||||
---
|
||||
|
||||
## 📋 État Final
|
||||
|
||||
### Backend (Port 8081)
|
||||
- ✅ Démarre correctement sans erreur
|
||||
- ✅ Client Keycloak initialisé (connexion lazy)
|
||||
- ✅ Accepte les tokens JWT Bearer
|
||||
- ✅ API REST accessibles
|
||||
|
||||
### Frontend (Port 8080)
|
||||
- ✅ Authentification OIDC fonctionnelle
|
||||
- ✅ PKCE activé (S256)
|
||||
- ✅ Extraction des rôles depuis access_token
|
||||
- ✅ Propagation du token au backend
|
||||
|
||||
### Keycloak (Port 8180)
|
||||
- ✅ Realm `lions-user-manager` configuré
|
||||
- ✅ Client `lions-user-manager-client` (secret: `NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO`)
|
||||
- ✅ 5 rôles métier créés
|
||||
- ✅ Utilisateur `testuser` avec tous les rôles assignés
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Étapes de Test
|
||||
|
||||
### 1. Redémarrer le Backend
|
||||
```bash
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
**Vérifications**:
|
||||
- ✅ Pas d'erreur `bruteForceStrategy`
|
||||
- ✅ Message: "Configuration automatique de Keycloak DÉSACTIVÉE"
|
||||
- ✅ Message: "Client Keycloak initialisé (connexion lazy)"
|
||||
|
||||
### 2. Redémarrer le Frontend
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
**Vérifications**:
|
||||
- ✅ Démarre sur port 8080
|
||||
- ✅ Pas d'erreur de configuration OIDC
|
||||
|
||||
### 3. Test d'Authentification Complète
|
||||
|
||||
#### a. Déconnexion + Reconnexion
|
||||
1. Accéder à http://localhost:8080
|
||||
2. **Se déconnecter** si déjà connecté (pour invalider l'ancien token)
|
||||
3. **Se reconnecter** avec `testuser` / `test123`
|
||||
4. Vérifier la redirection vers Keycloak
|
||||
5. Vérifier le retour après authentification
|
||||
|
||||
#### b. Vérifier les Rôles dans le Token
|
||||
Une fois reconnecté, le nouveau token JWT devrait contenir:
|
||||
```json
|
||||
{
|
||||
"realm_access": {
|
||||
"roles": [
|
||||
"admin",
|
||||
"user_manager",
|
||||
"user_viewer",
|
||||
"auditor",
|
||||
"sync_manager",
|
||||
"offline_access",
|
||||
"uma_authorization",
|
||||
"default-roles-lions-user-manager"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### c. Tester l'Accès au Backend
|
||||
1. Naviguer vers http://localhost:8080/pages/user-manager/users/list.xhtml
|
||||
2. **Vérifier**: Plus d'erreur 401 Unauthorized
|
||||
3. **Vérifier**: La liste des utilisateurs se charge
|
||||
4. **Logs Backend**: Devrait afficher que le token Bearer est reçu
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Debugging
|
||||
|
||||
### Vérifier le Token JWT
|
||||
Pour voir le contenu du token access_token après connexion, utiliser les DevTools:
|
||||
|
||||
1. Ouvrir les DevTools (F12)
|
||||
2. Onglet **Network**
|
||||
3. Filtrer par `XHR` ou `Fetch`
|
||||
4. Chercher les requêtes vers `localhost:8081/api/users`
|
||||
5. Vérifier l'en-tête `Authorization: Bearer <token>`
|
||||
6. Copier le token et le décoder sur https://jwt.io
|
||||
|
||||
### Logs Backend - Token Reçu
|
||||
Chercher dans les logs backend:
|
||||
```
|
||||
DEBUG [io.qu.oi.ru.OidcUtils] Looking for a token in the authorization header
|
||||
DEBUG [io.qu.oi.ru.BearerAuthenticationMechanism] Bearer access token is not available
|
||||
```
|
||||
|
||||
Si "Bearer access token is not available" → token non propagé
|
||||
Si absent → token bien propagé ✅
|
||||
|
||||
### Logs Frontend - Rôles Extraits
|
||||
Chercher dans les logs frontend:
|
||||
```
|
||||
DEBUG [io.qu.oi.ru.OidcUtils] No claim exists at the path 'realm_access/roles'
|
||||
```
|
||||
|
||||
Si ce message apparaît après reconnexion → rôles toujours non extraits
|
||||
Si absent → rôles correctement extraits ✅
|
||||
|
||||
---
|
||||
|
||||
## 📝 Modifications de Configuration
|
||||
|
||||
### Backend
|
||||
**Fichier**: `KeycloakTestUserConfig.java`
|
||||
```java
|
||||
void onStart(@Observes StartupEvent ev) {
|
||||
// DÉSACTIVÉ: Configuration manuelle via script
|
||||
log.info("Configuration automatique de Keycloak DÉSACTIVÉE");
|
||||
return;
|
||||
/* ANCIEN CODE DÉSACTIVÉ ... */
|
||||
}
|
||||
```
|
||||
|
||||
### Frontend
|
||||
**Fichier**: `application.properties`
|
||||
```properties
|
||||
# Extraction des rôles depuis access_token
|
||||
quarkus.oidc.roles.role-claim-path=realm_access/roles
|
||||
quarkus.oidc.roles.source=accesstoken
|
||||
|
||||
# Propagation du token (déjà configuré)
|
||||
quarkus.rest-client."lions-user-manager-api".bearer-token-propagation=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist de Validation Post-Corrections
|
||||
|
||||
### Backend
|
||||
- [ ] Démarre sans erreur `bruteForceStrategy`
|
||||
- [ ] Client Keycloak initialisé avec succès
|
||||
- [ ] Health check OK: http://localhost:8081/q/health
|
||||
- [ ] Keycloak health OK: http://localhost:8081/api/health/keycloak
|
||||
|
||||
### Frontend
|
||||
- [ ] Démarre sur port 8080
|
||||
- [ ] OIDC activé et configuré
|
||||
- [ ] Redirection vers Keycloak fonctionne
|
||||
- [ ] Authentification réussie avec testuser/test123
|
||||
- [ ] Token contient les 5 rôles métier
|
||||
|
||||
### Intégration Frontend ↔ Backend
|
||||
- [ ] Liste des utilisateurs se charge (plus de 401)
|
||||
- [ ] Token Bearer propagé au backend
|
||||
- [ ] Backend vérifie et accepte le token
|
||||
- [ ] Données retournées correctement
|
||||
|
||||
### Rôles Keycloak
|
||||
- [ ] 5 rôles métier existent dans le realm
|
||||
- [ ] testuser possède tous les rôles
|
||||
- [ ] Token JWT contient `realm_access.roles`
|
||||
- [ ] Rôles extraits de l'access_token (pas id_token)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Prochaines Étapes Recommandées
|
||||
|
||||
1. **Tester l'authentification complète** après reconnexion
|
||||
2. **Vérifier les autorisations** basées sur les rôles
|
||||
3. **Tester les opérations CRUD** (Create, Read, Update, Delete)
|
||||
4. **Tester la gestion des rôles** via l'interface
|
||||
5. **Tests d'audit** et de synchronisation
|
||||
6. **Documentation utilisateur** finale
|
||||
|
||||
---
|
||||
|
||||
## 📚 Documents de Référence
|
||||
|
||||
- `ETAT_FINAL.md` - État du projet avant ces corrections
|
||||
- `INSTRUCTIONS_TEST.md` - Instructions de test détaillées
|
||||
- `create-roles-and-assign.sh` - Script de création des rôles
|
||||
- `KEYCLOAK_SETUP.md` - Configuration Keycloak détaillée
|
||||
- `README_PORTS.md` - Configuration des ports
|
||||
|
||||
---
|
||||
|
||||
**Auteur**: Claude Code
|
||||
**Date**: 2025-12-05
|
||||
**Version**: 1.0.0
|
||||
@@ -1,288 +0,0 @@
|
||||
# Corrections Supplémentaires - Pages Rôles et Audit
|
||||
|
||||
**Date**: 2025-12-05
|
||||
**Statut**: ✅ Corrections appliquées
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Problèmes Identifiés
|
||||
|
||||
Après avoir résolu les problèmes d'authentification et de propagation du token JWT, de nouvelles erreurs sont apparues sur d'autres pages:
|
||||
|
||||
### 1. ❌ Page Rôles - Erreur 500 Backend
|
||||
**Erreur**: `Internal Server Error, status code 500` lors de l'appel à `getAllRealmRoles`
|
||||
|
||||
**Cause racine**:
|
||||
- `RoleServiceImpl.getAllRealmRoles()` appelle `keycloakAdminClient.realmExists(realmName)`
|
||||
- `realmExists()` appelait `.toRepresentation()` qui cause l'erreur `bruteForceStrategy`
|
||||
- Le realm par défaut était "master" au lieu de "lions-user-manager"
|
||||
|
||||
**Impact**:
|
||||
- Impossible de charger la liste des rôles
|
||||
- Erreur: `Le realm 'master' n'existe pas`
|
||||
|
||||
### 2. ❌ Composant roleSearchResults Introuvable
|
||||
**Erreur**: `Cannot find component for expression "roleSearchResults"`
|
||||
|
||||
**Cause**: L'attribut `update="roleSearchResults"` dans `p:ajax` ne trouvait pas le composant avec l'ID relatif
|
||||
|
||||
**Impact**: Erreur JSF lors du rendu de la page d'assignation des rôles
|
||||
|
||||
### 3. ❌ Realm par Défaut Incorrect
|
||||
**Problème**: Tous les beans utilisaient `realmName = "master"` par défaut
|
||||
|
||||
**Impact**: Les opérations échouaient car les données (utilisateurs, rôles) sont dans le realm `lions-user-manager`
|
||||
|
||||
---
|
||||
|
||||
## ✅ Corrections Appliquées
|
||||
|
||||
### Correction 1: Fix KeycloakAdminClientImpl.realmExists()
|
||||
|
||||
**Fichier**: `lions-user-manager-server-impl-quarkus/src/main/java/dev/lions/user/manager/client/KeycloakAdminClientImpl.java:145-162`
|
||||
|
||||
**Avant**:
|
||||
```java
|
||||
public boolean realmExists(String realmName) {
|
||||
try {
|
||||
getRealm(realmName).toRepresentation(); // ❌ Cause bruteForceStrategy error
|
||||
return true;
|
||||
} catch (NotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Après**:
|
||||
```java
|
||||
public boolean realmExists(String realmName) {
|
||||
try {
|
||||
// Essayer d'obtenir simplement la liste des rôles du realm
|
||||
// Si le realm n'existe pas, cela lancera une NotFoundException
|
||||
getRealm(realmName).roles().list();
|
||||
return true;
|
||||
} catch (NotFoundException e) {
|
||||
log.debug("Realm {} n'existe pas", realmName);
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
// En cas d'erreur (comme bruteForceStrategy),
|
||||
// on suppose que le realm existe
|
||||
log.debug("Erreur lors de la vérification du realm {} (probablement il existe): {}",
|
||||
realmName, e.getMessage());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Raison**:
|
||||
- `.roles().list()` ne charge pas la représentation complète du realm
|
||||
- Évite l'erreur de désérialisation `bruteForceStrategy`
|
||||
- En cas d'erreur autre que `NotFoundException`, on suppose que le realm existe
|
||||
|
||||
---
|
||||
|
||||
### Correction 2: Fix RoleGestionBean - Realm par Défaut
|
||||
|
||||
**Fichier**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/view/RoleGestionBean.java:52`
|
||||
|
||||
**Avant**:
|
||||
```java
|
||||
private String realmName = "master";
|
||||
```
|
||||
|
||||
**Après**:
|
||||
```java
|
||||
// Par défaut, utiliser le realm lions-user-manager où les rôles métier sont configurés
|
||||
private String realmName = "lions-user-manager";
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Correction 3: Fix UserListBean - Realm par Défaut
|
||||
|
||||
**Fichier**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/view/UserListBean.java:54`
|
||||
|
||||
**Avant**:
|
||||
```java
|
||||
// Le realm "master" est le realm d'administration...
|
||||
private String realmName = "master";
|
||||
```
|
||||
|
||||
**Après**:
|
||||
```java
|
||||
// Par défaut, utiliser le realm lions-user-manager où les utilisateurs sont configurés
|
||||
private String realmName = "lions-user-manager";
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Correction 4: Fix role-assignment.xhtml - Update AJAX
|
||||
|
||||
**Fichier**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/role-management/role-assignment.xhtml:171`
|
||||
|
||||
**Avant**:
|
||||
```xml
|
||||
<p:ajax event="keyup"
|
||||
delay="300"
|
||||
update="roleSearchResults" />
|
||||
```
|
||||
|
||||
**Après**:
|
||||
```xml
|
||||
<p:ajax event="keyup"
|
||||
delay="300"
|
||||
update="@parent" />
|
||||
```
|
||||
|
||||
**Raison**: `@parent` met à jour le composant parent directement sans avoir besoin de résoudre l'ID complet dans la hiérarchie JSF
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests à Effectuer
|
||||
|
||||
### 1. Page des Rôles
|
||||
|
||||
**URL**: http://localhost:8080/pages/user-manager/roles/list.xhtml
|
||||
|
||||
**Vérifications**:
|
||||
- [ ] La page se charge sans erreur 500
|
||||
- [ ] La liste des rôles s'affiche (au minimum les 5 rôles métier créés)
|
||||
- [ ] Pas d'erreur "Le realm 'master' n'existe pas"
|
||||
- [ ] Le realm sélectionné est "lions-user-manager" par défaut
|
||||
|
||||
**Résultat attendu**:
|
||||
```
|
||||
Liste des rôles:
|
||||
- admin
|
||||
- user_manager
|
||||
- user_viewer
|
||||
- auditor
|
||||
- sync_manager
|
||||
+ rôles par défaut Keycloak
|
||||
```
|
||||
|
||||
### 2. Assignation de Rôles
|
||||
|
||||
**URL**: Composant role-assignment dans les pages
|
||||
|
||||
**Vérifications**:
|
||||
- [ ] Pas d'erreur `Cannot find component for expression "roleSearchResults"`
|
||||
- [ ] La recherche de rôles fonctionne
|
||||
- [ ] L'assignation de rôles aux utilisateurs fonctionne
|
||||
|
||||
### 3. Page des Utilisateurs
|
||||
|
||||
**URL**: http://localhost:8080/pages/user-manager/users/list.xhtml
|
||||
|
||||
**Vérifications**:
|
||||
- [ ] La liste des utilisateurs du realm `lions-user-manager` s'affiche
|
||||
- [ ] Au minimum `testuser` doit être présent
|
||||
- [ ] Les rôles de testuser s'affichent correctement
|
||||
|
||||
### 4. Page d'Audit
|
||||
|
||||
**URL**: http://localhost:8080/pages/user-manager/audit/logs.xhtml
|
||||
|
||||
**Vérifications**:
|
||||
- [ ] La page se charge sans erreur
|
||||
- [ ] Pas d'erreur "does not have the property 'searchLogs'"
|
||||
- [ ] La recherche de logs fonctionne (même si aucun log n'est présent)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Résumé des Modifications
|
||||
|
||||
### Backend
|
||||
1. `KeycloakAdminClientImpl.java:145-162` - Méthode `realmExists()` réimplémentée
|
||||
|
||||
**Total Backend**: 1 fichier modifié
|
||||
|
||||
### Frontend
|
||||
1. `RoleGestionBean.java:52` - Realm par défaut changé à "lions-user-manager"
|
||||
2. `UserListBean.java:54` - Realm par défaut changé à "lions-user-manager"
|
||||
3. `role-assignment.xhtml:171` - Fix update AJAX
|
||||
|
||||
**Total Frontend**: 3 fichiers modifiés
|
||||
|
||||
---
|
||||
|
||||
## 🎯 État Actuel
|
||||
|
||||
### ✅ Fonctionnel
|
||||
- Authentification OIDC avec Keycloak
|
||||
- Propagation du token JWT (AuthHeaderFactory)
|
||||
- Liste des utilisateurs
|
||||
- Validation des tokens (audience "account")
|
||||
- DataTable avec rowKey
|
||||
|
||||
### ✅ Corrigé Aujourd'hui
|
||||
- Page des rôles (erreur 500 résolue)
|
||||
- Realm par défaut (lions-user-manager au lieu de master)
|
||||
- Vérification de l'existence du realm (sans bruteForceStrategy)
|
||||
- Composant roleSearchResults (update AJAX)
|
||||
|
||||
### 🔄 À Tester
|
||||
- Page des rôles - Liste et gestion
|
||||
- Page d'audit - Recherche de logs
|
||||
- Assignation de rôles aux utilisateurs
|
||||
- Autres opérations CRUD
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Problèmes Restants (Potentiels)
|
||||
|
||||
### Page d'Audit
|
||||
La page d'audit pourrait ne pas avoir de données car:
|
||||
- Aucune opération d'audit n'a encore été effectuée
|
||||
- Le service d'audit pourrait ne pas être actif
|
||||
|
||||
**Solution**: Effectuer quelques opérations (créer/modifier utilisateurs) pour générer des logs d'audit
|
||||
|
||||
### Autres Pages
|
||||
D'autres pages pourraient avoir des problèmes similaires:
|
||||
- Realm par défaut incorrect
|
||||
- Composants manquants dans les XHTML
|
||||
- Méthodes manquantes dans les beans
|
||||
|
||||
**Approche**: Tester chaque page une par une et corriger au fur et à mesure
|
||||
|
||||
---
|
||||
|
||||
## 💡 Leçons Apprises
|
||||
|
||||
### 1. Problème bruteForceStrategy Récurrent
|
||||
Ce problème apparaît dès qu'on essaie de lire la représentation complète d'un realm avec `.toRepresentation()`.
|
||||
|
||||
**Solutions**:
|
||||
- Utiliser des méthodes plus spécifiques (`.roles().list()`, `.users().list()`, etc.)
|
||||
- Attraper les exceptions et supposer que le realm existe en cas d'erreur de désérialisation
|
||||
- Ne jamais appeler `.toRepresentation()` si ce n'est pas absolument nécessaire
|
||||
|
||||
### 2. Realm par Défaut
|
||||
Tous les beans doivent utiliser le bon realm par défaut selon l'environnement:
|
||||
- **Dev**: `lions-user-manager` (realm de test)
|
||||
- **Prod**: Variable d'environnement configurable
|
||||
|
||||
**Bonne pratique**: Externaliser le realm par défaut dans `application.properties`
|
||||
|
||||
### 3. IDs JSF et AJAX Update
|
||||
Les composants JSF imbriqués nécessitent des références correctes:
|
||||
- `@parent` - met à jour le parent direct
|
||||
- `@form` - met à jour le formulaire entier
|
||||
- `@this` - met à jour le composant lui-même
|
||||
- `:componentId` - référence absolue depuis la racine
|
||||
|
||||
---
|
||||
|
||||
## 📚 Documents Associés
|
||||
|
||||
- `CORRECTIONS_FINALES.md` - Corrections 1-6 (authentification, propagation JWT, rowKey)
|
||||
- `SOLUTION_PROPAGATION_TOKEN.md` - Documentation technique AuthHeaderFactory
|
||||
- `INSTRUCTIONS_TEST_FINAL.md` - Instructions de test complètes
|
||||
- `RESUME_CORRECTIONS_COMPLETE.md` - Analyse architecturale
|
||||
|
||||
---
|
||||
|
||||
**Auteur**: Claude Code
|
||||
**Date**: 2025-12-05
|
||||
**Version**: 1.0.0
|
||||
@@ -1,301 +0,0 @@
|
||||
# Corrections - Timeout & ViewExpiredException
|
||||
|
||||
## 🐛 Problèmes identifiés
|
||||
|
||||
### 1. Timeout 30s sur `/api/users/search`
|
||||
```
|
||||
Erreur lors du chargement des utilisateurs:
|
||||
The timeout period of 30000ms has been exceeded while executing POST /api/users/search
|
||||
```
|
||||
|
||||
**Cause** : Le backend met trop de temps à récupérer les utilisateurs depuis Keycloak Admin API.
|
||||
|
||||
**Raisons possibles** :
|
||||
- Keycloak local lent au démarrage
|
||||
- Beaucoup d'utilisateurs à récupérer
|
||||
- Configuration Admin Client incorrecte (mauvais realm)
|
||||
|
||||
---
|
||||
|
||||
### 2. ViewExpiredException JSF
|
||||
```
|
||||
jakarta.faces.application.ViewExpiredException:
|
||||
View "/pages/user-manager/users/list.xhtml" could not be restored.
|
||||
```
|
||||
|
||||
**Cause** : La vue JSF a expiré pendant l'attente de la réponse du backend.
|
||||
|
||||
**Raisons** :
|
||||
- Timeout trop long (30s) → Session JSF expire avant la fin
|
||||
- Nombre limité de vues en session (50)
|
||||
- Rechargement de page pendant le chargement
|
||||
|
||||
---
|
||||
|
||||
## ✅ Solutions appliquées
|
||||
|
||||
### 1️⃣ Augmentation du timeout REST Client
|
||||
|
||||
**Fichier** : `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/application-dev.properties`
|
||||
|
||||
**Modification** :
|
||||
```properties
|
||||
# Timeout augmenté pour éviter les erreurs lors des appels Keycloak lents
|
||||
quarkus.rest-client."lions-user-manager-api".read-timeout=90000
|
||||
```
|
||||
|
||||
**Avant** : 30 secondes (30000ms) - **défini dans application.properties**
|
||||
**Après** : 90 secondes (90000ms) en DEV
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ Correction du realm Admin Client
|
||||
|
||||
**Fichier** : `lions-user-manager-server-impl-quarkus/src/main/resources/application-dev.properties`
|
||||
|
||||
**Problème** : Le backend essayait de s'authentifier sur le realm `lions-user-manager` au lieu de `master`.
|
||||
|
||||
**Modification** :
|
||||
```properties
|
||||
# IMPORTANT: L'utilisateur admin se trouve dans le realm "master", pas "lions-user-manager"
|
||||
lions.keycloak.server-url=http://localhost:8180
|
||||
lions.keycloak.admin-realm=master # ← Changé de "lions-user-manager" à "master"
|
||||
lions.keycloak.admin-client-id=admin-cli
|
||||
lions.keycloak.admin-username=admin
|
||||
lions.keycloak.admin-password=admin
|
||||
|
||||
# Timeout augmenté pour Keycloak local (peut être lent au démarrage)
|
||||
lions.keycloak.timeout-seconds=60 # ← Ajouté
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣.1 Ajout des permissions HTTP en DEV
|
||||
|
||||
**Fichier** : `lions-user-manager-server-impl-quarkus/src/main/resources/application-dev.properties`
|
||||
|
||||
**Problème** : Le backend retournait **403 Forbidden** même avec la sécurité désactivée, car aucune permission HTTP explicite n'était définie.
|
||||
|
||||
**Modification** :
|
||||
```properties
|
||||
# Permissions HTTP - Accès public à tous les endpoints en DEV
|
||||
quarkus.http.auth.permission.public.paths=/api/*,/q/*,/health/*,/metrics,/swagger-ui/*,/openapi
|
||||
quarkus.http.auth.permission.public.policy=permit
|
||||
```
|
||||
|
||||
**Avant** : Backend retournait 403 sur `/api/users/search`
|
||||
**Après** : Tous les endpoints `/api/*` sont accessibles sans authentification en DEV
|
||||
|
||||
**Vérification** :
|
||||
```bash
|
||||
curl -X POST http://localhost:8180/realms/master/protocol/openid-connect/token \
|
||||
-d "client_id=admin-cli" \
|
||||
-d "grant_type=password" \
|
||||
-d "username=admin" \
|
||||
-d "password=admin"
|
||||
|
||||
# ✅ Retourne un access_token → Authentification réussie
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ Amélioration de la configuration MyFaces
|
||||
|
||||
**Fichier** : `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/application.properties`
|
||||
|
||||
**Modifications** :
|
||||
```properties
|
||||
# Nombre de vues en session augmenté
|
||||
quarkus.myfaces.number-of-views-in-session=100 # Avant: 50
|
||||
quarkus.myfaces.number-of-sequential-views-in-session=20 # Avant: 10
|
||||
|
||||
# Timeout client augmenté (2h au lieu de 1h)
|
||||
quarkus.myfaces.client-view-state-timeout=7200000 # Avant: 3600000
|
||||
|
||||
# Mapping automatique activé
|
||||
quarkus.myfaces.automatic-extensionless-mapping=true # Ajouté
|
||||
```
|
||||
|
||||
**Bénéfices** :
|
||||
- ✅ Plus de vues conservées en mémoire (50 → 100)
|
||||
- ✅ Timeout client doublé (1h → 2h)
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣.1 Handler personnalisé ViewExpiredException (NOUVEAU)
|
||||
|
||||
**Fichiers créés** :
|
||||
- `CustomViewExpiredExceptionHandler.java`
|
||||
- `CustomExceptionHandlerFactory.java`
|
||||
- Configuration dans `faces-config.xml`
|
||||
|
||||
**Stratégie intelligente** :
|
||||
```java
|
||||
// Si ViewExpiredException détectée:
|
||||
if (session HTTP/OIDC valide) {
|
||||
// La vue JSF a expiré, mais l'utilisateur est toujours authentifié
|
||||
→ Rediriger vers la page d'origine (ou liste par défaut)
|
||||
} else {
|
||||
// La session HTTP/OIDC a expiré
|
||||
→ Invalider la session
|
||||
→ Rediriger vers /logout (Keycloak gère le logout complet)
|
||||
}
|
||||
```
|
||||
|
||||
**Bénéfices** :
|
||||
- ✅ **Déconnexion automatique** si la session expire
|
||||
- ✅ **Pas de boucle de redirection** vers pages protégées
|
||||
- ✅ **UX améliorée** : seulement rafraîchir si session valide
|
||||
- ✅ **Sécurité** : force la ré-authentification si nécessaire
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Test de la configuration
|
||||
|
||||
### Vérifier Keycloak
|
||||
```bash
|
||||
# Keycloak est accessible
|
||||
curl -I http://localhost:8180
|
||||
# → HTTP/1.1 302 Found ✅
|
||||
|
||||
# Le realm existe
|
||||
curl http://localhost:8180/realms/lions-user-manager
|
||||
# → {"realm":"lions-user-manager",...} ✅
|
||||
|
||||
# L'authentification admin fonctionne
|
||||
curl -X POST http://localhost:8180/realms/master/protocol/openid-connect/token \
|
||||
-d "client_id=admin-cli" -d "grant_type=password" \
|
||||
-d "username=admin" -d "password=admin"
|
||||
# → {"access_token":"..."} ✅
|
||||
```
|
||||
|
||||
### Redémarrer les applications
|
||||
|
||||
```bash
|
||||
# Terminal 1 : Backend (redémarrage nécessaire pour application-dev.properties)
|
||||
cd lions-user-manager/lions-user-manager-server-impl-quarkus
|
||||
# Arrêter avec Ctrl+C puis:
|
||||
mvn quarkus:dev
|
||||
|
||||
# Terminal 2 : Client (redémarrage nécessaire pour les nouvelles configs)
|
||||
cd lions-user-manager/lions-user-manager-client-quarkus-primefaces-freya
|
||||
# Arrêter avec Ctrl+C puis:
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
### Tester l'interface
|
||||
|
||||
1. Accéder à : http://localhost:8082
|
||||
2. Se connecter avec Keycloak
|
||||
3. Naviguer vers : `/pages/user-manager/users/list.xhtml`
|
||||
4. **Vérifier** : La liste des utilisateurs se charge (peut prendre jusqu'à 90s)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Résumé des timeouts
|
||||
|
||||
| Composant | Configuration | Avant | Après |
|
||||
|-----------|--------------|-------|-------|
|
||||
| **REST Client** (read) | `quarkus.rest-client.*.read-timeout` | 30s | 90s |
|
||||
| **Keycloak Admin** | `lions.keycloak.timeout-seconds` | 30s | 60s |
|
||||
| **MyFaces Client State** | `quarkus.myfaces.client-view-state-timeout` | 1h | 2h |
|
||||
| **Session HTTP** | `quarkus.http.session-timeout` | 60min | 60min |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Si le problème persiste
|
||||
|
||||
### Option 1 : Ajouter un cache côté backend
|
||||
|
||||
Éviter de requêter Keycloak à chaque fois :
|
||||
|
||||
```java
|
||||
@ApplicationScoped
|
||||
public class UserCacheService {
|
||||
|
||||
private final Cache<String, List<UserDTO>> cache;
|
||||
|
||||
@Inject
|
||||
UserService userService;
|
||||
|
||||
public UserCacheService() {
|
||||
cache = Caffeine.newBuilder()
|
||||
.expireAfterWrite(5, TimeUnit.MINUTES)
|
||||
.maximumSize(100)
|
||||
.build();
|
||||
}
|
||||
|
||||
public List<UserDTO> getCachedUsers(String realm) {
|
||||
return cache.get(realm, k -> userService.getAllUsers(realm, 0, 100).getUsers());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 2 : Pagination côté frontend
|
||||
|
||||
Limiter le nombre d'utilisateurs chargés :
|
||||
|
||||
```java
|
||||
// UserListBean.java
|
||||
private static final int DEFAULT_PAGE_SIZE = 20; // Au lieu de 100+
|
||||
|
||||
public void loadUsers() {
|
||||
UserSearchCriteriaDTO criteria = UserSearchCriteriaDTO.builder()
|
||||
.realmName(realmName)
|
||||
.page(currentPage)
|
||||
.pageSize(DEFAULT_PAGE_SIZE) // ← Pagination stricte
|
||||
.build();
|
||||
|
||||
UserSearchResultDTO result = userServiceClient.searchUsers(criteria);
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Option 3 : Lazy loading
|
||||
|
||||
Charger les utilisateurs seulement quand nécessaire :
|
||||
|
||||
```xhtml
|
||||
<!-- list.xhtml -->
|
||||
<p:dataTable value="#{userListBean.users}"
|
||||
lazy="true"
|
||||
paginator="true"
|
||||
rows="20">
|
||||
<!-- ... -->
|
||||
</p:dataTable>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist de vérification
|
||||
|
||||
- [x] Keycloak accessible sur http://localhost:8180
|
||||
- [x] Realm `lions-user-manager` existe
|
||||
- [x] Authentification admin `admin/admin` sur realm `master` fonctionne
|
||||
- [x] Timeout REST Client augmenté à 90s (DEV)
|
||||
- [x] Keycloak Admin Client configuré sur realm `master`
|
||||
- [x] Timeout Keycloak Admin augmenté à 60s
|
||||
- [x] MyFaces : Nombre de vues augmenté (100)
|
||||
- [x] MyFaces : Timeout client augmenté (2h)
|
||||
- [x] Redirection ViewExpired configurée
|
||||
- [x] **Permissions HTTP configurées en DEV (corrige le 403 Forbidden)**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Résultat attendu
|
||||
|
||||
Après redémarrage :
|
||||
1. ✅ Pas de timeout 30s
|
||||
2. ✅ Chargement réussi (peut prendre 10-60s selon le nombre d'utilisateurs)
|
||||
3. ✅ Pas de ViewExpiredException
|
||||
4. ✅ Liste des utilisateurs affichée
|
||||
|
||||
---
|
||||
|
||||
**Date** : 2025-12-25
|
||||
**Version** : 1.0.0
|
||||
**Statut** : ✅ CORRECTIONS APPLIQUÉES - Redémarrage requis
|
||||
@@ -1,113 +0,0 @@
|
||||
# 🔧 Correction du Warning DataTable
|
||||
|
||||
**Date**: 2025-12-18
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Warning Corrigé
|
||||
|
||||
**Message**:
|
||||
```
|
||||
DataTable with paginator=true should also set the rows attribute. ClientId: formUserList:userTable
|
||||
```
|
||||
|
||||
**Fichier**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/user-manager/users/list.xhtml`
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Analyse du Problème
|
||||
|
||||
Le DataTable avait déjà l'attribut `rows="#{userListBean.pageSize}"`, mais PrimeFaces générait un warning car :
|
||||
|
||||
1. **Valeur potentiellement null** : Si `userListBean.pageSize` est `null` ou non initialisé, PrimeFaces ne peut pas déterminer le nombre de lignes par page
|
||||
2. **Exigence PrimeFaces** : Quand `paginator="true"`, l'attribut `rows` doit avoir une valeur définie (non null)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Solution Appliquée
|
||||
|
||||
### Avant
|
||||
```xml
|
||||
<p:dataTable
|
||||
id="userTable"
|
||||
value="#{userListBean.users}"
|
||||
var="user"
|
||||
rowKey="#{user.id}"
|
||||
paginator="true"
|
||||
rows="#{userListBean.pageSize}"
|
||||
rowsPerPageTemplate="10,20,50"
|
||||
...>
|
||||
```
|
||||
|
||||
### Après
|
||||
```xml
|
||||
<p:dataTable
|
||||
id="userTable"
|
||||
value="#{userListBean.users}"
|
||||
var="user"
|
||||
rowKey="#{user.id}"
|
||||
paginator="true"
|
||||
rows="#{userListBean.pageSize != null ? userListBean.pageSize : 10}"
|
||||
rowsPerPageTemplate="10,20,50"
|
||||
...>
|
||||
```
|
||||
|
||||
**Changement** : Ajout d'une valeur par défaut de `10` si `pageSize` est `null` en utilisant l'opérateur ternaire EL.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Explication Technique
|
||||
|
||||
### Expression Language (EL) Utilisée
|
||||
|
||||
```xml
|
||||
rows="#{userListBean.pageSize != null ? userListBean.pageSize : 10}"
|
||||
```
|
||||
|
||||
**Comportement** :
|
||||
- Si `userListBean.pageSize` est défini et non null → utilise cette valeur
|
||||
- Si `userListBean.pageSize` est null → utilise `10` comme valeur par défaut
|
||||
|
||||
### Pourquoi 10 ?
|
||||
|
||||
- ✅ Valeur standard pour les tableaux paginés
|
||||
- ✅ Correspond à la première option dans `rowsPerPageTemplate="10,20,50"`
|
||||
- ✅ Bon compromis entre performance et lisibilité
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Résultat
|
||||
|
||||
### Avant
|
||||
- ⚠️ Warning à chaque chargement de la page
|
||||
- ⚠️ Comportement imprévisible si `pageSize` est null
|
||||
|
||||
### Après
|
||||
- ✅ Plus de warning
|
||||
- ✅ Comportement prévisible avec valeur par défaut
|
||||
- ✅ Pagination fonctionne correctement même si `pageSize` n'est pas initialisé
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Alternative (Si Nécessaire)
|
||||
|
||||
Si vous préférez une valeur fixe au lieu d'une valeur dynamique avec fallback :
|
||||
|
||||
```xml
|
||||
rows="10"
|
||||
```
|
||||
|
||||
**Avantage** : Plus simple, pas de dépendance à `pageSize`
|
||||
**Inconvénient** : Ne respecte pas la préférence utilisateur stockée dans `pageSize`
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [PrimeFaces DataTable Documentation](https://www.primefaces.org/docs/vdl/14.0.0/primefaces-p/dataTable.html)
|
||||
- [JSF Expression Language (EL)](https://jakarta.ee/specifications/faces/3.0/jakarta-faces-spec-3.0.html#el)
|
||||
|
||||
---
|
||||
|
||||
*Document créé le: 2025-12-18*
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
# Rapport de Couverture JaCoCo - Lions User Manager
|
||||
|
||||
## Couverture Globale Actuelle
|
||||
|
||||
- **Instructions** : 54% (4 320 missed sur 9 536 total)
|
||||
- **Branches** : 40% (347 missed sur 582 total)
|
||||
- **Lines** : 54% (1 069 missed sur 2 326 total)
|
||||
- **Methods** : 75% (107 missed sur 329 total)
|
||||
- **Classes** : 90% (4 missed sur 37 total)
|
||||
|
||||
## Couverture par Package
|
||||
|
||||
### ✅ Packages Bien Couverts (>80%)
|
||||
- `dev.lions.user.manager.mapper` : **99%** instructions, **97%** branches
|
||||
- `dev.lions.user.manager.resource` : **84%** instructions, **58%** branches
|
||||
|
||||
### ⚠️ Packages à Améliorer (<80%)
|
||||
- `dev.lions.user.manager.service.impl` : **40%** instructions, **31%** branches
|
||||
- `dev.lions.user.manager.client` : **36%** instructions, **38%** branches
|
||||
- `dev.lions.user.manager.config` : **11%** instructions, **0%** branches
|
||||
- `dev.lions.user.manager.security` : **0%** instructions, **0%** branches
|
||||
|
||||
## Actions Requises pour Atteindre 100%
|
||||
|
||||
1. **dev.lions.user.manager.security** (0%)
|
||||
- Créer des tests pour toutes les classes de sécurité
|
||||
|
||||
2. **dev.lions.user.manager.config** (11%)
|
||||
- Améliorer les tests pour les classes de configuration
|
||||
|
||||
3. **dev.lions.user.manager.client** (36%)
|
||||
- Créer des tests pour KeycloakAdminClientImpl
|
||||
|
||||
4. **dev.lions.user.manager.service.impl** (40%)
|
||||
- Améliorer les tests pour les services
|
||||
|
||||
## Rapport HTML
|
||||
|
||||
Le rapport détaillé est disponible dans :
|
||||
- `lions-user-manager-server-impl-quarkus/target/site/jacoco/index.html`
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
# 🔍 Debug OIDC Configuration - Encryption Secret
|
||||
|
||||
## Problème
|
||||
L'erreur `Secret key for encrypting state cookie is less than 16 characters long` persiste malgré la configuration.
|
||||
|
||||
## Solutions à essayer
|
||||
|
||||
### 1. Nettoyer le cache Quarkus
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean
|
||||
rm -rf target/
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
### 2. Vérifier que la propriété est chargée
|
||||
Ajouter dans `application-dev.properties` :
|
||||
```properties
|
||||
# Debug: Vérifier que la propriété est chargée
|
||||
quarkus.log.category."io.quarkus.oidc".level=DEBUG
|
||||
```
|
||||
|
||||
### 3. Utiliser une variable d'environnement
|
||||
Au lieu de mettre la valeur directement dans le fichier, utiliser une variable :
|
||||
```properties
|
||||
quarkus.oidc.token-state-manager.encryption-secret=${OIDC_ENCRYPTION_SECRET:NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO}
|
||||
```
|
||||
|
||||
Puis définir la variable d'environnement :
|
||||
```bash
|
||||
export OIDC_ENCRYPTION_SECRET=NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO
|
||||
```
|
||||
|
||||
### 4. Vérifier l'ordre de chargement
|
||||
Quarkus charge les fichiers dans cet ordre :
|
||||
1. `application.properties`
|
||||
2. `application-{profile}.properties` (ex: `application-dev.properties`)
|
||||
3. Variables d'environnement
|
||||
4. Propriétés système
|
||||
|
||||
Si la propriété est définie dans `application.properties` avec `%dev.` ET dans `application-dev.properties` sans préfixe, celle de `application-dev.properties` devrait prendre le dessus.
|
||||
|
||||
### 5. Vérifier le format de la valeur
|
||||
Assurez-vous qu'il n'y a pas d'espaces ou de caractères invisibles :
|
||||
```properties
|
||||
# ❌ MAUVAIS (espaces)
|
||||
quarkus.oidc.token-state-manager.encryption-secret= NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO
|
||||
|
||||
# ✅ BON
|
||||
quarkus.oidc.token-state-manager.encryption-secret=NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO
|
||||
```
|
||||
|
||||
### 6. Vérifier la longueur de la valeur
|
||||
La valeur `NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO` fait **32 caractères**, ce qui est suffisant.
|
||||
|
||||
### 7. Solution de contournement temporaire
|
||||
Si le problème persiste, désactiver temporairement le token state manager :
|
||||
```properties
|
||||
quarkus.oidc.token-state-manager.enabled=false
|
||||
```
|
||||
|
||||
**⚠️ ATTENTION** : Cette solution désactive le chiffrement des cookies d'état, ce qui peut être un problème de sécurité en production.
|
||||
|
||||
## Configuration actuelle
|
||||
|
||||
### application.properties (ligne 81)
|
||||
```properties
|
||||
%dev.quarkus.oidc.token-state-manager.encryption-secret=NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO
|
||||
```
|
||||
|
||||
### application-dev.properties (ligne 36)
|
||||
```properties
|
||||
quarkus.oidc.token-state-manager.encryption-secret=NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO
|
||||
```
|
||||
|
||||
## Vérification
|
||||
|
||||
Pour vérifier que la propriété est bien chargée, ajouter ce log au démarrage :
|
||||
```properties
|
||||
quarkus.log.category."io.quarkus.oidc.runtime".level=TRACE
|
||||
```
|
||||
|
||||
Les logs devraient montrer la valeur chargée.
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
# Debug du Token JWT
|
||||
|
||||
## Problème
|
||||
Le backend retourne `401 Unauthorized` lors des appels REST, même avec un token JWT valide.
|
||||
|
||||
## Vérifications à faire
|
||||
|
||||
### 1. Vérifier que le token contient les rôles
|
||||
|
||||
1. **Décoder le token JWT** :
|
||||
- Allez sur https://jwt.io
|
||||
- Collez le token JWT (récupéré depuis les cookies du navigateur ou les logs)
|
||||
- Vérifiez la présence du claim `roles` avec les rôles assignés
|
||||
|
||||
2. **Vérifier le mapper Keycloak** :
|
||||
- Connectez-vous à Keycloak : http://localhost:8180
|
||||
- Realm : `lions-user-manager`
|
||||
- Clients → `lions-user-manager-client`
|
||||
- Onglet "Mappers"
|
||||
- Vérifiez qu'il existe un mapper "realm roles" avec :
|
||||
- **Claim name** : `roles`
|
||||
- **Token Claim Name** : `roles`
|
||||
- **Add to access token** : `ON`
|
||||
- **Add to ID token** : `ON`
|
||||
|
||||
### 2. Vérifier la configuration Quarkus
|
||||
|
||||
**Backend** (`application-dev.properties`) :
|
||||
```properties
|
||||
quarkus.oidc.roles.role-claim-path=roles
|
||||
```
|
||||
|
||||
**Client** (`application.properties`) :
|
||||
```properties
|
||||
quarkus.oidc.roles.role-claim-path=roles
|
||||
```
|
||||
|
||||
### 3. Vérifier que le token est envoyé
|
||||
|
||||
Dans les logs du backend, vous devriez voir :
|
||||
- `Verifying the JWT token with the local JWK keys`
|
||||
- Si les rôles sont trouvés, vous ne devriez PAS voir `No claim exists at the path 'roles'`
|
||||
|
||||
### 4. Test manuel avec curl
|
||||
|
||||
```bash
|
||||
# 1. Obtenir un token
|
||||
TOKEN=$(curl -X POST "http://localhost:8180/realms/lions-user-manager/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=test-user" \
|
||||
-d "password=test123" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=lions-user-manager-client" \
|
||||
-d "client_secret=NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO" | jq -r '.access_token')
|
||||
|
||||
# 2. Décoder le token pour vérifier les rôles
|
||||
echo $TOKEN | cut -d. -f2 | base64 -d | jq .
|
||||
|
||||
# 3. Tester l'endpoint backend avec le token
|
||||
curl -X POST "http://localhost:8081/api/users/search" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"page": 0, "pageSize": 20}'
|
||||
```
|
||||
|
||||
### 5. Vérifier les logs Quarkus
|
||||
|
||||
Activez le logging DEBUG pour OIDC :
|
||||
```properties
|
||||
quarkus.log.category."io.quarkus.oidc".level=DEBUG
|
||||
```
|
||||
|
||||
Vous devriez voir dans les logs :
|
||||
- `Verifying the JWT token with the local JWK keys`
|
||||
- `No claim exists at the path 'roles'` → **PROBLÈME** : les rôles ne sont pas dans le token
|
||||
- Ou les rôles extraits correctement
|
||||
|
||||
### 6. Solution si les rôles ne sont pas dans le token
|
||||
|
||||
1. **Vérifier le mapper Keycloak** :
|
||||
- Le mapper doit avoir `claim.name=roles`
|
||||
- Le mapper doit être activé pour `access.token.claim=true`
|
||||
|
||||
2. **Recréer le mapper** :
|
||||
- Supprimez l'ancien mapper
|
||||
- Créez un nouveau mapper "realm roles" avec la configuration correcte
|
||||
|
||||
3. **Redémarrer le backend** :
|
||||
- `KeycloakTestUserConfig` devrait créer le mapper automatiquement au démarrage
|
||||
|
||||
### 7. Solution si le token n'est pas envoyé
|
||||
|
||||
Vérifiez que le client REST propage bien le token :
|
||||
```properties
|
||||
quarkus.rest-client."lions-user-manager-api".bearer-token-propagation=true
|
||||
```
|
||||
|
||||
### 8. Solution si le backend ne peut pas valider le token
|
||||
|
||||
Vérifiez que :
|
||||
- Le realm existe : `lions-user-manager`
|
||||
- L'URL du serveur est correcte : `http://localhost:8180`
|
||||
- Le discovery est activé : `quarkus.oidc.discovery-enabled=true`
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
# Démarrage du Backend - Lions User Manager
|
||||
|
||||
## Problème: Backend bloqué au démarrage
|
||||
|
||||
Le backend démarre mais reste bloqué sur "No tests found".
|
||||
|
||||
### Solution 1: Appuyer sur 'r'
|
||||
|
||||
Dans le terminal où le backend tourne, appuyez sur **`r`** (re-run) pour continuer le démarrage.
|
||||
|
||||
### Solution 2: Redémarrer proprement
|
||||
|
||||
Si la solution 1 ne fonctionne pas:
|
||||
|
||||
1. **Arrêter le backend** : Ctrl+C dans le terminal
|
||||
2. **Redémarrer** :
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\lions-user-manager\lions-user-manager-server-impl-quarkus
|
||||
mvn clean quarkus:dev
|
||||
```
|
||||
|
||||
### Solution 3: Utiliser le profile dev explicitement
|
||||
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\lions-user-manager\lions-user-manager-server-impl-quarkus
|
||||
mvn clean quarkus:dev -Dquarkus.profile=dev
|
||||
```
|
||||
|
||||
### Solution 4: Désactiver les tests au démarrage
|
||||
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\lions-user-manager\lions-user-manager-server-impl-quarkus
|
||||
mvn clean quarkus:dev -DskipTests
|
||||
```
|
||||
|
||||
## Vérification du démarrage réussi
|
||||
|
||||
Une fois le backend démarré, vous devriez voir:
|
||||
|
||||
```
|
||||
__ ____ __ _____ ___ __ ____ ______
|
||||
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
|
||||
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
|
||||
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
|
||||
...
|
||||
INFO [io.quarkus] (Quarkus Main Thread) lions-user-manager-server-impl-quarkus 1.0.0 on JVM (powered by Quarkus x.x.x) started in Xs.
|
||||
INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
|
||||
INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, hibernate-validator, micrometer, oidc, rest, rest-client-jackson, rest-jackson, security, smallrye-context-propagation, smallrye-fault-tolerance, smallrye-health, smallrye-openapi, swagger-ui, vertx]
|
||||
```
|
||||
|
||||
## Vérifier que le backend est accessible
|
||||
|
||||
```bash
|
||||
# Health check
|
||||
curl http://localhost:8081/q/health
|
||||
|
||||
# Swagger UI (dans le navigateur)
|
||||
http://localhost:8081/q/swagger-ui
|
||||
|
||||
# Dev UI (dans le navigateur)
|
||||
http://localhost:8081/q/dev
|
||||
```
|
||||
|
||||
## Si le port 8081 est déjà utilisé
|
||||
|
||||
```bash
|
||||
# Trouver le processus qui utilise le port 8081
|
||||
netstat -ano | findstr :8081
|
||||
|
||||
# Tuer le processus (remplacer PID par le numéro affiché)
|
||||
taskkill /PID <PID> /F
|
||||
```
|
||||
|
||||
## Ordre de démarrage recommandé
|
||||
|
||||
1. **Keycloak** (port 8180) - doit tourner en premier
|
||||
2. **Backend** (port 8081) - ensuite
|
||||
3. **Frontend** (port 8080) - en dernier
|
||||
|
||||
## Logs à surveiller
|
||||
|
||||
Si le backend ne démarre pas, vérifiez:
|
||||
- Warnings Hibernate ORM (normaux si pas de base de données)
|
||||
- Erreurs de connexion Keycloak (vérifier que Keycloak tourne sur 8180)
|
||||
- Erreurs de port déjà utilisé
|
||||
@@ -1,130 +0,0 @@
|
||||
# 🚀 Guide de Démarrage Rapide - Lions User Manager
|
||||
|
||||
## 📋 Vue d'ensemble
|
||||
|
||||
L'application **Lions User Manager** comprend deux modules à démarrer :
|
||||
|
||||
1. **Backend API** (`lions-user-manager-server-impl-quarkus`) - Port **8081**
|
||||
2. **Client Web** (`lions-user-manager-client-quarkus-primefaces-freya`) - Port **8080**
|
||||
|
||||
## ✅ Prérequis
|
||||
|
||||
1. **Java 17+** installé
|
||||
2. **Maven 3.8+** installé
|
||||
3. **Keycloak** démarré sur `http://localhost:8180`
|
||||
- Username: `admin`
|
||||
- Password: `admin`
|
||||
- Realm: `master`
|
||||
|
||||
## 🚀 Démarrage en 2 étapes
|
||||
|
||||
### Étape 1 : Démarrer le Backend (OBLIGATOIRE)
|
||||
|
||||
Ouvrir un **premier terminal** et exécuter :
|
||||
|
||||
```bash
|
||||
cd lions-user-manager/lions-user-manager-server-impl-quarkus
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
**Vérification** :
|
||||
- Le serveur démarre sur `http://localhost:8081`
|
||||
- Vous devriez voir dans les logs : `✅ Connexion à Keycloak réussie!`
|
||||
- Swagger UI disponible : `http://localhost:8081/q/swagger-ui`
|
||||
- Health Check : `http://localhost:8081/health`
|
||||
|
||||
### Étape 2 : Démarrer le Client
|
||||
|
||||
Ouvrir un **deuxième terminal** et exécuter :
|
||||
|
||||
```bash
|
||||
cd lions-user-manager/lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
**Vérification** :
|
||||
- Le client démarre sur `http://localhost:8080`
|
||||
- Accéder à : `http://localhost:8080/pages/user-manager/users/list.xhtml`
|
||||
|
||||
## 🔍 Vérifications
|
||||
|
||||
### Vérifier que Keycloak est accessible
|
||||
```bash
|
||||
curl http://localhost:8180/realms/master/.well-known/openid-configuration
|
||||
```
|
||||
|
||||
### Vérifier que le Backend est démarré
|
||||
```bash
|
||||
curl http://localhost:8081/health
|
||||
```
|
||||
|
||||
### Vérifier que le Client est démarré
|
||||
```bash
|
||||
curl http://localhost:8080
|
||||
```
|
||||
|
||||
## ⚠️ Erreurs courantes
|
||||
|
||||
### Erreur : `Connection refused: localhost:8081`
|
||||
**Cause** : Le serveur backend n'est pas démarré
|
||||
**Solution** : Démarrer le backend en premier (Étape 1)
|
||||
|
||||
### Erreur : `Impossible de se connecter à Keycloak`
|
||||
**Cause** : Keycloak n'est pas démarré ou les identifiants sont incorrects
|
||||
**Solution** :
|
||||
- Vérifier que Keycloak est démarré sur `http://localhost:8180`
|
||||
- Vérifier les identifiants dans `application-dev.properties` :
|
||||
```
|
||||
lions.keycloak.server-url=http://localhost:8180
|
||||
lions.keycloak.admin-username=admin
|
||||
lions.keycloak.admin-password=admin
|
||||
```
|
||||
|
||||
### Erreur : `Port 8080 already in use`
|
||||
**Cause** : Un autre service utilise le port 8080
|
||||
**Solution** : Arrêter le service ou changer le port dans `application-dev.properties`
|
||||
|
||||
## 📝 Ordre de démarrage recommandé
|
||||
|
||||
1. ✅ Démarrer **Keycloak** (si pas déjà démarré)
|
||||
2. ✅ Démarrer le **Backend** (port 8081)
|
||||
3. ✅ Démarrer le **Client** (port 8080)
|
||||
|
||||
## 🔄 Hot Reload
|
||||
|
||||
Les deux modules supportent le **hot reload** :
|
||||
- Modifier le code Java → Sauvegarder → Recompilation automatique
|
||||
- Modifier les fichiers XHTML → Rafraîchir le navigateur
|
||||
|
||||
## 📚 URLs utiles
|
||||
|
||||
### Backend
|
||||
- API Base : `http://localhost:8081/api`
|
||||
- Swagger UI : `http://localhost:8081/q/swagger-ui`
|
||||
- Health Check : `http://localhost:8081/health`
|
||||
- Metrics : `http://localhost:8081/metrics`
|
||||
|
||||
### Client
|
||||
- Application : `http://localhost:8080`
|
||||
- Dashboard : `http://localhost:8080/pages/user-manager/dashboard.xhtml`
|
||||
- Liste Utilisateurs : `http://localhost:8080/pages/user-manager/users/list.xhtml`
|
||||
- Liste Rôles : `http://localhost:8080/pages/user-manager/roles/list.xhtml`
|
||||
|
||||
## 🛠️ Commandes utiles
|
||||
|
||||
### Arrêter les serveurs
|
||||
- Appuyer sur `Ctrl+C` dans chaque terminal
|
||||
|
||||
### Recompiler sans redémarrer
|
||||
```bash
|
||||
mvn compile
|
||||
```
|
||||
|
||||
### Nettoyer et recompiler
|
||||
```bash
|
||||
mvn clean compile
|
||||
```
|
||||
|
||||
### Voir les logs détaillés
|
||||
Les logs sont déjà en mode DEBUG dans `application-dev.properties`
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
# Déploiement en Production - Lions User Manager
|
||||
|
||||
## ✅ Vérification de la Déployabilité
|
||||
|
||||
### 1. Configuration Production
|
||||
|
||||
#### Backend (server-impl-quarkus)
|
||||
- ✅ **Dockerfile.prod** : Multi-stage build optimisé avec sécurité renforcée
|
||||
- ✅ **application-prod.properties** : Configuration complète pour production
|
||||
- SSL/TLS activé (`quarkus.oidc.tls.verification=required`)
|
||||
- Base de données PostgreSQL configurée pour audit
|
||||
- Logging vers fichiers et base de données
|
||||
- Métriques Prometheus activées
|
||||
- Health checks configurés
|
||||
- Swagger UI désactivé
|
||||
- Sécurité renforcée (`deny-unannotated-endpoints=true`)
|
||||
|
||||
#### Frontend (client-quarkus-primefaces-freya)
|
||||
- ✅ **Dockerfile.prod** : Multi-stage build optimisé
|
||||
- ✅ Configuration OIDC pour production
|
||||
- ✅ CORS configuré pour les domaines de production
|
||||
|
||||
### 2. Dépendances Production
|
||||
|
||||
#### Backend
|
||||
- ✅ PostgreSQL (pour logs d'audit)
|
||||
- ✅ Keycloak (serveur d'authentification)
|
||||
- ✅ Variables d'environnement requises :
|
||||
- `KEYCLOAK_CLIENT_SECRET`
|
||||
- `KEYCLOAK_ADMIN_USERNAME`
|
||||
- `KEYCLOAK_ADMIN_PASSWORD`
|
||||
- `DB_USERNAME`
|
||||
- `DB_PASSWORD`
|
||||
- `DB_HOST`
|
||||
- `DB_PORT`
|
||||
- `DB_NAME`
|
||||
- `SSL_KEYSTORE_FILE`
|
||||
- `SSL_KEYSTORE_PASSWORD`
|
||||
|
||||
#### Frontend
|
||||
- ✅ Backend API accessible
|
||||
- ✅ Keycloak OIDC configuré
|
||||
- ✅ Variables d'environnement :
|
||||
- `QUARKUS_OIDC_AUTH_SERVER_URL`
|
||||
- `QUARKUS_OIDC_CLIENT_ID`
|
||||
- `LIONS_USER_MANAGER_BACKEND_URL`
|
||||
|
||||
### 3. Build Production
|
||||
|
||||
#### Backend
|
||||
```bash
|
||||
mvn clean package -DskipTests -pl lions-user-manager-server-impl-quarkus -Dquarkus.profile=prod
|
||||
```
|
||||
|
||||
#### Frontend
|
||||
```bash
|
||||
mvn clean package -DskipTests -pl lions-user-manager-client-quarkus-primefaces-freya -Dquarkus.profile=prod
|
||||
```
|
||||
|
||||
### 4. Docker Build
|
||||
|
||||
#### Backend
|
||||
```bash
|
||||
docker build -f lions-user-manager-server-impl-quarkus/Dockerfile.prod -t lions-user-manager-server:1.0.0 .
|
||||
```
|
||||
|
||||
#### Frontend
|
||||
```bash
|
||||
docker build -f lions-user-manager-client-quarkus-primefaces-freya/Dockerfile.prod -t lions-user-manager-client:1.0.0 .
|
||||
```
|
||||
|
||||
### 5. Points d'Attention
|
||||
|
||||
#### ⚠️ Variables d'Environnement
|
||||
Toutes les variables d'environnement sensibles doivent être configurées via :
|
||||
- Secrets Kubernetes
|
||||
- Variables d'environnement Docker
|
||||
- Configuration externe (Vault, etc.)
|
||||
|
||||
#### ⚠️ Base de Données
|
||||
- La base de données PostgreSQL est **obligatoire** en production pour les logs d'audit
|
||||
- Les migrations Flyway s'exécutent automatiquement au démarrage
|
||||
- Configuration requise dans `application-prod.properties`
|
||||
|
||||
#### ⚠️ SSL/TLS
|
||||
- Certificats SSL requis pour HTTPS
|
||||
- Configuration dans `application-prod.properties` :
|
||||
- `quarkus.http.ssl.certificate.key-store-file`
|
||||
- `quarkus.http.ssl.certificate.key-store-password`
|
||||
|
||||
#### ⚠️ Keycloak
|
||||
- Serveur Keycloak doit être accessible en HTTPS
|
||||
- Client `lions-user-manager` doit être configuré dans Keycloak
|
||||
- Secret client doit être fourni via variable d'environnement
|
||||
|
||||
### 6. Health Checks
|
||||
|
||||
Les endpoints de health check sont disponibles :
|
||||
- `/q/health` : Health check général
|
||||
- `/q/health/live` : Liveness probe
|
||||
- `/q/health/ready` : Readiness probe
|
||||
- `/q/metrics` : Métriques Prometheus
|
||||
|
||||
### 7. Monitoring
|
||||
|
||||
- ✅ Métriques Prometheus activées
|
||||
- ✅ Logging structuré vers fichiers
|
||||
- ✅ Logging vers base de données (audit)
|
||||
- ✅ Health checks configurés
|
||||
|
||||
### 8. Sécurité
|
||||
|
||||
- ✅ SSL/TLS requis
|
||||
- ✅ CORS configuré pour domaines spécifiques
|
||||
- ✅ OIDC avec vérification TLS
|
||||
- ✅ Endpoints non annotés refusés
|
||||
- ✅ Swagger UI désactivé en production
|
||||
|
||||
## ✅ Conclusion
|
||||
|
||||
Le projet est **déployable en production** avec les configurations suivantes :
|
||||
|
||||
1. ✅ Dockerfiles de production présents et optimisés
|
||||
2. ✅ Configuration production complète (`application-prod.properties`)
|
||||
3. ✅ Variables d'environnement documentées
|
||||
4. ✅ Health checks configurés
|
||||
5. ✅ Monitoring et métriques activés
|
||||
6. ✅ Sécurité renforcée
|
||||
7. ✅ Base de données configurée pour audit
|
||||
|
||||
**Actions requises avant déploiement** :
|
||||
1. Configurer les secrets Kubernetes/variables d'environnement
|
||||
2. Configurer la base de données PostgreSQL
|
||||
3. Configurer les certificats SSL/TLS
|
||||
4. Configurer Keycloak avec le client `lions-user-manager`
|
||||
5. Tester le build Docker en local
|
||||
6. Déployer via Kubernetes/Docker Compose
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
# Diagnostic 401 Unauthorized - Backend
|
||||
|
||||
## Problème
|
||||
|
||||
Erreur lors de l'appel au backend :
|
||||
```
|
||||
Received: 'Unauthorized, status code 401' when invoking REST Client method:
|
||||
'dev.lions.user.manager.client.service.RoleServiceClient#getAllRealmRoles'
|
||||
```
|
||||
|
||||
## Causes Possibles
|
||||
|
||||
### 1. Token JWT non envoyé au backend
|
||||
|
||||
**Vérification** :
|
||||
- Ouvrir les DevTools du navigateur (F12)
|
||||
- Aller dans l'onglet "Network"
|
||||
- Filtrer par "XHR" ou "Fetch"
|
||||
- Cliquer sur une requête vers `/api/roles/realm`
|
||||
- Vérifier l'en-tête `Authorization: Bearer <token>`
|
||||
|
||||
**Solution** :
|
||||
- Vérifier que `bearer-token-propagation=true` est configuré dans `application.properties`
|
||||
- Vérifier que le client est bien authentifié via OIDC
|
||||
|
||||
### 2. Backend ne peut pas valider le token
|
||||
|
||||
**Vérification** :
|
||||
- Vérifier les logs du backend pour voir les erreurs OIDC
|
||||
- Chercher les messages : `Bearer access token is not available`, `Token validation failed`, etc.
|
||||
|
||||
**Solution** :
|
||||
- Vérifier que `quarkus.oidc.enabled=true` dans `application-dev.properties`
|
||||
- Vérifier que `quarkus.oidc.auth-server-url` pointe vers le bon realm (`lions-user-manager`)
|
||||
- Vérifier que `quarkus.oidc.token.issuer` correspond au realm
|
||||
|
||||
### 3. Rôles non extraits du token
|
||||
|
||||
**Vérification** :
|
||||
- Vérifier les logs du backend pour voir : `No claim exists at the path 'realm_access/roles'`
|
||||
- Obtenir le token JWT et le décoder sur https://jwt.io
|
||||
- Vérifier que le claim `realm_access.roles` existe et contient les rôles
|
||||
|
||||
**Solution** :
|
||||
- Vérifier que `quarkus.oidc.roles.role-claim-path=realm_access/roles` est configuré
|
||||
- Vérifier que le client Keycloak a le scope "roles" activé
|
||||
- Vérifier que `fullScopeAllowed=true` est configuré pour le client
|
||||
|
||||
### 4. Token expiré
|
||||
|
||||
**Vérification** :
|
||||
- Vérifier les logs du backend pour voir : `Token expired`
|
||||
- Obtenir le token JWT et vérifier le claim `exp`
|
||||
|
||||
**Solution** :
|
||||
- Se reconnecter pour obtenir un nouveau token
|
||||
- Augmenter la durée de vie du token dans Keycloak si nécessaire
|
||||
|
||||
## Étapes de Diagnostic
|
||||
|
||||
### Étape 1 : Vérifier les logs du backend
|
||||
|
||||
Redémarrer le backend avec les logs DEBUG activés et chercher :
|
||||
|
||||
```bash
|
||||
# Logs à surveiller
|
||||
- "Bearer access token is not available"
|
||||
- "No claim exists at the path"
|
||||
- "Token validation failed"
|
||||
- "Roles extracted from claim"
|
||||
```
|
||||
|
||||
### Étape 2 : Vérifier le token JWT
|
||||
|
||||
1. Obtenir le token JWT (via DevTools ou script)
|
||||
2. Décoder sur https://jwt.io
|
||||
3. Vérifier :
|
||||
- `iss` : doit être `http://localhost:8180/realms/lions-user-manager`
|
||||
- `realm_access.roles` : doit contenir les rôles (`admin`, `user_manager`, etc.)
|
||||
- `exp` : doit être dans le futur
|
||||
|
||||
### Étape 3 : Vérifier la configuration OIDC
|
||||
|
||||
**Backend** (`application-dev.properties`) :
|
||||
```properties
|
||||
quarkus.oidc.enabled=true
|
||||
quarkus.oidc.auth-server-url=http://localhost:8180/realms/lions-user-manager
|
||||
quarkus.oidc.application-type=service
|
||||
quarkus.oidc.token.issuer=http://localhost:8180/realms/lions-user-manager
|
||||
quarkus.oidc.roles.role-claim-path=realm_access/roles
|
||||
quarkus.oidc.verify-access-token=true
|
||||
```
|
||||
|
||||
**Client** (`application.properties`) :
|
||||
```properties
|
||||
quarkus.rest-client."lions-user-manager-api".bearer-token-propagation=true
|
||||
```
|
||||
|
||||
### Étape 4 : Tester manuellement avec curl
|
||||
|
||||
```bash
|
||||
# 1. Obtenir un token
|
||||
TOKEN=$(curl -X POST "http://localhost:8180/realms/lions-user-manager/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=test-user" \
|
||||
-d "password=test123" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=lions-user-manager-client" \
|
||||
-d "client_secret=NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO" \
|
||||
-d "scope=openid profile email roles" | jq -r '.access_token')
|
||||
|
||||
# 2. Tester l'endpoint backend
|
||||
curl -X GET "http://localhost:8081/api/roles/realm?realm=master" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
## Configuration Actuelle
|
||||
|
||||
### Backend OIDC
|
||||
- **Realm** : `lions-user-manager`
|
||||
- **Type** : `service` (valide les tokens sans client-id/secret)
|
||||
- **Role Claim Path** : `realm_access/roles`
|
||||
- **Token Audience** : `optional` (accepte tous les clients)
|
||||
|
||||
### Client OIDC
|
||||
- **Realm** : `lions-user-manager`
|
||||
- **Client ID** : `lions-user-manager-client`
|
||||
- **Bearer Token Propagation** : `true`
|
||||
|
||||
## Solution Recommandée
|
||||
|
||||
1. **Vérifier que le backend est démarré** sur le port 8081
|
||||
2. **Vérifier que Keycloak est démarré** sur le port 8180
|
||||
3. **Vérifier que l'utilisateur `test-user` est connecté** au client
|
||||
4. **Vérifier les logs du backend** pour voir exactement où l'erreur se produit
|
||||
5. **Tester manuellement avec curl** pour isoler le problème
|
||||
|
||||
## Logs à Surveiller
|
||||
|
||||
### Backend (port 8081)
|
||||
```bash
|
||||
# Chercher ces messages dans les logs
|
||||
DEBUG [io.qu.oi.ru.BearerAuthenticationMechanism] Starting a bearer access token authentication
|
||||
DEBUG [io.qu.oi.ru.OidcUtils] Looking for a token in the authorization header
|
||||
DEBUG [io.qu.oi.ru.OidcUtils] Roles extracted from claim 'realm_access/roles': [...]
|
||||
```
|
||||
|
||||
### Client (port 8080)
|
||||
```bash
|
||||
# Chercher ces messages dans les logs
|
||||
DEBUG [io.qu.oi.ru.OidcAuthenticationMechanism] q_session_chunk_1 cookie set
|
||||
DEBUG [io.qu.oi.ru.OidcUtils] No claim exists at the path 'realm_access/roles'
|
||||
```
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
# 🔍 Guide de Diagnostic - Démarrage du Backend
|
||||
|
||||
## ⚠️ Problème : Le serveur semble démarrer mais le client ne peut pas se connecter
|
||||
|
||||
### 📋 Vérifications à effectuer
|
||||
|
||||
#### 1. Vérifier que le serveur a TERMINÉ son démarrage
|
||||
|
||||
Le serveur n'est **pas prêt** tant que vous ne voyez **PAS** ces messages dans les logs :
|
||||
|
||||
```
|
||||
✅ Connexion à Keycloak réussie!
|
||||
Listening on: http://localhost:8081
|
||||
```
|
||||
|
||||
**Les logs que vous voyez actuellement** (scanning OpenAPI, certificats SSL, etc.) sont **normaux** mais indiquent que le serveur est **encore en train de démarrer**.
|
||||
|
||||
#### 2. Attendre la fin du démarrage
|
||||
|
||||
**Le démarrage peut prendre 30 secondes à 2 minutes** selon votre machine. Attendez de voir :
|
||||
|
||||
```
|
||||
__ ____ __ _____ ___ __ ____ ______
|
||||
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
|
||||
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
|
||||
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
|
||||
|
||||
2025-01-XX XX:XX:XX,XXX INFO [io.quarkus] (main) lions-user-manager-server-impl-quarkus 1.0.0 on JVM (powered by Quarkus 3.15.1) started in X.XXXs. Listening on: http://localhost:8081
|
||||
2025-01-XX XX:XX:XX,XXX INFO [io.quarkus] (main) Profile dev activated.
|
||||
2025-01-XX XX:XX:XX,XXX INFO [io.quarkus] (main) Installed features: [cdi, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, smallrye-fault-tolerance, smallrye-health, smallrye-openapi, swagger-ui, vertx]
|
||||
```
|
||||
|
||||
#### 3. Vérifier la connexion Keycloak
|
||||
|
||||
Après le démarrage, vous devriez voir :
|
||||
|
||||
```
|
||||
========================================
|
||||
Initialisation du client Keycloak Admin
|
||||
========================================
|
||||
Server URL: http://localhost:8180
|
||||
Admin Realm: master
|
||||
Admin Client ID: admin-cli
|
||||
Admin Username: admin
|
||||
Connection Pool Size: 5
|
||||
Timeout: 30 secondes
|
||||
✅ Connexion à Keycloak réussie!
|
||||
```
|
||||
|
||||
**Si vous voyez une erreur ici**, c'est que Keycloak n'est pas accessible.
|
||||
|
||||
#### 4. Tester manuellement que le serveur répond
|
||||
|
||||
Une fois le serveur démarré, ouvrez un **nouveau terminal** et testez :
|
||||
|
||||
```bash
|
||||
# Test 1: Health Check
|
||||
curl http://localhost:8081/health
|
||||
|
||||
# Test 2: Swagger UI (ouvrir dans le navigateur)
|
||||
# http://localhost:8081/q/swagger-ui
|
||||
|
||||
# Test 3: API Roles
|
||||
curl "http://localhost:8081/api/roles/realm?realm=master"
|
||||
```
|
||||
|
||||
#### 5. Vérifier que Keycloak est accessible
|
||||
|
||||
```bash
|
||||
# Test Keycloak
|
||||
curl http://localhost:8180/realms/master/.well-known/openid-configuration
|
||||
```
|
||||
|
||||
**Si cette commande échoue**, Keycloak n'est pas démarré ou n'est pas accessible.
|
||||
|
||||
### 🐛 Problèmes courants
|
||||
|
||||
#### Problème 1 : Le serveur est bloqué sur "OIDC Dev Console: discovering..."
|
||||
|
||||
**Cause** : Quarkus essaie de découvrir le provider OIDC même si OIDC est désactivé.
|
||||
|
||||
**Solution** : J'ai ajouté dans `application-dev.properties` :
|
||||
```properties
|
||||
quarkus.oidc.enabled=false
|
||||
quarkus.oidc.dev-ui.enabled=false
|
||||
quarkus.oidc.discovery-enabled=false
|
||||
```
|
||||
|
||||
**Action** : Redémarrer le serveur après cette modification.
|
||||
|
||||
#### Problème 2 : "Connection refused: localhost:8180"
|
||||
|
||||
**Cause** : Keycloak n'est pas démarré.
|
||||
|
||||
**Solution** : Démarrer Keycloak sur `http://localhost:8180` avec les identifiants `admin`/`admin`.
|
||||
|
||||
#### Problème 3 : Le serveur démarre mais ne répond pas sur le port 8081
|
||||
|
||||
**Cause** : Le port 8081 est peut-être déjà utilisé par un autre processus.
|
||||
|
||||
**Vérification** :
|
||||
```bash
|
||||
# Windows
|
||||
netstat -ano | findstr :8081
|
||||
|
||||
# Si un processus utilise le port, notez le PID et arrêtez-le
|
||||
taskkill /PID <PID> /F
|
||||
```
|
||||
|
||||
#### Problème 4 : "Impossible de se connecter à Keycloak"
|
||||
|
||||
**Cause** : Les identifiants Keycloak sont incorrects ou Keycloak n'est pas accessible.
|
||||
|
||||
**Vérification** :
|
||||
1. Vérifier que Keycloak est démarré : `curl http://localhost:8180/health`
|
||||
2. Vérifier les identifiants dans `application-dev.properties` :
|
||||
```
|
||||
lions.keycloak.server-url=http://localhost:8180
|
||||
lions.keycloak.admin-username=admin
|
||||
lions.keycloak.admin-password=admin
|
||||
```
|
||||
|
||||
### ✅ Checklist de démarrage réussi
|
||||
|
||||
- [ ] Le serveur affiche "Listening on: http://localhost:8081"
|
||||
- [ ] Le message "✅ Connexion à Keycloak réussie!" apparaît
|
||||
- [ ] `curl http://localhost:8081/health` retourne une réponse
|
||||
- [ ] `curl http://localhost:8180/realms/master/.well-known/openid-configuration` fonctionne
|
||||
- [ ] Le client peut se connecter au backend
|
||||
|
||||
### 📝 Prochaines étapes
|
||||
|
||||
Une fois que le serveur a **complètement démarré** (avec le message "Listening on: http://localhost:8081"), vous pouvez :
|
||||
|
||||
1. Démarrer le client dans un autre terminal
|
||||
2. Accéder à `http://localhost:8080/pages/user-manager/roles/list.xhtml`
|
||||
3. Les rôles devraient se charger depuis Keycloak
|
||||
|
||||
### 🔄 Si le problème persiste
|
||||
|
||||
1. **Arrêter** le serveur (Ctrl+C)
|
||||
2. **Vérifier** que Keycloak est démarré : `curl http://localhost:8180/health`
|
||||
3. **Redémarrer** le serveur : `mvn quarkus:dev`
|
||||
4. **Attendre** le message "Listening on: http://localhost:8081"
|
||||
5. **Tester** : `curl http://localhost:8081/health`
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
# 📋 État des Lieux - Ce qui reste à faire pour Lions User Manager
|
||||
|
||||
**Date**: 2025-12-05
|
||||
**Version**: 1.0.0
|
||||
**Statut Global**: 🟡 ~75% complété
|
||||
|
||||
---
|
||||
|
||||
## ✅ CE QUI EST COMPLÉTÉ
|
||||
|
||||
### 1. Module `server-api` (100% ✅)
|
||||
- ✅ Tous les DTOs (UserDTO, RoleDTO, AuditLogDTO, etc.)
|
||||
- ✅ Toutes les interfaces de services (UserService, RoleService, AuditService, SyncService)
|
||||
- ✅ Tous les enums (StatutUser, TypeRole, TypeActionAudit)
|
||||
- ✅ Validation constants
|
||||
|
||||
### 2. Module `server-impl-quarkus` (~85% ✅)
|
||||
- ✅ Implémentation complète des services (UserServiceImpl, RoleServiceImpl, AuditServiceImpl)
|
||||
- ✅ KeycloakAdminClient avec résilience (Circuit Breaker, Retry, Timeout)
|
||||
- ✅ Resources REST (UserResource, RoleResource, AuditResource)
|
||||
- ✅ Configuration OIDC et sécurité
|
||||
- ✅ Health checks et métriques Prometheus
|
||||
- ✅ Configuration dev/prod
|
||||
- ✅ KeycloakTestUserConfig pour configuration automatique en dev
|
||||
- ⚠️ **À améliorer**: Gestion des erreurs et logging plus détaillé
|
||||
|
||||
### 3. Module `client-quarkus-primefaces-freya` (~70% ✅)
|
||||
- ✅ REST Clients (UserServiceClient, RoleServiceClient, AuditServiceClient, SyncServiceClient)
|
||||
- ✅ Beans JSF (UserListBean, UserProfilBean, UserCreationBean, RoleGestionBean, AuditConsultationBean, DashboardBean, UserSessionBean, SettingsBean)
|
||||
- ✅ Pages XHTML principales:
|
||||
- ✅ `/pages/user-manager/dashboard.xhtml` (avec KPIs)
|
||||
- ✅ `/pages/user-manager/users/list.xhtml` (liste et recherche)
|
||||
- ✅ `/pages/user-manager/users/create.xhtml` (création)
|
||||
- ✅ `/pages/user-manager/users/profile.xhtml` (profil)
|
||||
- ✅ `/pages/user-manager/users/edit.xhtml` (édition)
|
||||
- ✅ `/pages/user-manager/roles/list.xhtml` (gestion rôles)
|
||||
- ✅ `/pages/user-manager/roles/assign.xhtml` (attribution rôles)
|
||||
- ✅ `/pages/user-manager/audit/logs.xhtml` (journal d'audit)
|
||||
- ✅ `/pages/user-manager/settings.xhtml` (paramètres)
|
||||
- ✅ Composants réutilisables (14 composants créés):
|
||||
- ✅ User Management: `user-form.xhtml`, `user-search-bar.xhtml`, `user-data-table.xhtml`, `user-actions.xhtml`, `user-role-badge.xhtml`
|
||||
- ✅ Role Management: `role-form.xhtml`, `role-card.xhtml`, `role-assignment.xhtml`
|
||||
- ✅ Audit: `audit-stats-card.xhtml`
|
||||
- ✅ Shared: `kpi-card.xhtml`, `kpi-group.xhtml`, `dashboard-section.xhtml`, `button-user-action.xhtml`, `user-stat-card.xhtml`
|
||||
- ✅ Template principal avec Freya
|
||||
- ✅ Topbar avec informations utilisateur connecté
|
||||
- ✅ Menu de navigation
|
||||
- ✅ Configuration OIDC complète
|
||||
- ✅ Gestion de session utilisateur (UserSessionBean)
|
||||
- ✅ Déconnexion OIDC fonctionnelle
|
||||
- ⚠️ **Problème résolu**: Dashboard affiche maintenant les données avec meilleure gestion d'erreurs
|
||||
|
||||
---
|
||||
|
||||
## 🔄 CE QUI RESTE À FAIRE
|
||||
|
||||
### 1. Corrections et Améliorations Urgentes
|
||||
|
||||
#### 1.1 Dashboard - Affichage des Données
|
||||
- ✅ **RÉSOLU**: Amélioration de la gestion des erreurs dans `DashboardBean`
|
||||
- ✅ **RÉSOLU**: Ajout d'un bouton de rafraîchissement
|
||||
- ⚠️ **À vérifier**: S'assurer que les appels REST fonctionnent correctement (vérifier les logs backend)
|
||||
- ⚠️ **À améliorer**: Afficher des messages d'erreur utilisateur si les données ne se chargent pas
|
||||
|
||||
#### 1.2 Gestion des Erreurs
|
||||
- [ ] Améliorer l'affichage des erreurs dans toutes les pages (messages utilisateur clairs)
|
||||
- [ ] Ajouter un composant réutilisable pour les messages d'erreur/succès
|
||||
- [ ] Gérer les cas d'erreur réseau (timeout, connexion refusée)
|
||||
- [ ] Ajouter un indicateur de chargement pour les opérations longues
|
||||
|
||||
### 2. Fonctionnalités Manquantes
|
||||
|
||||
#### 2.1 Gestion des Utilisateurs
|
||||
- [ ] Page de détails utilisateur complète (avec historique, sessions actives)
|
||||
- [ ] Export CSV des utilisateurs
|
||||
- [ ] Import CSV des utilisateurs
|
||||
- [ ] Gestion des groupes Keycloak
|
||||
- [ ] Gestion des attributs personnalisés utilisateur
|
||||
- [ ] Réinitialisation de mot de passe avec envoi d'email
|
||||
- [ ] Désactivation/Activation en masse
|
||||
- [ ] Suppression d'utilisateurs
|
||||
|
||||
#### 2.2 Gestion des Rôles
|
||||
- [ ] Page de détails rôle (avec liste des utilisateurs ayant ce rôle)
|
||||
- [ ] Gestion des rôles composites (création, modification)
|
||||
- [ ] Export/Import des rôles
|
||||
- [ ] Gestion des permissions (si applicable)
|
||||
- [ ] Suppression de rôles (actuellement seulement création/affichage)
|
||||
|
||||
#### 2.3 Audit et Reporting
|
||||
- [ ] Graphiques et visualisations des statistiques d'audit
|
||||
- [ ] Export PDF des rapports d'audit
|
||||
- [ ] Filtres avancés pour la recherche d'audit
|
||||
- [ ] Alertes sur actions suspectes
|
||||
- [ ] Dashboard d'audit avec graphiques temporels
|
||||
|
||||
#### 2.4 Synchronisation
|
||||
- [ ] Page de synchronisation complète (`/pages/user-manager/sync/dashboard.xhtml`)
|
||||
- [ ] Affichage de l'état de synchronisation avec Keycloak
|
||||
- [ ] Statistiques de synchronisation
|
||||
- [ ] Logs de synchronisation
|
||||
|
||||
### 3. Améliorations UX/UI
|
||||
|
||||
#### 3.1 Composants Réutilisables
|
||||
- [ ] Composant de pagination réutilisable
|
||||
- [ ] Composant de filtre avancé réutilisable
|
||||
- [ ] Composant de recherche globale
|
||||
- [ ] Composant de notification/toast
|
||||
- [ ] Composant de confirmation de suppression générique
|
||||
- [ ] Composant de chargement/spinner
|
||||
|
||||
#### 3.2 Pages Manquantes
|
||||
- [ ] Page de détails utilisateur (`/pages/user-manager/users/details.xhtml`)
|
||||
- [ ] Page de détails rôle (`/pages/user-manager/roles/details.xhtml`)
|
||||
- [ ] Page de gestion des groupes (`/pages/user-manager/groups/list.xhtml`)
|
||||
- [ ] Page de statistiques avancées (`/pages/user-manager/statistics/advanced.xhtml`)
|
||||
|
||||
#### 3.3 Responsive Design
|
||||
- [ ] Vérifier et améliorer le responsive sur mobile/tablette
|
||||
- [ ] Optimiser les tableaux pour petits écrans
|
||||
- [ ] Améliorer les formulaires sur mobile
|
||||
|
||||
### 4. Intégration et Configuration
|
||||
|
||||
#### 4.1 Intégration avec UnionFlow
|
||||
- ✅ **FAIT**: Dépendance Maven ajoutée dans `unionflow-client-quarkus-primefaces-freya`
|
||||
- ✅ **FAIT**: Menu items ajoutés dans `unionflow` menu
|
||||
- [ ] Tester l'intégration complète dans `unionflow`
|
||||
- [ ] Vérifier que les redirections fonctionnent correctement
|
||||
- [ ] S'assurer que les styles Freya sont cohérents entre les deux applications
|
||||
|
||||
#### 4.2 Configuration Production
|
||||
- [ ] Configuration OIDC pour production (variables d'environnement)
|
||||
- [ ] Configuration des secrets Keycloak pour production
|
||||
- [ ] Configuration des URLs backend pour production
|
||||
- [ ] Documentation de déploiement production
|
||||
|
||||
#### 4.3 Tests
|
||||
- [ ] Tests unitaires pour les beans JSF
|
||||
- [ ] Tests d'intégration pour les REST Clients
|
||||
- [ ] Tests E2E pour les principales fonctionnalités
|
||||
- [ ] Tests de performance
|
||||
|
||||
### 5. Documentation
|
||||
|
||||
#### 5.1 Documentation Technique
|
||||
- [ ] Documentation complète de l'API REST (OpenAPI/Swagger amélioré)
|
||||
- [ ] Guide d'utilisation pour les développeurs
|
||||
- [ ] Guide de déploiement
|
||||
- [ ] Architecture détaillée
|
||||
|
||||
#### 5.2 Documentation Utilisateur
|
||||
- [ ] Guide utilisateur pour la gestion des utilisateurs
|
||||
- [ ] Guide utilisateur pour la gestion des rôles
|
||||
- [ ] Guide utilisateur pour la consultation des logs d'audit
|
||||
- [ ] FAQ
|
||||
|
||||
### 6. Sécurité et Performance
|
||||
|
||||
#### 6.1 Sécurité
|
||||
- [ ] Audit de sécurité complet
|
||||
- [ ] Vérification des permissions sur toutes les actions
|
||||
- [ ] Protection CSRF (si nécessaire)
|
||||
- [ ] Rate limiting sur les endpoints sensibles
|
||||
|
||||
#### 6.2 Performance
|
||||
- [ ] Optimisation des requêtes Keycloak (cache si possible)
|
||||
- [ ] Pagination efficace pour grandes listes
|
||||
- [ ] Lazy loading pour les données volumineuses
|
||||
- [ ] Compression des réponses REST
|
||||
|
||||
### 7. Déploiement et Infrastructure
|
||||
|
||||
#### 7.1 Kubernetes
|
||||
- [ ] Helm charts pour déploiement Kubernetes
|
||||
- [ ] Configuration des ConfigMaps et Secrets
|
||||
- [ ] Health checks Kubernetes
|
||||
- [ ] Ingress configuration
|
||||
|
||||
#### 7.2 Docker
|
||||
- [ ] Dockerfiles optimisés (multi-stage builds)
|
||||
- [ ] Images Docker publiées
|
||||
- [ ] Documentation de build Docker
|
||||
|
||||
---
|
||||
|
||||
## 🎯 PRIORITÉS RECOMMANDÉES
|
||||
|
||||
### Priorité 1 (Urgent - Bloquant)
|
||||
1. ✅ **RÉSOLU**: Dashboard affiche les données
|
||||
2. [ ] Améliorer la gestion des erreurs et affichage utilisateur
|
||||
3. [ ] Tester l'intégration complète avec `unionflow`
|
||||
4. [ ] Configuration production
|
||||
|
||||
### Priorité 2 (Important - Fonctionnalités clés)
|
||||
1. [ ] Page de détails utilisateur complète
|
||||
2. [ ] Gestion des groupes Keycloak
|
||||
3. [ ] Export/Import CSV
|
||||
4. [ ] Graphiques et visualisations audit
|
||||
|
||||
### Priorité 3 (Amélioration - Nice to have)
|
||||
1. [ ] Composants réutilisables supplémentaires
|
||||
2. [ ] Tests automatisés
|
||||
3. [ ] Documentation complète
|
||||
4. [ ] Optimisations performance
|
||||
|
||||
---
|
||||
|
||||
## 📊 STATISTIQUES
|
||||
|
||||
- **Modules complétés**: 2.5 / 3 (83%)
|
||||
- **Pages XHTML créées**: 9 / 12+ (75%)
|
||||
- **Composants réutilisables**: 14 créés
|
||||
- **Fonctionnalités principales**: ~70% implémentées
|
||||
- **Tests**: 0% (à créer)
|
||||
|
||||
---
|
||||
|
||||
## 🔗 LIENS UTILES
|
||||
|
||||
- **Documentation principale**: `README.md`
|
||||
- **Plan d'optimisation**: `ANALYSE_ET_PLAN_OPTIMISATION.md`
|
||||
- **Composants créés**: `COMPOSANTS_CREES.md`
|
||||
- **Pages créées**: `PAGES_XHTML_CREES.md`
|
||||
- **Intégration UnionFlow**: `INTEGRATION_UNIONFLOW.md`
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-12-05
|
||||
**Prochaine révision**: Après résolution des priorités 1
|
||||
|
||||
256
ETAT_FINAL.md
256
ETAT_FINAL.md
@@ -1,256 +0,0 @@
|
||||
# État Final du Projet Lions User Manager
|
||||
|
||||
## ✅ Composants Opérationnels
|
||||
|
||||
### Backend (Port 8081)
|
||||
**Statut**: ✅ **PLEINEMENT OPÉRATIONNEL**
|
||||
|
||||
- **URL**: http://localhost:8081
|
||||
- **Swagger UI**: http://localhost:8081/q/swagger-ui
|
||||
- **Dev UI**: http://localhost:8081/q/dev
|
||||
- **Health Check**: http://localhost:8081/q/health
|
||||
- **Keycloak Health**: http://localhost:8081/api/health/keycloak ✅ `{"connected":true,"status":"UP"}`
|
||||
|
||||
**Endpoints API disponibles**:
|
||||
- `/api/users` - Gestion des utilisateurs
|
||||
- `/api/roles` - Gestion des rôles
|
||||
- `/api/audit` - Logs d'audit
|
||||
- `/api/sync` - Synchronisation
|
||||
- `/api/health` - Health checks
|
||||
|
||||
### Keycloak (Port 8180)
|
||||
**Statut**: ✅ **OPÉRATIONNEL**
|
||||
|
||||
- **URL**: http://localhost:8180
|
||||
- **Admin Console**: http://localhost:8180/admin
|
||||
- **Credentials Admin**: `admin` / `admin`
|
||||
- **Realm**: `lions-user-manager`
|
||||
- **Client Frontend**: `lions-user-manager-client`
|
||||
- **Client Secret**: `client-secret-lions-2025`
|
||||
- **Test User**: `testuser` / `test123`
|
||||
|
||||
### Frontend (Port 8080)
|
||||
**Statut**: ⚠️ **PARTIELLEMENT OPÉRATIONNEL**
|
||||
|
||||
- **URL**: http://localhost:8080
|
||||
- **Problème**: Authentification OIDC requise, erreurs 403 lors des appels au backend
|
||||
|
||||
## 🔧 Corrections Apportées
|
||||
|
||||
### 1. Conflit RESTEasy / Keycloak
|
||||
**Fichier**: `lions-user-manager-server-impl-quarkus/pom.xml`
|
||||
|
||||
Remplacement de `keycloak-admin-client` par l'extension Quarkus compatible:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-keycloak-admin-rest-client</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### 2. Annotations de Validation sur Méthodes Privées
|
||||
**Fichier**: `RoleServiceImpl.java`
|
||||
|
||||
Suppression des annotations `@NotBlank`, `@NotNull` sur 9 méthodes privées qui causaient des erreurs de déploiement.
|
||||
|
||||
### 3. Continuous Testing Bloquant
|
||||
**Fichier**: `application-dev.properties`
|
||||
|
||||
```properties
|
||||
quarkus.test.continuous-testing=disabled
|
||||
```
|
||||
|
||||
### 4. Compatibilité Jackson/Keycloak
|
||||
**Fichier**: `KeycloakAdminClientImpl.java`
|
||||
|
||||
- Connexion "lazy" au lieu d'appeler `serverInfo()` ou `realms().findAll()` au démarrage
|
||||
- Évite les erreurs de désérialisation JSON (`cpuInfo`, `bruteForceStrategy`)
|
||||
|
||||
**Fichier créé**: `JacksonConfig.java`
|
||||
```java
|
||||
@Singleton
|
||||
public class JacksonConfig implements ObjectMapperCustomizer {
|
||||
@Override
|
||||
public void customize(ObjectMapper objectMapper) {
|
||||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Health Check Simplifié
|
||||
**Fichier**: `HealthResourceEndpoint.java`
|
||||
|
||||
Simplification du health check pour éviter les appels Keycloak problématiques:
|
||||
```java
|
||||
boolean initialized = keycloakAdminClient.getInstance() != null;
|
||||
```
|
||||
|
||||
### 6. Propriété Manquante dans DTO
|
||||
**Fichier**: `UserSearchCriteriaDTO.java`
|
||||
|
||||
Ajout de la propriété `telephone` manquante:
|
||||
```java
|
||||
@Schema(description = "Numéro de téléphone", example = "+225 01 02 03 04 05")
|
||||
private String telephone;
|
||||
```
|
||||
|
||||
## 📋 Problèmes Résolus
|
||||
|
||||
| Problème | Solution | Statut |
|
||||
|----------|----------|--------|
|
||||
| Backend ne démarre pas | Conflit RESTEasy résolu | ✅ |
|
||||
| Annotations sur méthodes privées | Suppression annotations | ✅ |
|
||||
| Tests bloquent le démarrage | Continuous testing désactivé | ✅ |
|
||||
| Port 5005 occupé | Processus zombie tué | ✅ |
|
||||
| Erreur "cpuInfo" Keycloak | Connexion lazy | ✅ |
|
||||
| Erreur "bruteForceStrategy" | JacksonConfig + health check simplifié | ✅ |
|
||||
| Property 'telephone' manquante | Ajout dans UserSearchCriteriaDTO | ✅ |
|
||||
|
||||
## ⚠️ Problèmes Restants
|
||||
|
||||
### Frontend - Erreur 403
|
||||
**Symptôme**: Le frontend retourne "Forbidden" et ne peut pas appeler le backend.
|
||||
|
||||
**Cause probable**:
|
||||
1. Configuration OIDC incorrecte dans le frontend
|
||||
2. Le frontend ne s'authentifie pas correctement avec Keycloak
|
||||
3. Le backend refuse les appels non authentifiés
|
||||
|
||||
**Logs d'erreur**:
|
||||
```
|
||||
SEVERE [de.li.us.ma.cl.vi.UserListBean] Erreur lors du chargement des utilisateurs:
|
||||
Received: 'Forbidden, status code 403' when invoking REST Client method:
|
||||
'dev.lions.user.manager.client.service.UserServiceClient#searchUsers'
|
||||
```
|
||||
|
||||
**À vérifier**:
|
||||
- Configuration OIDC du frontend dans `application.properties`
|
||||
- Secret client Keycloak correspond bien à `client-secret-lions-2025`
|
||||
- URL Keycloak correcte: `http://localhost:8180`
|
||||
|
||||
## 🚀 Commandes de Démarrage
|
||||
|
||||
### 1. Keycloak (si pas déjà démarré)
|
||||
```bash
|
||||
# Vérifier si Keycloak tourne
|
||||
curl http://localhost:8180/health
|
||||
|
||||
# Si non, démarrer (selon votre installation)
|
||||
```
|
||||
|
||||
### 2. Backend
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\lions-user-manager\lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev -Ddebug=false
|
||||
```
|
||||
|
||||
**Vérification**:
|
||||
- Logo Quarkus ASCII art s'affiche
|
||||
- Message: `✅ Client Keycloak initialisé (connexion lazy)`
|
||||
- `Listening on: http://localhost:8081`
|
||||
|
||||
### 3. Frontend
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\lions-user-manager\lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
## 📝 Configuration Keycloak
|
||||
|
||||
### Realm: lions-user-manager
|
||||
- **Créé**: ✅
|
||||
- **Enabled**: ✅
|
||||
|
||||
### Client: lions-user-manager-client
|
||||
- **Type**: confidential
|
||||
- **Access Type**: confidential
|
||||
- **Valid Redirect URIs**: `http://localhost:8080/*`
|
||||
- **Web Origins**: `http://localhost:8080`
|
||||
- **Client Secret**: `client-secret-lions-2025`
|
||||
|
||||
### Utilisateurs de Test
|
||||
- **Admin**: `admin` / `admin` (realm master)
|
||||
- **Test User**: `testuser` / `test123` (realm lions-user-manager)
|
||||
- **Rôles**: admin, user_manager, user_viewer, auditor, sync_manager
|
||||
|
||||
## 🔍 URLs Importantes
|
||||
|
||||
### Backend
|
||||
- Swagger UI: http://localhost:8081/q/swagger-ui
|
||||
- Dev UI: http://localhost:8081/q/dev
|
||||
- Health: http://localhost:8081/q/health
|
||||
- Keycloak Health: http://localhost:8081/api/health/keycloak
|
||||
- API Users: http://localhost:8081/api/users?realm=lions-user-manager
|
||||
|
||||
### Frontend
|
||||
- Accueil: http://localhost:8080
|
||||
- (Nécessite authentification OIDC)
|
||||
|
||||
### Keycloak
|
||||
- Admin Console: http://localhost:8180/admin
|
||||
- Realm lions-user-manager: http://localhost:8180/realms/lions-user-manager
|
||||
|
||||
## 📊 Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Navigateur Web │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 1. Accès http://localhost:8080
|
||||
│ 2. Redirection OIDC vers Keycloak
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ KEYCLOAK (Port 8180) │
|
||||
│ - Authentifie l'utilisateur │
|
||||
│ - Retourne token JWT │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 3. Token retourné
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ FRONTEND (Port 8080) ⚠️ │
|
||||
│ - JSF/PrimeFaces │
|
||||
│ - OIDC Web App │
|
||||
│ - ⚠️ Erreur 403 vers backend │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 4. Appels API REST
|
||||
│ (actuellement bloqués 403)
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ BACKEND (Port 8081) ✅ │
|
||||
│ - API REST │
|
||||
│ - Keycloak Admin Client │
|
||||
│ - ✅ Client Keycloak initialisé │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 5. Admin API Keycloak
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ KEYCLOAK (Port 8180) ✅ │
|
||||
│ - Gestion users/roles │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🎯 Prochaines Étapes
|
||||
|
||||
1. ✅ Backend opérationnel
|
||||
2. ✅ Keycloak configuré
|
||||
3. ✅ Client Keycloak connecté
|
||||
4. ⏳ **Corriger authentification frontend → backend**
|
||||
5. ⏳ Tester l'authentification utilisateur complète
|
||||
6. ⏳ Tester les endpoints API
|
||||
|
||||
## 📚 Documents Créés
|
||||
|
||||
- `README_PORTS.md` - Configuration des ports
|
||||
- `TEST_BACKEND.md` - Comment tester le backend
|
||||
- `KEYCLOAK_SETUP.md` - Configuration Keycloak
|
||||
- `BACKEND_DEMARRAGE_SUCCESS.md` - Problèmes résolus pour le backend
|
||||
- `DEMARRAGE_BACKEND.md` - Guide de démarrage
|
||||
- `ETAT_FINAL.md` - Ce document
|
||||
@@ -1,99 +0,0 @@
|
||||
# Explication des Permissions dans lions-user-manager
|
||||
|
||||
## Architecture des Permissions
|
||||
|
||||
Il y a **deux niveaux de permissions** distincts dans `lions-user-manager` :
|
||||
|
||||
### 1. Permissions OIDC (Authentification/Autorisation Frontend → Backend)
|
||||
|
||||
**Qui** : L'utilisateur connecté au frontend (`test-user`)
|
||||
|
||||
**Où** : Le realm où l'utilisateur se connecte (`lions-user-manager`)
|
||||
|
||||
**Comment** :
|
||||
- L'utilisateur `test-user` se connecte via OIDC dans le realm `lions-user-manager`
|
||||
- Il obtient un token JWT contenant ses rôles (`admin`, `user_manager`, etc.) dans le claim `realm_access.roles`
|
||||
- Le frontend envoie ce token au backend dans l'en-tête `Authorization: Bearer <token>`
|
||||
- Le backend vérifie ces rôles avec `@RolesAllowed` pour **autoriser l'accès aux endpoints**
|
||||
|
||||
**Rôles nécessaires** (dans le realm `lions-user-manager`) :
|
||||
- `admin` - Accès complet
|
||||
- `user_manager` - Gestion des utilisateurs
|
||||
- `user_viewer` - Consultation des utilisateurs
|
||||
- `role_manager` - Gestion des rôles
|
||||
- `role_viewer` - Consultation des rôles
|
||||
- `auditor` - Consultation des logs
|
||||
- `sync_manager` - Gestion de la synchronisation
|
||||
|
||||
### 2. Permissions Admin API (Opérations Keycloak)
|
||||
|
||||
**Qui** : Le backend (`lions-user-manager-server-impl-quarkus`)
|
||||
|
||||
**Où** : Le realm `master` (realm d'administration)
|
||||
|
||||
**Comment** :
|
||||
- Le backend utilise les credentials `admin/admin` du realm `master` pour se connecter à l'API Admin Keycloak
|
||||
- Ces credentials permettent de gérer **TOUS les realms**, y compris `master`, `lions-user-manager`, `btpxpress`, etc.
|
||||
- Le backend effectue les opérations (créer utilisateur, assigner rôles, etc.) via l'API Admin Keycloak
|
||||
|
||||
**Configuration** (dans `application-dev.properties`) :
|
||||
```properties
|
||||
lions.keycloak.admin-realm=master
|
||||
lions.keycloak.admin-username=admin
|
||||
lions.keycloak.admin-password=admin
|
||||
```
|
||||
|
||||
## Réponse à la Question
|
||||
|
||||
**Question** : `test-user` a-t-il les droits admin pour manipuler l'administration Keycloak `master` ?
|
||||
|
||||
**Réponse** : **NON, et ce n'est pas nécessaire !**
|
||||
|
||||
**Explication** :
|
||||
1. `test-user` a les rôles nécessaires dans le realm `lions-user-manager` pour **autoriser l'accès** aux endpoints du backend
|
||||
2. Le backend utilise ensuite les credentials `admin/admin` du realm `master` pour **effectuer les opérations** sur n'importe quel realm (y compris `master`)
|
||||
3. Donc `test-user` n'a **pas besoin** d'avoir des droits dans le realm `master` pour que le backend puisse gérer ce realm
|
||||
|
||||
## Flux Complet
|
||||
|
||||
```
|
||||
1. test-user (realm: lions-user-manager)
|
||||
→ Se connecte via OIDC
|
||||
→ Obtient token JWT avec rôles: [admin, user_manager, ...]
|
||||
|
||||
2. Frontend
|
||||
→ Envoie requête au backend avec token JWT
|
||||
→ Exemple: GET /api/users/search?realm=master
|
||||
|
||||
3. Backend
|
||||
→ Vérifie les rôles dans le token JWT avec @RolesAllowed
|
||||
→ Si autorisé, utilise admin/admin (realm: master) pour effectuer l'opération
|
||||
→ Appelle l'API Admin Keycloak: GET /admin/realms/master/users
|
||||
|
||||
4. Keycloak Admin API
|
||||
→ Accepte la requête car elle vient de admin/admin (realm: master)
|
||||
→ Retourne les utilisateurs du realm master
|
||||
```
|
||||
|
||||
## Cas d'Usage
|
||||
|
||||
### Cas 1 : Gérer les utilisateurs du realm `lions-user-manager`
|
||||
- `test-user` a les rôles dans `lions-user-manager` ✅
|
||||
- Backend utilise `admin/admin` pour gérer `lions-user-manager` ✅
|
||||
- **Résultat** : ✅ Fonctionne
|
||||
|
||||
### Cas 2 : Gérer les utilisateurs du realm `master`
|
||||
- `test-user` a les rôles dans `lions-user-manager` ✅ (pour autoriser l'accès)
|
||||
- Backend utilise `admin/admin` pour gérer `master` ✅
|
||||
- **Résultat** : ✅ Fonctionne aussi !
|
||||
|
||||
## Conclusion
|
||||
|
||||
**`test-user` n'a PAS besoin d'avoir des droits dans le realm `master`** car :
|
||||
- Les rôles de `test-user` servent uniquement à **autoriser l'accès** aux endpoints du backend
|
||||
- Le backend utilise **ses propres credentials admin** (`admin/admin` du realm `master`) pour effectuer les opérations
|
||||
|
||||
C'est une architecture sécurisée qui sépare :
|
||||
- **Autorisation utilisateur** (via OIDC et rôles dans le token JWT)
|
||||
- **Permissions opérationnelles** (via credentials admin du backend)
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
# Résumé Final - Tests et Couverture JaCoCo
|
||||
|
||||
## Tests Créés
|
||||
|
||||
### Server-API
|
||||
- ✅ UserSearchCriteriaDTOTest (10 tests)
|
||||
- ✅ RoleAssignmentDTOTest (11 tests)
|
||||
- ✅ AuditLogDTOTest (5 tests)
|
||||
- ✅ StatutUserTest (4 tests)
|
||||
- ✅ TypeRoleTest (4 tests)
|
||||
- ✅ TypeActionAuditTest (4 tests)
|
||||
- ✅ RealmAssignmentDTOTest (12 tests - corrigé)
|
||||
|
||||
### Server-Impl-Quarkus
|
||||
- ✅ JacksonConfigTest
|
||||
- ✅ KeycloakTestUserConfigTest
|
||||
- ✅ DevSecurityContextProducerTest
|
||||
- ✅ RealmResourceAdditionalTest
|
||||
- ✅ RoleMapperAdditionalTest
|
||||
- ✅ AuditServiceImplAdditionalTest
|
||||
|
||||
### Client-Quarkus-Primefaces-Freya
|
||||
- ✅ RestClientExceptionMapperTest
|
||||
- ✅ AuthHeaderFactoryTest
|
||||
|
||||
## Couverture Actuelle
|
||||
|
||||
D'après le dernier rapport JaCoCo généré :
|
||||
- **Instructions** : 54%
|
||||
- **Branches** : 40%
|
||||
- **Lines** : 54%
|
||||
- **Methods** : 75%
|
||||
- **Classes** : 90%
|
||||
|
||||
## Packages à Améliorer
|
||||
|
||||
1. **dev.lions.user.manager.security** - 0% → Tests créés
|
||||
2. **dev.lions.user.manager.config** - 11% → Tests créés
|
||||
3. **dev.lions.user.manager.client** - 36% → Amélioration nécessaire
|
||||
4. **dev.lions.user.manager.service.impl** - 40% → Amélioration nécessaire
|
||||
|
||||
## Prochaines Étapes
|
||||
|
||||
1. Corriger les erreurs dans DevSecurityContextProducerTest
|
||||
2. Générer le rapport JaCoCo final
|
||||
3. Créer des tests supplémentaires pour atteindre 100% si nécessaire
|
||||
|
||||
## Commandes
|
||||
|
||||
```bash
|
||||
# Générer le rapport JaCoCo
|
||||
mvn clean test jacoco:report
|
||||
|
||||
# Voir le rapport
|
||||
# Ouvrir: lions-user-manager-server-impl-quarkus/target/site/jacoco/index.html
|
||||
```
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
# Compatibilité PrimeFaces Freya Extension avec Lions User Manager
|
||||
|
||||
## ✅ RÉPONSE : OUI, 100% COMPATIBLE !
|
||||
|
||||
**lions-user-manager** peut utiliser **primefaces-freya-extension** strictement et sans aucun problème.
|
||||
|
||||
## 📊 Analyse de compatibilité
|
||||
|
||||
### Versions identiques ou compatibles
|
||||
|
||||
| Composant | lions-user-manager | primefaces-freya-extension | Compatibilité |
|
||||
|-----------|-------------------|---------------------------|---------------|
|
||||
| **Java** | 17 | 17 | ✅ **Identique** |
|
||||
| **Quarkus** | 3.15.1 | 3.15.1 | ✅ **Identique** |
|
||||
| **PrimeFaces** | 14.0.5 | 14.0.0 | ✅ **Compatible** (même version majeure) |
|
||||
| **Freya Theme** | 5.0.0 | 5.0.0 | ✅ **Identique** |
|
||||
| **Jakarta Faces** | 4.0 (via quarkus-primefaces) | 4.0 (via quarkus-myfaces) | ✅ **Compatible** |
|
||||
| **Maven** | 3.8+ | 3.8+ | ✅ **Compatible** |
|
||||
|
||||
### Conclusion technique
|
||||
|
||||
**Aucun conflit de version détecté. L'intégration est 100% sûre.**
|
||||
|
||||
## 🎯 Bénéfices de l'intégration
|
||||
|
||||
### 1. Réduction massive du code
|
||||
|
||||
**Avant (PrimeFaces standard) :**
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel for="username" value="Nom d'utilisateur">
|
||||
<span class="p-error"> *</span>
|
||||
</p:outputLabel>
|
||||
<p:inputText id="username" value="#{userBean.username}" required="true" />
|
||||
<p:message for="username" />
|
||||
</div>
|
||||
```
|
||||
|
||||
**Après (Freya Extension) :**
|
||||
```xml
|
||||
<fr:fieldInput label="Nom d'utilisateur" value="#{userBean.username}" required="true" />
|
||||
```
|
||||
|
||||
**Résultat : 80% moins de code !**
|
||||
|
||||
### 2. Composants utiles pour lions-user-manager
|
||||
|
||||
| Composant | Usage dans lions-user-manager |
|
||||
|-----------|------------------------------|
|
||||
| `fr:fieldInput` | Username, firstName, lastName, email |
|
||||
| `fr:fieldPassword` | Mot de passe utilisateur |
|
||||
| `fr:fieldSelect` | Sélection de rôles, groupes, organisations |
|
||||
| `fr:fieldCheckbox` | Actif/Inactif, Email vérifié, Compte verrouillé |
|
||||
| `fr:fieldCalendar` | Date de création, dernière connexion |
|
||||
| `fr:dataTable` | Liste des utilisateurs avec pagination |
|
||||
| `fr:actionDialog` | Dialogs d'édition/suppression |
|
||||
| `fr:formDialog` | Dialog de création d'utilisateur |
|
||||
| `fr:growl` | Notifications de succès/erreur |
|
||||
| `fr:commandButton` | Boutons d'action (Créer, Éditer, Supprimer) |
|
||||
| `fr:tree` | Hiérarchie des organisations |
|
||||
| `fr:badge` | Nombre de rôles, groupes |
|
||||
| `fr:tag` | Statut utilisateur (Actif, Inactif, Verrouillé) |
|
||||
|
||||
### 3. Avantages pour le développement
|
||||
|
||||
- ✅ **Développement plus rapide** - Moins de boilerplate à écrire
|
||||
- ✅ **Cohérence visuelle** - Tous les formulaires utilisent le même pattern
|
||||
- ✅ **Maintenance simplifiée** - Un seul endroit pour modifier le pattern
|
||||
- ✅ **Accessibilité améliorée** - Support WCAG 2.1 AA intégré
|
||||
- ✅ **Code plus lisible** - Moins de bruit visuel dans les fichiers XHTML
|
||||
|
||||
## 🚀 Guide d'intégration rapide
|
||||
|
||||
### Étape 1 : Installer primefaces-freya-extension
|
||||
|
||||
```powershell
|
||||
# Exécuter le script d'intégration automatique
|
||||
.\integrate-freya-extension.ps1
|
||||
```
|
||||
|
||||
Ou manuellement :
|
||||
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\primefaces-freya-extension
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
### Étape 2 : Ajouter la dépendance
|
||||
|
||||
**Dans `lions-user-manager/pom.xml` :**
|
||||
```xml
|
||||
<properties>
|
||||
<primefaces-freya-extension.version>1.0.0-SNAPSHOT</primefaces-freya-extension.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.lions</groupId>
|
||||
<artifactId>primefaces-freya-extension-runtime</artifactId>
|
||||
<version>${primefaces-freya-extension.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
```
|
||||
|
||||
**Dans `lions-user-manager-client-quarkus-primefaces-freya/pom.xml` :**
|
||||
```xml
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.lions</groupId>
|
||||
<artifactId>primefaces-freya-extension-runtime</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
### Étape 3 : Utiliser dans vos pages XHTML
|
||||
|
||||
```xml
|
||||
<html xmlns:fr="http://primefaces.org/freya">
|
||||
|
||||
<h:form>
|
||||
<fr:fieldInput label="Nom d'utilisateur" value="#{userBean.username}" required="true" />
|
||||
<fr:fieldInput label="Email" value="#{userBean.email}" required="true" />
|
||||
<fr:fieldPassword label="Mot de passe" value="#{userBean.password}" required="true" />
|
||||
|
||||
<fr:commandButton value="Créer"
|
||||
action="#{userBean.create}"
|
||||
severity="success"
|
||||
icon="pi pi-user-plus" />
|
||||
</h:form>
|
||||
```
|
||||
|
||||
## 📈 Impact estimé sur lions-user-manager
|
||||
|
||||
### Réduction de code
|
||||
|
||||
| Fichier | Lignes avant | Lignes après | Réduction |
|
||||
|---------|--------------|--------------|-----------|
|
||||
| users.xhtml | ~500 lignes | ~100 lignes | **80%** |
|
||||
| user-edit.xhtml | ~300 lignes | ~60 lignes | **80%** |
|
||||
| user-create.xhtml | ~250 lignes | ~50 lignes | **80%** |
|
||||
| **TOTAL** | **~1050 lignes** | **~210 lignes** | **80%** |
|
||||
|
||||
### Temps de développement
|
||||
|
||||
- **Création d'un formulaire** : 30 min → 5 min (**83% plus rapide**)
|
||||
- **Ajout d'un champ** : 5 min → 30 sec (**90% plus rapide**)
|
||||
- **Modification du pattern** : 2h (tous les fichiers) → 5 min (un seul fichier) (**96% plus rapide**)
|
||||
|
||||
## 🎨 Exemples concrets pour lions-user-manager
|
||||
|
||||
### Formulaire de création d'utilisateur
|
||||
|
||||
```xml
|
||||
<fr:formDialog widgetVar="createUserDialog"
|
||||
header="Créer un utilisateur"
|
||||
saveAction="#{userBean.create}"
|
||||
saveUpdate="userTable">
|
||||
|
||||
<fr:fieldInput label="Nom d'utilisateur"
|
||||
value="#{userBean.newUser.username}"
|
||||
required="true"
|
||||
placeholder="Ex: jdupont" />
|
||||
|
||||
<fr:fieldInput label="Prénom"
|
||||
value="#{userBean.newUser.firstName}"
|
||||
required="true" />
|
||||
|
||||
<fr:fieldInput label="Nom"
|
||||
value="#{userBean.newUser.lastName}"
|
||||
required="true" />
|
||||
|
||||
<fr:fieldInput label="Email"
|
||||
value="#{userBean.newUser.email}"
|
||||
required="true"
|
||||
placeholder="prenom.nom@example.com" />
|
||||
|
||||
<fr:fieldPassword label="Mot de passe"
|
||||
value="#{userBean.newUser.password}"
|
||||
required="true"
|
||||
feedback="true" />
|
||||
|
||||
<fr:fieldSelect label="Rôle"
|
||||
value="#{userBean.newUser.role}"
|
||||
required="true">
|
||||
<f:selectItem itemLabel="-- Choisir --" itemValue="" />
|
||||
<f:selectItems value="#{userBean.availableRoles}" />
|
||||
</fr:fieldSelect>
|
||||
|
||||
<fr:fieldCheckbox label="Compte actif"
|
||||
value="#{userBean.newUser.enabled}" />
|
||||
|
||||
<fr:fieldCheckbox label="Email vérifié"
|
||||
value="#{userBean.newUser.emailVerified}" />
|
||||
</fr:formDialog>
|
||||
```
|
||||
|
||||
### Liste des utilisateurs avec actions
|
||||
|
||||
```xml
|
||||
<fr:dataTable value="#{userBean.users}"
|
||||
var="user"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
selectionMode="single"
|
||||
selection="#{userBean.selectedUser}">
|
||||
|
||||
<p:column headerText="Nom d'utilisateur">
|
||||
<h:outputText value="#{user.username}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Nom complet">
|
||||
<h:outputText value="#{user.firstName} #{user.lastName}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Email">
|
||||
<h:outputText value="#{user.email}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Statut">
|
||||
<fr:tag value="Actif" severity="success" rendered="#{user.enabled}" />
|
||||
<fr:tag value="Inactif" severity="danger" rendered="#{!user.enabled}" />
|
||||
</p:column>
|
||||
|
||||
<p:column headerText="Actions">
|
||||
<fr:commandButton icon="pi pi-pencil"
|
||||
severity="info"
|
||||
action="#{userBean.edit(user)}"
|
||||
update="editDialog"
|
||||
oncomplete="PF('editDialog').show()" />
|
||||
|
||||
<fr:commandButton icon="pi pi-trash"
|
||||
severity="danger"
|
||||
action="#{userBean.delete(user)}"
|
||||
update="userTable" />
|
||||
</p:column>
|
||||
</fr:dataTable>
|
||||
```
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- **Guide d'intégration complet** : [INTEGRATION_FREYA_EXTENSION.md](INTEGRATION_FREYA_EXTENSION.md)
|
||||
- **Script d'intégration** : [integrate-freya-extension.ps1](integrate-freya-extension.ps1)
|
||||
- **Documentation Freya Extension** : [../primefaces-freya-extension/README.md](../primefaces-freya-extension/README.md)
|
||||
|
||||
## ✅ Conclusion
|
||||
|
||||
**L'intégration de primefaces-freya-extension dans lions-user-manager est :**
|
||||
|
||||
- ✅ **Techniquement compatible** (versions identiques/compatibles)
|
||||
- ✅ **Fortement recommandée** (réduction de 80% du code)
|
||||
- ✅ **Facile à mettre en œuvre** (script automatique fourni)
|
||||
- ✅ **Bénéfique pour la maintenance** (cohérence et simplicité)
|
||||
- ✅ **Améliore l'accessibilité** (WCAG 2.1 AA)
|
||||
|
||||
**Verdict : GO ! 🚀**
|
||||
|
||||
2626
HANDOFF_COMPLET.md
2626
HANDOFF_COMPLET.md
File diff suppressed because it is too large
Load Diff
@@ -1,408 +0,0 @@
|
||||
# ✅ IMPLÉMENTATION TERMINÉE - Lions User Manager Landing Page
|
||||
|
||||
**Date** : 2025-12-25
|
||||
**Statut** : 🎉 **PRODUCTION READY**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Mission accomplie
|
||||
|
||||
La page d'accueil professionnelle de **Lions User Manager** a été créée avec succès en utilisant les couleurs **officielles du template Freya Blue** acheté.
|
||||
|
||||
---
|
||||
|
||||
## 📊 Tests de validation
|
||||
|
||||
### ✅ Test 1 : Page accessible
|
||||
```bash
|
||||
curl -I http://localhost:8082/
|
||||
```
|
||||
**Résultat** : `HTTP/1.1 200 OK` ✅
|
||||
|
||||
### ✅ Test 2 : Branding Freya Blue
|
||||
```bash
|
||||
curl -s http://localhost:8082/ | grep "FREYA BLUE"
|
||||
```
|
||||
**Résultat** : `FREYA BLUE` trouvé ✅
|
||||
|
||||
### ✅ Test 3 : Couleur principale #4F8EEC
|
||||
```bash
|
||||
curl -s http://localhost:8082/ | grep -o "#4F8EEC" | wc -l
|
||||
```
|
||||
**Résultat** : `3 occurrences` ✅
|
||||
|
||||
### ✅ Test 4 : Aucune trace de violet (ancienne version)
|
||||
```bash
|
||||
curl -s http://localhost:8082/ | grep -c "rgba(139, 92, 246"
|
||||
```
|
||||
**Résultat** : `0 occurrences` ✅ (parfait!)
|
||||
|
||||
### ✅ Test 5 : Shadows bleues Freya
|
||||
```bash
|
||||
curl -s http://localhost:8082/ | grep -c "rgba(79, 142, 236"
|
||||
```
|
||||
**Résultat** : `8 occurrences` ✅
|
||||
|
||||
### ✅ Test 6 : Alert session expirée
|
||||
```bash
|
||||
curl -s "http://localhost:8082/?expired=true" | grep "Votre session a expiré"
|
||||
```
|
||||
**Résultat** : `Votre session a expiré` trouvé ✅
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Palette de couleurs appliquée
|
||||
|
||||
### Freya Blue (Template Variant 1)
|
||||
```
|
||||
Primary: #4F8EEC ⭐ Couleur principale
|
||||
Hover: #387FE9 🔵 Au survol
|
||||
Active: #2C6DCC 🔷 Cliqué
|
||||
Dark: #2159A8 ⬛ Gradients foncés
|
||||
```
|
||||
|
||||
### Shadows & Effects
|
||||
```
|
||||
rgba(79, 142, 236, 0.35) - Box shadows normales
|
||||
rgba(79, 142, 236, 0.45) - Box shadows hover
|
||||
rgba(79, 142, 236, 0.12) - Background blobs animés
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 Fichiers implémentés
|
||||
|
||||
### 1. Landing Page
|
||||
**Fichier** : `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/index.html`
|
||||
|
||||
**Taille** : ~32KB
|
||||
**Type** : HTML statique (pas de JSF)
|
||||
**Caractéristiques** :
|
||||
- ✅ Freya Blue colors (#4F8EEC)
|
||||
- ✅ 6 sections professionnelles
|
||||
- ✅ Animations fluides (IntersectionObserver)
|
||||
- ✅ Responsive mobile/tablet/desktop
|
||||
- ✅ Alert session expirée conditionnelle
|
||||
- ✅ Glassmorphism navbar
|
||||
- ✅ Compteurs animés
|
||||
- ✅ Smooth scroll
|
||||
|
||||
### 2. Configuration
|
||||
**Fichier** : `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/application.properties`
|
||||
|
||||
**Ligne 45** :
|
||||
```properties
|
||||
quarkus.myfaces.view-expired-exception-handler-redirect-page=/index.html?expired=true
|
||||
```
|
||||
|
||||
**Ligne 92** :
|
||||
```properties
|
||||
quarkus.http.auth.permission.public.paths=/,/index.html,...
|
||||
```
|
||||
|
||||
### 3. Documentation
|
||||
**Fichiers créés** :
|
||||
- ✅ `PAGE_ACCUEIL.md` - Documentation initiale
|
||||
- ✅ `PAGE_ACCUEIL_FREYA_ENTERPRISE.md` - Version enterprise (violet - obsolète)
|
||||
- ✅ `PAGE_ACCUEIL_FREYA_BLUE_FINAL.md` - Documentation finale Freya Blue ⭐
|
||||
- ✅ `IMPLEMENTATION_COMPLETE.md` - Ce fichier (résumé final)
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Architecture de la page
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ NAVBAR (Fixed + Glassmorphism) │
|
||||
│ • Logo avec gradient bleu #4F8EEC → #2C6DCC│
|
||||
│ • CTA "Accéder à la console" │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ HERO SECTION │
|
||||
│ • Background gradient blanc → #EBF3FE │
|
||||
│ • Badge "Plateforme IAM Centralisée" │
|
||||
│ • H1 gradient bleu animé │
|
||||
│ • 2 CTA (Primary bleu + Secondary white) │
|
||||
│ • Alert session expirée (si ?expired=true)│
|
||||
├─────────────────────────────────────────────┤
|
||||
│ STATS SECTION (Social Proof) │
|
||||
│ • 4 cartes avec compteurs animés │
|
||||
│ • 10,000+ utilisateurs │
|
||||
│ • 50+ royaumes │
|
||||
│ • 99.9% disponibilité │
|
||||
│ • 24/7 support │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ FEATURES SECTION (Métier) │
|
||||
│ • 6 cartes fonctionnalités │
|
||||
│ • Gestion utilisateurs │
|
||||
│ • Attribution rôles (RBAC) │
|
||||
│ • Audit & Analytics │
|
||||
│ • Synchronisation (API/Webhooks) │
|
||||
│ • Sécurité avancée (MFA/AES-256) │
|
||||
│ • Multi-tenant │
|
||||
│ • Hover: icône blanche sur fond bleu │
|
||||
│ • Barre gradient bleue en haut │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ CTA SECTION (Final Push) │
|
||||
│ • Background gradient bleu foncé │
|
||||
│ • Message "Prêt à transformer..." │
|
||||
│ • CTA white button │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ FOOTER (Dark) │
|
||||
│ • Logo bleu + tagline │
|
||||
│ • Copyright © 2025 │
|
||||
│ • Badges: OpenID Connect, Quarkus, Freya │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Flux utilisateur
|
||||
|
||||
### Scénario 1 : Premier accès
|
||||
```
|
||||
http://localhost:8082
|
||||
↓
|
||||
Affiche landing page Freya Blue
|
||||
↓
|
||||
Utilisateur lit les fonctionnalités
|
||||
↓
|
||||
Clique "Se connecter avec Keycloak"
|
||||
↓
|
||||
Redirigé vers /pages/user-manager/dashboard.xhtml
|
||||
↓
|
||||
Quarkus OIDC intercepte → Keycloak
|
||||
↓
|
||||
Login Keycloak
|
||||
↓
|
||||
Dashboard authentifié
|
||||
```
|
||||
|
||||
### Scénario 2 : Session expirée
|
||||
```
|
||||
Utilisateur sur /pages/user-manager/users/list.xhtml
|
||||
↓
|
||||
Session HTTP expire (60 minutes)
|
||||
↓
|
||||
ViewExpiredException détectée
|
||||
↓
|
||||
Redirigé vers /index.html?expired=true
|
||||
↓
|
||||
Alerte rouge "Votre session a expiré"
|
||||
↓
|
||||
Clique "Se connecter avec Keycloak"
|
||||
↓
|
||||
OIDC force nouvelle authentification
|
||||
↓
|
||||
Dashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Principes de design appliqués
|
||||
|
||||
### DRY (Don't Repeat Yourself)
|
||||
```css
|
||||
:root {
|
||||
--primary-500: #4F8EEC;
|
||||
--primary-600: #387FE9;
|
||||
--primary-700: #2C6DCC;
|
||||
}
|
||||
|
||||
/* Utilisé partout via var() */
|
||||
background: linear-gradient(135deg, var(--primary-500), var(--primary-700));
|
||||
box-shadow: 0 4px 14px rgba(79, 142, 236, 0.35);
|
||||
```
|
||||
|
||||
### WOW Factor
|
||||
- ✨ Animations fluides (fadeInUp, slideDown, float)
|
||||
- ✨ Compteurs animés au scroll
|
||||
- ✨ Glassmorphism navbar (backdrop-filter blur)
|
||||
- ✨ Gradients dynamiques
|
||||
- ✨ Micro-interactions hover
|
||||
- ✨ Smooth scroll
|
||||
|
||||
### Métier (Business-Oriented)
|
||||
- 🏢 Vocabulaire technique IAM
|
||||
- 🏢 Fonctionnalités B2B (RBAC, MFA, SOC2)
|
||||
- 🏢 Social proof (stats)
|
||||
- 🏢 Messages professionnels
|
||||
|
||||
### Parfait (Perfect Execution)
|
||||
- ✅ 0 erreurs console
|
||||
- ✅ 0 warnings
|
||||
- ✅ HTML5 sémantique
|
||||
- ✅ Responsive complet
|
||||
- ✅ Accessibilité (contraste, tailles)
|
||||
- ✅ Performance (32KB, 4 requests)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Comparaison versions
|
||||
|
||||
| Aspect | Version Violette (obsolète) | Version Freya Blue (finale) |
|
||||
|--------|----------------------------|----------------------------|
|
||||
| **Couleur** | #8b5cf6 (violet) ❌ | #4F8EEC (bleu Freya) ✅ |
|
||||
| **Template** | Inventé | Acheté capitalisé ✅ |
|
||||
| **Shadows** | rgba(139, 92, 246, ...) ❌ | rgba(79, 142, 236, ...) ✅ |
|
||||
| **Branding** | Incohérent | Freya Blue officiel ✅ |
|
||||
| **Gradients** | Purple → Dark purple ❌ | Blue → Dark blue ✅ |
|
||||
| **Compteur traces** | 0 bleu, 8 violet ❌ | 8 bleu, 0 violet ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Technologies utilisées
|
||||
|
||||
| Tech | Version | Rôle |
|
||||
|------|---------|------|
|
||||
| HTML5 | - | Structure sémantique |
|
||||
| CSS3 | - | Custom Properties, Grid, Flexbox |
|
||||
| JavaScript | ES6+ | Vanilla (IntersectionObserver, Events) |
|
||||
| PrimeIcons | 7.0.0 | Icônes professionnelles |
|
||||
| Inter | Variable | Typographie Google Fonts |
|
||||
| Freya Blue | Variant 1 | Template acheté |
|
||||
|
||||
**Frameworks** : AUCUN (vanilla pur) → Performance maximale
|
||||
|
||||
---
|
||||
|
||||
## 📈 Performance
|
||||
|
||||
### Métriques
|
||||
- **Taille HTML** : ~32KB
|
||||
- **Requests** : 4 total
|
||||
- 1x HTML (32KB)
|
||||
- 1x PrimeIcons CSS (50KB CDN)
|
||||
- 2x Google Fonts (Inter)
|
||||
- **Temps de chargement** : <500ms (localhost)
|
||||
- **Bundle JavaScript** : 0KB (inline vanilla)
|
||||
- **Bundle CSS** : 0KB (inline)
|
||||
|
||||
### Score
|
||||
- **Lighthouse Performance** : 95+ (estimé)
|
||||
- **Accessibilité** : 100 (semantic HTML, contraste)
|
||||
- **Best Practices** : 100 (HTTPS, no deprecated)
|
||||
- **SEO** : 100 (meta, title, structure)
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Enseignements
|
||||
|
||||
### Ce qui a fonctionné
|
||||
1. ✅ **Simplicité** : HTML statique > JSF pour landing page
|
||||
2. ✅ **DRY** : CSS variables = maintenance facile
|
||||
3. ✅ **Vanilla JS** : 0 framework = performance maximale
|
||||
4. ✅ **Template officiel** : Freya Blue capitalisé
|
||||
|
||||
### Ce qui a été corrigé
|
||||
1. ❌ Purple → ✅ Freya Blue (#4F8EEC)
|
||||
2. ❌ index.xhtml (JSF) → ✅ index.html (statique)
|
||||
3. ❌ CustomExceptionHandler complexe → ✅ Config MyFaces simple
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Résultat final
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────┐
|
||||
│ 🏆 ÉVALUATION GLOBALE │
|
||||
├──────────────────────────────────────────┤
|
||||
│ Design Freya Blue: ⭐⭐⭐⭐⭐ │
|
||||
│ Couleurs template: ⭐⭐⭐⭐⭐ │
|
||||
│ Performance: ⭐⭐⭐⭐⭐ │
|
||||
│ Responsive: ⭐⭐⭐⭐⭐ │
|
||||
│ Code Quality (DRY): ⭐⭐⭐⭐⭐ │
|
||||
│ WOW Factor: ⭐⭐⭐⭐⭐ │
|
||||
│ Métier/Business: ⭐⭐⭐⭐⭐ │
|
||||
├──────────────────────────────────────────┤
|
||||
│ TOTAL: 35/35 = PARFAIT ✅ │
|
||||
└──────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Checklist finale
|
||||
|
||||
### Design & UX
|
||||
- [x] Palette Freya Blue (#4F8EEC) appliquée
|
||||
- [x] Template acheté capitalisé (Variant 1)
|
||||
- [x] Aucune trace de violet (#8b5cf6)
|
||||
- [x] Animations fluides
|
||||
- [x] Responsive mobile/tablet/desktop
|
||||
- [x] Glassmorphism navbar
|
||||
- [x] Hover effects partout
|
||||
|
||||
### Fonctionnel
|
||||
- [x] Page accessible sans authentification
|
||||
- [x] Redirection session expirée → /index.html?expired=true
|
||||
- [x] Alert conditionnelle affichée
|
||||
- [x] Compteurs animés au scroll
|
||||
- [x] Smooth scroll vers ancres
|
||||
- [x] Navigation vers dashboard.xhtml
|
||||
|
||||
### Technique
|
||||
- [x] HTML5 sémantique
|
||||
- [x] CSS modern (Grid, Flexbox, Variables)
|
||||
- [x] JavaScript vanilla ES6+
|
||||
- [x] 0 erreurs console
|
||||
- [x] 0 dépendances framework
|
||||
- [x] Performance optimisée
|
||||
|
||||
### Métier
|
||||
- [x] Vocabulaire IAM technique
|
||||
- [x] 6 fonctionnalités B2B détaillées
|
||||
- [x] Social proof (stats)
|
||||
- [x] Messages professionnels
|
||||
- [x] 3 CTA bien placés
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines étapes (optionnelles)
|
||||
|
||||
### Court terme
|
||||
- [ ] Tests manuels dans navigateur
|
||||
- [ ] Vérifier flow complet avec Keycloak
|
||||
- [ ] Screenshots pour documentation
|
||||
|
||||
### Moyen terme
|
||||
- [ ] Logo SVG personnalisé
|
||||
- [ ] Screenshots interface (section démo)
|
||||
- [ ] Témoignages clients
|
||||
|
||||
### Long terme
|
||||
- [ ] Dark mode toggle
|
||||
- [ ] i18n (FR/EN)
|
||||
- [ ] PWA (Service Worker)
|
||||
- [ ] Cookie banner RGPD
|
||||
|
||||
---
|
||||
|
||||
## 📚 Documentation disponible
|
||||
|
||||
1. **PAGE_ACCUEIL_FREYA_BLUE_FINAL.md** - Guide technique complet ⭐
|
||||
2. **IMPLEMENTATION_COMPLETE.md** - Ce fichier (résumé)
|
||||
3. **application.properties** - Configuration Quarkus
|
||||
4. **index.html** - Code source de la page
|
||||
|
||||
---
|
||||
|
||||
## ✅ Conclusion
|
||||
|
||||
La page d'accueil **Lions User Manager** est maintenant **100% prête pour la production** avec :
|
||||
|
||||
1. ✅ **Couleurs Freya Blue officielles** du template acheté
|
||||
2. ✅ **Design professionnel** niveau enterprise AAA
|
||||
3. ✅ **Performance optimale** (32KB, vanilla JS)
|
||||
4. ✅ **Responsive parfait** sur tous devices
|
||||
5. ✅ **Métier B2B** avec vocabulaire IAM technique
|
||||
6. ✅ **WOW Factor** avec animations et micro-interactions
|
||||
7. ✅ **DRY** avec CSS variables partout
|
||||
8. ✅ **Tests validés** (couleurs, alert, navigation)
|
||||
|
||||
**Le template Freya Blue a été parfaitement capitalisé ! 🎉**
|
||||
|
||||
---
|
||||
|
||||
**Auteur** : Claude Sonnet 4.5
|
||||
**Date** : 2025-12-25
|
||||
**Version** : 1.0.0 FINAL
|
||||
**Statut** : ✅ PRODUCTION READY
|
||||
@@ -1,224 +0,0 @@
|
||||
# Instructions de Test - Lions User Manager
|
||||
|
||||
## ✅ Configuration Terminée
|
||||
|
||||
Tous les composants sont maintenant configurés et opérationnels !
|
||||
|
||||
## 🚀 Architecture Actuelle
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Navigateur Web │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 1. http://localhost:8080
|
||||
│ Redirection OIDC →
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ KEYCLOAK (Port 8180) ✅ │
|
||||
│ - Realm: lions-user-manager │
|
||||
│ - Client: lions-user-manager-client │
|
||||
│ - Secret: client-secret-lions-2025 │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 2. Authentification
|
||||
│ testuser / test123
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ FRONTEND (Port 8080) ✅ │
|
||||
│ - OIDC activé │
|
||||
│ - Reçoit token JWT │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 3. Appels API avec token JWT
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ BACKEND (Port 8081) ✅ │
|
||||
│ - Vérifie le token JWT │
|
||||
│ - Appelle Keycloak Admin API │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 📋 Étapes de Test
|
||||
|
||||
### 1. Vérifier que tous les services tournent
|
||||
|
||||
```bash
|
||||
# Backend (port 8081)
|
||||
curl http://localhost:8081/q/health
|
||||
|
||||
# Keycloak (port 8180)
|
||||
curl http://localhost:8180/realms/lions-user-manager
|
||||
|
||||
# Frontend (port 8080) - devrait rediriger
|
||||
curl -I http://localhost:8080
|
||||
```
|
||||
|
||||
### 2. Tester l'authentification complète
|
||||
|
||||
1. **Ouvrir le navigateur** : http://localhost:8080
|
||||
|
||||
2. **Redirection automatique** vers Keycloak :
|
||||
- URL sera : `http://localhost:8180/realms/lions-user-manager/protocol/openid-connect/auth?...`
|
||||
|
||||
3. **Se connecter** avec les credentials :
|
||||
- **Username** : `testuser`
|
||||
- **Password** : `test123`
|
||||
|
||||
4. **Redirection** vers le frontend authentifié
|
||||
|
||||
5. **Accéder aux pages protégées** :
|
||||
- http://localhost:8080/pages/user-manager/users/list.xhtml
|
||||
|
||||
### 3. Tester les API Backend directement
|
||||
|
||||
#### Avec token (authentifié)
|
||||
|
||||
```bash
|
||||
# 1. Obtenir un token
|
||||
TOKEN=$(curl -s -X POST "http://localhost:8180/realms/lions-user-manager/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=lions-user-manager-client" \
|
||||
-d "client_secret=client-secret-lions-2025" \
|
||||
-d "username=testuser" \
|
||||
-d "password=test123" \
|
||||
-d "grant_type=password" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
# 2. Appeler l'API avec le token
|
||||
curl -H "Authorization: Bearer $TOKEN" \
|
||||
"http://localhost:8081/api/users?realm=lions-user-manager"
|
||||
```
|
||||
|
||||
## 🔑 Credentials
|
||||
|
||||
### Keycloak Admin
|
||||
- **URL** : http://localhost:8180/admin
|
||||
- **Username** : `admin`
|
||||
- **Password** : `admin`
|
||||
- **Realm** : `master`
|
||||
|
||||
### Test User (Application)
|
||||
- **URL** : http://localhost:8080
|
||||
- **Username** : `testuser`
|
||||
- **Password** : `test123`
|
||||
- **Realm** : `lions-user-manager`
|
||||
|
||||
### Client Configuration
|
||||
- **Client ID** : `lions-user-manager-client`
|
||||
- **Client Secret** : `client-secret-lions-2025`
|
||||
- **Realm** : `lions-user-manager`
|
||||
|
||||
## 📊 Endpoints de Test
|
||||
|
||||
### Frontend
|
||||
- **Accueil** : http://localhost:8080
|
||||
- **Users List** : http://localhost:8080/pages/user-manager/users/list.xhtml
|
||||
- **Roles List** : http://localhost:8080/pages/user-manager/roles/list.xhtml
|
||||
|
||||
### Backend API
|
||||
- **Swagger UI** : http://localhost:8081/q/swagger-ui
|
||||
- **Dev UI** : http://localhost:8081/q/dev
|
||||
- **Health** : http://localhost:8081/q/health
|
||||
- **Keycloak Health** : http://localhost:8081/api/health/keycloak
|
||||
- **Users API** : http://localhost:8081/api/users?realm=lions-user-manager
|
||||
- **Roles API** : http://localhost:8081/api/roles/realm?realm=lions-user-manager
|
||||
|
||||
### Keycloak
|
||||
- **Admin Console** : http://localhost:8180/admin
|
||||
- **Realm Info** : http://localhost:8180/realms/lions-user-manager
|
||||
- **Well-known** : http://localhost:8180/realms/lions-user-manager/.well-known/openid-configuration
|
||||
|
||||
## ⚠️ Troubleshooting
|
||||
|
||||
### Frontend retourne "Forbidden"
|
||||
- **Cause** : Pas authentifié
|
||||
- **Solution** : Allez sur http://localhost:8080, laissez-vous rediriger vers Keycloak et authentifiez-vous
|
||||
|
||||
### Erreur "Client not found"
|
||||
- **Cause** : Configuration Keycloak incorrecte
|
||||
- **Solution** : Vérifier que le client `lions-user-manager-client` existe dans le realm `lions-user-manager`
|
||||
|
||||
### Backend retourne 403
|
||||
- **Cause** : Token invalide ou manquant
|
||||
- **Solution** : S'assurer que le frontend envoie bien le token JWT dans l'en-tête `Authorization`
|
||||
|
||||
### "Invalid redirect_uri"
|
||||
- **Cause** : Les redirect URIs ne sont pas configurées correctement
|
||||
- **Solution** : Dans Keycloak Admin, vérifier que `http://localhost:8080/*` est bien dans les Valid Redirect URIs
|
||||
|
||||
## 🧪 Scénarios de Test
|
||||
|
||||
### Scénario 1 : Authentification et Liste des Utilisateurs
|
||||
1. Ouvrir http://localhost:8080
|
||||
2. Se connecter avec testuser/test123
|
||||
3. Naviguer vers la liste des utilisateurs
|
||||
4. Vérifier que les utilisateurs s'affichent
|
||||
|
||||
### Scénario 2 : Créer un Utilisateur
|
||||
1. S'authentifier (voir Scénario 1)
|
||||
2. Cliquer sur "Nouveau Utilisateur"
|
||||
3. Remplir le formulaire
|
||||
4. Sauvegarder
|
||||
5. Vérifier que l'utilisateur apparaît dans la liste
|
||||
|
||||
### Scénario 3 : Gestion des Rôles
|
||||
1. S'authentifier
|
||||
2. Aller sur la page des rôles
|
||||
3. Assigner des rôles à un utilisateur
|
||||
4. Vérifier que les rôles sont bien assignés
|
||||
|
||||
### Scénario 4 : API Backend Directe
|
||||
```bash
|
||||
# Obtenir token
|
||||
TOKEN=$(curl -s -X POST "http://localhost:8180/realms/lions-user-manager/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=lions-user-manager-client" \
|
||||
-d "client_secret=client-secret-lions-2025" \
|
||||
-d "username=testuser" \
|
||||
-d "password=test123" \
|
||||
-d "grant_type=password" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
# Lister utilisateurs
|
||||
curl -H "Authorization: Bearer $TOKEN" \
|
||||
"http://localhost:8081/api/users?realm=lions-user-manager"
|
||||
|
||||
# Lister rôles
|
||||
curl -H "Authorization: Bearer $TOKEN" \
|
||||
"http://localhost:8081/api/roles/realm?realm=lions-user-manager"
|
||||
```
|
||||
|
||||
## ✅ Checklist de Validation
|
||||
|
||||
- [ ] Backend démarre sur port 8081
|
||||
- [ ] Keycloak accessible sur port 8180
|
||||
- [ ] Frontend démarre sur port 8080
|
||||
- [ ] Redirection OIDC fonctionne (frontend → Keycloak)
|
||||
- [ ] Authentification réussie avec testuser/test123
|
||||
- [ ] Pages protégées accessibles après authentification
|
||||
- [ ] API Backend retourne des données
|
||||
- [ ] Token JWT est correctement transmis
|
||||
- [ ] Swagger UI accessible et fonctionnel
|
||||
|
||||
## 🎯 Prochaines Étapes (Post-Test)
|
||||
|
||||
1. ✅ Validation de l'authentification complète
|
||||
2. ⏳ Tests fonctionnels de toutes les pages
|
||||
3. ⏳ Tests CRUD complets (Create, Read, Update, Delete)
|
||||
4. ⏳ Tests de gestion des rôles
|
||||
5. ⏳ Tests d'audit
|
||||
6. ⏳ Tests de synchronisation
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- Le frontend utilise maintenant OIDC avec Keycloak local
|
||||
- Le backend vérifie les tokens JWT via OIDC
|
||||
- Tous les appels API nécessitent un token valide
|
||||
- Le test user `testuser` a les rôles : `admin`, `user_manager`
|
||||
|
||||
---
|
||||
|
||||
**Date de configuration** : 2025-12-05
|
||||
**Environnement** : Développement (DEV)
|
||||
@@ -1,396 +0,0 @@
|
||||
# Instructions de Test Final - Lions User Manager
|
||||
|
||||
**Date**: 2025-12-05
|
||||
**Statut**: Toutes les corrections appliquées ✅
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Résumé des Corrections Appliquées
|
||||
|
||||
### ✅ Problème 1: Rôles Keycloak Manquants
|
||||
- Créé 5 rôles métier: admin, user_manager, user_viewer, auditor, sync_manager
|
||||
- Assigné tous les rôles à testuser
|
||||
- Script: `create-roles-and-assign.sh`
|
||||
|
||||
### ✅ Problème 2: KeycloakTestUserConfig - Erreur bruteForceStrategy
|
||||
- Désactivé la configuration automatique
|
||||
- Fichier: `KeycloakTestUserConfig.java:62-68`
|
||||
|
||||
### ✅ Problème 3: Extraction des Rôles depuis ID Token
|
||||
- Configuré extraction depuis access_token
|
||||
- Propriété: `quarkus.oidc.roles.source=accesstoken`
|
||||
- Fichier frontend: `application.properties:64`
|
||||
|
||||
### ✅ Problème 4: Propagation du Token JWT
|
||||
- Créé `AuthHeaderFactory` pour injection automatique du token
|
||||
- Enregistré sur tous les REST Clients
|
||||
- Fichiers: `AuthHeaderFactory.java` + 4 REST Clients
|
||||
|
||||
### ✅ Problème 5: Vérification de l'Audience JWT
|
||||
- Configuré backend pour accepter audience "account"
|
||||
- Propriété: `quarkus.oidc.token.audience=account`
|
||||
- Fichier backend: `application-dev.properties:25`
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Test Complet - Étape par Étape
|
||||
|
||||
### Prérequis
|
||||
|
||||
1. **Keycloak** doit être démarré sur port 8180
|
||||
2. **Backend** doit être démarré sur port 8081
|
||||
3. **Frontend** doit être démarré sur port 8080
|
||||
|
||||
Si ce n'est pas le cas, suivre les instructions de démarrage ci-dessous.
|
||||
|
||||
---
|
||||
|
||||
### Démarrage des Services
|
||||
|
||||
#### 1. Keycloak (si nécessaire)
|
||||
```bash
|
||||
cd /path/to/keycloak
|
||||
bin/kc.sh start-dev --http-port=8180
|
||||
```
|
||||
|
||||
Vérifier: http://localhost:8180 → Console admin accessible
|
||||
|
||||
#### 2. Backend
|
||||
```bash
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
**Attendre les logs suivants**:
|
||||
```
|
||||
✓ Configuration automatique de Keycloak DÉSACTIVÉE
|
||||
✓ Client Keycloak initialisé (connexion lazy)
|
||||
✓ Listening on: http://localhost:8081
|
||||
```
|
||||
|
||||
**NE PAS voir**:
|
||||
```
|
||||
❌ ERROR UnrecognizedPropertyException: bruteForceStrategy
|
||||
```
|
||||
|
||||
#### 3. Frontend
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
**Attendre les logs suivants**:
|
||||
```
|
||||
✓ Listening on: http://localhost:8080
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Test 1: Authentification OIDC
|
||||
|
||||
#### Étape 1.1: Se Déconnecter (Important!)
|
||||
**Pourquoi?** Pour obtenir un nouveau token avec les nouveaux rôles et la nouvelle configuration.
|
||||
|
||||
1. Accéder à http://localhost:8080
|
||||
2. Si déjà connecté, cliquer sur le bouton de déconnexion
|
||||
3. Ou accéder directement à: http://localhost:8080/q/oidc/logout
|
||||
|
||||
#### Étape 1.2: Se Reconnecter
|
||||
1. Accéder à http://localhost:8080
|
||||
2. Vous devez être redirigé vers Keycloak
|
||||
3. Entrer les identifiants:
|
||||
- **Username**: `testuser`
|
||||
- **Password**: `test123`
|
||||
4. Cliquer sur "Sign In"
|
||||
5. Vous devez être redirigé vers http://localhost:8080
|
||||
|
||||
**✅ Résultat attendu**: Connexion réussie, page d'accueil affichée
|
||||
|
||||
**❌ Échec possible**:
|
||||
- Si Keycloak ne redirige pas → Vérifier configuration OIDC frontend
|
||||
- Si "Invalid credentials" → Vérifier que testuser existe dans Keycloak
|
||||
|
||||
#### Étape 1.3: Vérifier le Token JWT (optionnel)
|
||||
1. Ouvrir DevTools (F12)
|
||||
2. Onglet **Network**
|
||||
3. Cocher "Preserve log"
|
||||
4. Rafraîchir la page (F5)
|
||||
5. Chercher une requête vers `/q/oidc/callback` ou `/token`
|
||||
6. Copier le paramètre `access_token` depuis la réponse
|
||||
7. Aller sur https://jwt.io
|
||||
8. Coller le token dans le décodeur
|
||||
9. Vérifier les claims:
|
||||
```json
|
||||
{
|
||||
"realm_access": {
|
||||
"roles": [
|
||||
"admin",
|
||||
"user_manager",
|
||||
"user_viewer",
|
||||
"auditor",
|
||||
"sync_manager",
|
||||
"offline_access",
|
||||
"uma_authorization",
|
||||
"default-roles-lions-user-manager"
|
||||
]
|
||||
},
|
||||
"aud": "account",
|
||||
"iss": "http://localhost:8180/realms/lions-user-manager"
|
||||
}
|
||||
```
|
||||
|
||||
**✅ Résultat attendu**: Token contient les 5 rôles métier + rôles par défaut
|
||||
|
||||
---
|
||||
|
||||
### Test 2: Appel Backend - Liste des Utilisateurs
|
||||
|
||||
#### Étape 2.1: Naviguer vers la Liste des Utilisateurs
|
||||
1. Une fois connecté sur http://localhost:8080
|
||||
2. Naviguer vers: http://localhost:8080/pages/user-manager/users/list.xhtml
|
||||
|
||||
**✅ Résultat attendu**:
|
||||
- Page se charge sans erreur
|
||||
- Liste des utilisateurs s'affiche (peut être vide si aucun utilisateur dans le realm)
|
||||
- Aucun message d'erreur 401 Unauthorized
|
||||
|
||||
**❌ Échec possible**:
|
||||
- Erreur 401 → Vérifier logs backend et frontend (voir section Debugging)
|
||||
- Page blanche → Vérifier logs JSF dans le frontend
|
||||
- Timeout → Vérifier que le backend est démarré
|
||||
|
||||
#### Étape 2.2: Vérifier les Logs Frontend
|
||||
Chercher dans la console du frontend (terminal où mvn quarkus:dev tourne):
|
||||
|
||||
**✅ Logs attendus**:
|
||||
```
|
||||
FINE Token Bearer ajouté au header Authorization
|
||||
DEBUG Chargement de X utilisateurs
|
||||
```
|
||||
|
||||
**❌ Logs problématiques**:
|
||||
```
|
||||
WARNING Token JWT non disponible ou vide
|
||||
SEVERE Erreur lors du chargement des utilisateurs: Received: 'Unauthorized, status code 401'
|
||||
```
|
||||
|
||||
#### Étape 2.3: Vérifier les Logs Backend
|
||||
Chercher dans la console du backend:
|
||||
|
||||
**✅ Logs attendus**:
|
||||
```
|
||||
DEBUG [io.qu.oi.ru.BearerAuthenticationMechanism] Starting a bearer access token authentication
|
||||
DEBUG [io.qu.oi.ru.OidcIdentityProvider] Starting creating SecurityIdentity
|
||||
DEBUG [io.qu.oi.ru.OidcIdentityProvider] Token verification succeeded
|
||||
DEBUG Recherche d'utilisateurs avec critères: UserSearchCriteriaDTO(realmName=master, ...)
|
||||
INFO Found X users in realm master
|
||||
```
|
||||
|
||||
**❌ Logs problématiques**:
|
||||
```
|
||||
ERROR Bearer access token is not available
|
||||
ERROR Audience (aud) claim [account] doesn't contain an acceptable identifier
|
||||
ERROR Token verification has failed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Test 3: Opérations CRUD
|
||||
|
||||
#### Étape 3.1: Rechercher un Utilisateur
|
||||
1. Sur la page `/pages/user-manager/users/list.xhtml`
|
||||
2. Entrer un terme de recherche dans le champ "Rechercher"
|
||||
3. Cliquer sur "Rechercher"
|
||||
|
||||
**✅ Résultat attendu**: Liste filtrée affichée sans erreur
|
||||
|
||||
#### Étape 3.2: Activer/Désactiver un Utilisateur
|
||||
1. Cliquer sur le bouton "Activer" ou "Désactiver" d'un utilisateur
|
||||
2. Vérifier le message de succès
|
||||
|
||||
**✅ Résultat attendu**: Message "Utilisateur activé/désactivé avec succès"
|
||||
|
||||
#### Étape 3.3: Supprimer un Utilisateur (optionnel)
|
||||
**⚠️ Attention**: Ne supprimez PAS testuser!
|
||||
|
||||
1. Cliquer sur le bouton "Supprimer" d'un utilisateur
|
||||
2. Confirmer la suppression
|
||||
|
||||
**✅ Résultat attendu**: Message "Utilisateur supprimé avec succès"
|
||||
|
||||
---
|
||||
|
||||
### Test 4: Vérifier les Rôles et Autorisations
|
||||
|
||||
#### Étape 4.1: Accès aux Pages Protégées
|
||||
1. Tester l'accès à différentes pages:
|
||||
- http://localhost:8080/pages/user-manager/users/list.xhtml
|
||||
- http://localhost:8080/pages/user-manager/roles/list.xhtml
|
||||
- http://localhost:8080/pages/user-manager/audit/list.xhtml
|
||||
|
||||
**✅ Résultat attendu**: Toutes les pages accessibles (testuser a tous les rôles)
|
||||
|
||||
#### Étape 4.2: Test avec un Utilisateur sans Rôles (optionnel)
|
||||
1. Via Keycloak Admin Console, créer un nouvel utilisateur sans rôles
|
||||
2. Se déconnecter de testuser
|
||||
3. Se connecter avec le nouvel utilisateur
|
||||
4. Essayer d'accéder aux pages protégées
|
||||
|
||||
**✅ Résultat attendu**: Accès refusé ou 403 Forbidden (selon configuration)
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Debugging - Problèmes Courants
|
||||
|
||||
### Problème 1: "Token JWT non disponible ou vide"
|
||||
|
||||
**Cause**: `JsonWebToken` non injecté dans le contexte CDI
|
||||
|
||||
**Solutions**:
|
||||
1. Vérifier que l'utilisateur est connecté
|
||||
2. Se déconnecter et reconnecter
|
||||
3. Redémarrer le frontend:
|
||||
```bash
|
||||
# Arrêter (Ctrl+C)
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
### Problème 2: "Bearer access token is not available"
|
||||
|
||||
**Cause**: Token pas envoyé au backend OU AuthHeaderFactory pas actif
|
||||
|
||||
**Solutions**:
|
||||
1. Vérifier que `AuthHeaderFactory` est compilé:
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn compile
|
||||
```
|
||||
2. Vérifier que les REST Clients ont `@RegisterClientHeaders(AuthHeaderFactory.class)`
|
||||
3. Redémarrer le frontend pour forcer le rechargement
|
||||
|
||||
### Problème 3: "Audience (aud) claim doesn't contain..."
|
||||
|
||||
**Cause**: Backend attend une audience différente
|
||||
|
||||
**Solutions**:
|
||||
1. Vérifier `application-dev.properties:25` du backend:
|
||||
```properties
|
||||
quarkus.oidc.token.audience=account
|
||||
```
|
||||
2. Si modifié, redémarrer le backend:
|
||||
```bash
|
||||
# Arrêter (Ctrl+C)
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
### Problème 4: "No claim exists at the path 'realm_access/roles'"
|
||||
|
||||
**Cause**: Rôles extraits depuis id_token au lieu de access_token
|
||||
|
||||
**Solutions**:
|
||||
1. Vérifier `application.properties:64` du frontend:
|
||||
```properties
|
||||
quarkus.oidc.roles.source=accesstoken
|
||||
```
|
||||
2. Se déconnecter et reconnecter pour obtenir un nouveau token
|
||||
3. Vérifier le token sur jwt.io (doit contenir realm_access.roles)
|
||||
|
||||
### Problème 5: Hot Reload ne fonctionne pas
|
||||
|
||||
**Cause**: Quarkus dev mode n'a pas détecté les changements
|
||||
|
||||
**Solution**: Force clean + recompile
|
||||
```bash
|
||||
# Frontend
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean compile quarkus:dev
|
||||
|
||||
# Backend
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Checklist de Validation Complète
|
||||
|
||||
### Configuration Keycloak
|
||||
- [x] Realm `lions-user-manager` existe
|
||||
- [x] Client `lions-user-manager-client` configuré
|
||||
- [x] 5 rôles métier créés: admin, user_manager, user_viewer, auditor, sync_manager
|
||||
- [x] testuser existe avec password `test123`
|
||||
- [x] testuser possède tous les rôles
|
||||
|
||||
### Configuration Backend
|
||||
- [x] Port 8081
|
||||
- [x] `KeycloakTestUserConfig` désactivé (pas d'erreur bruteForceStrategy)
|
||||
- [x] `quarkus.oidc.token.audience=account` configuré
|
||||
- [x] Démarre sans erreur
|
||||
- [x] Health check OK: http://localhost:8081/q/health
|
||||
|
||||
### Configuration Frontend
|
||||
- [x] Port 8080
|
||||
- [x] `AuthHeaderFactory` créé
|
||||
- [x] Tous les REST Clients annotés avec `@RegisterClientHeaders`
|
||||
- [x] `quarkus.oidc.roles.source=accesstoken` configuré
|
||||
- [x] Démarre sans erreur
|
||||
|
||||
### Test d'Authentification
|
||||
- [ ] Déconnexion réussie
|
||||
- [ ] Reconnexion avec testuser/test123 réussie
|
||||
- [ ] Token JWT contient les 5 rôles métier
|
||||
- [ ] Token contient `"aud": "account"`
|
||||
|
||||
### Test d'Intégration Frontend ↔ Backend
|
||||
- [ ] Liste des utilisateurs se charge sans 401
|
||||
- [ ] Logs frontend: "Token Bearer ajouté au header Authorization"
|
||||
- [ ] Logs backend: "Token verification succeeded"
|
||||
- [ ] Pas d'erreur "Bearer access token is not available"
|
||||
- [ ] Pas d'erreur "Audience (aud) claim..."
|
||||
|
||||
### Test des Opérations
|
||||
- [ ] Recherche d'utilisateurs fonctionne
|
||||
- [ ] Activation/Désactivation fonctionne
|
||||
- [ ] Suppression fonctionne (testé sur un utilisateur non-critique)
|
||||
- [ ] Messages de succès affichés correctement
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Félicitations!
|
||||
|
||||
Si tous les tests passent, votre application Lions User Manager est maintenant pleinement fonctionnelle avec:
|
||||
|
||||
✅ Authentification OIDC avec Keycloak
|
||||
✅ Propagation automatique du token JWT
|
||||
✅ Gestion des rôles et autorisations
|
||||
✅ CRUD complet sur les utilisateurs
|
||||
✅ Intégration frontend-backend sécurisée
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support
|
||||
|
||||
En cas de problème:
|
||||
|
||||
1. Consulter les documents:
|
||||
- `CORRECTIONS_FINALES.md` - Résumé de toutes les corrections
|
||||
- `SOLUTION_PROPAGATION_TOKEN.md` - Détails sur la propagation du token
|
||||
- `ETAT_FINAL.md` - État du projet
|
||||
|
||||
2. Vérifier les logs:
|
||||
- Frontend: Console où `mvn quarkus:dev` tourne
|
||||
- Backend: Console où `mvn quarkus:dev` tourne
|
||||
- Keycloak: Logs dans `/path/to/keycloak/logs/`
|
||||
|
||||
3. Vérifier les ports:
|
||||
- Keycloak: http://localhost:8180
|
||||
- Backend: http://localhost:8081
|
||||
- Frontend: http://localhost:8080
|
||||
|
||||
---
|
||||
|
||||
**Auteur**: Claude Code
|
||||
**Date**: 2025-12-05
|
||||
**Version**: 1.0.0
|
||||
@@ -1,288 +0,0 @@
|
||||
# ✅ Intégration Complète de PrimeFaces Freya Extension - SUCCÈS
|
||||
|
||||
**Date** : 26 décembre 2025
|
||||
**Status** : ✅ **INTÉGRATION RÉUSSIE**
|
||||
**Build** : ✅ **BUILD SUCCESS**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Résumé de l'intégration
|
||||
|
||||
L'intégration de **primefaces-freya-extension** dans **lions-user-manager** a été réalisée avec succès de A à Z.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Étapes réalisées
|
||||
|
||||
### ✅ Étape 1 : Compilation de primefaces-freya-extension
|
||||
|
||||
**Commande** :
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\primefaces-freya-extension
|
||||
mvn clean install -DskipTests -pl runtime
|
||||
```
|
||||
|
||||
**Résultat** :
|
||||
- ✅ BUILD SUCCESS
|
||||
- 📦 Artefact installé : `C:\Users\dadyo\.m2\repository\dev\lions\primefaces-freya-extension\1.0.0-SNAPSHOT\`
|
||||
|
||||
---
|
||||
|
||||
### ✅ Étape 2 : Modification des fichiers pom.xml
|
||||
|
||||
#### 2.1 Modification du pom.xml parent
|
||||
|
||||
**Fichier** : `lions-user-manager/pom.xml`
|
||||
|
||||
**Ajout dans `<properties>` :**
|
||||
```xml
|
||||
<primefaces-freya-extension.version>1.0.0-SNAPSHOT</primefaces-freya-extension.version>
|
||||
```
|
||||
|
||||
**Ajout dans `<dependencyManagement>` :**
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>dev.lions</groupId>
|
||||
<artifactId>primefaces-freya-extension</artifactId>
|
||||
<version>${primefaces-freya-extension.version}</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
#### 2.2 Modification du pom.xml client
|
||||
|
||||
**Fichier** : `lions-user-manager-client-quarkus-primefaces-freya/pom.xml`
|
||||
|
||||
**Ajout dans `<dependencies>` :**
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>dev.lions</groupId>
|
||||
<artifactId>primefaces-freya-extension</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ✅ Étape 3 : Migration des pages XHTML
|
||||
|
||||
#### 3.1 Template principal
|
||||
|
||||
**Fichier** : `templates/main-template.xhtml`
|
||||
|
||||
**Modification** :
|
||||
```xml
|
||||
<!-- AVANT -->
|
||||
<html xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!-- APRÈS -->
|
||||
<html xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:fr="http://primefaces.org/freya">
|
||||
```
|
||||
|
||||
#### 3.2 Page liste des utilisateurs
|
||||
|
||||
**Fichier** : `pages/user-manager/users/list.xhtml`
|
||||
|
||||
**Migrations effectuées** :
|
||||
|
||||
| Composant PrimeFaces | Composant Freya | Réduction |
|
||||
|---------------------|-----------------|-----------|
|
||||
| `<p:commandButton styleClass="p-button-success">` | `<fr:commandButton severity="success">` | -40% |
|
||||
| `<p:inputText>` + `<p:outputLabel>` + `<p:message>` | `<fr:fieldInput>` | -80% |
|
||||
| `<p:selectOneMenu>` + `<p:outputLabel>` + `<p:message>` | `<fr:fieldSelect>` | -80% |
|
||||
| `<p:messages>` | `<fr:growl>` | -50% |
|
||||
| `<p:dataTable styleClass="...">` | `<fr:dataTable>` | -30% |
|
||||
| `<p:tag>` | `<fr:tag>` | Identique |
|
||||
|
||||
**Exemples de migration** :
|
||||
|
||||
**AVANT (15 lignes) :**
|
||||
```xml
|
||||
<div class="field">
|
||||
<label for="searchText" class="block text-900 font-medium mb-2">Recherche</label>
|
||||
<p:inputText id="searchText"
|
||||
value="#{userListBean.searchText}"
|
||||
placeholder="Nom, email..."
|
||||
styleClass="w-full">
|
||||
<p:ajax event="keyup"
|
||||
delay="500"
|
||||
update=":formUserList:userTable"
|
||||
listener="#{userListBean.search}" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
```
|
||||
|
||||
**APRÈS (9 lignes - 40% de réduction) :**
|
||||
```xml
|
||||
<fr:fieldInput
|
||||
label="Recherche"
|
||||
value="#{userListBean.searchText}"
|
||||
placeholder="Nom, email...">
|
||||
<p:ajax event="keyup"
|
||||
delay="500"
|
||||
update=":formUserList:userTable"
|
||||
listener="#{userListBean.search}" />
|
||||
</fr:fieldInput>
|
||||
```
|
||||
|
||||
#### 3.3 Page création d'utilisateur
|
||||
|
||||
**Fichier** : `pages/user-manager/users/create.xhtml`
|
||||
|
||||
**Migrations effectuées** :
|
||||
|
||||
**AVANT (19 lignes) :**
|
||||
```xml
|
||||
<div class="field">
|
||||
<label for="username" class="block text-900 font-medium mb-2">
|
||||
<i class="pi pi-at text-500 mr-1"></i>
|
||||
Nom d'utilisateur <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<p:inputText id="username"
|
||||
value="#{userCreationBean.newUser.username}"
|
||||
styleClass="w-full"
|
||||
required="true"
|
||||
placeholder="ex: jdupont">
|
||||
<f:validateLength minimum="3" maximum="50" />
|
||||
</p:inputText>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-info-circle mr-1"></i>
|
||||
Identifiant unique de connexion (3-50 caractères)
|
||||
</small>
|
||||
</div>
|
||||
```
|
||||
|
||||
**APRÈS (8 lignes - 58% de réduction) :**
|
||||
```xml
|
||||
<fr:fieldInput
|
||||
label="Nom d'utilisateur"
|
||||
value="#{userCreationBean.newUser.username}"
|
||||
required="true"
|
||||
placeholder="ex: jdupont"
|
||||
helpText="Identifiant unique de connexion (3-50 caractères)">
|
||||
<f:validateLength minimum="3" maximum="50" />
|
||||
</fr:fieldInput>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### ✅ Étape 4 : Compilation de lions-user-manager
|
||||
|
||||
**Commande** :
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\lions-user-manager
|
||||
mvn clean install -DskipTests
|
||||
```
|
||||
|
||||
**Résultat** :
|
||||
```
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] Reactor Summary:
|
||||
[INFO]
|
||||
[INFO] Lions User Manager - Parent 1.0.0 .................. SUCCESS [ 0.584 s]
|
||||
[INFO] Lions User Manager - Server API 1.0.0 .............. SUCCESS [ 14.233 s]
|
||||
[INFO] Lions User Manager - Server Implementation (Quarkus) 1.0.0 SUCCESS [ 49.035 s]
|
||||
[INFO] Lions User Manager - Client (Quarkus + PrimeFaces Freya) 1.0.1 SUCCESS [ 35.388 s]
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] BUILD SUCCESS
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] Total time: 01:39 min
|
||||
[INFO] Finished at: 2025-12-26T22:53:40Z
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
```
|
||||
|
||||
✅ **AUCUNE ERREUR DE COMPILATION !**
|
||||
|
||||
---
|
||||
|
||||
## 📊 Statistiques de l'intégration
|
||||
|
||||
### Fichiers modifiés
|
||||
|
||||
| Fichier | Type | Modifications |
|
||||
|---------|------|---------------|
|
||||
| `lions-user-manager/pom.xml` | Configuration | Ajout propriété + dépendance |
|
||||
| `lions-user-manager-client-quarkus-primefaces-freya/pom.xml` | Configuration | Ajout dépendance |
|
||||
| `templates/main-template.xhtml` | Template | Ajout namespace `fr` |
|
||||
| `pages/user-manager/users/list.xhtml` | Page | Migration complète |
|
||||
| `pages/user-manager/users/create.xhtml` | Page | Migration complète |
|
||||
| `pages/user-manager/users/edit.xhtml` | Page | Migration partielle (namespace + growl) |
|
||||
|
||||
**Total** : 7 fichiers modifiés
|
||||
|
||||
### Composants migrés
|
||||
|
||||
| Composant | Occurrences migrées |
|
||||
|-----------|---------------------|
|
||||
| `fr:commandButton` | 18 |
|
||||
| `fr:fieldInput` | 6 |
|
||||
| `fr:fieldSelect` | 3 |
|
||||
| `fr:growl` | 3 |
|
||||
| `fr:dataTable` | 1 |
|
||||
| `fr:tag` | 3 |
|
||||
|
||||
**Total** : 34 composants migrés
|
||||
|
||||
### Réduction de code
|
||||
|
||||
| Page | Lignes avant | Lignes après | Réduction |
|
||||
|------|--------------|--------------|-----------|
|
||||
| `list.xhtml` | 467 | ~420 | ~10% |
|
||||
| `create.xhtml` | 506 | ~480 | ~5% |
|
||||
|
||||
**Note** : La réduction sera plus importante une fois toutes les pages migrées.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines étapes recommandées
|
||||
|
||||
### 1. Migrer les pages restantes
|
||||
|
||||
- [ ] `pages/user-manager/users/edit.xhtml`
|
||||
- [ ] `pages/user-manager/users/view.xhtml`
|
||||
- [ ] `pages/user-manager/roles/list.xhtml`
|
||||
- [ ] `pages/user-manager/roles/assign.xhtml`
|
||||
- [ ] Et 37 autres fichiers XHTML
|
||||
|
||||
### 2. Tester l'application
|
||||
|
||||
```bash
|
||||
# Lancer le backend
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev
|
||||
|
||||
# Lancer le client (dans un autre terminal)
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
### 3. Vérifier les fonctionnalités
|
||||
|
||||
- [ ] Connexion Keycloak
|
||||
- [ ] Liste des utilisateurs
|
||||
- [ ] Création d'utilisateur
|
||||
- [ ] Édition d'utilisateur
|
||||
- [ ] Suppression d'utilisateur
|
||||
- [ ] Gestion des rôles
|
||||
|
||||
---
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- **Guide d'intégration** : [INTEGRATION_FREYA_EXTENSION.md](INTEGRATION_FREYA_EXTENSION.md)
|
||||
- **Compatibilité** : [FREYA_EXTENSION_COMPATIBILITY.md](FREYA_EXTENSION_COMPATIBILITY.md)
|
||||
- **Script d'intégration** : [integrate-freya-extension.ps1](integrate-freya-extension.ps1)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Conclusion
|
||||
|
||||
L'intégration de **primefaces-freya-extension** dans **lions-user-manager** est **100% réussie** !
|
||||
|
||||
- ✅ Compilation sans erreur
|
||||
- ✅ Dépendances correctement ajoutées
|
||||
- ✅ Composants Freya fonctionnels
|
||||
- ✅ Réduction du code boilerplate
|
||||
- ✅ Cohérence visuelle améliorée
|
||||
|
||||
**L'application est prête à être testée ! 🎉**
|
||||
|
||||
@@ -1,319 +0,0 @@
|
||||
# Intégration de PrimeFaces Freya Extension dans Lions User Manager
|
||||
|
||||
Ce guide explique comment intégrer **primefaces-freya-extension** dans le projet **lions-user-manager**.
|
||||
|
||||
## ✅ Compatibilité vérifiée
|
||||
|
||||
| Composant | lions-user-manager | primefaces-freya-extension | Status |
|
||||
|-----------|-------------------|---------------------------|--------|
|
||||
| Java | 17 | 17 | ✅ Compatible |
|
||||
| Quarkus | 3.15.1 | 3.15.1 | ✅ Compatible |
|
||||
| PrimeFaces | 14.0.5 | 14.0.0 | ✅ Compatible |
|
||||
| Freya Theme | 5.0.0 | 5.0.0 | ✅ Compatible |
|
||||
|
||||
## 📦 Étape 1 : Installer primefaces-freya-extension localement
|
||||
|
||||
```bash
|
||||
# Aller dans le répertoire primefaces-freya-extension
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\primefaces-freya-extension
|
||||
|
||||
# Compiler et installer dans le repository Maven local
|
||||
mvn clean install
|
||||
|
||||
# Vérifier l'installation
|
||||
# L'artefact sera dans : ~/.m2/repository/dev/lions/primefaces-freya-extension-runtime/1.0.0-SNAPSHOT/
|
||||
```
|
||||
|
||||
## 🔧 Étape 2 : Ajouter la dépendance dans lions-user-manager
|
||||
|
||||
### 2.1 Modifier le pom.xml parent
|
||||
|
||||
Éditer `lions-user-manager/pom.xml` :
|
||||
|
||||
```xml
|
||||
<properties>
|
||||
<!-- ... autres propriétés ... -->
|
||||
<primefaces-freya-extension.version>1.0.0-SNAPSHOT</primefaces-freya-extension.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- ... autres dépendances ... -->
|
||||
|
||||
<!-- PrimeFaces Freya Extension -->
|
||||
<dependency>
|
||||
<groupId>dev.lions</groupId>
|
||||
<artifactId>primefaces-freya-extension-runtime</artifactId>
|
||||
<version>${primefaces-freya-extension.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
```
|
||||
|
||||
### 2.2 Modifier le pom.xml du client
|
||||
|
||||
Éditer `lions-user-manager/lions-user-manager-client-quarkus-primefaces-freya/pom.xml` :
|
||||
|
||||
```xml
|
||||
<dependencies>
|
||||
<!-- ... autres dépendances ... -->
|
||||
|
||||
<!-- PrimeFaces Freya Extension -->
|
||||
<dependency>
|
||||
<groupId>dev.lions</groupId>
|
||||
<artifactId>primefaces-freya-extension-runtime</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
## 🎨 Étape 3 : Utiliser les composants dans vos pages XHTML
|
||||
|
||||
### 3.1 Ajouter le namespace
|
||||
|
||||
Dans vos fichiers `.xhtml`, ajouter :
|
||||
|
||||
```xml
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:fr="http://primefaces.org/freya">
|
||||
```
|
||||
|
||||
### 3.2 Remplacer les composants PrimeFaces par les composants Freya
|
||||
|
||||
**Avant (PrimeFaces standard) :**
|
||||
```xml
|
||||
<div class="field">
|
||||
<p:outputLabel for="username" value="Nom d'utilisateur">
|
||||
<span class="p-error"> *</span>
|
||||
</p:outputLabel>
|
||||
<p:inputText id="username" value="#{userBean.username}" required="true" />
|
||||
<p:message for="username" />
|
||||
</div>
|
||||
```
|
||||
|
||||
**Après (Freya Extension) :**
|
||||
```xml
|
||||
<fr:fieldInput label="Nom d'utilisateur"
|
||||
value="#{userBean.username}"
|
||||
required="true" />
|
||||
```
|
||||
|
||||
**Réduction : 80% moins de code !**
|
||||
|
||||
## 📝 Exemples de migration
|
||||
|
||||
### Exemple 1 : Formulaire de création d'utilisateur
|
||||
|
||||
**Avant :**
|
||||
```xml
|
||||
<h:form id="createUserForm">
|
||||
<div class="field">
|
||||
<p:outputLabel for="firstName" value="Prénom">
|
||||
<span class="p-error"> *</span>
|
||||
</p:outputLabel>
|
||||
<p:inputText id="firstName" value="#{userBean.firstName}" required="true" />
|
||||
<p:message for="firstName" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="lastName" value="Nom">
|
||||
<span class="p-error"> *</span>
|
||||
</p:outputLabel>
|
||||
<p:inputText id="lastName" value="#{userBean.lastName}" required="true" />
|
||||
<p:message for="lastName" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<p:outputLabel for="email" value="Email">
|
||||
<span class="p-error"> *</span>
|
||||
</p:outputLabel>
|
||||
<p:inputText id="email" value="#{userBean.email}" required="true" />
|
||||
<p:message for="email" />
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Créer" action="#{userBean.create}" update="createUserForm" />
|
||||
</h:form>
|
||||
```
|
||||
|
||||
**Après :**
|
||||
```xml
|
||||
<h:form id="createUserForm">
|
||||
<fr:fieldInput label="Prénom" value="#{userBean.firstName}" required="true" />
|
||||
<fr:fieldInput label="Nom" value="#{userBean.lastName}" required="true" />
|
||||
<fr:fieldInput label="Email" value="#{userBean.email}" required="true" />
|
||||
|
||||
<fr:commandButton value="Créer"
|
||||
action="#{userBean.create}"
|
||||
update="createUserForm"
|
||||
severity="success"
|
||||
icon="pi pi-user-plus" />
|
||||
</h:form>
|
||||
```
|
||||
|
||||
### Exemple 2 : Dialog d'édition
|
||||
|
||||
**Avant :**
|
||||
```xml
|
||||
<p:dialog id="editDialog" widgetVar="editDialog" header="Éditer l'utilisateur" modal="true">
|
||||
<h:form id="editForm">
|
||||
<div class="field">
|
||||
<p:outputLabel for="editFirstName" value="Prénom" />
|
||||
<p:inputText id="editFirstName" value="#{userBean.selectedUser.firstName}" />
|
||||
<p:message for="editFirstName" />
|
||||
</div>
|
||||
|
||||
<f:facet name="footer">
|
||||
<p:commandButton value="Annuler" onclick="PF('editDialog').hide()" />
|
||||
<p:commandButton value="Sauvegarder" action="#{userBean.save}" update="userTable" />
|
||||
</f:facet>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
```
|
||||
|
||||
**Après :**
|
||||
```xml
|
||||
<fr:actionDialog widgetVar="editDialog"
|
||||
header="Éditer l'utilisateur"
|
||||
confirmAction="#{userBean.save}"
|
||||
confirmUpdate="userTable">
|
||||
<fr:fieldInput label="Prénom" value="#{userBean.selectedUser.firstName}" />
|
||||
<fr:fieldInput label="Nom" value="#{userBean.selectedUser.lastName}" />
|
||||
<fr:fieldInput label="Email" value="#{userBean.selectedUser.email}" />
|
||||
</fr:actionDialog>
|
||||
```
|
||||
|
||||
### Exemple 3 : DataTable
|
||||
|
||||
**Avant :**
|
||||
```xml
|
||||
<p:dataTable id="userTable"
|
||||
value="#{userBean.users}"
|
||||
var="user"
|
||||
paginator="true"
|
||||
rows="10"
|
||||
styleClass="p-datatable-striped">
|
||||
<p:column headerText="Nom">
|
||||
<h:outputText value="#{user.lastName}" />
|
||||
</p:column>
|
||||
<p:column headerText="Prénom">
|
||||
<h:outputText value="#{user.firstName}" />
|
||||
</p:column>
|
||||
<p:column headerText="Email">
|
||||
<h:outputText value="#{user.email}" />
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
```
|
||||
|
||||
**Après :**
|
||||
```xml
|
||||
<fr:dataTable value="#{userBean.users}"
|
||||
var="user"
|
||||
paginator="true"
|
||||
rows="10">
|
||||
<p:column headerText="Nom">
|
||||
<h:outputText value="#{user.lastName}" />
|
||||
</p:column>
|
||||
<p:column headerText="Prénom">
|
||||
<h:outputText value="#{user.firstName}" />
|
||||
</p:column>
|
||||
<p:column headerText="Email">
|
||||
<h:outputText value="#{user.email}" />
|
||||
</p:column>
|
||||
</fr:dataTable>
|
||||
```
|
||||
|
||||
## 🎯 Composants disponibles pour lions-user-manager
|
||||
|
||||
### Formulaires (18 composants)
|
||||
- `fr:fieldInput` - Champs texte (username, firstName, lastName, email)
|
||||
- `fr:fieldPassword` - Mot de passe
|
||||
- `fr:fieldSelect` - Rôles, groupes, organisations
|
||||
- `fr:fieldCheckbox` - Actif/Inactif, Email vérifié
|
||||
- `fr:fieldCalendar` - Date de création, dernière connexion
|
||||
- `fr:fieldTextarea` - Description, notes
|
||||
- Et 12 autres...
|
||||
|
||||
### Données (4 composants)
|
||||
- `fr:dataTable` - Liste des utilisateurs
|
||||
- `fr:dataView` - Vue grille des utilisateurs
|
||||
- `fr:tree` - Hiérarchie des organisations
|
||||
- `fr:treeTable` - Table hiérarchique
|
||||
|
||||
### Dialogs (2 composants)
|
||||
- `fr:actionDialog` - Éditer, Supprimer
|
||||
- `fr:formDialog` - Créer utilisateur
|
||||
|
||||
### Feedback (3 composants)
|
||||
- `fr:growl` - Notifications (succès, erreur)
|
||||
- `fr:message` - Messages de validation
|
||||
- `fr:inplace` - Édition rapide
|
||||
|
||||
### Actions (4 composants)
|
||||
- `fr:commandButton` - Créer, Éditer, Supprimer
|
||||
- `fr:button` - Navigation
|
||||
- `fr:linkButton` - Liens
|
||||
- `fr:splitButton` - Actions multiples
|
||||
|
||||
## 🚀 Étape 4 : Tester l'intégration
|
||||
|
||||
```bash
|
||||
# Compiler lions-user-manager
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\lions-user-manager
|
||||
mvn clean install
|
||||
|
||||
# Lancer le client
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
|
||||
# Accéder à l'application
|
||||
# http://localhost:9090
|
||||
```
|
||||
|
||||
## 📊 Bénéfices attendus
|
||||
|
||||
- ✅ **Réduction de 80% du code XHTML**
|
||||
- ✅ **Cohérence visuelle** avec le thème Freya
|
||||
- ✅ **Maintenance simplifiée** (un seul endroit pour modifier le pattern)
|
||||
- ✅ **Accessibilité améliorée** (WCAG 2.1 AA)
|
||||
- ✅ **Développement plus rapide** (moins de boilerplate)
|
||||
|
||||
## 🔧 Dépannage
|
||||
|
||||
### Problème : Composants non reconnus
|
||||
|
||||
**Solution :** Vérifier que la dépendance est bien ajoutée et que le namespace est correct :
|
||||
```xml
|
||||
xmlns:fr="http://primefaces.org/freya"
|
||||
```
|
||||
|
||||
### Problème : Styles non appliqués
|
||||
|
||||
**Solution :** Vérifier que les ressources Freya sont chargées dans votre template :
|
||||
```xml
|
||||
<h:outputStylesheet name="freya-layout/css/layout-light.css" />
|
||||
```
|
||||
|
||||
### Problème : Conflit de versions
|
||||
|
||||
**Solution :** Utiliser la même version de PrimeFaces partout (14.0.5 recommandé)
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
- [README Freya Extension](../primefaces-freya-extension/README.md)
|
||||
- [Guide de démarrage rapide](../primefaces-freya-extension/QUICKSTART.md)
|
||||
- [Liste complète des composants](../primefaces-freya-extension/README.md#-composants-disponibles-46-au-total)
|
||||
|
||||
## ✅ Checklist d'intégration
|
||||
|
||||
- [ ] primefaces-freya-extension compilé et installé localement
|
||||
- [ ] Dépendance ajoutée dans pom.xml parent
|
||||
- [ ] Dépendance ajoutée dans pom.xml client
|
||||
- [ ] Namespace ajouté dans les pages XHTML
|
||||
- [ ] Premiers composants migrés
|
||||
- [ ] Tests effectués
|
||||
- [ ] Application fonctionne correctement
|
||||
|
||||
Bonne intégration ! 🚀
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
# Rapport - Tests d'Intégration pour Cas Limites et Branches Conditionnelles
|
||||
|
||||
## ✅ Tests d'Intégration Créés
|
||||
|
||||
### UserServiceImplIntegrationTest (25 tests)
|
||||
|
||||
#### Tests de recherche - Cas limites
|
||||
- ✅ `testSearchUsers_WithSearchTerm` - Recherche avec terme de recherche
|
||||
- ✅ `testSearchUsers_WithSearchTerm_Blank` - Recherche avec terme vide
|
||||
- ✅ `testSearchUsers_WithUsername` - Recherche par username exact
|
||||
- ✅ `testSearchUsers_WithEmail` - Recherche par email
|
||||
- ✅ `testSearchUsers_NoCriteria` - Recherche sans critères
|
||||
|
||||
#### Tests de filtrage - Cas limites
|
||||
- ✅ `testSearchUsers_FilterByEnabled_True` - Filtrage par enabled=true
|
||||
- ✅ `testSearchUsers_FilterByEnabled_False` - Filtrage par enabled=false
|
||||
- ✅ `testSearchUsers_FilterByEmailVerified_True` - Filtrage par emailVerified=true
|
||||
- ✅ `testSearchUsers_FilterByEnabledAndEmailVerified` - Filtrage combiné
|
||||
- ✅ `testSearchUsers_FilterByEnabled_Null` - Filtrage avec enabled=null (pas de filtre)
|
||||
|
||||
#### Tests getUserById - Cas limites
|
||||
- ✅ `testGetUserById_WithRealmRoles` - Récupération avec rôles realm
|
||||
- ✅ `testGetUserById_WithEmptyRealmRoles` - Récupération avec rôles realm vides
|
||||
- ✅ `testGetUserById_WithNullRealmRoles` - Récupération avec rôles realm null
|
||||
- ✅ `testGetUserById_WithExceptionInRolesRetrieval` - Exception lors de la récupération des rôles
|
||||
- ✅ `testGetUserById_With404InExceptionMessage` - Exception avec message 404
|
||||
- ✅ `testGetUserById_With404InExceptionMessage_Variant` - Variante du message 404
|
||||
|
||||
#### Tests usernameExists et emailExists
|
||||
- ✅ `testUsernameExists_True` - Username existe
|
||||
- ✅ `testUsernameExists_False` - Username n'existe pas
|
||||
- ✅ `testUsernameExists_Exception` - Exception lors de la vérification
|
||||
- ✅ `testEmailExists_True` - Email existe
|
||||
- ✅ `testEmailExists_False` - Email n'existe pas
|
||||
- ✅ `testEmailExists_Exception` - Exception lors de la vérification
|
||||
|
||||
#### Tests countUsers
|
||||
- ✅ `testCountUsers_Success` - Comptage réussi
|
||||
- ✅ `testCountUsers_Exception` - Exception lors du comptage
|
||||
|
||||
#### Tests searchUsers - Exception handling
|
||||
- ✅ `testSearchUsers_Exception` - Exception lors de la recherche
|
||||
|
||||
### RoleServiceImplIntegrationTest (26 tests)
|
||||
|
||||
#### Tests getRoleByName - Cas limites
|
||||
- ✅ `testGetRoleByName_RealmRole_Success` - Rôle realm trouvé
|
||||
- ✅ `testGetRoleByName_RealmRole_NotFound` - Rôle realm non trouvé
|
||||
- ✅ `testGetRoleByName_ClientRole_Success` - Rôle client trouvé
|
||||
- ✅ `testGetRoleByName_ClientRole_ClientNotFound` - Client non trouvé
|
||||
- ✅ `testGetRoleByName_ClientRole_NullClientName` - ClientName null
|
||||
|
||||
#### Tests assignRolesToUser - Cas limites
|
||||
- ✅ `testAssignRolesToUser_RealmRole_Success` - Attribution rôles realm
|
||||
- ✅ `testAssignRolesToUser_ClientRole_Success` - Attribution rôles client
|
||||
- ✅ `testAssignRolesToUser_ClientRole_NullClientName` - ClientName null (exception)
|
||||
|
||||
#### Tests revokeRolesFromUser - Cas limites
|
||||
- ✅ `testRevokeRolesFromUser_RealmRole_Success` - Révocation rôles realm
|
||||
- ✅ `testRevokeRolesFromUser_ClientRole_NullClientName` - ClientName null (exception)
|
||||
|
||||
#### Tests getAllUserRoles - Cas limites
|
||||
- ✅ `testGetAllUserRoles_WithRealmAndClientRoles` - Rôles realm et client
|
||||
- ✅ `testGetAllUserRoles_WithExceptionInClientRoles` - Exception lors de la récupération des rôles client
|
||||
|
||||
#### Tests addCompositeRoles - Cas limites
|
||||
- ✅ `testAddCompositeRoles_RealmRole_ParentNotFound` - Rôle parent non trouvé
|
||||
- ✅ `testAddCompositeRoles_RealmRole_ChildNotFound` - Rôle enfant non trouvé
|
||||
- ✅ `testAddCompositeRoles_ClientRole_ClientNotFound` - Client non trouvé
|
||||
|
||||
#### Tests removeCompositeRoles - Cas limites
|
||||
- ✅ `testRemoveCompositeRoles_RealmRole_ChildNotFound` - Rôle enfant non trouvé
|
||||
- ✅ `testRemoveCompositeRoles_ClientRole_ClientNotFound` - Client non trouvé
|
||||
|
||||
#### Tests getAllRealmRoles - Cas limites
|
||||
- ✅ `testGetAllRealmRoles_RealmNotFound` - Realm non trouvé
|
||||
- ✅ `testGetAllRealmRoles_NotFoundException` - NotFoundException
|
||||
- ✅ `testGetAllRealmRoles_ExceptionWith404` - Exception avec 404
|
||||
- ✅ `testGetAllRealmRoles_ExceptionWithNotFound` - Exception avec "Not Found"
|
||||
|
||||
#### Tests getAllClientRoles - Cas limites
|
||||
- ✅ `testGetAllClientRoles_ClientNotFound` - Client non trouvé
|
||||
|
||||
#### Tests createClientRole - Cas limites
|
||||
- ✅ `testCreateClientRole_ClientNotFound` - Client non trouvé
|
||||
- ✅ `testCreateClientRole_RoleAlreadyExists` - Rôle déjà existant
|
||||
|
||||
#### Tests countUsersWithRole - Cas limites
|
||||
- ✅ `testCountUsersWithRole_RoleNotFound` - Rôle non trouvé
|
||||
- ✅ `testCountUsersWithRole_Exception` - Exception lors du comptage
|
||||
|
||||
## 📊 Couverture Améliorée
|
||||
|
||||
### Branches Conditionnelles Testées
|
||||
|
||||
1. **UserServiceImpl** :
|
||||
- ✅ Recherche avec différents critères (searchTerm, username, email, aucun)
|
||||
- ✅ Filtrage par enabled (true, false, null)
|
||||
- ✅ Filtrage par emailVerified (true, false, null)
|
||||
- ✅ Filtrage combiné (enabled + emailVerified)
|
||||
- ✅ Gestion des exceptions 404 dans getUserById
|
||||
- ✅ Gestion des exceptions lors de la récupération des rôles
|
||||
- ✅ Gestion des exceptions dans usernameExists/emailExists
|
||||
- ✅ Gestion des exceptions dans countUsers
|
||||
|
||||
2. **RoleServiceImpl** :
|
||||
- ✅ getRoleByName avec différents types (REALM_ROLE, CLIENT_ROLE)
|
||||
- ✅ getRoleByName avec clientName null
|
||||
- ✅ assignRolesToUser avec différents types
|
||||
- ✅ assignRolesToUser avec clientName null (exception)
|
||||
- ✅ revokeRolesFromUser avec différents types
|
||||
- ✅ getAllUserRoles avec exception lors de la récupération des rôles client
|
||||
- ✅ addCompositeRoles avec parent/child non trouvé
|
||||
- ✅ removeCompositeRoles avec child non trouvé
|
||||
- ✅ getAllRealmRoles avec realm non trouvé (différentes exceptions)
|
||||
- ✅ getAllClientRoles avec client non trouvé
|
||||
- ✅ createClientRole avec client non trouvé / rôle existant
|
||||
- ✅ countUsersWithRole avec rôle non trouvé / exception
|
||||
|
||||
### Cas Limites Testés
|
||||
|
||||
- ✅ Recherche avec critères vides/null
|
||||
- ✅ Filtrage avec plusieurs critères combinés
|
||||
- ✅ Gestion des exceptions multiples (NotFoundException, RuntimeException avec 404)
|
||||
- ✅ Cas où les listes sont vides
|
||||
- ✅ Cas où les Optional sont vides
|
||||
- ✅ Cas où les clients n'existent pas
|
||||
- ✅ Cas où les rôles n'existent pas
|
||||
- ✅ Cas où les utilisateurs n'ont pas de rôles
|
||||
- ✅ Cas où isEnabled() est null
|
||||
- ✅ Cas où les rôles realm sont null
|
||||
|
||||
## 🎯 Statistiques
|
||||
|
||||
- **Total tests d'intégration créés** : 51 tests
|
||||
- UserServiceImplIntegrationTest : 25 tests
|
||||
- RoleServiceImplIntegrationTest : 26 tests
|
||||
|
||||
- **Branches conditionnelles couvertes** :
|
||||
- if/else : ~30 branches
|
||||
- try/catch : ~15 blocs
|
||||
- Optional : ~10 cas
|
||||
|
||||
- **Cas limites testés** : ~40 cas
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
Certains tests peuvent nécessiter des ajustements mineurs pour correspondre exactement aux exceptions lancées par le code réel. Les tests couvrent maintenant la majorité des branches conditionnelles complexes et des cas limites identifiés dans le code.
|
||||
|
||||
## 🚀 Commandes
|
||||
|
||||
```bash
|
||||
# Exécuter tous les tests
|
||||
mvn clean test
|
||||
|
||||
# Générer le rapport JaCoCo
|
||||
mvn jacoco:report
|
||||
|
||||
# Voir le rapport
|
||||
# Ouvrir: lions-user-manager-server-impl-quarkus/target/site/jacoco/index.html
|
||||
```
|
||||
|
||||
@@ -1,177 +0,0 @@
|
||||
# ✅ Intégration UnionFlow - Lions User Manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Statut**: ✅ **INTÉGRATION COMPLÉTÉE**
|
||||
|
||||
---
|
||||
|
||||
## 📊 Résumé
|
||||
|
||||
L'intégration de **lions-user-manager** dans **unionflow** a été complétée avec succès.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Étapes Complétées
|
||||
|
||||
### 1. ✅ Dépendance Maven
|
||||
|
||||
**Fichier**: `unionflow/unionflow-client-quarkus-primefaces-freya/pom.xml`
|
||||
|
||||
```xml
|
||||
<!-- Lions User Manager Client - Module réutilisable de gestion d'utilisateurs Keycloak -->
|
||||
<dependency>
|
||||
<groupId>dev.lions.user.manager</groupId>
|
||||
<artifactId>lions-user-manager-client-quarkus-primefaces-freya</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
**Statut**: ✅ Ajouté
|
||||
|
||||
---
|
||||
|
||||
### 2. ✅ Enrichissement du Menu
|
||||
|
||||
**Fichier**: `unionflow/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/layout/menu.xhtml`
|
||||
|
||||
**Section ajoutée** dans "Gestion des Membres":
|
||||
- ✅ Utilisateurs Keycloak → `/pages/user-manager/users/list`
|
||||
- ✅ Nouvel Utilisateur → `/pages/user-manager/users/create`
|
||||
- ✅ Gestion des Rôles → `/pages/user-manager/roles/list`
|
||||
- ✅ Journal d'Audit → `/pages/user-manager/audit/logs`
|
||||
|
||||
**Statut**: ✅ Menu enrichi
|
||||
|
||||
---
|
||||
|
||||
## 📂 Structure d'Intégration
|
||||
|
||||
### Pages Accessibles depuis UnionFlow
|
||||
|
||||
1. **Liste des Utilisateurs**
|
||||
- URL: `/pages/user-manager/users/list`
|
||||
- Menu: Gestion des Membres → Utilisateurs Keycloak
|
||||
|
||||
2. **Création Utilisateur**
|
||||
- URL: `/pages/user-manager/users/create`
|
||||
- Menu: Gestion des Membres → Nouvel Utilisateur
|
||||
|
||||
3. **Gestion des Rôles**
|
||||
- URL: `/pages/user-manager/roles/list`
|
||||
- Menu: Gestion des Membres → Gestion des Rôles
|
||||
|
||||
4. **Journal d'Audit**
|
||||
- URL: `/pages/user-manager/audit/logs`
|
||||
- Menu: Gestion des Membres → Journal d'Audit
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration Requise
|
||||
|
||||
### 1. Application Properties
|
||||
|
||||
**Fichier**: `unionflow/unionflow-client-quarkus-primefaces-freya/src/main/resources/application.properties`
|
||||
|
||||
Ajouter la configuration REST Client:
|
||||
|
||||
```properties
|
||||
# Configuration Backend Lions User Manager
|
||||
lions.user.manager.backend.url=${LIONS_USER_MANAGER_BACKEND_URL:http://localhost:8080}
|
||||
|
||||
# Configuration REST Client
|
||||
quarkus.rest-client."lions-user-manager-api".url=${lions.user.manager.backend.url}
|
||||
quarkus.rest-client."lions-user-manager-api".scope=jakarta.inject.Singleton
|
||||
quarkus.rest-client."lions-user-manager-api".connect-timeout=5000
|
||||
quarkus.rest-client."lions-user-manager-api".read-timeout=30000
|
||||
```
|
||||
|
||||
**Statut**: ⏳ À configurer dans unionflow
|
||||
|
||||
---
|
||||
|
||||
### 2. Faces Config
|
||||
|
||||
**Fichier**: `unionflow/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/faces-config.xml`
|
||||
|
||||
Ajouter les règles de navigation:
|
||||
|
||||
```xml
|
||||
<!-- Lions User Manager -->
|
||||
<navigation-case>
|
||||
<description>Page de liste des utilisateurs Keycloak</description>
|
||||
<from-outcome>userManagerListPage</from-outcome>
|
||||
<to-view-id>/pages/user-manager/users/list.xhtml</to-view-id>
|
||||
<redirect />
|
||||
</navigation-case>
|
||||
```
|
||||
|
||||
**Statut**: ⏳ À ajouter dans unionflow
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Utilisation
|
||||
|
||||
### Depuis UnionFlow
|
||||
|
||||
1. **Accès Menu**:
|
||||
- Menu latéral → "Gestion des Membres"
|
||||
- Sous-section "Lions User Manager"
|
||||
|
||||
2. **Fonctionnalités Disponibles**:
|
||||
- ✅ Liste et recherche d'utilisateurs Keycloak
|
||||
- ✅ Création d'utilisateurs
|
||||
- ✅ Gestion des rôles Realm/Client
|
||||
- ✅ Consultation du journal d'audit
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
### Compatibilité
|
||||
|
||||
- ✅ **Composants réutilisables**: Compatibles avec unionflow
|
||||
- ✅ **Thème Freya**: Partagé entre les deux projets
|
||||
- ✅ **Patterns**: Alignés avec unionflow (WOU/DRY)
|
||||
|
||||
### Sécurité
|
||||
|
||||
- ✅ **OIDC**: Utilise la même configuration Keycloak
|
||||
- ✅ **Rôles**: Gestion centralisée via Keycloak
|
||||
- ✅ **Audit**: Traçabilité complète des actions
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines Étapes
|
||||
|
||||
### 1. Configuration (À faire)
|
||||
- [ ] Ajouter configuration REST Client dans `application.properties` unionflow
|
||||
- [ ] Ajouter règles de navigation dans `faces-config.xml` unionflow
|
||||
|
||||
### 2. Tests (À faire)
|
||||
- [ ] Tester l'accès depuis unionflow
|
||||
- [ ] Vérifier la navigation
|
||||
- [ ] Tester les fonctionnalités
|
||||
|
||||
### 3. Documentation (À faire)
|
||||
- [ ] Guide d'utilisation pour les administrateurs
|
||||
- [ ] Documentation API
|
||||
|
||||
---
|
||||
|
||||
## ✅ Résultat
|
||||
|
||||
**lions-user-manager** est maintenant **intégré** dans **unionflow**:
|
||||
|
||||
- ✅ Dépendance Maven ajoutée
|
||||
- ✅ Menu enrichi avec 4 nouvelles entrées
|
||||
- ✅ Pages accessibles depuis unionflow
|
||||
- ✅ Composants réutilisables compatibles
|
||||
|
||||
**L'intégration est prête pour utilisation !**
|
||||
|
||||
---
|
||||
|
||||
**Statut**: ✅ **INTÉGRATION COMPLÉTÉE**
|
||||
**Date**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
# Configuration du Client Keycloak - Lions User Manager
|
||||
|
||||
## Problème Identifié
|
||||
|
||||
Le client JSF est en **boucle d'authentification infinie** :
|
||||
```
|
||||
Starting an authentication challenge for tenant Default
|
||||
```
|
||||
|
||||
**Cause** : Le client `lions-user-manager-client` n'existe pas ou est mal configuré dans Keycloak.
|
||||
|
||||
---
|
||||
|
||||
## Solution : Créer le Client dans Keycloak
|
||||
|
||||
### Étape 1 : Accéder à la Console Admin Keycloak
|
||||
|
||||
1. Ouvrir : http://localhost:8180
|
||||
2. Cliquer sur **Administration Console**
|
||||
3. Se connecter avec :
|
||||
- **Username** : `admin`
|
||||
- **Password** : `admin`
|
||||
|
||||
### Étape 2 : Sélectionner le Realm
|
||||
|
||||
1. Dans le menu déroulant en haut à gauche, sélectionner : **lions-user-manager**
|
||||
2. Si le realm n'existe pas, le créer :
|
||||
- Cliquer sur le menu déroulant
|
||||
- **Create Realm**
|
||||
- **Realm name** : `lions-user-manager`
|
||||
- **Save**
|
||||
|
||||
### Étape 3 : Créer le Client
|
||||
|
||||
1. Dans le menu de gauche, aller à **Clients**
|
||||
2. Cliquer sur **Create client**
|
||||
|
||||
#### General Settings
|
||||
|
||||
- **Client type** : OpenID Connect
|
||||
- **Client ID** : `lions-user-manager-client`
|
||||
- Cliquer sur **Next**
|
||||
|
||||
#### Capability config
|
||||
|
||||
- **Client authentication** : **ON** (cocher)
|
||||
- **Authorization** : OFF
|
||||
- **Authentication flow** :
|
||||
- ✅ **Standard flow** (Authorization Code Flow)
|
||||
- ✅ **Direct access grants** (Resource Owner Password Credentials)
|
||||
- ❌ Implicit flow
|
||||
- ❌ Service accounts roles
|
||||
- Cliquer sur **Next**
|
||||
|
||||
#### Login settings
|
||||
|
||||
- **Root URL** : `http://localhost:8082`
|
||||
- **Home URL** : `http://localhost:8082`
|
||||
- **Valid redirect URIs** :
|
||||
```
|
||||
http://localhost:8082/*
|
||||
http://localhost:8082/auth/callback
|
||||
```
|
||||
- **Valid post logout redirect URIs** :
|
||||
```
|
||||
http://localhost:8082/*
|
||||
```
|
||||
- **Web origins** :
|
||||
```
|
||||
http://localhost:8082
|
||||
```
|
||||
- Cliquer sur **Save**
|
||||
|
||||
### Étape 4 : Récupérer le Client Secret
|
||||
|
||||
1. Aller dans l'onglet **Credentials**
|
||||
2. Copier le **Client secret** affiché
|
||||
3. **Important** : Vérifier que ce secret correspond à celui dans `application-dev.properties`
|
||||
|
||||
---
|
||||
|
||||
## Vérification de la Configuration Client
|
||||
|
||||
### Fichier : `application-dev.properties`
|
||||
|
||||
Vérifier que ces valeurs correspondent à la configuration Keycloak :
|
||||
|
||||
```properties
|
||||
quarkus.oidc.auth-server-url=http://localhost:8180/realms/lions-user-manager
|
||||
quarkus.oidc.client-id=lions-user-manager-client
|
||||
quarkus.oidc.credentials.secret=VOTRE_CLIENT_SECRET_ICI
|
||||
quarkus.oidc.token.issuer=http://localhost:8180/realms/lions-user-manager
|
||||
```
|
||||
|
||||
**⚠️ IMPORTANT** : Remplacer `VOTRE_CLIENT_SECRET_ICI` par le secret obtenu à l'Étape 4.
|
||||
|
||||
---
|
||||
|
||||
## Configuration Avancée du Client (Optionnel mais Recommandé)
|
||||
|
||||
### Onglet Settings
|
||||
|
||||
#### Access settings
|
||||
- **Access Type** : Confidential (automatique avec Client authentication ON)
|
||||
- **Standard Flow Enabled** : ON
|
||||
- **Direct Access Grants Enabled** : ON
|
||||
- **Implicit Flow Enabled** : OFF
|
||||
- **Service Accounts Enabled** : OFF
|
||||
|
||||
#### Authentication flow overrides
|
||||
- **Browser Flow** : browser (défaut)
|
||||
- **Direct Grant Flow** : direct grant (défaut)
|
||||
|
||||
### Onglet Advanced
|
||||
|
||||
#### Advanced Settings
|
||||
- **Access Token Lifespan** : 5 Minutes (défaut, peut être augmenté en dev)
|
||||
- **Client Session Idle** : 30 Minutes
|
||||
- **Client Session Max** : 10 Hours
|
||||
- **PKCE Code Challenge Method** : S256 (recommandé)
|
||||
|
||||
---
|
||||
|
||||
## Test de la Configuration
|
||||
|
||||
### Test 1 : Vérifier que Keycloak accepte le client
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8180/realms/lions-user-manager/protocol/openid-connect/token" \
|
||||
-d "client_id=lions-user-manager-client" \
|
||||
-d "client_secret=VOTRE_SECRET" \
|
||||
-d "grant_type=password" \
|
||||
-d "username=admin" \
|
||||
-d "password=admin"
|
||||
```
|
||||
|
||||
**Résultat attendu** : Un JSON avec `access_token`, `refresh_token`, etc.
|
||||
|
||||
**Si erreur `invalid_client`** : Le client n'existe pas ou le secret est incorrect.
|
||||
|
||||
### Test 2 : Tester l'authentification via le navigateur
|
||||
|
||||
1. Arrêter le client JSF (Ctrl+C)
|
||||
2. Supprimer les cookies du navigateur pour `localhost:8082`
|
||||
3. Redémarrer le client : `mvn quarkus:dev`
|
||||
4. Accéder à : http://localhost:8082/pages/user-manager/users/list.xhtml
|
||||
5. **Résultat attendu** : Redirection vers Keycloak pour login
|
||||
|
||||
---
|
||||
|
||||
## Checklist de Vérification
|
||||
|
||||
- [ ] Realm `lions-user-manager` existe dans Keycloak
|
||||
- [ ] Client `lions-user-manager-client` existe dans le realm
|
||||
- [ ] Client authentication est **ON**
|
||||
- [ ] Standard flow est **enabled**
|
||||
- [ ] Valid redirect URIs contient `http://localhost:8082/*`
|
||||
- [ ] Client secret dans `application-dev.properties` correspond au secret Keycloak
|
||||
- [ ] Keycloak est accessible sur http://localhost:8180
|
||||
- [ ] Le client JSF redémarre après modification du secret
|
||||
|
||||
---
|
||||
|
||||
## Dépannage
|
||||
|
||||
### Problème : "invalid_client"
|
||||
- **Cause** : Client ID ou secret incorrect
|
||||
- **Solution** : Vérifier que le client existe et que le secret correspond
|
||||
|
||||
### Problème : "invalid_redirect_uri"
|
||||
- **Cause** : L'URL de redirection n'est pas dans la liste des Valid redirect URIs
|
||||
- **Solution** : Ajouter `http://localhost:8082/*` dans les Valid redirect URIs
|
||||
|
||||
### Problème : Boucle infinie d'authentification
|
||||
- **Cause** : Le client ne peut pas échanger le code d'autorisation contre un token
|
||||
- **Solution** :
|
||||
1. Vérifier que Standard Flow est enabled
|
||||
2. Vérifier le client secret
|
||||
3. Vérifier les redirect URIs
|
||||
4. Supprimer les cookies du navigateur
|
||||
|
||||
### Problème : "unauthorized_client"
|
||||
- **Cause** : Le flow d'authentification n'est pas autorisé
|
||||
- **Solution** : Activer "Standard flow" dans la configuration du client
|
||||
|
||||
---
|
||||
|
||||
## Redémarrage après Configuration
|
||||
|
||||
Après avoir créé/modifié le client dans Keycloak :
|
||||
|
||||
```bash
|
||||
# Arrêter le client JSF (Ctrl+C dans le terminal)
|
||||
|
||||
# Redémarrer
|
||||
cd lions-user-manager/lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Date** : 2025-12-25
|
||||
**Statut** : Configuration requise avant utilisation
|
||||
@@ -1,202 +0,0 @@
|
||||
# Configuration Keycloak pour lions-user-manager (Mode DEV)
|
||||
|
||||
## Problème résolu
|
||||
|
||||
**Erreur HTTP 405 sur `/api/users/search`** : Cette erreur se produisait car le client et le serveur utilisaient des realms Keycloak différents. Les tokens générés pour un realm ne sont pas valides pour un autre realm.
|
||||
|
||||
## Configuration corrigée
|
||||
|
||||
### Client (lions-user-manager-client-quarkus-primefaces-freya)
|
||||
- **Realm** : `lions-user-manager`
|
||||
- **Auth Server** : `http://localhost:8180/realms/lions-user-manager`
|
||||
- **Client ID** : `lions-user-manager-client`
|
||||
- **Secret** : `NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO`
|
||||
|
||||
### Serveur (lions-user-manager-server-impl-quarkus) - Mode DEV
|
||||
- **Realm** : `lions-user-manager`
|
||||
- **Auth Server** : `http://localhost:8180/realms/lions-user-manager`
|
||||
- **Client ID** : `lions-user-manager-backend`
|
||||
- **Secret** : `NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO`
|
||||
- **Admin Client** : `admin-cli` sur le realm `lions-user-manager`
|
||||
|
||||
---
|
||||
|
||||
## Étapes de configuration dans Keycloak (http://localhost:8180)
|
||||
|
||||
### 1. Créer le realm `lions-user-manager`
|
||||
|
||||
1. Connectez-vous à Keycloak : http://localhost:8180
|
||||
2. Cliquez sur le dropdown en haut à gauche (actuellement sur "Master")
|
||||
3. Cliquez sur **"Create Realm"**
|
||||
4. Nom du realm : `lions-user-manager`
|
||||
5. **Enabled** : `ON`
|
||||
6. Cliquez sur **"Create"**
|
||||
|
||||
### 2. Créer le client backend `lions-user-manager-backend`
|
||||
|
||||
1. Dans le realm `lions-user-manager`, allez dans **Clients** → **Create client**
|
||||
2. **Client ID** : `lions-user-manager-backend`
|
||||
3. **Client Protocol** : `openid-connect`
|
||||
4. Cliquez sur **"Next"**
|
||||
5. **Client authentication** : `ON` (pour avoir un client confidentiel)
|
||||
6. **Authorization** : `OFF`
|
||||
7. **Standard flow** : `ON`
|
||||
8. **Direct access grants** : `ON`
|
||||
9. **Service accounts roles** : `ON`
|
||||
10. Cliquez sur **"Next"** puis **"Save"**
|
||||
11. Allez dans l'onglet **"Credentials"**
|
||||
12. Copiez le **Client secret** : `NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO`
|
||||
- Si le secret est différent, régénérez-le ou mettez à jour `application.properties`
|
||||
|
||||
### 3. Créer le client frontend `lions-user-manager-client`
|
||||
|
||||
1. Dans le realm `lions-user-manager`, allez dans **Clients** → **Create client**
|
||||
2. **Client ID** : `lions-user-manager-client`
|
||||
3. **Client Protocol** : `openid-connect`
|
||||
4. Cliquez sur **"Next"**
|
||||
5. **Client authentication** : `ON`
|
||||
6. **Authorization** : `OFF`
|
||||
7. **Standard flow** : `ON`
|
||||
8. **Direct access grants** : `ON`
|
||||
9. Cliquez sur **"Next"**
|
||||
10. **Valid redirect URIs** :
|
||||
- `http://localhost:8082/*`
|
||||
- `http://localhost:8082/auth/callback`
|
||||
11. **Valid post logout redirect URIs** : `http://localhost:8082/*`
|
||||
12. **Web origins** : `http://localhost:8082`
|
||||
13. Cliquez sur **"Save"**
|
||||
14. Allez dans l'onglet **"Credentials"**
|
||||
15. Vérifiez que le **Client secret** est : `NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO`
|
||||
|
||||
### 4. Créer les rôles
|
||||
|
||||
1. Dans le realm `lions-user-manager`, allez dans **Realm roles**
|
||||
2. Cliquez sur **"Create role"**
|
||||
3. Créez les rôles suivants :
|
||||
- **admin** : Administrateur système
|
||||
- **user_manager** : Gestionnaire d'utilisateurs
|
||||
- **user_viewer** : Consultation uniquement
|
||||
|
||||
### 5. Créer un utilisateur de test
|
||||
|
||||
1. Dans le realm `lions-user-manager`, allez dans **Users** → **Add user**
|
||||
2. **Username** : `testadmin`
|
||||
3. **Email** : `admin@test.local`
|
||||
4. **First name** : `Test`
|
||||
5. **Last name** : `Admin`
|
||||
6. **Email verified** : `ON`
|
||||
7. **Enabled** : `ON`
|
||||
8. Cliquez sur **"Create"**
|
||||
9. Allez dans l'onglet **"Credentials"**
|
||||
10. Cliquez sur **"Set password"**
|
||||
- Password : `admin123`
|
||||
- Temporary : `OFF`
|
||||
11. Allez dans l'onglet **"Role mapping"**
|
||||
12. Cliquez sur **"Assign role"**
|
||||
13. Sélectionnez les rôles : `admin` et `user_manager`
|
||||
14. Cliquez sur **"Assign"**
|
||||
|
||||
### 6. Configurer le scope "roles"
|
||||
|
||||
1. Dans le realm `lions-user-manager`, allez dans **Client scopes**
|
||||
2. Trouvez ou créez le scope **"roles"**
|
||||
3. Vérifiez qu'il est assigné au client `lions-user-manager-client`
|
||||
4. Dans le scope "roles", allez dans **"Mappers"**
|
||||
5. Vérifiez qu'il y a un mapper pour `realm roles` :
|
||||
- **Name** : `realm roles`
|
||||
- **Mapper Type** : `User Realm Role`
|
||||
- **Token Claim Name** : `realm_access.roles`
|
||||
- **Claim JSON Type** : `String`
|
||||
- **Add to ID token** : `ON`
|
||||
- **Add to access token** : `ON`
|
||||
- **Add to userinfo** : `ON`
|
||||
|
||||
---
|
||||
|
||||
## Vérification de la configuration
|
||||
|
||||
### 1. Tester l'authentification client
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8180/realms/lions-user-manager/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=lions-user-manager-client" \
|
||||
-d "client_secret=NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO" \
|
||||
-d "grant_type=password" \
|
||||
-d "username=testadmin" \
|
||||
-d "password=admin123" \
|
||||
-d "scope=openid profile email roles"
|
||||
```
|
||||
|
||||
Vous devriez recevoir un **access_token** et un **id_token**.
|
||||
|
||||
### 2. Vérifier le token
|
||||
|
||||
Copiez l'`access_token` et décodez-le sur https://jwt.io
|
||||
|
||||
Vérifiez que le token contient :
|
||||
- `"iss": "http://localhost:8180/realms/lions-user-manager"`
|
||||
- `"azp": "lions-user-manager-client"`
|
||||
- `"realm_access": { "roles": ["admin", "user_manager", ...] }`
|
||||
|
||||
### 3. Tester l'API backend
|
||||
|
||||
Avec le token obtenu, testez l'endpoint :
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8081/api/users/search" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
|
||||
-d '{
|
||||
"realmName": "lions-user-manager",
|
||||
"page": 0,
|
||||
"pageSize": 20
|
||||
}'
|
||||
```
|
||||
|
||||
Si tout est correct, vous devriez recevoir une réponse 200 avec la liste des utilisateurs.
|
||||
|
||||
---
|
||||
|
||||
## Logs utiles pour le debugging
|
||||
|
||||
### Serveur (lions-user-manager-server)
|
||||
```bash
|
||||
cd lions-user-manager/lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
Recherchez dans les logs :
|
||||
- `Token Bearer ajouté au header Authorization` (client)
|
||||
- `POST /api/users/search - Recherche d'utilisateurs` (serveur)
|
||||
- Erreurs d'authentification OIDC
|
||||
|
||||
### Client (lions-user-manager-client)
|
||||
```bash
|
||||
cd lions-user-manager/lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
Recherchez dans les logs :
|
||||
- `Token JWT non disponible` (problème de connexion)
|
||||
- `Erreur lors de la recherche` (problème d'API)
|
||||
|
||||
---
|
||||
|
||||
## Résumé des modifications effectuées
|
||||
|
||||
### Fichiers modifiés
|
||||
|
||||
1. **`lions-user-manager-server-impl-quarkus/src/main/resources/application.properties`**
|
||||
- Ajout de la configuration dev pour OIDC pointant vers `http://localhost:8180/realms/lions-user-manager`
|
||||
- Ajout de la configuration dev pour Keycloak Admin Client
|
||||
- Ajout du realm `lions-user-manager` aux realms autorisés en dev
|
||||
|
||||
### Prochaines étapes
|
||||
|
||||
1. Configurez Keycloak selon les étapes ci-dessus
|
||||
2. Redémarrez le serveur backend : `mvn quarkus:dev`
|
||||
3. Redémarrez le client frontend : `mvn quarkus:dev`
|
||||
4. Connectez-vous avec `testadmin` / `admin123`
|
||||
5. Accédez à `/pages/user-manager/users/list.xhtml`
|
||||
6. L'erreur HTTP 405 devrait disparaître ✅
|
||||
@@ -1,167 +0,0 @@
|
||||
# Configuration Keycloak - lions-user-manager
|
||||
|
||||
## ✅ Configuration effectuée
|
||||
|
||||
La configuration Keycloak a été effectuée avec succès via le script `setup-keycloak-simple.sh`.
|
||||
|
||||
## 📋 Clients créés
|
||||
|
||||
### 1. Client Backend: `lions-user-manager`
|
||||
- **Type**: Service Account (client credentials)
|
||||
- **Client ID**: `lions-user-manager`
|
||||
- **Secret**: `sD8hT13lG6c79WOWQk3dVzya5pfPhzw3`
|
||||
- **Port**: 8081
|
||||
- **Redirect URIs**: `http://localhost:8081/*`
|
||||
- **Web Origins**: `http://localhost:8081`, `http://localhost:8080`
|
||||
- **Usage**: API REST backend pour gérer les utilisateurs Keycloak
|
||||
|
||||
### 2. Client Frontend: `lions-user-manager-client`
|
||||
- **Type**: Confidential (authorization code flow)
|
||||
- **Client ID**: `lions-user-manager-client`
|
||||
- **Secret**: `client-secret-lions-2025`
|
||||
- **Port**: 8080
|
||||
- **Redirect URIs**: `http://localhost:8080/*`, `http://localhost:8081/*`
|
||||
- **Web Origins**: `*`
|
||||
- **Standard Flow**: Activé
|
||||
- **Direct Access Grants**: Activé
|
||||
- **Usage**: Interface web JSF/PrimeFaces
|
||||
|
||||
## 👥 Utilisateur de test
|
||||
|
||||
- **Username**: `testuser`
|
||||
- **Password**: `test123`
|
||||
- **Email**: `test@lions.dev`
|
||||
- **Nom complet**: Test User
|
||||
- **Rôles**: `admin`, `user_manager`
|
||||
|
||||
## 🔐 Rôles créés
|
||||
|
||||
Les rôles suivants ont été créés dans le realm `master`:
|
||||
|
||||
1. **admin** - Accès complet à toutes les fonctionnalités
|
||||
2. **user_manager** - Gestion des utilisateurs et des rôles
|
||||
3. **user_viewer** - Consultation en lecture seule
|
||||
4. **auditor** - Consultation des logs d'audit
|
||||
5. **sync_manager** - Gestion de la synchronisation
|
||||
|
||||
## 🚀 Démarrage des applications
|
||||
|
||||
### Backend (port 8081)
|
||||
|
||||
Le backend est configuré avec OIDC désactivé car il utilise directement l'API Admin de Keycloak via service account.
|
||||
|
||||
```bash
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
**Configuration dans `application-dev.properties`**:
|
||||
```properties
|
||||
# OIDC désactivé pour le backend (utilise service account)
|
||||
quarkus.oidc.enabled=false
|
||||
|
||||
# API Admin Keycloak
|
||||
lions.keycloak.server-url=http://localhost:8180
|
||||
lions.keycloak.admin-username=admin
|
||||
lions.keycloak.admin-password=admin
|
||||
```
|
||||
|
||||
### Frontend (port 8080)
|
||||
|
||||
Le frontend utilise OIDC pour l'authentification des utilisateurs.
|
||||
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
**Configuration dans `application-dev.properties`**:
|
||||
```properties
|
||||
# OIDC activé pour le frontend
|
||||
quarkus.oidc.auth-server-url=http://localhost:8180/realms/master
|
||||
quarkus.oidc.client-id=lions-user-manager-client
|
||||
quarkus.oidc.credentials.secret=client-secret-lions-2025
|
||||
```
|
||||
|
||||
## 🌐 URLs d'accès
|
||||
|
||||
- **Keycloak Admin**: http://localhost:8180/admin (admin/admin)
|
||||
- **Backend API**: http://localhost:8081
|
||||
- **Frontend Web**: http://localhost:8080
|
||||
- **Swagger UI**: http://localhost:8081/q/swagger-ui
|
||||
|
||||
## 🔧 Résolution des problèmes
|
||||
|
||||
### Problème: "Forbidden" sur http://localhost:8081
|
||||
|
||||
**Cause**: OIDC est désactivé dans le backend, ce qui provoque une erreur de sécurité.
|
||||
|
||||
**Solution**: Le backend est accessible uniquement via les endpoints API qui ne nécessitent pas d'authentification utilisateur (il utilise le service account pour communiquer avec Keycloak).
|
||||
|
||||
Testez plutôt:
|
||||
```bash
|
||||
curl http://localhost:8081/api/users?realm=master
|
||||
```
|
||||
|
||||
### Problème: "Client not found" sur les pages XHTML
|
||||
|
||||
**Cause**: Le client `lions-user-manager-client` n'était pas configuré dans Keycloak.
|
||||
|
||||
**Solution**: ✅ Résolu par le script `setup-keycloak-simple.sh`
|
||||
|
||||
### Problème: Impossible de se connecter avec testuser
|
||||
|
||||
**Vérifications**:
|
||||
1. Vérifier que l'utilisateur existe dans Keycloak Admin Console
|
||||
2. Vérifier que le mot de passe est `test123`
|
||||
3. Vérifier que le compte est activé (`enabled: true`)
|
||||
|
||||
## 📝 Test de connexion
|
||||
|
||||
### Test via curl (backend)
|
||||
|
||||
```bash
|
||||
# 1. Obtenir un token avec le client backend
|
||||
curl -X POST http://localhost:8180/realms/master/protocol/openid-connect/token \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=lions-user-manager" \
|
||||
-d "client_secret=sD8hT13lG6c79WOWQk3dVzya5pfPhzw3" \
|
||||
-d "grant_type=client_credentials"
|
||||
|
||||
# 2. Test avec authentification utilisateur
|
||||
curl -X POST http://localhost:8180/realms/master/protocol/openid-connect/token \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=lions-user-manager-client" \
|
||||
-d "client_secret=client-secret-lions-2025" \
|
||||
-d "username=testuser" \
|
||||
-d "password=test123" \
|
||||
-d "grant_type=password"
|
||||
```
|
||||
|
||||
### Test via navigateur (frontend)
|
||||
|
||||
1. Ouvrir http://localhost:8080
|
||||
2. Vous serez redirigé vers Keycloak pour l'authentification
|
||||
3. Se connecter avec `testuser` / `test123`
|
||||
4. Vous serez redirigé vers l'application
|
||||
|
||||
## 🔄 Réinitialisation de la configuration
|
||||
|
||||
Pour réinitialiser et reconfigurer Keycloak:
|
||||
|
||||
```bash
|
||||
# 1. Supprimer les clients existants (via Admin Console ou API)
|
||||
# 2. Relancer le script
|
||||
bash setup-keycloak-simple.sh
|
||||
```
|
||||
|
||||
## 📚 Documentation complémentaire
|
||||
|
||||
- [Keycloak Documentation](https://www.keycloak.org/documentation)
|
||||
- [Quarkus OIDC Guide](https://quarkus.io/guides/security-oidc-code-flow-authentication)
|
||||
- [PrimeFaces Documentation](https://www.primefaces.org/showcase/)
|
||||
|
||||
---
|
||||
|
||||
**Date de configuration**: 2025-12-04
|
||||
**Script utilisé**: `setup-keycloak-simple.sh`
|
||||
@@ -1,99 +0,0 @@
|
||||
# 🚀 Lancement de Lions User Manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
|
||||
---
|
||||
|
||||
## 📋 Instructions de Lancement
|
||||
|
||||
### 1. Compilation
|
||||
|
||||
```bash
|
||||
cd C:\Users\dadyo\PersonalProjects\lions-workspace\lions-user-manager
|
||||
mvn clean install -DskipTests
|
||||
```
|
||||
|
||||
### 2. Lancement en Mode Développement
|
||||
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
### 3. Accès à l'Application
|
||||
|
||||
Une fois l'application démarrée, accédez à:
|
||||
|
||||
- **URL**: http://localhost:8081
|
||||
- **Page d'accueil**: http://localhost:8081/index.xhtml
|
||||
- **Liste des utilisateurs**: http://localhost:8081/pages/user-manager/users/list.xhtml
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Configuration Requise
|
||||
|
||||
### Variables d'Environnement (Optionnel)
|
||||
|
||||
```bash
|
||||
# Backend URL (par défaut: http://localhost:8080)
|
||||
LIONS_USER_MANAGER_BACKEND_URL=http://localhost:8080
|
||||
|
||||
# Keycloak (si nécessaire)
|
||||
KEYCLOAK_AUTH_SERVER_URL=https://security.lions.dev/realms/master
|
||||
KEYCLOAK_CLIENT_ID=lions-user-manager-client
|
||||
KEYCLOAK_CLIENT_SECRET=<secret>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Vérification
|
||||
|
||||
### 1. Vérifier que l'application démarre
|
||||
|
||||
Vous devriez voir dans les logs:
|
||||
```
|
||||
__ ____ __ _____ ___ __ ____ ______
|
||||
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
|
||||
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
|
||||
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
|
||||
```
|
||||
|
||||
### 2. Vérifier les endpoints
|
||||
|
||||
- Health Check: http://localhost:8081/health
|
||||
- Metrics: http://localhost:8081/metrics
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Dépannage
|
||||
|
||||
### Port déjà utilisé
|
||||
|
||||
Si le port 8081 est déjà utilisé, modifiez dans `application.properties`:
|
||||
```properties
|
||||
quarkus.http.port=8082
|
||||
```
|
||||
|
||||
### Erreur de compilation
|
||||
|
||||
Vérifiez que tous les modules sont compilés:
|
||||
```bash
|
||||
mvn clean install -DskipTests
|
||||
```
|
||||
|
||||
### Erreur REST Client
|
||||
|
||||
Vérifiez que le backend est démarré et accessible à l'URL configurée.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
- L'application démarre en mode développement par défaut
|
||||
- Le hot-reload est activé (modifications automatiques)
|
||||
- Les logs sont en mode DEBUG en développement
|
||||
|
||||
---
|
||||
|
||||
**Bon test ! 🎉**
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
# 📊 Résumé de la Migration XHTML vers Freya Extension
|
||||
|
||||
**Date** : 26 décembre 2025
|
||||
**Status** : ✅ **MIGRATION PARTIELLE RÉUSSIE**
|
||||
**Build** : ✅ **BUILD SUCCESS**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Objectif
|
||||
|
||||
Migrer toutes les pages XHTML de **lions-user-manager** vers les composants **Freya Extension** pour :
|
||||
- Réduire le code boilerplate
|
||||
- Améliorer la cohérence visuelle
|
||||
- Faciliter la maintenance
|
||||
- Améliorer l'accessibilité
|
||||
|
||||
---
|
||||
|
||||
## ✅ Pages migrées (3/12)
|
||||
|
||||
### 1. ✅ `templates/main-template.xhtml`
|
||||
**Status** : **COMPLET**
|
||||
|
||||
**Modifications** :
|
||||
- Ajout du namespace `xmlns:fr="http://primefaces.org/freya"`
|
||||
|
||||
---
|
||||
|
||||
### 2. ✅ `pages/user-manager/users/list.xhtml`
|
||||
**Status** : **COMPLET**
|
||||
|
||||
**Composants migrés** :
|
||||
- `fr:growl` (1) - Remplacement de `p:messages`
|
||||
- `fr:fieldInput` (2) - Champs de recherche
|
||||
- `fr:fieldSelect` (2) - Filtres de sélection
|
||||
- `fr:dataTable` (1) - Table des utilisateurs
|
||||
- `fr:commandButton` (12) - Boutons d'action
|
||||
- `fr:tag` (1) - Tags de statut
|
||||
|
||||
**Réduction de code** : ~10% (467 → ~420 lignes)
|
||||
|
||||
---
|
||||
|
||||
### 3. ✅ `pages/user-manager/users/create.xhtml`
|
||||
**Status** : **COMPLET**
|
||||
|
||||
**Composants migrés** :
|
||||
- `fr:growl` (1) - Messages globaux
|
||||
- `fr:fieldInput` (4) - Champs de formulaire (username, email, prénom, nom)
|
||||
- `fr:fieldSelect` (1) - Sélection du realm
|
||||
- `fr:commandButton` (5) - Boutons d'action
|
||||
- `fr:tag` (2) - Tags de statut dans l'aperçu
|
||||
|
||||
**Réduction de code** : ~15% (506 → ~430 lignes)
|
||||
|
||||
**Note** : Les champs `p:password` n'ont pas été migrés car il n'existe pas d'équivalent `fr:fieldPassword` dans Freya Extension.
|
||||
|
||||
---
|
||||
|
||||
### 4. 🔄 `pages/user-manager/users/edit.xhtml`
|
||||
**Status** : **PARTIEL**
|
||||
|
||||
**Modifications** :
|
||||
- Ajout du namespace `xmlns:fr="http://primefaces.org/freya"`
|
||||
- Migration de `p:messages` vers `fr:growl`
|
||||
|
||||
**À faire** :
|
||||
- Migrer les champs de formulaire vers `fr:fieldInput`
|
||||
- Migrer les boutons vers `fr:commandButton`
|
||||
- Migrer les tags vers `fr:tag`
|
||||
|
||||
---
|
||||
|
||||
## ⏳ Pages restantes (8/12)
|
||||
|
||||
### 5. ⏳ `pages/user-manager/users/view.xhtml`
|
||||
**Status** : **NON MIGRÉ**
|
||||
|
||||
### 6. ⏳ `pages/user-manager/users/profile.xhtml`
|
||||
**Status** : **NON MIGRÉ**
|
||||
|
||||
### 7. ⏳ `pages/user-manager/roles/list.xhtml`
|
||||
**Status** : **NON MIGRÉ**
|
||||
|
||||
### 8. ⏳ `pages/user-manager/roles/assign.xhtml`
|
||||
**Status** : **NON MIGRÉ**
|
||||
|
||||
### 9. ⏳ `pages/user-manager/dashboard.xhtml`
|
||||
**Status** : **NON MIGRÉ**
|
||||
|
||||
### 10. ⏳ `pages/user-manager/settings.xhtml`
|
||||
**Status** : **NON MIGRÉ**
|
||||
|
||||
### 11. ⏳ `pages/user-manager/audit/logs.xhtml`
|
||||
**Status** : **NON MIGRÉ**
|
||||
|
||||
### 12. ⏳ `pages/user-manager/sync/dashboard.xhtml`
|
||||
**Status** : **NON MIGRÉ**
|
||||
|
||||
---
|
||||
|
||||
## 📊 Statistiques globales
|
||||
|
||||
| Métrique | Valeur |
|
||||
|----------|--------|
|
||||
| **Pages totales** | 12 |
|
||||
| **Pages migrées (complètes)** | 3 |
|
||||
| **Pages migrées (partielles)** | 1 |
|
||||
| **Pages restantes** | 8 |
|
||||
| **Progression** | 25% (3/12) |
|
||||
| **Composants migrés** | 34 |
|
||||
| **Réduction de code moyenne** | ~12% |
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Composants Freya utilisés
|
||||
|
||||
| Composant | Description | Occurrences |
|
||||
|-----------|-------------|-------------|
|
||||
| `fr:growl` | Messages de notification | 3 |
|
||||
| `fr:fieldInput` | Champ de saisie avec label et aide | 6 |
|
||||
| `fr:fieldSelect` | Liste déroulante avec label et aide | 3 |
|
||||
| `fr:commandButton` | Bouton d'action avec severity | 18 |
|
||||
| `fr:dataTable` | Table de données | 1 |
|
||||
| `fr:tag` | Badge/Tag de statut | 3 |
|
||||
|
||||
**Total** : 34 composants migrés
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Avantages constatés
|
||||
|
||||
### 1. **Réduction du code boilerplate**
|
||||
|
||||
**AVANT (19 lignes)** :
|
||||
```xml
|
||||
<div class="field">
|
||||
<label for="username" class="block text-900 font-medium mb-2">
|
||||
<i class="pi pi-at text-500 mr-1"></i>
|
||||
Nom d'utilisateur <span class="text-red-500">*</span>
|
||||
</label>
|
||||
<p:inputText id="username"
|
||||
value="#{userCreationBean.newUser.username}"
|
||||
styleClass="w-full"
|
||||
required="true"
|
||||
placeholder="ex: jdupont">
|
||||
<f:validateLength minimum="3" maximum="50" />
|
||||
</p:inputText>
|
||||
<small class="text-500">
|
||||
<i class="pi pi-info-circle mr-1"></i>
|
||||
Identifiant unique de connexion (3-50 caractères)
|
||||
</small>
|
||||
</div>
|
||||
```
|
||||
|
||||
**APRÈS (8 lignes - 58% de réduction)** :
|
||||
```xml
|
||||
<fr:fieldInput
|
||||
label="Nom d'utilisateur"
|
||||
value="#{userCreationBean.newUser.username}"
|
||||
required="true"
|
||||
placeholder="ex: jdupont"
|
||||
helpText="Identifiant unique de connexion (3-50 caractères)">
|
||||
<f:validateLength minimum="3" maximum="50" />
|
||||
</fr:fieldInput>
|
||||
```
|
||||
|
||||
### 2. **Cohérence visuelle**
|
||||
- Tous les formulaires utilisent le même pattern
|
||||
- Styles Freya appliqués automatiquement
|
||||
- Accessibilité WCAG 2.1 AA intégrée
|
||||
|
||||
### 3. **Maintenance simplifiée**
|
||||
- Un seul endroit pour modifier le pattern (composant Freya)
|
||||
- Moins de code à maintenir
|
||||
- Moins de risques d'erreurs
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines étapes
|
||||
|
||||
### 1. **Migrer les pages restantes**
|
||||
|
||||
**Priorité HAUTE** :
|
||||
- `pages/user-manager/users/edit.xhtml` (finir la migration)
|
||||
- `pages/user-manager/users/view.xhtml`
|
||||
- `pages/user-manager/roles/list.xhtml`
|
||||
|
||||
**Priorité MOYENNE** :
|
||||
- `pages/user-manager/dashboard.xhtml`
|
||||
- `pages/user-manager/settings.xhtml`
|
||||
- `pages/user-manager/roles/assign.xhtml`
|
||||
|
||||
**Priorité BASSE** :
|
||||
- `pages/user-manager/users/profile.xhtml`
|
||||
- `pages/user-manager/audit/logs.xhtml`
|
||||
- `pages/user-manager/sync/dashboard.xhtml`
|
||||
|
||||
### 2. **Tester l'application**
|
||||
|
||||
```bash
|
||||
# Terminal 1 : Lancer le backend
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev
|
||||
|
||||
# Terminal 2 : Lancer le client
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
**Accès** :
|
||||
- Backend : http://localhost:8080
|
||||
- Client : http://localhost:9090
|
||||
|
||||
### 3. **Créer des composants Freya manquants**
|
||||
|
||||
**Composants à créer** :
|
||||
- `fr:fieldPassword` - Champ de mot de passe avec feedback
|
||||
- `fr:fieldTextarea` - Zone de texte multiligne
|
||||
- `fr:fieldCheckbox` - Case à cocher avec label
|
||||
|
||||
---
|
||||
|
||||
## ✅ Conclusion
|
||||
|
||||
**La migration partielle est réussie !**
|
||||
|
||||
- ✅ **3 pages complètement migrées**
|
||||
- ✅ **1 page partiellement migrée**
|
||||
- ✅ **34 composants migrés**
|
||||
- ✅ **Compilation sans erreur**
|
||||
- ✅ **Réduction de code de ~12%**
|
||||
|
||||
**L'application est prête à être testée ! 🎉**
|
||||
|
||||
**Prochaine étape** : Migrer les 8 pages restantes pour atteindre 100% de migration.
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
# 🔐 Configuration OIDC - Encryption Secret
|
||||
|
||||
## ❓ Qu'est-ce que `quarkus.oidc.token-state-manager.encryption-secret` ?
|
||||
|
||||
Cette propriété est **requise** lorsque OIDC est activé dans Quarkus. Elle sert à chiffrer les cookies d'état utilisés lors du flux d'authentification OIDC.
|
||||
|
||||
## ⚠️ Exigences
|
||||
|
||||
- **Longueur minimale** : 16 caractères
|
||||
- **Recommandé** : 32 caractères ou plus pour une meilleure sécurité
|
||||
- **Type** : Chaîne de caractères aléatoire
|
||||
|
||||
## 📍 Où trouver le secret dans Keycloak ?
|
||||
|
||||
### Pour le Client (lions-user-manager-client)
|
||||
|
||||
1. **Accéder à Keycloak Admin Console** : `http://localhost:8180/admin`
|
||||
2. **Se connecter** avec `admin` / `admin`
|
||||
3. **Sélectionner le Realm** : `lions-user-manager` (ou le realm que vous utilisez)
|
||||
4. **Aller dans** : `Clients` → `lions-user-manager-client`
|
||||
5. **Onglet** : `Credentials` (ou `Settings` → `Credentials`)
|
||||
6. **Copier** : Le `Client Secret` (ou `Secret`)
|
||||
|
||||
### Exemple de configuration
|
||||
|
||||
```properties
|
||||
# Dans application-dev.properties (CLIENT)
|
||||
quarkus.oidc.auth-server-url=http://localhost:8180/realms/lions-user-manager
|
||||
quarkus.oidc.client-id=lions-user-manager-client
|
||||
quarkus.oidc.credentials.secret=<SECRET_COPIÉ_DE_KEYCLOAK>
|
||||
quarkus.oidc.token-state-manager.encryption-secret=<CLÉ_DE_CHIFFREMENT_16_CHARS_MIN>
|
||||
```
|
||||
|
||||
## 🔑 Différence entre les deux secrets
|
||||
|
||||
### 1. `quarkus.oidc.credentials.secret`
|
||||
- **Source** : Keycloak (Client Secret)
|
||||
- **Usage** : Authentification du client auprès de Keycloak
|
||||
- **Où le trouver** : Keycloak Admin Console → Clients → [votre-client] → Credentials → Secret
|
||||
|
||||
### 2. `quarkus.oidc.token-state-manager.encryption-secret`
|
||||
- **Source** : Vous (générez vous-même)
|
||||
- **Usage** : Chiffrement des cookies d'état OIDC
|
||||
- **Génération** : Chaîne aléatoire d'au moins 16 caractères
|
||||
|
||||
## ✅ Solution actuelle
|
||||
|
||||
Dans `application-dev.properties` du **client**, j'ai ajouté :
|
||||
|
||||
```properties
|
||||
quarkus.oidc.token-state-manager.encryption-secret=client-secret-lions-2025-encryption-key-min-16-chars
|
||||
```
|
||||
|
||||
Cette clé fait **48 caractères** et est suffisante pour le développement.
|
||||
|
||||
## 🔒 Pour la production
|
||||
|
||||
En production, utilisez une clé générée de manière sécurisée :
|
||||
|
||||
```bash
|
||||
# Générer une clé aléatoire de 32 caractères
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
Ou utilisez un outil en ligne pour générer une clé aléatoire.
|
||||
|
||||
## 📝 Notes importantes
|
||||
|
||||
1. **Le secret de chiffrement n'est PAS le Client Secret de Keycloak**
|
||||
2. **C'est une clé que vous générez vous-même** pour chiffrer les cookies
|
||||
3. **Elle doit être la même** pour tous les nœuds d'un cluster (en production)
|
||||
4. **Ne la commitez PAS** dans le dépôt Git si elle contient des informations sensibles
|
||||
|
||||
## 🎯 Configuration actuelle
|
||||
|
||||
- **Client Secret Keycloak** : `NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO` (dans `application-dev.properties`)
|
||||
- **Encryption Secret** : `client-secret-lions-2025-encryption-key-min-16-chars` (ajouté)
|
||||
|
||||
Ces deux valeurs sont **différentes** et servent à des **usages différents**.
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
# ✅ Optimisation Complète - Lions User Manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Statut**: ✅ **100% COMPLÉTÉ**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Mission Accomplie
|
||||
|
||||
Le projet **lions-user-manager** a été **totalement optimisé** pour être un **module réutilisable** intégré à l'écosystème **lionsdev** et à **unionflow**, avec des composants réutilisables à l'instar de unionflow.
|
||||
|
||||
---
|
||||
|
||||
## 📊 Bilan Complet
|
||||
|
||||
### ✅ Composants Réutilisables: **14/14** (100%)
|
||||
|
||||
#### User Management (5)
|
||||
1. ✅ `user-card.xhtml` - Carte utilisateur avec actions
|
||||
2. ✅ `user-form.xhtml` - Formulaire création/modification
|
||||
3. ✅ `user-search-bar.xhtml` - Barre de recherche avancée
|
||||
4. ✅ `user-actions.xhtml` - Boutons d'action (3 layouts)
|
||||
5. ✅ `user-role-badge.xhtml` - Badge de rôle
|
||||
|
||||
#### Role Management (3)
|
||||
6. ✅ `role-card.xhtml` - Carte rôle
|
||||
7. ✅ `role-form.xhtml` - Formulaire rôle
|
||||
8. ✅ `role-assignment.xhtml` - Attribution/révocation rôles
|
||||
|
||||
#### Audit (2)
|
||||
9. ✅ `audit-log-row.xhtml` - Ligne de log d'audit
|
||||
10. ✅ `audit-stats-card.xhtml` - Carte statistiques audit
|
||||
|
||||
#### Shared (4)
|
||||
11. ✅ `button-user-action.xhtml` - Bouton générique
|
||||
12. ✅ `user-stat-card.xhtml` - Carte statistique
|
||||
13. ✅ `user-form-field.xhtml` - Champ formulaire générique
|
||||
14. ✅ `user-data-table.xhtml` - Tableau de données
|
||||
|
||||
### ✅ REST Clients: **4/4** (100%)
|
||||
|
||||
1. ✅ `UserServiceClient.java` - 12 méthodes
|
||||
2. ✅ `RoleServiceClient.java` - 15 méthodes
|
||||
3. ✅ `AuditServiceClient.java` - 10 méthodes
|
||||
4. ✅ `SyncServiceClient.java` - 6 méthodes
|
||||
|
||||
### ✅ Beans JSF: **5/5** (100%)
|
||||
|
||||
1. ✅ `UserListBean.java` - Liste et recherche utilisateurs
|
||||
2. ✅ `UserProfilBean.java` - Profil et édition utilisateur
|
||||
3. ✅ `UserCreationBean.java` - Création utilisateur
|
||||
4. ✅ `RoleGestionBean.java` - Gestion des rôles
|
||||
5. ✅ `AuditConsultationBean.java` - Consultation audit
|
||||
|
||||
### ✅ Pages XHTML: **7/7** (100%)
|
||||
|
||||
#### Users (4)
|
||||
1. ✅ `list.xhtml` - Liste utilisateurs avec recherche
|
||||
2. ✅ `create.xhtml` - Création utilisateur
|
||||
3. ✅ `profile.xhtml` - Profil utilisateur
|
||||
4. ✅ `edit.xhtml` - Édition utilisateur
|
||||
|
||||
#### Roles (2)
|
||||
5. ✅ `list.xhtml` - Liste rôles Realm/Client
|
||||
6. ✅ `assign.xhtml` - Attribution de rôles
|
||||
|
||||
#### Audit (1)
|
||||
7. ✅ `logs.xhtml` - Journal d'audit avec statistiques
|
||||
|
||||
#### Sync (1)
|
||||
8. ✅ `dashboard.xhtml` - Dashboard synchronisation
|
||||
|
||||
### ✅ Layout Components: **4/4** (100%)
|
||||
|
||||
1. ✅ `main-template.xhtml` - Template principal
|
||||
2. ✅ `topbar.xhtml` - Barre supérieure
|
||||
3. ✅ `footer.xhtml` - Pied de page
|
||||
4. ✅ `page-header.xhtml` - En-tête de page
|
||||
5. ✅ `menu.xhtml` - Menu navigation
|
||||
|
||||
---
|
||||
|
||||
## 📈 Statistiques Globales
|
||||
|
||||
| Catégorie | Créé | Statut |
|
||||
|-----------|------|--------|
|
||||
| **Composants réutilisables** | 14 | ✅ 100% |
|
||||
| **REST Clients** | 4 | ✅ 100% |
|
||||
| **Beans JSF** | 5 | ✅ 100% |
|
||||
| **Pages XHTML** | 7 | ✅ 100% |
|
||||
| **Layout Components** | 4 | ✅ 100% |
|
||||
| **Documents** | 6 | ✅ 100% |
|
||||
| **TOTAL** | **40 fichiers** | ✅ **100%** |
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Caractéristiques
|
||||
|
||||
### Pattern WOU/DRY
|
||||
- ✅ Chaque composant est écrit une fois et réutilisé partout
|
||||
- ✅ Paramètres configurables avec valeurs par défaut
|
||||
- ✅ Documentation inline complète
|
||||
|
||||
### Compatibilité
|
||||
- ✅ Compatible avec unionflow
|
||||
- ✅ Compatible avec thème Freya
|
||||
- ✅ Compatible avec PrimeFaces 14.0.5+
|
||||
- ✅ Compatible avec Quarkus 3.15.1+
|
||||
|
||||
### Qualité
|
||||
- ✅ Validation JSF intégrée
|
||||
- ✅ Gestion d'erreurs complète
|
||||
- ✅ Logging structuré
|
||||
- ✅ Messages utilisateur (success/error)
|
||||
- ✅ Accessibilité respectée
|
||||
|
||||
---
|
||||
|
||||
## 📂 Structure Finale Complète
|
||||
|
||||
```
|
||||
lions-user-manager/
|
||||
├── lions-user-manager-server-api/ ✅ 100%
|
||||
├── lions-user-manager-server-impl-quarkus/ ✅ 60%
|
||||
└── lions-user-manager-client-quarkus-primefaces-freya/ ✅ 100%
|
||||
├── src/main/java/dev/lions/user/manager/client/
|
||||
│ ├── service/ # REST Clients (4) ✅
|
||||
│ └── view/ # Beans JSF (5) ✅
|
||||
└── src/main/resources/META-INF/resources/
|
||||
├── templates/
|
||||
│ ├── components/ # Composants (14) ✅
|
||||
│ │ ├── user-management/ (5)
|
||||
│ │ ├── role-management/ (3)
|
||||
│ │ ├── audit/ (2)
|
||||
│ │ ├── shared/ (4)
|
||||
│ │ └── layout/ (4)
|
||||
│ └── main-template.xhtml ✅
|
||||
└── pages/user-manager/ # Pages (7) ✅
|
||||
├── users/ (4)
|
||||
├── roles/ (2)
|
||||
├── audit/ (1)
|
||||
└── sync/ (1)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prêt pour Intégration
|
||||
|
||||
### Avec UnionFlow
|
||||
Le module est prêt pour intégration dans unionflow:
|
||||
- ✅ Composants réutilisables compatibles
|
||||
- ✅ Patterns alignés
|
||||
- ✅ Menu prêt à être enrichi
|
||||
- ✅ Pages d'intégration à créer
|
||||
|
||||
### Avec Autres Projets LionsDev
|
||||
Le module peut être utilisé dans:
|
||||
- ✅ btpxpress
|
||||
- ✅ afterwork
|
||||
- ✅ Tout autre projet nécessitant la gestion d'utilisateurs
|
||||
|
||||
---
|
||||
|
||||
## 📝 Documentation
|
||||
|
||||
### Documents Créés
|
||||
1. ✅ `ANALYSE_ET_PLAN_OPTIMISATION.md` - Plan complet
|
||||
2. ✅ `RESUME_ANALYSE.md` - Résumé exécutif
|
||||
3. ✅ `COMPOSANTS_CREES.md` - Liste composants
|
||||
4. ✅ `REST_CLIENTS_ET_BEANS_CREES.md` - REST Clients et Beans
|
||||
5. ✅ `PAGES_XHTML_CREES.md` - Pages XHTML
|
||||
6. ✅ `RESUME_FINAL.md` - Résumé final
|
||||
7. ✅ `OPTIMISATION_COMPLETE.md` - Ce document
|
||||
|
||||
### Documentation Inline
|
||||
- ✅ Chaque composant a sa documentation
|
||||
- ✅ Exemples d'utilisation pour chaque composant
|
||||
- ✅ README.md dans `templates/components/`
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Objectifs Atteints
|
||||
|
||||
### ✅ Réutilisabilité
|
||||
- ✅ Composants modulaires
|
||||
- ✅ Paramètres configurables
|
||||
- ✅ Pattern WOU/DRY
|
||||
- ✅ Documentation complète
|
||||
|
||||
### ✅ Intégration Écosystème
|
||||
- ✅ Structure compatible lionsdev
|
||||
- ✅ Patterns alignés unionflow
|
||||
- ✅ Prêt pour intégration
|
||||
|
||||
### ✅ Qualité
|
||||
- ✅ Validation intégrée
|
||||
- ✅ Gestion d'erreurs
|
||||
- ✅ Logging structuré
|
||||
- ✅ Messages utilisateur
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Prochaines Étapes Recommandées
|
||||
|
||||
### 1. Configuration (Priorité 1)
|
||||
- [ ] Compléter `application.properties` avec configuration REST Client
|
||||
- [ ] Créer `faces-config.xml` pour navigation
|
||||
- [ ] Configurer Freya Theme dans POM.xml
|
||||
|
||||
### 2. Intégration UnionFlow (Priorité 2)
|
||||
- [ ] Ajouter dépendance Maven dans `unionflow/pom.xml`
|
||||
- [ ] Enrichir menu unionflow (section "Gestion des Membres")
|
||||
- [ ] Créer pages d'intégration dans unionflow
|
||||
|
||||
### 3. Tests (Priorité 3)
|
||||
- [ ] Tests unitaires Beans JSF
|
||||
- [ ] Tests d'intégration REST Clients
|
||||
- [ ] Tests UI (pages XHTML)
|
||||
|
||||
### 4. Publication (Priorité 4)
|
||||
- [ ] Publier modules dans repository Maven lionsdev
|
||||
- [ ] Créer guide d'intégration
|
||||
- [ ] Documenter l'API
|
||||
|
||||
---
|
||||
|
||||
## 🏆 Résultat
|
||||
|
||||
**lions-user-manager** est maintenant un **module réutilisable complet et optimisé** avec:
|
||||
|
||||
- ✅ **14 composants réutilisables** prêts à l'emploi
|
||||
- ✅ **4 REST Clients** pour communication API
|
||||
- ✅ **5 Beans JSF** pour logique métier
|
||||
- ✅ **7 pages XHTML** utilisant les composants
|
||||
- ✅ **4 composants layout** pour structure
|
||||
- ✅ **6 documents** de documentation
|
||||
|
||||
**Le module est prêt pour:**
|
||||
- ✅ Utilisation dans lions-user-manager
|
||||
- ✅ Intégration avec unionflow
|
||||
- ✅ Réutilisation dans d'autres projets lionsdev
|
||||
|
||||
---
|
||||
|
||||
**🎉 OPTIMISATION 100% COMPLÉTÉE ! 🎉**
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
**Auteur**: Auto (Cursor AI)
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
# 📋 Organisation de la Configuration - Best Practices
|
||||
|
||||
## ❌ Problème actuel : Doublons entre les fichiers
|
||||
|
||||
Il y a des configurations dupliquées entre :
|
||||
- `application.properties` (avec préfixes `%dev.` et `%prod.`)
|
||||
- `application-dev.properties` (sans préfixe)
|
||||
- `application-prod.properties` (presque vide)
|
||||
|
||||
## ✅ Solution recommandée : Deux approches possibles
|
||||
|
||||
### Approche 1 : Tout dans application.properties (Recommandée)
|
||||
|
||||
**Principe** : Un seul fichier avec des sections claires
|
||||
|
||||
```
|
||||
application.properties
|
||||
├── Configuration de base (tous profils)
|
||||
├── Section %dev.* (surcharges dev)
|
||||
└── Section %prod.* (surcharges prod)
|
||||
|
||||
application-dev.properties
|
||||
└── UNIQUEMENT les surcharges spécifiques non couvertes par %dev.*
|
||||
|
||||
application-prod.properties
|
||||
└── UNIQUEMENT les surcharges spécifiques non couvertes par %prod.*
|
||||
```
|
||||
|
||||
**Avantages** :
|
||||
- ✅ Tout est visible au même endroit
|
||||
- ✅ Facile de comparer dev vs prod
|
||||
- ✅ Moins de fichiers à maintenir
|
||||
|
||||
### Approche 2 : Séparation complète (Alternative)
|
||||
|
||||
**Principe** : Chaque profil dans son propre fichier
|
||||
|
||||
```
|
||||
application.properties
|
||||
└── Configuration de base uniquement (sans préfixes %dev/%prod)
|
||||
|
||||
application-dev.properties
|
||||
└── TOUTES les configurations dev (sans préfixe %dev.)
|
||||
|
||||
application-prod.properties
|
||||
└── TOUTES les configurations prod (sans préfixe %prod.)
|
||||
```
|
||||
|
||||
**Avantages** :
|
||||
- ✅ Séparation claire des environnements
|
||||
- ✅ Fichiers plus petits
|
||||
- ✅ Facile de voir ce qui change entre dev et prod
|
||||
|
||||
## 🎯 Recommandation pour ce projet
|
||||
|
||||
**Utiliser l'Approche 1** car :
|
||||
1. La configuration OIDC est déjà bien organisée dans `application.properties`
|
||||
2. `application-dev.properties` devrait contenir UNIQUEMENT :
|
||||
- Logging spécifique dev
|
||||
- Surcharges non couvertes par `%dev.*` dans `application.properties`
|
||||
3. `application-prod.properties` peut être supprimé ou gardé pour des surcharges très spécifiques
|
||||
|
||||
## 📝 Règles à suivre
|
||||
|
||||
1. **Pas de doublons** : Si une propriété est dans `application.properties` avec `%dev.`, ne pas la remettre dans `application-dev.properties`
|
||||
2. **Ordre de priorité** (du plus spécifique au moins spécifique) :
|
||||
- Variables d'environnement
|
||||
- `application-{profile}.properties`
|
||||
- `%{profile}.property` dans `application.properties`
|
||||
- `property` dans `application.properties`
|
||||
3. **Clarté** : Un commentaire indiquant où trouver la configuration principale
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
# ✅ Pages XHTML Créées - Lions User Manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Statut**: ✅ **PAGES XHTML CRÉÉES** (7 pages)
|
||||
|
||||
---
|
||||
|
||||
## 📊 Résumé
|
||||
|
||||
**Total**: 7 pages XHTML créées utilisant les composants réutilisables
|
||||
|
||||
---
|
||||
|
||||
## 📄 Liste des Pages Créées
|
||||
|
||||
### 👤 Users (4 pages)
|
||||
|
||||
#### 1. ✅ **list.xhtml**
|
||||
**Localisation**: `pages/user-manager/users/list.xhtml`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Liste paginée des utilisateurs
|
||||
- Statistiques (Total, Actifs, Désactivés, Realm)
|
||||
- Barre de recherche avec options avancées
|
||||
- Tableau utilisateurs avec actions
|
||||
|
||||
**Composants utilisés**:
|
||||
- `user-search-bar.xhtml` - Barre de recherche
|
||||
- `user-data-table.xhtml` - Tableau de données
|
||||
- `user-stat-card.xhtml` - Cartes statistiques
|
||||
- `button-user-action.xhtml` - Boutons d'action
|
||||
|
||||
---
|
||||
|
||||
#### 2. ✅ **create.xhtml**
|
||||
**Localisation**: `pages/user-manager/users/create.xhtml`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Création d'un nouvel utilisateur
|
||||
- Formulaire complet avec validation
|
||||
- Sélection de realm
|
||||
- Champs mot de passe
|
||||
|
||||
**Composants utilisés**:
|
||||
- `user-form.xhtml` - Formulaire utilisateur
|
||||
|
||||
---
|
||||
|
||||
#### 3. ✅ **profile.xhtml**
|
||||
**Localisation**: `pages/user-manager/users/profile.xhtml`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Affichage profil utilisateur
|
||||
- Mode édition/lecture
|
||||
- Carte utilisateur
|
||||
- Actions rapides (reset password, activate/deactivate, logout sessions)
|
||||
|
||||
**Composants utilisés**:
|
||||
- `user-card.xhtml` - Carte utilisateur
|
||||
- `user-form.xhtml` - Formulaire (mode édition/lecture)
|
||||
- `button-user-action.xhtml` - Boutons d'action
|
||||
|
||||
---
|
||||
|
||||
#### 4. ✅ **edit.xhtml**
|
||||
**Localisation**: `pages/user-manager/users/edit.xhtml`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Édition d'un utilisateur existant
|
||||
- Formulaire pré-rempli
|
||||
- Pas de champs mot de passe
|
||||
|
||||
**Composants utilisés**:
|
||||
- `user-form.xhtml` - Formulaire (mode edit)
|
||||
|
||||
---
|
||||
|
||||
### 🛡️ Roles (2 pages)
|
||||
|
||||
#### 5. ✅ **list.xhtml**
|
||||
**Localisation**: `pages/user-manager/roles/list.xhtml`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Liste des rôles Realm et Client
|
||||
- Filtres (realm, client, type)
|
||||
- Création rôles Realm/Client via dialogs
|
||||
- Affichage en cartes
|
||||
|
||||
**Composants utilisés**:
|
||||
- `role-card.xhtml` - Carte rôle
|
||||
- `role-form.xhtml` - Formulaire rôle (dans dialogs)
|
||||
- `button-user-action.xhtml` - Boutons d'action
|
||||
|
||||
---
|
||||
|
||||
#### 6. ✅ **assign.xhtml**
|
||||
**Localisation**: `pages/user-manager/roles/assign.xhtml`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Attribution/révocation de rôles à un utilisateur
|
||||
- Séparation Realm/Client roles
|
||||
- Recherche de rôles
|
||||
|
||||
**Composants utilisés**:
|
||||
- `role-assignment.xhtml` - Interface attribution
|
||||
|
||||
---
|
||||
|
||||
### 📊 Audit (1 page)
|
||||
|
||||
#### 7. ✅ **logs.xhtml**
|
||||
**Localisation**: `pages/user-manager/audit/logs.xhtml`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Consultation logs d'audit
|
||||
- Statistiques (Total, Réussies, Échouées, Taux)
|
||||
- Filtres de recherche avancés
|
||||
- Pagination
|
||||
- Export CSV
|
||||
|
||||
**Composants utilisés**:
|
||||
- `audit-stats-card.xhtml` - Cartes statistiques
|
||||
- `audit-log-row.xhtml` - Lignes de log
|
||||
- `button-user-action.xhtml` - Boutons d'action
|
||||
|
||||
---
|
||||
|
||||
### 🔄 Sync (1 page)
|
||||
|
||||
#### 8. ✅ **dashboard.xhtml**
|
||||
**Localisation**: `pages/user-manager/sync/dashboard.xhtml`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Health checks Keycloak
|
||||
- Actions de synchronisation
|
||||
- État de la connexion
|
||||
|
||||
**Composants utilisés**:
|
||||
- `button-user-action.xhtml` - Boutons d'action
|
||||
|
||||
---
|
||||
|
||||
## 📐 Patterns Utilisés
|
||||
|
||||
### Template Pattern
|
||||
Toutes les pages utilisent:
|
||||
```xhtml
|
||||
<ui:composition template="/templates/main-template.xhtml">
|
||||
<ui:define name="content">
|
||||
<!-- Contenu de la page -->
|
||||
</ui:define>
|
||||
</ui:composition>
|
||||
```
|
||||
|
||||
### Composants Réutilisables
|
||||
- ✅ Utilisation systématique des composants créés
|
||||
- ✅ Pattern WOU/DRY respecté
|
||||
- ✅ Paramètres configurables
|
||||
|
||||
### Structure Cohérente
|
||||
- ✅ En-tête avec `page-header.xhtml`
|
||||
- ✅ Statistiques en cartes
|
||||
- ✅ Formulaires avec composants réutilisables
|
||||
- ✅ Actions groupées
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration Requise
|
||||
|
||||
### Template Principal
|
||||
Les pages nécessitent un template principal à créer:
|
||||
- `templates/main-template.xhtml` - Template de base avec layout Freya
|
||||
|
||||
### Beans JSF
|
||||
Toutes les pages utilisent les beans créés:
|
||||
- `userListBean`
|
||||
- `userProfilBean`
|
||||
- `userCreationBean`
|
||||
- `roleGestionBean`
|
||||
- `auditConsultationBean`
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
1. **Template manquant**: Le template `/templates/main-template.xhtml` doit être créé (inspiré de unionflow)
|
||||
2. **Navigation**: Les outcomes de navigation doivent être configurés dans `faces-config.xml`
|
||||
3. **Dialogs**: Certains dialogs sont intégrés dans les composants (ex: reset password)
|
||||
4. **Pagination**: Pagination manuelle dans audit (à améliorer avec DataTable)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines Étapes
|
||||
|
||||
1. ✅ **Pages XHTML créées** - TERMINÉ
|
||||
2. ⏳ **Template principal** - À créer
|
||||
3. ⏳ **Configuration faces-config.xml** - À créer
|
||||
4. ⏳ **Configuration application.properties** - À compléter
|
||||
5. ⏳ **Intégration unionflow** - À faire
|
||||
|
||||
---
|
||||
|
||||
**Statut**: ✅ **100% COMPLÉTÉ**
|
||||
**Date**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
|
||||
201
PAGE_ACCUEIL.md
201
PAGE_ACCUEIL.md
@@ -1,201 +0,0 @@
|
||||
# Page d'accueil - Lions User Manager
|
||||
|
||||
## ✅ Création réussie
|
||||
|
||||
Une page d'accueil professionnelle et publique a été créée pour Lions User Manager.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Fichiers créés
|
||||
|
||||
### 1. Page d'accueil statique
|
||||
**Fichier** : `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/index.html`
|
||||
|
||||
**Type** : HTML pur (pas de JSF, pas de backing bean)
|
||||
|
||||
**Avantages** :
|
||||
- ✅ **Pas de dépendances** : Aucun bean JSF requis
|
||||
- ✅ **Chargement ultra-rapide** : Pas de traitement serveur
|
||||
- ✅ **Toujours accessible** : Même si backend down ou erreur de configuration
|
||||
- ✅ **Responsive** : Adapté mobile, tablette, desktop
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Fonctionnalités de la page
|
||||
|
||||
### 1. Design moderne
|
||||
- Gradient violet/bleu (branding Lions)
|
||||
- Icônes PrimeIcons
|
||||
- Animations fluides (fadeInUp, slideDown)
|
||||
- Ombres et effets de profondeur
|
||||
|
||||
### 2. Sections
|
||||
- **Logo et titre** : Identité visuelle forte
|
||||
- **Description** : Explication claire de l'application
|
||||
- **4 fonctionnalités clés** :
|
||||
- Gestion des utilisateurs
|
||||
- Attribution des rôles
|
||||
- Audit et statistiques
|
||||
- Synchronisation
|
||||
- **Bouton de connexion** : Redirige vers `/pages/user-manager/dashboard.xhtml`
|
||||
|
||||
### 3. Alerte de session expirée
|
||||
- **Affichage conditionnel** : Visible uniquement si `?expired=true` dans l'URL
|
||||
- **Design** : Bannière rouge/rose avec icône d'avertissement
|
||||
- **Message** : "Votre session a expiré. Veuillez vous reconnecter pour continuer."
|
||||
- **Animation** : SlideDown au chargement
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
### Chemins publics
|
||||
```properties
|
||||
# application.properties
|
||||
quarkus.http.auth.permission.public.paths=/,/index.html,...
|
||||
```
|
||||
|
||||
✅ La page est **accessible sans authentification**.
|
||||
|
||||
### Redirection en cas de session expirée
|
||||
```properties
|
||||
# application.properties
|
||||
quarkus.myfaces.view-expired-exception-handler-redirect-page=/index.html?expired=true
|
||||
```
|
||||
|
||||
**Comportement** :
|
||||
1. Si **vue JSF expirée** → Redirige vers `/index.html?expired=true`
|
||||
2. L'utilisateur voit l'**alerte rouge** "Votre session a expiré"
|
||||
3. Il clique sur **"Se connecter avec Keycloak"**
|
||||
4. **Keycloak gère l'authentification** → Redirige vers dashboard après login
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Flux utilisateur
|
||||
|
||||
### Scénario 1 : Premier accès
|
||||
```
|
||||
Utilisateur visite http://localhost:8082
|
||||
↓
|
||||
Affiche index.html (page d'accueil)
|
||||
↓
|
||||
Clique "Se connecter avec Keycloak"
|
||||
↓
|
||||
Redirigé vers /pages/user-manager/dashboard.xhtml
|
||||
↓
|
||||
Quarkus OIDC intercepte → Redirige vers Keycloak
|
||||
↓
|
||||
Utilisateur se connecte sur Keycloak
|
||||
↓
|
||||
Redirigé vers dashboard (authentifié)
|
||||
```
|
||||
|
||||
### Scénario 2 : Session expirée
|
||||
```
|
||||
Utilisateur travaille sur /pages/user-manager/users/list.xhtml
|
||||
↓
|
||||
Session HTTP/OIDC expire (timeout)
|
||||
↓
|
||||
Utilisateur rafraîchit la page
|
||||
↓
|
||||
ViewExpiredException détectée par MyFaces
|
||||
↓
|
||||
Redirigé vers /index.html?expired=true
|
||||
↓
|
||||
Affiche alerte rouge "Votre session a expiré"
|
||||
↓
|
||||
Clique "Se connecter avec Keycloak"
|
||||
↓
|
||||
Quarkus OIDC force ré-authentification
|
||||
↓
|
||||
Redirigé vers dashboard après login
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
### Test 1 : Page d'accueil accessible
|
||||
```bash
|
||||
curl -I http://localhost:8082/
|
||||
# → HTTP/1.1 200 OK
|
||||
|
||||
curl -I http://localhost:8082/index.html
|
||||
# → HTTP/1.1 200 OK
|
||||
```
|
||||
✅ **RÉUSSI**
|
||||
|
||||
### Test 2 : Alerte session expirée
|
||||
```bash
|
||||
curl -s http://localhost:8082/index.html?expired=true | grep "session-expired-alert"
|
||||
# → Trouve l'élément HTML avec l'alerte
|
||||
```
|
||||
✅ **RÉUSSI**
|
||||
|
||||
### Test 3 : Redirection vers dashboard déclenche authentification
|
||||
```
|
||||
1. Ouvrir http://localhost:8082 dans un navigateur
|
||||
2. Cliquer "Se connecter avec Keycloak"
|
||||
3. Vérifier redirection vers Keycloak login
|
||||
```
|
||||
✅ **À TESTER MANUELLEMENT**
|
||||
|
||||
---
|
||||
|
||||
## 📝 Fichiers supprimés
|
||||
|
||||
### Approche complexe abandonnée
|
||||
- ❌ `CustomViewExpiredExceptionHandler.java` (sur-compliqué)
|
||||
- ❌ `CustomExceptionHandlerFactory.java` (sur-compliqué)
|
||||
- ❌ `index.xhtml` (JSF, causait erreurs avec beans)
|
||||
|
||||
### Pourquoi ?
|
||||
L'approche avec `CustomExceptionHandler` était **trop complexe** pour un besoin simple :
|
||||
- Vérification manuelle de session OIDC
|
||||
- Code supplémentaire à maintenir
|
||||
- **Quarkus OIDC gère déjà automatiquement** l'expiration de session
|
||||
|
||||
**Solution retenue** : Page HTML statique + configuration MyFaces standard.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Avantages de la solution finale
|
||||
|
||||
| Critère | Solution statique (retenue) | Solution CustomHandler (rejetée) |
|
||||
|---------|----------------------------|----------------------------------|
|
||||
| **Complexité** | ✅ 1 fichier HTML | ❌ 3 fichiers Java + config |
|
||||
| **Maintenance** | ✅ Facile | ❌ Complexe |
|
||||
| **Performance** | ✅ Ultra-rapide | ⚠️ Traitement serveur |
|
||||
| **Fiabilité** | ✅ Toujours accessible | ⚠️ Dépend de beans |
|
||||
| **Sécurité** | ✅ Quarkus OIDC gère tout | ⚠️ Vérification manuelle |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines étapes
|
||||
|
||||
### Optionnel : Personnalisation
|
||||
1. **Logo** : Remplacer `<i class="pi pi-users"></i>` par un logo SVG
|
||||
2. **Couleurs** : Ajuster le gradient selon la charte graphique
|
||||
3. **Textes** : Adapter les descriptions selon le besoin métier
|
||||
4. **Langue** : Ajouter traduction EN si nécessaire
|
||||
|
||||
### Recommandé : Tests manuels
|
||||
1. ✅ Accès à http://localhost:8082
|
||||
2. ✅ Clic sur "Se connecter avec Keycloak"
|
||||
3. ✅ Authentification Keycloak
|
||||
4. ✅ Redirection vers dashboard
|
||||
5. ✅ Laisser session expirer → Vérifier redirection vers index.html?expired=true
|
||||
|
||||
---
|
||||
|
||||
## 📖 Documentation officielle
|
||||
|
||||
- **MyFaces ViewExpiredException** : [MyFaces Webconfig](https://myfaces.apache.org/core40/myfaces-impl/webconfig.html)
|
||||
- **Quarkus OIDC** : [Web Authentication Guide](https://quarkus.io/guides/security-oidc-web-authentication)
|
||||
- **Quarkus Static Resources** : [HTTP Reference](https://quarkus.io/guides/http-reference#serving-static-resources)
|
||||
|
||||
---
|
||||
|
||||
**Date** : 2025-12-25
|
||||
**Version** : 1.0.0
|
||||
**Statut** : ✅ IMPLÉMENTÉ ET TESTÉ
|
||||
@@ -1,742 +0,0 @@
|
||||
# 🚀 Lions User Manager - Landing Page FREYA BLUE
|
||||
|
||||
## ✨ Page d'accueil Freya Blue niveau AAA - PARFAITE
|
||||
|
||||
**Statut** : ✅ **IMPLÉMENTÉ ET TESTÉ**
|
||||
**Qualité** : 🏆 **ENTERPRISE GRADE**
|
||||
**Design** : 🎨 **FREYA BLUE TEMPLATE (Variant 1)**
|
||||
**Performance** : ⚡ **OPTIMISÉE (32KB)**
|
||||
**Couleurs** : 🔵 **#4F8EEC - Freya Blue Officiel**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Caractéristiques WOW
|
||||
|
||||
### Design Level
|
||||
- ✅ **Palette Freya Blue** : Couleurs professionnelles du template acheté
|
||||
- ✅ **Primary Color** : #4F8EEC (bleu professionnel, PAS violet)
|
||||
- ✅ **Typographie Inter** : Police moderne Google Fonts
|
||||
- ✅ **Animations fluides** : slideDown, fadeInUp, float
|
||||
- ✅ **Micro-interactions** : Hover effects sur tous les éléments
|
||||
- ✅ **Glassmorphism** : Navbar avec backdrop-filter blur
|
||||
- ✅ **Gradients dynamiques** : Bleu dégradé avec var(--primary-500) → var(--primary-700)
|
||||
|
||||
### Architecture
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ NAVBAR (Fixed, Glassmorphism) │
|
||||
│ • Logo avec gradient bleu │
|
||||
│ • CTA button bleu dégradé │
|
||||
├─────────────────────────────────────┤
|
||||
│ HERO SECTION │
|
||||
│ • Background gradient bleu léger │
|
||||
│ • Badge "Plateforme IAM" │
|
||||
│ • H1 Gradient animé (bleu) │
|
||||
│ • Subtitle + 2 CTA buttons bleus │
|
||||
│ • Alert session expirée │
|
||||
├─────────────────────────────────────┤
|
||||
│ STATS SECTION (4 cards) │
|
||||
│ • Compteurs animés │
|
||||
│ • Hover effects bleus │
|
||||
│ • IntersectionObserver │
|
||||
├─────────────────────────────────────┤
|
||||
│ FEATURES SECTION (6 cards) │
|
||||
│ • Gestion utilisateurs │
|
||||
│ • Attribution rôles │
|
||||
│ • Audit & Analytics │
|
||||
│ • Synchronisation │
|
||||
│ • Sécurité avancée │
|
||||
│ • Multi-tenant │
|
||||
│ • Hover: icône devient bleue │
|
||||
│ • Barre gradient bleue en haut │
|
||||
├─────────────────────────────────────┤
|
||||
│ CTA SECTION (Gradient bleu foncé) │
|
||||
│ • Background bleu avec blob animé │
|
||||
│ • CTA white button │
|
||||
├─────────────────────────────────────┤
|
||||
│ FOOTER (Dark) │
|
||||
│ • Logo + infos │
|
||||
│ • Copyright │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Palette de couleurs Freya Blue (Template Acheté)
|
||||
|
||||
### Primary (Bleu Freya) - #4F8EEC
|
||||
```css
|
||||
--primary-color: #4F8EEC /* Couleur principale du template */
|
||||
--primary-50: #EBF3FE /* Background ultra-léger */
|
||||
--primary-100: #D7E7FD /* Background léger */
|
||||
--primary-200: #AECFFB /* Borders légers */
|
||||
--primary-300: #86B7F9 /* Borders */
|
||||
--primary-400: #5D9FF6 /* Accents */
|
||||
--primary-500: #4F8EEC /* Primary base ⭐ */
|
||||
--primary-600: #387FE9 /* Primary hover */
|
||||
--primary-700: #2C6DCC /* Primary active */
|
||||
--primary-800: #2159A8 /* Gradient end */
|
||||
--primary-900: #164684 /* Gradient dark */
|
||||
```
|
||||
|
||||
### Surface (Gris neutres Freya)
|
||||
```css
|
||||
--surface-0: #ffffff /* White pur */
|
||||
--surface-50: #FAFAFA /* Background cards */
|
||||
--surface-100: #F5F5F5 /* Background sections */
|
||||
--surface-200: #EEEEEE /* Borders */
|
||||
--surface-300: #E0E0E0 /* Borders hover */
|
||||
--surface-400: #BDBDBD /* Gris moyen */
|
||||
--surface-500: #9E9E9E /* Gris */
|
||||
--surface-600: #757575 /* Gris foncé */
|
||||
--surface-700: #616161 /* Gris très foncé */
|
||||
--surface-800: #424242 /* Footer dark */
|
||||
--surface-900: #212121 /* Footer darker */
|
||||
```
|
||||
|
||||
### Text (Freya)
|
||||
```css
|
||||
--text-color: #495057 /* Texte principal */
|
||||
--text-color-secondary: #6c757d /* Texte secondaire */
|
||||
```
|
||||
|
||||
### Semantic Colors
|
||||
```css
|
||||
--blue-500: #4F8EEC /* Info (primary) */
|
||||
--green-500: #34D399 /* Success */
|
||||
--red-500: #EF4444 /* Danger */
|
||||
--yellow-500: #F59E0B /* Warning */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔵 Utilisation des couleurs Freya Blue
|
||||
|
||||
### Gradients (utilisant var() pour DRY)
|
||||
```css
|
||||
/* Logo, boutons, hover effects */
|
||||
background: linear-gradient(135deg, var(--primary-500), var(--primary-700));
|
||||
/* = linear-gradient(135deg, #4F8EEC, #2C6DCC) */
|
||||
|
||||
/* Hero background */
|
||||
background: linear-gradient(180deg, var(--surface-0) 0%, var(--primary-50) 100%);
|
||||
/* = linear-gradient(180deg, #ffffff 0%, #EBF3FE 100%) */
|
||||
|
||||
/* CTA section */
|
||||
background: linear-gradient(135deg, var(--primary-600) 0%, var(--primary-800) 100%);
|
||||
/* = linear-gradient(135deg, #387FE9 0%, #2159A8 100%) */
|
||||
```
|
||||
|
||||
### Box Shadows (bleu Freya avec opacité)
|
||||
```css
|
||||
/* Logo, boutons navbar */
|
||||
box-shadow: 0 4px 14px rgba(79, 142, 236, 0.35);
|
||||
/* RGB de #4F8EEC = (79, 142, 236) */
|
||||
|
||||
/* Hover states */
|
||||
box-shadow: 0 6px 20px rgba(79, 142, 236, 0.45);
|
||||
|
||||
/* Cards */
|
||||
box-shadow: 0 8px 24px rgba(79, 142, 236, 0.4);
|
||||
```
|
||||
|
||||
### Backgrounds animés
|
||||
```css
|
||||
/* Blob animé dans hero */
|
||||
background: radial-gradient(circle, rgba(79, 142, 236, 0.12) 0%, transparent 70%);
|
||||
|
||||
/* CTA section blob */
|
||||
background: radial-gradient(circle, rgba(79, 142, 236, 0.15) 0%, transparent 70%);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Sections détaillées
|
||||
|
||||
### 1️⃣ NAVBAR (Fixed + Glassmorphism)
|
||||
**Effet** : Navbar fixe avec effet verre dépoli
|
||||
```css
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(12px);
|
||||
```
|
||||
|
||||
**Logo** :
|
||||
```css
|
||||
.logo-icon {
|
||||
background: linear-gradient(135deg, var(--primary-500), var(--primary-700));
|
||||
box-shadow: 0 4px 14px rgba(79, 142, 236, 0.35); /* Bleu Freya */
|
||||
}
|
||||
```
|
||||
|
||||
**CTA Button** :
|
||||
```css
|
||||
.nav-cta {
|
||||
background: linear-gradient(135deg, var(--primary-500), var(--primary-700));
|
||||
box-shadow: 0 4px 14px rgba(79, 142, 236, 0.35);
|
||||
}
|
||||
|
||||
.nav-cta:hover {
|
||||
box-shadow: 0 6px 20px rgba(79, 142, 236, 0.45);
|
||||
background: linear-gradient(135deg, var(--primary-600), var(--primary-800));
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ HERO SECTION
|
||||
**Gradient background animé**
|
||||
```css
|
||||
background: linear-gradient(180deg, var(--surface-0) 0%, var(--primary-50) 100%);
|
||||
/* = Blanc vers bleu très léger (#EBF3FE) */
|
||||
```
|
||||
|
||||
**Blob animé** :
|
||||
```css
|
||||
.hero::before {
|
||||
background: radial-gradient(circle, rgba(79, 142, 236, 0.12) 0%, transparent 70%);
|
||||
animation: float 20s ease-in-out infinite;
|
||||
}
|
||||
```
|
||||
|
||||
**H1 avec gradient bleu** :
|
||||
```css
|
||||
.hero h1 {
|
||||
background: linear-gradient(135deg, var(--primary-600), var(--primary-800));
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
/* = Gradient bleu #387FE9 → #2159A8 */
|
||||
}
|
||||
```
|
||||
|
||||
**CTA Primary** :
|
||||
```css
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, var(--primary-500), var(--primary-700));
|
||||
box-shadow: 0 8px 24px rgba(79, 142, 236, 0.4);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: linear-gradient(135deg, var(--primary-600), var(--primary-800));
|
||||
box-shadow: 0 12px 32px rgba(79, 142, 236, 0.5);
|
||||
}
|
||||
```
|
||||
|
||||
**Alert session expirée** :
|
||||
```css
|
||||
.session-expired-alert {
|
||||
background: linear-gradient(135deg, #FEE2E2, #FECACA);
|
||||
border-left: 4px solid var(--red-500);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ STATS SECTION (Social Proof)
|
||||
**4 statistiques clés** :
|
||||
- 10,000+ Utilisateurs gérés
|
||||
- 50+ Royaumes actifs
|
||||
- 99.9% Disponibilité
|
||||
- 24/7 Support 24/7
|
||||
|
||||
**Interactions** :
|
||||
```css
|
||||
.stat-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
```
|
||||
|
||||
**Compteurs animés** :
|
||||
- IntersectionObserver déclenche animation au scroll
|
||||
- Compte de 0 à target en 2000ms
|
||||
- Format avec `.toLocaleString('fr-FR')`
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ FEATURES SECTION (Cœur métier)
|
||||
|
||||
**6 feature cards** avec :
|
||||
- Icône 64x64 avec gradient bleu au hover
|
||||
- Barre gradient bleue en haut (scaleX animation)
|
||||
- Titre font-weight 800
|
||||
- Description
|
||||
- 3 bullet points avec checkmarks verts
|
||||
|
||||
**Hover effects** :
|
||||
```css
|
||||
.feature-card {
|
||||
border-top: 3px solid transparent;
|
||||
}
|
||||
|
||||
.feature-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, var(--primary-500), var(--primary-700));
|
||||
transform: scaleX(0);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-card:hover::before {
|
||||
transform: scaleX(1); /* Barre bleue apparaît */
|
||||
}
|
||||
|
||||
.feature-card:hover .feature-icon {
|
||||
background: linear-gradient(135deg, var(--primary-500), var(--primary-700));
|
||||
box-shadow: 0 8px 24px rgba(79, 142, 236, 0.4);
|
||||
}
|
||||
|
||||
.feature-card:hover .feature-icon i {
|
||||
color: white; /* Icône devient blanche sur fond bleu */
|
||||
transform: scale(1.1);
|
||||
}
|
||||
```
|
||||
|
||||
**Fonctionnalités présentées** :
|
||||
|
||||
1. **Gestion des utilisateurs**
|
||||
- Import/Export CSV massif
|
||||
- Recherche multi-critères
|
||||
- Modification par lot
|
||||
|
||||
2. **Attribution des rôles**
|
||||
- Gestion RBAC complète
|
||||
- Hiérarchie de rôles
|
||||
- Permissions dynamiques
|
||||
|
||||
3. **Audit & Analytics**
|
||||
- Logs d'authentification
|
||||
- Rapports personnalisés
|
||||
- Alertes de sécurité
|
||||
|
||||
4. **Synchronisation**
|
||||
- API REST complète
|
||||
- Webhooks événementiels
|
||||
- Connecteurs pré-configurés
|
||||
|
||||
5. **Sécurité avancée**
|
||||
- MFA/2FA obligatoire
|
||||
- Chiffrement AES-256
|
||||
- SOC 2 Type II conforme
|
||||
|
||||
6. **Multi-tenant**
|
||||
- Isolation par royaume
|
||||
- Personnalisation par org
|
||||
- Délégation d'administration
|
||||
|
||||
---
|
||||
|
||||
### 5️⃣ CTA SECTION (Final Push)
|
||||
**Background** : Gradient bleu foncé avec blob animé
|
||||
```css
|
||||
.cta-section {
|
||||
background: linear-gradient(135deg, var(--primary-600) 0%, var(--primary-800) 100%);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cta-section::before {
|
||||
background: radial-gradient(circle, rgba(79, 142, 236, 0.15) 0%, transparent 70%);
|
||||
animation: float 20s ease-in-out infinite;
|
||||
}
|
||||
```
|
||||
|
||||
**Message** :
|
||||
> "Prêt à transformer votre gestion IAM ?"
|
||||
> Rejoignez des centaines d'entreprises qui ont simplifié leur gestion des identités et accès avec Lions User Manager.
|
||||
|
||||
**Button** : White avec shadow bleue
|
||||
```css
|
||||
.cta-button {
|
||||
background: white;
|
||||
color: var(--primary-600);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
transform: translateY(-2px) scale(1.05);
|
||||
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6️⃣ FOOTER (Professional)
|
||||
**Background** : `--surface-900` (#212121 dark)
|
||||
|
||||
**Contenu** :
|
||||
- Logo bleu + nom
|
||||
- Tagline : "Plateforme professionnelle de gestion centralisée des utilisateurs et identités"
|
||||
- Divider
|
||||
- Copyright © 2025 Lions User Manager
|
||||
- Badges : OpenID Connect, Quarkus, PrimeFaces Freya
|
||||
|
||||
---
|
||||
|
||||
## 💻 JavaScript Interactif
|
||||
|
||||
### 1. Session Expired Alert
|
||||
```javascript
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.get('expired') === 'true') {
|
||||
document.getElementById('sessionExpiredAlert').classList.add('show');
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Navbar Scroll Effect
|
||||
```javascript
|
||||
window.addEventListener('scroll', () => {
|
||||
const navbar = document.querySelector('.navbar');
|
||||
if (window.scrollY > 50) {
|
||||
navbar.classList.add('scrolled');
|
||||
} else {
|
||||
navbar.classList.remove('scrolled');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Animated Counters
|
||||
```javascript
|
||||
function animateCounter(element) {
|
||||
const target = parseInt(element.getAttribute('data-target'));
|
||||
const duration = 2000;
|
||||
const step = target / (duration / 16);
|
||||
let current = 0;
|
||||
|
||||
const timer = setInterval(() => {
|
||||
current += step;
|
||||
if (current >= target) {
|
||||
element.textContent = target.toLocaleString('fr-FR');
|
||||
clearInterval(timer);
|
||||
} else {
|
||||
element.textContent = Math.floor(current).toLocaleString('fr-FR');
|
||||
}
|
||||
}, 16);
|
||||
}
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting && entry.target.getAttribute('data-target')) {
|
||||
animateCounter(entry.target);
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.5 });
|
||||
|
||||
document.querySelectorAll('.stat-number').forEach(stat => observer.observe(stat));
|
||||
```
|
||||
|
||||
### 4. Smooth Scroll
|
||||
```javascript
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(this.getAttribute('href'));
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📱 Responsive Design
|
||||
|
||||
### Breakpoints
|
||||
```css
|
||||
@media (max-width: 768px) {
|
||||
/* Mobile-first adjustments */
|
||||
.hero h1 {
|
||||
font-size: 2.5rem; /* 3.75rem → 2.5rem */
|
||||
}
|
||||
|
||||
.features-grid {
|
||||
grid-template-columns: 1fr; /* 3 colonnes → 1 colonne */
|
||||
}
|
||||
|
||||
.stats-container {
|
||||
grid-template-columns: 1fr; /* 4 colonnes → 1 colonne */
|
||||
}
|
||||
|
||||
.hero-cta-group {
|
||||
flex-direction: column; /* Horizontal → Vertical */
|
||||
}
|
||||
|
||||
.btn-primary, .btn-secondary {
|
||||
width: 100%; /* Auto → 100% */
|
||||
}
|
||||
|
||||
.navbar-container {
|
||||
padding: 0 1rem; /* 2rem → 1rem */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Optimisations mobile** :
|
||||
- Hero H1 : 3.75rem → 2.5rem
|
||||
- Padding sections réduit : 6rem → 4rem
|
||||
- Grid : auto-fit → 1 colonne fixe
|
||||
- CTA buttons : 100% width
|
||||
- Navbar padding réduit
|
||||
- Stats et Features en colonne unique
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Performance
|
||||
|
||||
### Métriques
|
||||
- **Taille** : ~32KB (HTML + CSS + JS inline)
|
||||
- **Fonts** : Inter via Google Fonts avec preconnect
|
||||
- **Icons** : PrimeIcons 7.0.0 (CDN, ~50KB)
|
||||
- **CSS** : Inline (pas de fichier externe)
|
||||
- **JS** : Inline vanilla (pas de framework)
|
||||
- **Requests** : ~4 total (HTML + 2 fonts + 1 icons)
|
||||
|
||||
### Optimisations
|
||||
✅ **Pas de jQuery** : Vanilla JS pur (0KB)
|
||||
✅ **Pas de Bootstrap** : CSS custom léger
|
||||
✅ **Pas de framework JS** : Performance maximale
|
||||
✅ **IntersectionObserver** : Animations on-demand (pas de scroll listener lourd)
|
||||
✅ **Font preconnect** : Chargement Google Fonts optimisé
|
||||
✅ **Transitions CSS** : Hardware accelerated (transform, opacity)
|
||||
✅ **DRY avec CSS Variables** : Maintainabilité maximale
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Checklist Qualité
|
||||
|
||||
### Design ✅
|
||||
- [x] Palette Freya Blue respectée (#4F8EEC, pas violet)
|
||||
- [x] Template acheté capitalisé (Variant 1 - Blue)
|
||||
- [x] Typographie Inter professionnelle
|
||||
- [x] Animations fluides et subtiles
|
||||
- [x] Micro-interactions sur hover
|
||||
- [x] Responsive parfait (mobile, tablette, desktop)
|
||||
- [x] Accessibilité (contraste, tailles, semantic HTML)
|
||||
|
||||
### Contenu Métier ✅
|
||||
- [x] Proposition de valeur claire (IAM centralisée)
|
||||
- [x] 6 fonctionnalités détaillées (RBAC, MFA, Audit, etc.)
|
||||
- [x] Social proof (stats avec compteurs animés)
|
||||
- [x] 3 CTA bien placés (navbar, hero, footer)
|
||||
- [x] Message professionnel B2B
|
||||
- [x] Vocabulaire IAM technique (Keycloak, OIDC, RBAC)
|
||||
|
||||
### Technique ✅
|
||||
- [x] HTML5 sémantique (header, section, footer)
|
||||
- [x] CSS moderne (Grid, Flexbox, Custom Properties)
|
||||
- [x] JavaScript vanilla ES6+ (pas de dépendances)
|
||||
- [x] Performance optimisée (32KB, 4 requests)
|
||||
- [x] Pas d'erreurs console
|
||||
- [x] SEO-friendly (title, meta description)
|
||||
|
||||
### Interactions ✅
|
||||
- [x] Navbar scroll effect (glassmorphism + shadow)
|
||||
- [x] Compteurs animés (IntersectionObserver)
|
||||
- [x] Smooth scroll vers ancres
|
||||
- [x] Alert session expirée conditionnelle
|
||||
- [x] Hover effects partout (transform, shadow, gradient)
|
||||
- [x] Loading optimisé (preconnect fonts)
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests de validation
|
||||
|
||||
### Test 1 : Couleurs Freya Blue
|
||||
```bash
|
||||
grep "rgba(79, 142, 236" index.html
|
||||
# → 8 occurrences (toutes les ombres bleues)
|
||||
|
||||
grep "rgba(139, 92, 246" index.html
|
||||
# → 0 occurrences (aucune trace de violet)
|
||||
|
||||
grep "#4F8EEC" index.html
|
||||
# → Plusieurs occurrences (couleur principale)
|
||||
|
||||
grep "#8b5cf6" index.html
|
||||
# → 0 occurrences (aucune trace de violet)
|
||||
```
|
||||
✅ **RÉUSSI** : Freya Blue uniquement
|
||||
|
||||
### Test 2 : Page charge
|
||||
```bash
|
||||
curl -I http://localhost:8082/
|
||||
# → HTTP/1.1 200 OK
|
||||
# → Content-Type: text/html
|
||||
```
|
||||
✅ **RÉUSSI**
|
||||
|
||||
### Test 3 : Alert session expirée
|
||||
```bash
|
||||
curl -s "http://localhost:8082/?expired=true" | grep "Votre session a expiré"
|
||||
# → Trouve le message d'alerte
|
||||
```
|
||||
✅ **RÉUSSI**
|
||||
|
||||
### Test 4 : Navigation
|
||||
- ✅ Logo → Retour accueil
|
||||
- ✅ CTA navbar → /pages/user-manager/dashboard.xhtml
|
||||
- ✅ CTA hero → /pages/user-manager/dashboard.xhtml
|
||||
- ✅ CTA secondaire → Scroll vers #features
|
||||
- ✅ CTA final → /pages/user-manager/dashboard.xhtml
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Déploiement
|
||||
|
||||
### URL de production
|
||||
- **Développement** : http://localhost:8082
|
||||
- **Production** : https://lions-user-manager.yourdomain.com
|
||||
|
||||
### Configuration requise
|
||||
```properties
|
||||
# application.properties
|
||||
# Chemins publics (permettre accès sans auth)
|
||||
quarkus.http.auth.permission.public.paths=/,/index.html,...
|
||||
|
||||
# Redirection en cas de session expirée
|
||||
quarkus.myfaces.view-expired-exception-handler-redirect-page=/index.html?expired=true
|
||||
```
|
||||
|
||||
### Flux utilisateur
|
||||
|
||||
#### Scénario 1 : Premier accès
|
||||
```
|
||||
http://localhost:8082
|
||||
↓
|
||||
Affiche index.html (landing page Freya Blue)
|
||||
↓
|
||||
Clique "Se connecter avec Keycloak"
|
||||
↓
|
||||
Redirigé vers /pages/user-manager/dashboard.xhtml
|
||||
↓
|
||||
Quarkus OIDC intercepte → Keycloak login
|
||||
↓
|
||||
Dashboard (authentifié)
|
||||
```
|
||||
|
||||
#### Scénario 2 : Session expirée
|
||||
```
|
||||
Utilisateur sur /pages/user-manager/users/list.xhtml
|
||||
↓
|
||||
Session expire (timeout 60 min)
|
||||
↓
|
||||
ViewExpiredException
|
||||
↓
|
||||
Redirigé vers /index.html?expired=true
|
||||
↓
|
||||
Alerte rouge "Votre session a expiré"
|
||||
↓
|
||||
Clique "Se connecter avec Keycloak"
|
||||
↓
|
||||
OIDC force ré-authentification
|
||||
↓
|
||||
Dashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Améliorations futures (optionnelles)
|
||||
|
||||
### Version 2.0
|
||||
- [ ] Logo SVG personnalisé Lions (remplacer icône)
|
||||
- [ ] Screenshots de l'interface (section démo)
|
||||
- [ ] Témoignages clients (social proof)
|
||||
- [ ] Vidéo démo en background hero
|
||||
- [ ] Blog/actualités (section news)
|
||||
- [ ] Dark mode toggle
|
||||
- [ ] i18n (FR/EN avec drapeaux)
|
||||
- [ ] Cookie banner RGPD
|
||||
|
||||
### Performance
|
||||
- [ ] Lazy loading images (si ajoutées)
|
||||
- [ ] Critical CSS inline (déjà fait)
|
||||
- [ ] Service Worker (PWA offline)
|
||||
- [ ] Preload fonts (.woff2 local)
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Technologies utilisées
|
||||
|
||||
| Technologie | Version | Usage | Raison |
|
||||
|-------------|---------|-------|--------|
|
||||
| **HTML5** | - | Structure sémantique | SEO, accessibilité |
|
||||
| **CSS3** | - | Custom Variables, Grid, Flexbox, Animations | DRY, maintainabilité |
|
||||
| **JavaScript** | ES6+ | Vanilla, IntersectionObserver, Event Listeners | Performance (0 framework) |
|
||||
| **PrimeIcons** | 7.0.0 | Icônes professionnelles | Cohérence avec PrimeFaces |
|
||||
| **Inter Font** | Variable | Google Fonts typographie | Lisibilité, modernité |
|
||||
| **Freya Blue** | Variant 1 | Couleurs template acheté | Branding cohérent |
|
||||
|
||||
---
|
||||
|
||||
## 🏆 Niveau de qualité
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────┐
|
||||
│ ÉVALUATION FINALE │
|
||||
├────────────────────────────────────────────────┤
|
||||
│ Design Freya Blue: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Performance: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Responsive: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Accessibilité: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Code Quality (DRY): ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Métier/Business: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ WOW Factor: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
├────────────────────────────────────────────────┤
|
||||
│ TOTAL: 35/35 = PARFAIT ✅ │
|
||||
└────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Conclusion
|
||||
|
||||
Cette landing page est de **niveau ENTERPRISE AAA avec Freya Blue** :
|
||||
- ✅ **Design Freya Blue** (#4F8EEC) - Template acheté capitalisé
|
||||
- ✅ **Métier** : Orientée B2B IAM avec vocabulaire technique
|
||||
- ✅ **Parfaite** : Qualité irréprochable sur tous les aspects
|
||||
- ✅ **WOW** : Animations, interactions, effets visuels professionnels
|
||||
- ✅ **DRY** : CSS Variables pour toutes les couleurs, pas de répétition
|
||||
- ✅ **GO** : Performance optimale, prête pour la production
|
||||
|
||||
**La page capitalise 100% sur le template Freya Blue acheté ! 🚀**
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Vérification technique
|
||||
|
||||
### Validation couleurs Freya Blue
|
||||
```bash
|
||||
# Vérifier aucune trace de violet (ancienne version)
|
||||
grep -i "purple\|violet\|#8b5cf6\|rgba(139, 92, 246" index.html
|
||||
# → Résultat : 0 occurrences ✅
|
||||
|
||||
# Vérifier présence Freya Blue
|
||||
grep "#4F8EEC\|rgba(79, 142, 236" index.html
|
||||
# → Résultat : 8+ occurrences ✅
|
||||
|
||||
# Vérifier variables CSS
|
||||
grep "var(--primary-500)\|var(--primary-600)\|var(--primary-700)" index.html
|
||||
# → Résultat : Nombreuses occurrences (DRY) ✅
|
||||
```
|
||||
|
||||
### Validation structure
|
||||
```bash
|
||||
# Sections présentes
|
||||
grep -E "<section|<header|<footer" index.html | wc -l
|
||||
# → 7 sections sémantiques ✅
|
||||
|
||||
# JavaScript vanilla (pas de jQuery, React, etc.)
|
||||
grep -E "jquery|react|vue|angular" index.html
|
||||
# → 0 occurrences ✅
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Date** : 2025-12-25
|
||||
**Version** : 2.0.1 FREYA BLUE FINAL
|
||||
**Statut** : ✅ **PRODUCTION READY**
|
||||
**Template** : Freya Blue (Variant 1) - **CAPITALISÉ**
|
||||
@@ -1,448 +0,0 @@
|
||||
# 🚀 Lions User Manager - Landing Page ENTERPRISE
|
||||
|
||||
## ✨ Page d'accueil Freya niveau AAA - PARFAITE
|
||||
|
||||
**Statut** : ✅ **IMPLÉMENTÉ ET TESTÉ**
|
||||
**Qualité** : 🏆 **ENTERPRISE GRADE**
|
||||
**Design** : 🎨 **FREYA PROFESSIONAL**
|
||||
**Performance** : ⚡ **OPTIMISÉE (32KB)**
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Caractéristiques WOW
|
||||
|
||||
### Design Level
|
||||
- ✅ **Palette Freya** : Couleurs professionnelles violet/pourpre
|
||||
- ✅ **Typographie Inter** : Police moderne Google Fonts
|
||||
- ✅ **Animations fluides** : slideDown, fadeInUp, float
|
||||
- ✅ **Micro-interactions** : Hover effects sur tous les éléments
|
||||
- ✅ **Glassmorphism** : Navbar avec backdrop-filter blur
|
||||
- ✅ **Gradients dynamiques** : Multiples gradients animés
|
||||
|
||||
### Architecture
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ NAVBAR (Fixed, Glassmorphism) │
|
||||
├─────────────────────────────────────┤
|
||||
│ HERO SECTION │
|
||||
│ • Badge "Plateforme IAM" │
|
||||
│ • H1 Gradient animé │
|
||||
│ • Subtitle + 2 CTA buttons │
|
||||
│ • Alert session expirée │
|
||||
├─────────────────────────────────────┤
|
||||
│ STATS SECTION (4 cards) │
|
||||
│ • Compteurs animés │
|
||||
│ • Hover effects │
|
||||
├─────────────────────────────────────┤
|
||||
│ FEATURES SECTION (6 cards) │
|
||||
│ • Gestion utilisateurs │
|
||||
│ • Attribution rôles │
|
||||
│ • Audit & Analytics │
|
||||
│ • Synchronisation │
|
||||
│ • Sécurité avancée │
|
||||
│ • Multi-tenant │
|
||||
├─────────────────────────────────────┤
|
||||
│ CTA SECTION (Gradient purple) │
|
||||
│ • Message fort │
|
||||
│ • CTA white button │
|
||||
├─────────────────────────────────────┤
|
||||
│ FOOTER (Dark) │
|
||||
│ • Logo + infos │
|
||||
│ • Copyright │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Palette de couleurs Freya
|
||||
|
||||
### Primary (Violet/Pourpre)
|
||||
```css
|
||||
--primary-50: #f5f3ff /* Background ultra-léger */
|
||||
--primary-100: #ede9fe /* Background léger */
|
||||
--primary-200: #ddd6fe /* Borders légers */
|
||||
--primary-300: #c4b5fd /* Borders */
|
||||
--primary-400: #a78bfa /* Accents */
|
||||
--primary-500: #8b5cf6 /* Primary base */
|
||||
--primary-600: #7c3aed /* Primary hover */
|
||||
--primary-700: #6d28d9 /* Primary active */
|
||||
--primary-800: #5b21b6 /* Gradient end */
|
||||
--primary-900: #4c1d95 /* Gradient dark */
|
||||
```
|
||||
|
||||
### Surface (Gris neutres)
|
||||
```css
|
||||
--surface-0: #ffffff /* White pur */
|
||||
--surface-50: #fafafa /* Background cards */
|
||||
--surface-100: #f5f5f5 /* Background sections */
|
||||
--surface-200: #eeeeee /* Borders */
|
||||
--surface-300: #e0e0e0 /* Borders hover */
|
||||
--surface-800: #424242 /* Footer dark */
|
||||
--surface-900: #212121 /* Footer darker */
|
||||
```
|
||||
|
||||
### Text
|
||||
```css
|
||||
--text-color: #1e293b /* Texte principal */
|
||||
--text-secondary: #64748b /* Texte secondaire */
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Sections détaillées
|
||||
|
||||
### 1️⃣ NAVBAR (Fixed + Glassmorphism)
|
||||
**Effet** : Navbar fixe avec effet verre dépoli
|
||||
```css
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(12px);
|
||||
```
|
||||
|
||||
**Interactions** :
|
||||
- Scroll → Ajoute shadow
|
||||
- Logo cliquable → Retour accueil
|
||||
- CTA button → Accès console
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ HERO SECTION
|
||||
**Gradient background animé**
|
||||
```css
|
||||
background: linear-gradient(180deg, white 0%, #f5f3ff 100%);
|
||||
```
|
||||
|
||||
**Éléments** :
|
||||
- ✅ **Badge** : "Plateforme IAM Centralisée" avec icône shield
|
||||
- ✅ **H1** : Gradient text, font-size 3.75rem, font-weight 900
|
||||
- ✅ **Subtitle** : 1.375rem, couleur secondaire
|
||||
- ✅ **2 CTA** : Primary (gradient violet) + Secondary (white bordered)
|
||||
- ✅ **Alert session expirée** : Conditionnelle si `?expired=true`
|
||||
|
||||
**Animations** :
|
||||
- Badge : `slideDown` 0.8s
|
||||
- H1 : `fadeInUp` 0.8s delay 0.2s
|
||||
- Subtitle : `fadeInUp` 0.8s delay 0.4s
|
||||
- CTA : `fadeInUp` 0.8s delay 0.6s
|
||||
- Background blob : `float` 20s infinite
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ STATS SECTION (Social Proof)
|
||||
**4 statistiques clés** :
|
||||
- 10,000 Utilisateurs gérés
|
||||
- 50 Royaumes actifs
|
||||
- 99.9% Disponibilité
|
||||
- 24 Support 24/7
|
||||
|
||||
**Interactions** :
|
||||
- Hover → translateY(-5px) + shadow
|
||||
- Scroll in view → Compteurs animés (IntersectionObserver)
|
||||
|
||||
**Animation compteurs** :
|
||||
```javascript
|
||||
// Compte de 0 à target en 2000ms
|
||||
// Utilise setInterval avec step calculation
|
||||
// S'arrête automatiquement à la valeur cible
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ FEATURES SECTION (Cœur métier)
|
||||
|
||||
**6 feature cards** avec :
|
||||
- Icône 64x64 gradient
|
||||
- Titre font-weight 800
|
||||
- Description
|
||||
- 3 bullet points avec checkmarks
|
||||
|
||||
**Fonctionnalités présentées** :
|
||||
|
||||
1. **Gestion des utilisateurs**
|
||||
- Import/Export CSV massif
|
||||
- Recherche multi-critères
|
||||
- Modification par lot
|
||||
|
||||
2. **Attribution des rôles**
|
||||
- Gestion RBAC complète
|
||||
- Hiérarchie de rôles
|
||||
- Permissions dynamiques
|
||||
|
||||
3. **Audit & Analytics**
|
||||
- Logs d'authentification
|
||||
- Rapports personnalisés
|
||||
- Alertes de sécurité
|
||||
|
||||
4. **Synchronisation**
|
||||
- API REST complète
|
||||
- Webhooks événementiels
|
||||
- Connecteurs pré-configurés
|
||||
|
||||
5. **Sécurité avancée**
|
||||
- MFA/2FA obligatoire
|
||||
- Chiffrement AES-256
|
||||
- SOC 2 Type II conforme
|
||||
|
||||
6. **Multi-tenant**
|
||||
- Isolation par royaume
|
||||
- Personnalisation par org
|
||||
- Délégation d'administration
|
||||
|
||||
**Interactions** :
|
||||
- Hover → translateY(-8px)
|
||||
- Hover → Barre gradient top apparaît (scaleX 0 → 1)
|
||||
- Hover icône → Background devient violet + icône blanche + scale(1.1)
|
||||
|
||||
---
|
||||
|
||||
### 5️⃣ CTA SECTION (Final Push)
|
||||
**Background** : Gradient violet foncé avec blob animé
|
||||
|
||||
**Message** :
|
||||
> "Prêt à transformer votre gestion IAM ?"
|
||||
> Rejoignez des centaines d'entreprises...
|
||||
|
||||
**Button** : White avec shadow + hover scale(1.05)
|
||||
|
||||
---
|
||||
|
||||
### 6️⃣ FOOTER (Professional)
|
||||
**Background** : `--surface-900` (dark)
|
||||
|
||||
**Contenu** :
|
||||
- Logo + nom
|
||||
- Tagline : "Plateforme professionnelle..."
|
||||
- Divider
|
||||
- Copyright © 2025
|
||||
- Badges : OpenID Connect, Quarkus, PrimeFaces Freya
|
||||
|
||||
---
|
||||
|
||||
## 💻 JavaScript Interactif
|
||||
|
||||
### 1. Session Expired Alert
|
||||
```javascript
|
||||
if (urlParams.get('expired') === 'true') {
|
||||
document.getElementById('sessionExpiredAlert').classList.add('show');
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Navbar Scroll Effect
|
||||
```javascript
|
||||
window.addEventListener('scroll', () => {
|
||||
if (window.scrollY > 50) {
|
||||
navbar.classList.add('scrolled');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Animated Counters
|
||||
```javascript
|
||||
// IntersectionObserver déclenche l'animation
|
||||
// Compteur anime de 0 à target en 2000ms
|
||||
// Format avec toLocaleString()
|
||||
```
|
||||
|
||||
### 4. Smooth Scroll
|
||||
```javascript
|
||||
// Scroll smooth vers ancres #features
|
||||
target.scrollIntoView({ behavior: 'smooth' });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📱 Responsive Design
|
||||
|
||||
### Breakpoints
|
||||
```css
|
||||
@media (max-width: 768px) {
|
||||
/* Mobile-first adjustments */
|
||||
.hero h1 { font-size: 2.5rem; }
|
||||
.features-grid { grid-template-columns: 1fr; }
|
||||
.stats-container { grid-template-columns: 1fr; }
|
||||
.hero-cta-group { flex-direction: column; }
|
||||
.btn-primary, .btn-secondary { width: 100%; }
|
||||
}
|
||||
```
|
||||
|
||||
**Optimisations mobile** :
|
||||
- Hero H1 : 3.75rem → 2.5rem
|
||||
- Padding sections réduit
|
||||
- Grid : auto-fit → 1 colonne
|
||||
- CTA buttons : 100% width
|
||||
- Navbar padding réduit
|
||||
|
||||
---
|
||||
|
||||
## ⚡ Performance
|
||||
|
||||
### Métriques
|
||||
- **Taille** : 32KB (optimisé)
|
||||
- **Fonts** : Inter via Google Fonts (preconnect)
|
||||
- **Icons** : PrimeIcons 7.0.0 (CDN)
|
||||
- **CSS** : Inline (pas de fichier externe)
|
||||
- **JS** : Inline vanilla (pas de framework)
|
||||
|
||||
### Optimisations
|
||||
✅ **Pas de jQuery** : Vanilla JS pur
|
||||
✅ **Pas de Bootstrap** : CSS custom
|
||||
✅ **Pas de framework JS** : Performance maximale
|
||||
✅ **IntersectionObserver** : Animations on-demand
|
||||
✅ **Font preconnect** : Chargement Google Fonts optimisé
|
||||
✅ **Transitions CSS** : Hardware accelerated
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Checklist Qualité
|
||||
|
||||
### Design ✅
|
||||
- [x] Palette Freya respectée
|
||||
- [x] Typographie Inter professionnelle
|
||||
- [x] Animations fluides et subtiles
|
||||
- [x] Micro-interactions sur hover
|
||||
- [x] Responsive parfait (mobile, tablette, desktop)
|
||||
- [x] Accessibilité (contraste, tailles)
|
||||
|
||||
### Contenu Métier ✅
|
||||
- [x] Proposition de valeur claire
|
||||
- [x] 6 fonctionnalités détaillées
|
||||
- [x] Social proof (stats)
|
||||
- [x] 3 CTA bien placés
|
||||
- [x] Message professionnel B2B
|
||||
- [x] Vocabulaire IAM technique
|
||||
|
||||
### Technique ✅
|
||||
- [x] HTML5 sémantique
|
||||
- [x] CSS moderne (Grid, Flexbox, Variables)
|
||||
- [x] JavaScript vanilla (pas de dépendances)
|
||||
- [x] Performance optimisée (32KB)
|
||||
- [x] Pas d'erreurs console
|
||||
- [x] SEO-friendly (title, meta)
|
||||
|
||||
### Interactions ✅
|
||||
- [x] Navbar scroll effect
|
||||
- [x] Compteurs animés
|
||||
- [x] Smooth scroll
|
||||
- [x] Alert session expirée
|
||||
- [x] Hover effects partout
|
||||
- [x] Loading optimisé
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
### Test 1 : Page charge
|
||||
```bash
|
||||
curl -I http://localhost:8082/
|
||||
# → HTTP/1.1 200 OK
|
||||
# → Content-Length: 32444
|
||||
```
|
||||
✅ **RÉUSSI**
|
||||
|
||||
### Test 2 : Contenu Freya
|
||||
```bash
|
||||
curl -s http://localhost:8082/ | grep "Freya"
|
||||
# → /* Freya Color Palette - Professional Enterprise */
|
||||
# → Powered by Quarkus & PrimeFaces Freya
|
||||
```
|
||||
✅ **RÉUSSI**
|
||||
|
||||
### Test 3 : Alert session expirée
|
||||
```bash
|
||||
curl -s "http://localhost:8082/?expired=true" | grep "Votre session a expiré"
|
||||
# → Votre session a expiré pour des raisons de sécurité...
|
||||
```
|
||||
✅ **RÉUSSI**
|
||||
|
||||
### Test 4 : Navigation
|
||||
- ✅ Logo → Retour accueil
|
||||
- ✅ CTA navbar → Dashboard
|
||||
- ✅ CTA hero → Dashboard
|
||||
- ✅ CTA secondaire → Scroll vers features
|
||||
- ✅ CTA final → Dashboard
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Déploiement
|
||||
|
||||
### URL de production
|
||||
- **Développement** : http://localhost:8082
|
||||
- **Production** : https://lions-user-manager.yourdomain.com
|
||||
|
||||
### Configuration requise
|
||||
```properties
|
||||
# application.properties
|
||||
quarkus.http.auth.permission.public.paths=/,/index.html,...
|
||||
quarkus.myfaces.view-expired-exception-handler-redirect-page=/index.html?expired=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Améliorations futures (optionnelles)
|
||||
|
||||
### Version 2.0
|
||||
- [ ] Logo SVG personnalisé (remplacer icône)
|
||||
- [ ] Screenshots de l'interface (section démo)
|
||||
- [ ] Témoignages clients (social proof)
|
||||
- [ ] Vidéo démo (hero background)
|
||||
- [ ] Blog/actualités (section news)
|
||||
- [ ] Dark mode toggle
|
||||
- [ ] i18n (FR/EN)
|
||||
- [ ] Cookie banner (RGPD)
|
||||
|
||||
### Performance
|
||||
- [ ] Lazy loading images
|
||||
- [ ] Critical CSS inline
|
||||
- [ ] Service Worker (PWA)
|
||||
- [ ] Preload fonts
|
||||
|
||||
---
|
||||
|
||||
## 🎓 Technologies utilisées
|
||||
|
||||
| Technologie | Version | Usage |
|
||||
|-------------|---------|-------|
|
||||
| **HTML5** | - | Structure sémantique |
|
||||
| **CSS3** | - | Custom Variables, Grid, Flexbox, Animations |
|
||||
| **JavaScript** | ES6+ | Vanilla, IntersectionObserver, Event Listeners |
|
||||
| **PrimeIcons** | 7.0.0 | Icônes professionnelles |
|
||||
| **Inter Font** | Variable | Google Fonts typographie |
|
||||
| **Freya Palette** | - | Couleurs PrimeFaces Freya |
|
||||
|
||||
---
|
||||
|
||||
## 🏆 Niveau de qualité
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────┐
|
||||
│ ÉVALUATION FINALE │
|
||||
├────────────────────────────────────────┤
|
||||
│ Design: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Performance: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Responsive: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Accessibilité: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Code Quality: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
│ Métier/Business: ⭐⭐⭐⭐⭐ (5/5) │
|
||||
├────────────────────────────────────────┤
|
||||
│ TOTAL: 30/30 = PARFAIT ✅ │
|
||||
└────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Conclusion
|
||||
|
||||
Cette landing page est de **niveau ENTERPRISE AAA** :
|
||||
- ✅ **Design Freya** professionnel et moderne
|
||||
- ✅ **Métier** : Orientée B2B IAM avec vocabulaire technique
|
||||
- ✅ **Parfaite** : Qualité irréprochable sur tous les aspects
|
||||
- ✅ **WOW** : Animations, interactions, effets visuels
|
||||
- ✅ **DRY** : Code CSS avec variables, pas de répétition
|
||||
- ✅ **GO** : Performance optimale, prête pour la production
|
||||
|
||||
**La page est prête à impressionner vos utilisateurs ! 🚀**
|
||||
|
||||
---
|
||||
|
||||
**Date** : 2025-12-25
|
||||
**Version** : 2.0.0 ENTERPRISE
|
||||
**Statut** : ✅ **PRODUCTION READY**
|
||||
@@ -1,484 +0,0 @@
|
||||
# 🚀 Guide de Préparation Production - Lions User Manager
|
||||
|
||||
**Date**: 2025-01-15
|
||||
**Version**: 1.0.0
|
||||
**Statut**: ⚠️ **OBLIGATOIRE AVANT DÉPLOIEMENT**
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ IMPORTANT
|
||||
|
||||
**NE PAS DÉPLOYER** avant d'avoir complété toutes les étapes de ce guide. Le déploiement échouera si :
|
||||
- ❌ Keycloak n'est pas configuré (clients, rôles, utilisateurs)
|
||||
- ❌ La base de données PostgreSQL n'existe pas
|
||||
- ❌ Les secrets et variables d'environnement ne sont pas configurés
|
||||
|
||||
---
|
||||
|
||||
## 📋 Table des Matières
|
||||
|
||||
1. [Prérequis](#prérequis)
|
||||
2. [Configuration Keycloak Production](#configuration-keycloak-production)
|
||||
3. [Configuration Base de Données PostgreSQL](#configuration-base-de-données-postgresql)
|
||||
4. [Préparation des Secrets](#préparation-des-secrets)
|
||||
5. [Vérification Pré-Déploiement](#vérification-pré-déploiement)
|
||||
6. [Checklist Complète](#checklist-complète)
|
||||
|
||||
---
|
||||
|
||||
## 1. Prérequis
|
||||
|
||||
### Infrastructure Requise
|
||||
|
||||
- ✅ **Keycloak** : Accessible sur `https://security.lions.dev`
|
||||
- ✅ **PostgreSQL** : Base de données disponible dans le cluster Kubernetes
|
||||
- ✅ **Accès SSH** : Accès au VPS/cluster pour exécuter les commandes
|
||||
- ✅ **kubectl** : Configuré et connecté au cluster de production
|
||||
- ✅ **kcadm.sh** : Keycloak Admin CLI (optionnel, pour scripts)
|
||||
|
||||
### Accès Requis
|
||||
|
||||
- ✅ Accès admin à Keycloak (`master` realm)
|
||||
- ✅ Accès admin au cluster Kubernetes
|
||||
- ✅ Accès à la base de données PostgreSQL
|
||||
|
||||
---
|
||||
|
||||
## 2. Configuration Keycloak Production
|
||||
|
||||
### 2.1. Créer le Realm (si nécessaire)
|
||||
|
||||
Le realm `master` est utilisé par défaut pour gérer tous les autres realms.
|
||||
|
||||
**Vérification** :
|
||||
```bash
|
||||
# Via Keycloak Admin Console
|
||||
https://security.lions.dev/admin
|
||||
# Realm: master
|
||||
# User: admin
|
||||
```
|
||||
|
||||
### 2.2. Créer les Clients OIDC
|
||||
|
||||
#### Client Frontend (`lions-user-manager-client`)
|
||||
|
||||
**Configuration requise** :
|
||||
- **Client ID** : `lions-user-manager-client`
|
||||
- **Type** : `public` (ou `confidential` avec secret)
|
||||
- **Realm** : `master`
|
||||
- **Redirect URIs** :
|
||||
- `https://user-manager.lions.dev/*`
|
||||
- `https://admin.lions.dev/*`
|
||||
- `https://user-manager.lions.dev/auth/callback`
|
||||
- **Web Origins** :
|
||||
- `https://user-manager.lions.dev`
|
||||
- `https://admin.lions.dev`
|
||||
- **Standard Flow** : ✅ Activé
|
||||
- **Direct Access Grants** : ❌ Désactivé (sécurité)
|
||||
- **Service Accounts** : ❌ Désactivé
|
||||
- **PKCE** : ✅ Activé (recommandé)
|
||||
|
||||
**Script PowerShell** : `scripts/setup-keycloak-production.ps1` (à créer)
|
||||
|
||||
#### Client Backend (`lions-user-manager`)
|
||||
|
||||
**Configuration requise** :
|
||||
- **Client ID** : `lions-user-manager`
|
||||
- **Type** : `confidential` (avec secret)
|
||||
- **Realm** : `master`
|
||||
- **Service Accounts** : ✅ Activé (OBLIGATOIRE)
|
||||
- **Standard Flow** : ❌ Désactivé
|
||||
- **Direct Access Grants** : ✅ Activé (pour service account)
|
||||
- **Authorization** : ✅ Activé
|
||||
|
||||
**Rôles à assigner au Service Account** :
|
||||
- `admin` (dans le realm `master`)
|
||||
- Ou créer un rôle spécifique `lions-user-manager-service` avec les permissions nécessaires
|
||||
|
||||
**Script PowerShell** : `scripts/setup-keycloak-production.ps1` (à créer)
|
||||
|
||||
### 2.3. Créer les Rôles Realm
|
||||
|
||||
Les rôles suivants doivent exister dans le realm `master` :
|
||||
|
||||
| Rôle | Description | Utilisation |
|
||||
|------|-------------|-------------|
|
||||
| `admin` | Administrateur système | Accès complet à tous les endpoints |
|
||||
| `user_manager` | Gestionnaire utilisateur | CRUD utilisateurs |
|
||||
| `user_viewer` | Visualiseur utilisateur | Lecture seule utilisateurs |
|
||||
| `auditor` | Auditeur | Consultation logs d'audit |
|
||||
| `sync_manager` | Gestionnaire synchronisation | Gestion synchronisation |
|
||||
| `role_manager` | Gestionnaire rôles | CRUD rôles |
|
||||
| `role_viewer` | Visualiseur rôles | Lecture seule rôles |
|
||||
|
||||
**Script** : `scripts/setup-keycloak-roles-production.ps1` (à créer)
|
||||
|
||||
### 2.4. Configurer les Protocol Mappers
|
||||
|
||||
**Client Scope** : `roles` (déjà existant dans Keycloak)
|
||||
|
||||
**Vérifier que le mapper inclut** :
|
||||
- ✅ `realm_access.roles` dans l'access token
|
||||
- ✅ `roles` dans l'id token (optionnel)
|
||||
|
||||
**Configuration** :
|
||||
1. Aller dans **Client Scopes** → `roles`
|
||||
2. Onglet **Mappers**
|
||||
3. Vérifier que `realm roles` existe et est configuré pour l'access token
|
||||
|
||||
### 2.5. Créer un Utilisateur de Test (Optionnel)
|
||||
|
||||
Pour tester l'application en production :
|
||||
|
||||
- **Username** : `admin-user-manager`
|
||||
- **Email** : `admin-user-manager@lions.dev`
|
||||
- **Password** : (générer un mot de passe fort)
|
||||
- **Rôles** : Assigner `admin`, `user_manager`, `auditor`
|
||||
|
||||
---
|
||||
|
||||
## 3. Configuration Base de Données PostgreSQL
|
||||
|
||||
### 3.1. Créer la Base de Données
|
||||
|
||||
**Nom** : `lions_audit`
|
||||
|
||||
**Script PowerShell** : `scripts/setup-database-production.ps1` (à créer)
|
||||
|
||||
**Commandes manuelles** :
|
||||
```bash
|
||||
# Se connecter au pod PostgreSQL
|
||||
kubectl exec -it -n postgresql <postgres-pod-name> -- psql -U <postgres-user> -d postgres
|
||||
|
||||
# Créer la base de données
|
||||
CREATE DATABASE lions_audit OWNER <postgres-user>;
|
||||
|
||||
# Créer l'utilisateur (si nécessaire)
|
||||
CREATE USER lions_audit_user WITH PASSWORD '<strong-password>';
|
||||
|
||||
# Octroyer les privilèges
|
||||
GRANT ALL PRIVILEGES ON DATABASE lions_audit TO lions_audit_user;
|
||||
|
||||
# Se connecter à la nouvelle base
|
||||
\c lions_audit
|
||||
|
||||
# Vérifier les privilèges
|
||||
\l
|
||||
```
|
||||
|
||||
### 3.2. Vérifier les Migrations Flyway
|
||||
|
||||
Les migrations Flyway seront exécutées automatiquement au démarrage du backend si :
|
||||
- `quarkus.flyway.migrate-at-start=true` (déjà configuré dans `application-prod.properties`)
|
||||
|
||||
**Vérification** :
|
||||
- Les fichiers de migration sont dans `lions-user-manager-server-impl-quarkus/src/main/resources/db/migration/`
|
||||
- Flyway créera automatiquement les tables nécessaires
|
||||
|
||||
### 3.3. Configuration de Connexion
|
||||
|
||||
**Variables d'environnement requises** :
|
||||
```bash
|
||||
DB_HOST=lions-db.lions.svc.cluster.local # Service Kubernetes
|
||||
DB_PORT=5432
|
||||
DB_NAME=lions_audit
|
||||
DB_USERNAME=lions_audit_user
|
||||
DB_PASSWORD=<strong-password>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Préparation des Secrets
|
||||
|
||||
### 4.1. Secrets Keycloak
|
||||
|
||||
#### Frontend Client Secret
|
||||
|
||||
**Où le trouver** :
|
||||
1. Keycloak Admin Console → **Clients** → `lions-user-manager-client`
|
||||
2. Onglet **Credentials**
|
||||
3. Copier le **Secret** (si client confidential)
|
||||
|
||||
**Si client public** : Pas de secret nécessaire
|
||||
|
||||
#### Backend Service Account Secret
|
||||
|
||||
**Où le trouver** :
|
||||
1. Keycloak Admin Console → **Clients** → `lions-user-manager`
|
||||
2. Onglet **Credentials**
|
||||
3. Copier le **Secret**
|
||||
|
||||
#### OIDC Encryption Secret
|
||||
|
||||
**Générer un secret de 32 caractères minimum** :
|
||||
```bash
|
||||
# Linux/Mac
|
||||
openssl rand -base64 32
|
||||
|
||||
# PowerShell
|
||||
-join ((48..57) + (65..90) + (97..122) | Get-Random -Count 32 | ForEach-Object {[char]$_})
|
||||
```
|
||||
|
||||
**Stockage** : À stocker dans Kubernetes Secret
|
||||
|
||||
### 4.2. Secrets Base de Données
|
||||
|
||||
**Générer un mot de passe fort** :
|
||||
```bash
|
||||
# Linux/Mac
|
||||
openssl rand -base64 24
|
||||
|
||||
# PowerShell
|
||||
-join ((48..57) + (65..90) + (97..122) | Get-Random -Count 24 | ForEach-Object {[char]$_})
|
||||
```
|
||||
|
||||
### 4.3. Créer les Kubernetes Secrets
|
||||
|
||||
**Namespace** : `lions-user-manager` (ou `applications`)
|
||||
|
||||
**Secret pour Frontend** :
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: lions-user-manager-client-secrets
|
||||
namespace: lions-user-manager
|
||||
type: Opaque
|
||||
stringData:
|
||||
KEYCLOAK_CLIENT_SECRET: <frontend-client-secret>
|
||||
OIDC_ENCRYPTION_SECRET: <32-char-encryption-secret>
|
||||
LIONS_USER_MANAGER_BACKEND_URL: https://api.lions.dev/lions-user-manager
|
||||
```
|
||||
|
||||
**Secret pour Backend** :
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: lions-user-manager-server-secrets
|
||||
namespace: lions-user-manager
|
||||
type: Opaque
|
||||
stringData:
|
||||
KEYCLOAK_CLIENT_SECRET: <backend-service-account-secret>
|
||||
KEYCLOAK_ADMIN_USERNAME: <keycloak-admin-username>
|
||||
KEYCLOAK_ADMIN_PASSWORD: <keycloak-admin-password>
|
||||
DB_PASSWORD: <database-password>
|
||||
SSL_KEYSTORE_PASSWORD: <ssl-keystore-password>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Vérification Pré-Déploiement
|
||||
|
||||
### 5.1. Vérifier Keycloak
|
||||
|
||||
```bash
|
||||
# Tester la connexion Keycloak
|
||||
curl -k https://security.lions.dev/realms/master/.well-known/openid-configuration
|
||||
|
||||
# Tester l'obtention d'un token (service account)
|
||||
curl -X POST https://security.lions.dev/realms/master/protocol/openid-connect/token \
|
||||
-d "client_id=lions-user-manager" \
|
||||
-d "client_secret=<secret>" \
|
||||
-d "grant_type=client_credentials"
|
||||
```
|
||||
|
||||
### 5.2. Vérifier la Base de Données
|
||||
|
||||
```bash
|
||||
# Tester la connexion PostgreSQL
|
||||
kubectl exec -it -n postgresql <postgres-pod-name> -- psql -U lions_audit_user -d lions_audit -c "SELECT version();"
|
||||
```
|
||||
|
||||
### 5.3. Vérifier les Secrets Kubernetes
|
||||
|
||||
```bash
|
||||
# Lister les secrets
|
||||
kubectl get secrets -n lions-user-manager
|
||||
|
||||
# Vérifier un secret (sans afficher les valeurs)
|
||||
kubectl describe secret lions-user-manager-client-secrets -n lions-user-manager
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Checklist Complète
|
||||
|
||||
### ✅ Configuration Keycloak
|
||||
|
||||
- [ ] Realm `master` accessible
|
||||
- [ ] Client frontend `lions-user-manager-client` créé
|
||||
- [ ] Client backend `lions-user-manager` créé avec service account
|
||||
- [ ] Secret frontend récupéré (si client confidential)
|
||||
- [ ] Secret backend (service account) récupéré
|
||||
- [ ] Rôles créés : `admin`, `user_manager`, `user_viewer`, `auditor`, `sync_manager`, `role_manager`, `role_viewer`
|
||||
- [ ] Rôles assignés au service account backend
|
||||
- [ ] Protocol mapper `roles` configuré pour inclure `realm_access.roles`
|
||||
- [ ] Utilisateur de test créé (optionnel)
|
||||
- [ ] Test de connexion Keycloak réussi
|
||||
|
||||
### ✅ Configuration Base de Données
|
||||
|
||||
- [ ] Base de données `lions_audit` créée
|
||||
- [ ] Utilisateur `lions_audit_user` créé
|
||||
- [ ] Privilèges accordés
|
||||
- [ ] Test de connexion réussi
|
||||
- [ ] Migrations Flyway prêtes (fichiers dans `db/migration/`)
|
||||
|
||||
### ✅ Secrets et Configuration
|
||||
|
||||
- [ ] Secret OIDC encryption généré (32+ caractères)
|
||||
- [ ] Secrets Kubernetes créés (frontend + backend)
|
||||
- [ ] Variables d'environnement documentées
|
||||
- [ ] ConfigMaps Kubernetes préparés (si nécessaire)
|
||||
|
||||
### ✅ Infrastructure
|
||||
|
||||
- [ ] Namespace Kubernetes créé
|
||||
- [ ] Ingress configuré (si exposition externe)
|
||||
- [ ] Certificats TLS/SSL préparés
|
||||
- [ ] Health checks configurés
|
||||
|
||||
### ✅ Tests
|
||||
|
||||
- [ ] Test Keycloak : Obtenir un token service account
|
||||
- [ ] Test Database : Connexion PostgreSQL
|
||||
- [ ] Test Secrets : Vérifier les secrets Kubernetes
|
||||
|
||||
---
|
||||
|
||||
## 7. Scripts de Configuration
|
||||
|
||||
### 7.1. Script Keycloak Production
|
||||
|
||||
**Fichier** : `scripts/setup-keycloak-production.ps1` ✅ **CRÉÉ**
|
||||
|
||||
Ce script :
|
||||
1. ✅ Se connecte à Keycloak production (`https://security.lions.dev`)
|
||||
2. ✅ Crée les clients OIDC (frontend + backend)
|
||||
3. ✅ Crée les rôles realm (admin, user_manager, user_viewer, auditor, sync_manager, role_manager, role_viewer)
|
||||
4. ✅ Vérifie le protocol mapper `roles`
|
||||
5. ✅ Assigne les rôles au service account backend
|
||||
6. ✅ Affiche les secrets récupérés
|
||||
|
||||
**Utilisation** :
|
||||
```powershell
|
||||
.\scripts\setup-keycloak-production.ps1 `
|
||||
-AdminUsername "admin" `
|
||||
-AdminPassword "your-admin-password"
|
||||
```
|
||||
|
||||
### 7.2. Script Base de Données Production
|
||||
|
||||
**Fichier** : `scripts/setup-database-production.ps1` ✅ **CRÉÉ**
|
||||
|
||||
Ce script :
|
||||
1. ✅ Se connecte au cluster Kubernetes via SSH
|
||||
2. ✅ Trouve le pod PostgreSQL
|
||||
3. ✅ Crée la base de données `lions_audit`
|
||||
4. ✅ Crée l'utilisateur `lions_audit_user`
|
||||
5. ✅ Octroie les privilèges
|
||||
6. ✅ Teste la connexion
|
||||
|
||||
**Utilisation** :
|
||||
```powershell
|
||||
.\scripts\setup-database-production.ps1 `
|
||||
-VpsHost "lions@176.57.150.2" `
|
||||
-DatabasePassword "strong-password-123"
|
||||
```
|
||||
|
||||
### 7.3. Script Création Secrets Kubernetes
|
||||
|
||||
**Fichier** : `scripts/create-kubernetes-secrets-production.ps1` ✅ **CRÉÉ**
|
||||
|
||||
Ce script :
|
||||
1. ✅ Crée le namespace si nécessaire
|
||||
2. ✅ Crée le secret frontend (KEYCLOAK_CLIENT_SECRET, OIDC_ENCRYPTION_SECRET, LIONS_USER_MANAGER_BACKEND_URL)
|
||||
3. ✅ Crée le secret backend (KEYCLOAK_CLIENT_SECRET, KEYCLOAK_ADMIN_PASSWORD, DB_PASSWORD)
|
||||
4. ✅ Vérifie la création des secrets
|
||||
|
||||
**Utilisation** :
|
||||
```powershell
|
||||
.\scripts\create-kubernetes-secrets-production.ps1 `
|
||||
-VpsHost "lions@176.57.150.2" `
|
||||
-FrontendClientSecret "<frontend-secret>" `
|
||||
-BackendClientSecret "<backend-secret>" `
|
||||
-OidcEncryptionSecret "<32-char-secret>" `
|
||||
-KeycloakAdminPassword "<admin-password>" `
|
||||
-DatabasePassword "<db-password>"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Ordre d'Exécution
|
||||
|
||||
**IMPORTANT** : Respecter cet ordre :
|
||||
|
||||
1. ✅ **Configuration Keycloak** (clients, rôles, secrets)
|
||||
2. ✅ **Configuration Base de Données** (création DB, utilisateur)
|
||||
3. ✅ **Création Secrets Kubernetes** (secrets, configmaps)
|
||||
4. ✅ **Vérification** (tests de connexion)
|
||||
5. ✅ **Déploiement** (via lionsctl ou kubectl)
|
||||
|
||||
---
|
||||
|
||||
## 9. Commandes de Déploiement (APRÈS Configuration)
|
||||
|
||||
Une fois toutes les configurations terminées :
|
||||
|
||||
**Server (Backend)** :
|
||||
```bash
|
||||
cd ../lions-infrastructure-2025/lionsctl
|
||||
./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/lions-user-manager-server-impl-quarkus -b main -j 17 -e production -c k2 -m gbanedahoud@gmail.com
|
||||
```
|
||||
|
||||
**Client (Frontend)** :
|
||||
```bash
|
||||
cd ../lions-infrastructure-2025/lionsctl
|
||||
./lionsctl.exe pipeline -u https://git.lions.dev/lionsdev/lions-user-manager-client-quarkus-primefaces-freya -b main -j 17 -e production -c k2 -m gbanedahoud@gmail.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Troubleshooting
|
||||
|
||||
### Erreur : "401 Unauthorized" lors du démarrage
|
||||
|
||||
**Cause** : Secret Keycloak incorrect ou client non configuré
|
||||
**Solution** : Vérifier les secrets dans Keycloak et Kubernetes
|
||||
|
||||
### Erreur : "Database connection failed"
|
||||
|
||||
**Cause** : Base de données non créée ou credentials incorrects
|
||||
**Solution** : Vérifier la création de la DB et les credentials
|
||||
|
||||
### Erreur : "Roles not found in token"
|
||||
|
||||
**Cause** : Protocol mapper non configuré
|
||||
**Solution** : Vérifier le mapper `roles` dans Keycloak
|
||||
|
||||
---
|
||||
|
||||
## ✅ Conclusion
|
||||
|
||||
**NE PAS DÉPLOYER** avant d'avoir complété toutes les étapes de ce guide.
|
||||
|
||||
**Ordre** :
|
||||
1. ⚠️ Configuration Keycloak (OBLIGATOIRE)
|
||||
2. ⚠️ Configuration Base de Données (OBLIGATOIRE)
|
||||
3. ⚠️ Création Secrets Kubernetes (OBLIGATOIRE)
|
||||
4. ✅ Vérification (OBLIGATOIRE)
|
||||
5. 🚀 Déploiement (après vérification)
|
||||
|
||||
---
|
||||
|
||||
**Document généré le** : 2025-01-15
|
||||
**Dernière mise à jour** : 2025-01-15
|
||||
|
||||
**Scripts créés** :
|
||||
- ✅ `scripts/setup-keycloak-production.ps1` : Configuration Keycloak
|
||||
- ✅ `scripts/setup-database-production.ps1` : Configuration PostgreSQL
|
||||
- ✅ `scripts/create-kubernetes-secrets-production.ps1` : Création secrets Kubernetes
|
||||
|
||||
**Prochaine étape** : Exécuter les scripts dans l'ordre indiqué ci-dessus
|
||||
|
||||
@@ -1,408 +0,0 @@
|
||||
# 📊 Rapport de Progrès - lions-user-manager
|
||||
|
||||
**Date**: 2025-01-09
|
||||
**Version**: 1.0.0
|
||||
**Statut Global**: 🟡 En cours (40% complété)
|
||||
|
||||
---
|
||||
|
||||
## 📦 Vue d'Ensemble du Projet
|
||||
|
||||
Le **lions-user-manager** est un module de gestion centralisée des utilisateurs Keycloak avec:
|
||||
- ✅ Architecture multi-modules Maven (3 modules)
|
||||
- ✅ Gestion via Keycloak Admin REST API uniquement (ZÉRO accès direct DB)
|
||||
- ✅ Multi-realm avec délégation de permissions
|
||||
- 🔄 Audit trail complet (en cours)
|
||||
- 🔄 Interface PrimeFaces Freya (à venir)
|
||||
- 🔄 Déploiement Kubernetes via Helm (à venir)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Module 1: **server-api** - COMPLÉTÉ (100%)
|
||||
|
||||
### 📁 Structure Créée (15 fichiers)
|
||||
|
||||
#### DTOs (7 fichiers)
|
||||
- [x] `BaseDTO.java` - Classe de base avec id, dates, audit
|
||||
- [x] `UserDTO.java` - DTO utilisateur complet (60+ champs)
|
||||
- [x] `UserSearchCriteriaDTO.java` - Critères de recherche avancés
|
||||
- [x] `UserSearchResultDTO.java` - Résultats paginés
|
||||
- [x] `RoleDTO.java` - DTO rôle avec composites
|
||||
- [x] `RoleAssignmentDTO.java` - Attribution/révocation de rôles
|
||||
- [x] `AuditLogDTO.java` - Logs d'audit détaillés
|
||||
|
||||
#### Enums (3 fichiers)
|
||||
- [x] `StatutUser.java` - 7 statuts (ACTIF, INACTIF, SUSPENDU, etc.)
|
||||
- [x] `TypeRole.java` - Types de rôles (REALM_ROLE, CLIENT_ROLE, COMPOSITE_ROLE)
|
||||
- [x] `TypeActionAudit.java` - 30+ types d'actions pour audit trail
|
||||
|
||||
#### Services Interfaces (4 fichiers)
|
||||
- [x] `UserService.java` - 25+ méthodes de gestion utilisateurs
|
||||
- CRUD complet
|
||||
- Recherche avancée
|
||||
- Activation/Désactivation
|
||||
- Réinitialisation mot de passe
|
||||
- Gestion sessions
|
||||
- Export/Import CSV
|
||||
|
||||
- [x] `RoleService.java` - 20+ méthodes de gestion rôles
|
||||
- CRUD Realm et Client roles
|
||||
- Attribution/Révocation
|
||||
- Rôles composites
|
||||
- Vérification permissions
|
||||
|
||||
- [x] `AuditService.java` - Méthodes audit logging
|
||||
- Log success/failure
|
||||
- Recherche par acteur, ressource, action
|
||||
- Statistiques et rapports
|
||||
- Export CSV
|
||||
- Purge logs anciens
|
||||
|
||||
- [x] `SyncService.java` - Synchronisation avec Keycloak
|
||||
- Sync users/roles par realm
|
||||
- Vérification cohérence
|
||||
- Health checks Keycloak
|
||||
|
||||
#### Validation
|
||||
- [x] `ValidationConstants.java` - Constantes centralisées
|
||||
|
||||
### 📊 Statut
|
||||
- ✅ **Compilation**: SUCCESS
|
||||
- ✅ **Installation Maven**: SUCCESS
|
||||
- ✅ **Couverture**: 100% des contrats définis
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Module 2: **server-impl-quarkus** - EN COURS (60%)
|
||||
|
||||
### 📁 Structure Créée (7 fichiers)
|
||||
|
||||
#### Configuration (3 fichiers)
|
||||
- [x] `application.properties` - Configuration de base
|
||||
- [x] `application-dev.properties` - Config développement
|
||||
- Keycloak local (localhost:8180)
|
||||
- Logging DEBUG
|
||||
- CORS permissif
|
||||
- Dev tools activés
|
||||
|
||||
- [x] `application-prod.properties` - Config production
|
||||
- Keycloak sécurisé (https://security.lions.dev)
|
||||
- Logging INFO
|
||||
- SSL/TLS requis
|
||||
- Audit DB obligatoire
|
||||
- Métriques Prometheus
|
||||
- GELF logging
|
||||
|
||||
#### Client Keycloak (2 fichiers)
|
||||
- [x] `KeycloakAdminClient.java` - Interface
|
||||
- [x] `KeycloakAdminClientImpl.java` - Implémentation
|
||||
- ✅ Circuit Breaker (@CircuitBreaker)
|
||||
- ✅ Retry mechanism (@Retry - 3 tentatives)
|
||||
- ✅ Timeout (30s)
|
||||
- ✅ Connection pooling
|
||||
- ✅ Auto-reconnect
|
||||
- ✅ Health checks
|
||||
|
||||
#### Mappers (1 fichier)
|
||||
- [x] `UserMapper.java` - Conversion UserRepresentation ↔ UserDTO
|
||||
- toDTO()
|
||||
- toRepresentation()
|
||||
- toDTOList()
|
||||
- Gestion attributs personnalisés
|
||||
|
||||
#### Services Implementation (1 fichier)
|
||||
- [x] `UserServiceImpl.java` - Implémentation complète UserService
|
||||
- ✅ 25+ méthodes implémentées
|
||||
- ✅ searchUsers() - Recherche avancée
|
||||
- ✅ getUserById/ByUsername/ByEmail()
|
||||
- ✅ createUser() - Avec validation username/email
|
||||
- ✅ updateUser()
|
||||
- ✅ deleteUser() - Hard/Soft delete
|
||||
- ✅ activateUser/deactivateUser/suspendUser()
|
||||
- ✅ resetPassword()
|
||||
- ✅ sendVerificationEmail()
|
||||
- ✅ logoutAllSessions()
|
||||
- ✅ getActiveSessions()
|
||||
- 🔄 exportUsersToCSV() - TODO
|
||||
- 🔄 importUsersFromCSV() - TODO
|
||||
|
||||
#### REST Resources (2 fichiers)
|
||||
- [x] `UserResource.java` - Endpoints REST pour users
|
||||
- POST /api/users/search - Recherche
|
||||
- GET /api/users/{userId} - Récupération
|
||||
- GET /api/users - Liste paginée
|
||||
- POST /api/users - Création
|
||||
- PUT /api/users/{userId} - Mise à jour
|
||||
- DELETE /api/users/{userId} - Suppression
|
||||
- POST /api/users/{userId}/activate - Activation
|
||||
- POST /api/users/{userId}/deactivate - Désactivation
|
||||
- POST /api/users/{userId}/reset-password - Reset password
|
||||
- POST /api/users/{userId}/send-verification-email - Vérif email
|
||||
- POST /api/users/{userId}/logout-sessions - Logout
|
||||
- GET /api/users/{userId}/sessions - Sessions actives
|
||||
- ✅ OpenAPI/Swagger documenté
|
||||
- ✅ @RolesAllowed (admin, user_manager, user_viewer)
|
||||
|
||||
- [x] `KeycloakHealthCheck.java` - Health check Keycloak
|
||||
- [x] `HealthResourceEndpoint.java` - Endpoints health
|
||||
- GET /api/health/keycloak
|
||||
- GET /api/health/status
|
||||
|
||||
### 📊 Statut
|
||||
- ✅ **Compilation**: SUCCESS
|
||||
- 🔄 **Packaging Quarkus**: EN COURS (build en background)
|
||||
- ⚠️ **Issues résolues**:
|
||||
- Conflict RESTEasy Classic vs Quarkus REST → Exclusions ajoutées
|
||||
- Lombok @Slf4j → Configuré
|
||||
- Fault Tolerance → Dépendance ajoutée
|
||||
|
||||
### 🚧 À Faire
|
||||
- [ ] `RoleServiceImpl.java`
|
||||
- [ ] `RoleMapper.java`
|
||||
- [ ] `RoleResource.java`
|
||||
- [ ] `AuditServiceImpl.java`
|
||||
- [ ] `AuditMapper.java`
|
||||
- [ ] `AuditResource.java`
|
||||
- [ ] `SyncServiceImpl.java`
|
||||
- [ ] `SyncResource.java`
|
||||
- [ ] Entity `AuditLog.java` (si DB activée)
|
||||
- [ ] Repository `AuditLogRepository.java`
|
||||
- [ ] Flyway migrations (V1__create_audit_tables.sql)
|
||||
- [ ] Tests unitaires
|
||||
- [ ] Tests d'intégration (Testcontainers)
|
||||
|
||||
---
|
||||
|
||||
## ⏳ Module 3: **client-quarkus-primefaces-freya** - À FAIRE (0%)
|
||||
|
||||
### 📋 Plan (50+ fichiers à créer)
|
||||
|
||||
#### Configuration
|
||||
- [ ] `pom.xml` - Dépendances
|
||||
- Quarkus PrimeFaces 3.13.3
|
||||
- PrimeFaces 14.0.5
|
||||
- **Freya Theme 5.0.0-jakarta** (depuis git.lions.dev/lionsdev/btpxpress-maven-repo)
|
||||
- Quarkus REST Client
|
||||
- Quarkus OIDC
|
||||
|
||||
- [ ] `application.properties`
|
||||
- [ ] `application-dev.properties`
|
||||
- [ ] `application-prod.properties`
|
||||
|
||||
#### REST Clients (4 fichiers)
|
||||
- [ ] `UserServiceClient.java` - @RegisterRestClient
|
||||
- [ ] `RoleServiceClient.java`
|
||||
- [ ] `AuditServiceClient.java`
|
||||
- [ ] `SyncServiceClient.java`
|
||||
|
||||
#### DTOs Client (versions simplifiées)
|
||||
- [ ] `UserDTO.java`
|
||||
- [ ] `RoleDTO.java`
|
||||
- [ ] `AuditLogDTO.java`
|
||||
|
||||
#### JSF Backing Beans (10+ fichiers)
|
||||
- [ ] `UserRechercheBean.java` - Recherche utilisateurs
|
||||
- [ ] `UserListeBean.java` - Liste paginée
|
||||
- [ ] `UserCreationBean.java` - Création
|
||||
- [ ] `UserProfilBean.java` - Détails/édition
|
||||
- [ ] `UserActionsBean.java` - Actions (activate/deactivate/etc)
|
||||
- [ ] `RoleGestionBean.java` - Gestion rôles
|
||||
- [ ] `RoleAttributionBean.java` - Attribution rôles
|
||||
- [ ] `AuditConsultationBean.java` - Consultation logs
|
||||
- [ ] `AuditStatsBean.java` - Statistiques
|
||||
- [ ] `SyncDashboardBean.java` - Synchronisation
|
||||
|
||||
#### Pages XHTML (15+ fichiers)
|
||||
Avec PrimeFaces Freya Theme
|
||||
|
||||
**Gestion Utilisateurs**:
|
||||
- [ ] `users-search.xhtml` - Recherche avancée
|
||||
- [ ] `users-list.xhtml` - Liste avec DataTable
|
||||
- [ ] `user-create.xhtml` - Formulaire création
|
||||
- [ ] `user-profile.xhtml` - Détails utilisateur
|
||||
- [ ] `user-edit.xhtml` - Édition
|
||||
- [ ] `user-password-reset.xhtml` - Reset password
|
||||
|
||||
**Gestion Rôles**:
|
||||
- [ ] `roles-list.xhtml` - Liste rôles
|
||||
- [ ] `role-create.xhtml` - Création rôle
|
||||
- [ ] `role-edit.xhtml` - Édition rôle
|
||||
- [ ] `role-assign.xhtml` - Attribution
|
||||
|
||||
**Audit**:
|
||||
- [ ] `audit-logs.xhtml` - Consultation logs
|
||||
- [ ] `audit-stats.xhtml` - Statistiques
|
||||
- [ ] `audit-dashboard.xhtml` - Dashboard
|
||||
|
||||
**Sync**:
|
||||
- [ ] `sync-dashboard.xhtml` - Synchronisation
|
||||
- [ ] `sync-status.xhtml` - Statut
|
||||
|
||||
**Layout**:
|
||||
- [ ] `layout.xhtml` - Template principal
|
||||
- [ ] `menu.xhtml` - Menu navigation
|
||||
- [ ] `topbar.xhtml` - Barre supérieure
|
||||
|
||||
#### Sécurité (3 fichiers)
|
||||
- [ ] `JwtTokenManager.java` - Gestion tokens
|
||||
- [ ] `AuthenticationFilter.java` - Filtre auth
|
||||
- [ ] `PermissionChecker.java` - Vérification permissions
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Infrastructure - À FAIRE (0%)
|
||||
|
||||
### Helm Charts
|
||||
- [ ] `Chart.yaml`
|
||||
- [ ] `values.yaml`
|
||||
- [ ] `values-dev.yaml`
|
||||
- [ ] `values-prod.yaml`
|
||||
- [ ] `templates/deployment-server.yaml`
|
||||
- [ ] `templates/deployment-client.yaml`
|
||||
- [ ] `templates/service-server.yaml`
|
||||
- [ ] `templates/service-client.yaml`
|
||||
- [ ] `templates/ingress.yaml`
|
||||
- [ ] `templates/configmap.yaml`
|
||||
- [ ] `templates/secret.yaml`
|
||||
- [ ] `templates/pvc.yaml` (pour logs)
|
||||
|
||||
### Scripts
|
||||
- [ ] `kcadm-provision.sh` - Provisionnement Keycloak
|
||||
- Création realm
|
||||
- Création clients
|
||||
- Création service account
|
||||
- Attribution permissions Admin API
|
||||
|
||||
- [ ] `rotate-secrets.sh` - Rotation secrets
|
||||
- [ ] `setup-keycloak-client.ps1` - Setup Windows
|
||||
- [ ] `deploy.sh` - Script déploiement
|
||||
|
||||
### Dockerfiles
|
||||
- [ ] `Dockerfile.server` - Image serveur
|
||||
- [ ] `Dockerfile.client` - Image client
|
||||
- [ ] `.dockerignore`
|
||||
|
||||
---
|
||||
|
||||
## 📚 Documentation - À FAIRE (0%)
|
||||
|
||||
- [ ] `docs/architecture.md` - Architecture détaillée
|
||||
- [ ] `docs/runbook.md` - Guide opérationnel
|
||||
- [ ] `docs/security-policy.md` - Politique sécurité
|
||||
- [ ] `docs/integration-guide.md` - Guide intégration
|
||||
- [ ] `docs/api-reference.md` - Référence API
|
||||
- [ ] `docs/troubleshooting.md` - Dépannage
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests - À FAIRE (0%)
|
||||
|
||||
### Tests Unitaires
|
||||
- [ ] `UserServiceImplTest.java`
|
||||
- [ ] `RoleServiceImplTest.java`
|
||||
- [ ] `AuditServiceImplTest.java`
|
||||
- [ ] `UserMapperTest.java`
|
||||
- [ ] `RoleMapperTest.java`
|
||||
|
||||
### Tests Intégration (avec Testcontainers)
|
||||
- [ ] `UserResourceIT.java`
|
||||
- [ ] `RoleResourceIT.java`
|
||||
- [ ] `AuditResourceIT.java`
|
||||
- [ ] `KeycloakAdminClientIT.java`
|
||||
|
||||
### Objectif Couverture
|
||||
- **Minimum**: 80% (Jacoco configuré)
|
||||
|
||||
---
|
||||
|
||||
## 📈 Métriques Globales
|
||||
|
||||
| Module | Fichiers Créés | Fichiers Restants | % Complété |
|
||||
|--------|----------------|-------------------|------------|
|
||||
| **server-api** | 15 | 0 | ✅ 100% |
|
||||
| **server-impl** | 7 | ~15 | 🔄 60% |
|
||||
| **client** | 0 | ~50 | ⏳ 0% |
|
||||
| **Infrastructure** | 0 | ~15 | ⏳ 0% |
|
||||
| **Documentation** | 1 | ~6 | ⏳ 14% |
|
||||
| **Tests** | 0 | ~10 | ⏳ 0% |
|
||||
| **TOTAL** | **23** | **~96** | **🟡 40%** |
|
||||
|
||||
---
|
||||
|
||||
## 🔑 Points Clés Techniques
|
||||
|
||||
### ✅ Réalisations
|
||||
1. **Architecture Solide**: Séparation claire API / Impl / Client
|
||||
2. **Résilience**: Circuit Breaker, Retry, Timeout sur Keycloak
|
||||
3. **Sécurité**: @RolesAllowed, OIDC, validation complète
|
||||
4. **Observabilité**: Health checks, métriques Prometheus
|
||||
5. **Configuration**: Profils dev/prod séparés
|
||||
6. **Compliance**: ZÉRO accès direct DB Keycloak (Admin API only)
|
||||
|
||||
### ⚠️ Challenges Résolus
|
||||
1. ✅ Conflict Quarkus REST vs RESTEasy Classic → Exclusions POM
|
||||
2. ✅ Lombok configuration → Annotation processors
|
||||
3. ✅ Classes publiques multiples → Fichiers séparés
|
||||
|
||||
### 🚧 Prochaines Étapes Prioritaires
|
||||
1. **Terminer RoleService & RoleResource** (backend complet)
|
||||
2. **Implémenter AuditService** (logging obligatoire)
|
||||
3. **Démarrer module client** (UI PrimeFaces Freya)
|
||||
4. **Tests d'intégration** (Testcontainers Keycloak)
|
||||
5. **Helm charts** (déploiement K8s)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Roadmap
|
||||
|
||||
### Phase 1: Backend Core (1-2 jours) - EN COURS
|
||||
- [x] Module server-api
|
||||
- [x] UserService complet
|
||||
- [x] UserResource REST
|
||||
- [ ] RoleService
|
||||
- [ ] RoleResource
|
||||
- [ ] AuditService
|
||||
- [ ] Tests unitaires
|
||||
|
||||
### Phase 2: Client UI (2-3 jours)
|
||||
- [ ] Configuration module client
|
||||
- [ ] REST Clients
|
||||
- [ ] Pages XHTML utilisateurs
|
||||
- [ ] Pages XHTML rôles
|
||||
- [ ] Layout Freya Theme
|
||||
|
||||
### Phase 3: Infrastructure (1 jour)
|
||||
- [ ] Helm charts
|
||||
- [ ] Dockerfiles
|
||||
- [ ] Scripts Keycloak
|
||||
- [ ] CI/CD pipeline
|
||||
|
||||
### Phase 4: Tests & Documentation (1 jour)
|
||||
- [ ] Tests intégration
|
||||
- [ ] Documentation complète
|
||||
- [ ] Guide déploiement
|
||||
|
||||
---
|
||||
|
||||
## 📞 Notes Importantes
|
||||
|
||||
### Configuration Freya Theme
|
||||
- Repository Maven custom: `git.lions.dev/lionsdev/btpxpress-maven-repo`
|
||||
- JAR: `org/primefaces/freya-theme/5.0.0-jakarta/freya-theme-5.0.0-jakarta.jar`
|
||||
- À configurer dans le POM du module client
|
||||
|
||||
### Keycloak Admin API
|
||||
- **Version**: 23.0.3
|
||||
- **Contrainte stricte**: Aucun accès direct à la base de données Keycloak
|
||||
- Toutes les opérations via REST API Admin uniquement
|
||||
|
||||
### Déploiement
|
||||
- **Dev**: Keycloak local (localhost:8180)
|
||||
- **Prod**: Keycloak cluster (https://security.lions.dev)
|
||||
- **Audit DB**: PostgreSQL (optionnel en dev, obligatoire en prod)
|
||||
|
||||
---
|
||||
|
||||
**Dernière mise à jour**: 2025-01-09 12:55 UTC
|
||||
**Auteur**: Claude Code
|
||||
**Version**: 1.0.0
|
||||
571
README.md
571
README.md
@@ -1,502 +1,181 @@
|
||||
# Lions User Manager
|
||||
|
||||
Module de gestion centralisée des utilisateurs via Keycloak Admin REST API.
|
||||
> Gestion centralisée des utilisateurs via Keycloak Admin API — Backend REST + Frontend JSF PrimeFaces Freya
|
||||
|
||||
## 🎯 Objectif
|
||||
|
||||
Fournir une gestion complète des utilisateurs Keycloak via une interface PrimeFaces Freya moderne et une API REST sécurisée, en respectant strictement les contraintes suivantes:
|
||||
|
||||
- ✅ **AUCUNE écriture directe dans la DB Keycloak** (utilisation exclusive de l'Admin REST API)
|
||||
- ✅ **Architecture multi-modules Maven** (API, Impl, Client)
|
||||
- ✅ **Authentification OIDC via Keycloak**
|
||||
- ✅ **Délégation multi-realm** (superadmin global, admin de realm)
|
||||
- ✅ **Audit complet** (qui, quoi, quand, IP, succès/échec)
|
||||
- ✅ **Tests avec Testcontainers** (80% minimum de couverture)
|
||||
- ✅ **Déploiement Kubernetes via Helm**
|
||||
|
||||
## 🏗️ Architecture
|
||||
## Architecture
|
||||
|
||||
```
|
||||
lions-user-manager/
|
||||
├── lions-user-manager-server-api # Contrats (DTOs, interfaces, enums)
|
||||
├── lions-user-manager-server-impl-quarkus # Implémentation (Resources, Services, Keycloak Client)
|
||||
└── lions-user-manager-client-quarkus-primefaces-freya # UI (PrimeFaces, Beans JSF, REST Clients)
|
||||
├── pom.xml # POM parent (multi-modules)
|
||||
├── lions-user-manager-server-api/ # Contrats API : DTOs, interfaces, enums
|
||||
├── lions-user-manager-server-impl-quarkus/ # Serveur REST Quarkus + Keycloak Admin
|
||||
├── lions-user-manager-client-quarkus-primefaces-freya/ # Client Web JSF + PrimeFaces Freya
|
||||
└── scripts/ # Scripts DevOps (Keycloak, DB, Git)
|
||||
```
|
||||
|
||||
### Modules
|
||||
## Stack Technique
|
||||
|
||||
#### 1. **server-api** (JAR)
|
||||
Contrats purs sans dépendances lourdes:
|
||||
- DTOs avec validation Bean
|
||||
- Interfaces de services
|
||||
- Enums métiers
|
||||
- Constantes de validation
|
||||
| Composant | Technologie | Version |
|
||||
|-----------|------------|---------|
|
||||
| Runtime | Java | 17 |
|
||||
| Framework | Quarkus | 3.15.1 |
|
||||
| UI Framework | PrimeFaces (Freya theme) | 14.0.5 |
|
||||
| Auth | Keycloak (OIDC + Admin API) | 26.0.4 |
|
||||
| Base de données | PostgreSQL + Hibernate ORM Panache | — |
|
||||
| Migration DB | Flyway | — |
|
||||
| Build | Maven | — |
|
||||
| Tests | JUnit 5, Mockito 5, Testcontainers, REST-Assured | — |
|
||||
|
||||
**Package**: `dev.lions.user.manager.server.api`
|
||||
## Modules
|
||||
|
||||
#### 2. **server-impl-quarkus** (JAR)
|
||||
Implémentation serveur Quarkus:
|
||||
- Resources REST JAX-RS (`/api/users`, `/api/roles`, `/api/audit`)
|
||||
- Services métier (implémentations des interfaces)
|
||||
- **KeycloakAdminClient** (interface + impl)
|
||||
- Configuration sécurité OIDC
|
||||
- Entités JPA pour audit local (optionnel)
|
||||
### `server-api`
|
||||
Contrats partagés entre serveur et client :
|
||||
- **DTOs** : `UserDTO`, `RoleDTO`, `AuditLogDTO`, `RealmAssignmentDTO`, etc.
|
||||
- **Interfaces Service** : `UserService`, `RoleService`, `AuditService`, `SyncService`, `RealmAuthorizationService`
|
||||
- **Enums** : `StatutUser`, `TypeRole`, `TypeActionAudit`
|
||||
- **Validations** : `ValidationConstants`
|
||||
|
||||
**Package**: `dev.lions.user.manager.server`
|
||||
### `server-impl-quarkus`
|
||||
API REST backend :
|
||||
- **Resources** : `UserResource`, `RoleResource`, `AuditResource`, `RealmAssignmentResource`, `SyncResource`, `RealmResource`
|
||||
- **Services** : Implémentations complètes avec gestion d'erreurs et audit
|
||||
- **Keycloak Admin Client** : Gestion des utilisateurs, rôles, realms via Keycloak Admin API
|
||||
- **Health & Metrics** : `/health`, `/metrics` (Prometheus), `/q/swagger-ui`
|
||||
- **Audit** : Traçabilité des actions sur table PostgreSQL
|
||||
|
||||
#### 3. **client-quarkus-primefaces-freya** (JAR)
|
||||
Client web PrimeFaces Freya:
|
||||
- Services REST Client (MicroProfile Rest Client)
|
||||
- Beans JSF (@Named, @SessionScoped/@RequestScoped)
|
||||
- Pages XHTML PrimeFaces
|
||||
- Filtres de sécurité
|
||||
- Converters & Validators JSF
|
||||
### `client-quarkus-primefaces-freya`
|
||||
Interface web admin :
|
||||
- **Pages** : Dashboard, Gestion Utilisateurs (CRUD), Rôles, Audit, Synchronisation, Realm Assignment
|
||||
- **Beans JSF** : `DashboardBean`, `UserListBean`, `UserCreationBean`, `UserProfilBean`, `RoleGestionBean`, `AuditConsultationBean`, etc.
|
||||
- **REST Clients** : Communication type-safe avec le serveur via MicroProfile REST Client
|
||||
- **Thème** : PrimeFaces Freya (enterprise dark/light)
|
||||
|
||||
**Package**: `dev.lions.user.manager.client`
|
||||
## Prérequis
|
||||
|
||||
## 🚀 Stack Technique
|
||||
- **Java 17+**
|
||||
- **Maven 3.9+**
|
||||
- **Docker Desktop** (pour Keycloak et PostgreSQL)
|
||||
- **Keycloak** accessible sur `localhost:8180`
|
||||
- **PostgreSQL** accessible sur `localhost:5432`
|
||||
|
||||
| Technologie | Version |
|
||||
|------------|---------|
|
||||
| Java | 17+ |
|
||||
| Quarkus | 3.15.1 |
|
||||
| PrimeFaces | 14.0.5 |
|
||||
| Quarkus PrimeFaces | 3.13.3 |
|
||||
| Keycloak Admin Client | 23.0.3 |
|
||||
| PostgreSQL (optionnel) | 15+ |
|
||||
| Lombok | 1.18.30 |
|
||||
| MapStruct | 1.5.5.Final |
|
||||
| Testcontainers | 1.19.3 |
|
||||
## Démarrage Rapide
|
||||
|
||||
## 📂 Structure du Projet
|
||||
|
||||
### Module server-api
|
||||
|
||||
```
|
||||
lions-user-manager-server-api/
|
||||
└── src/main/java/dev/lions/user/manager/server/api/
|
||||
├── dto/
|
||||
│ ├── base/
|
||||
│ │ └── BaseDTO.java # DTO de base avec UUID id
|
||||
│ ├── user/
|
||||
│ │ ├── UserDTO.java # DTO utilisateur complet
|
||||
│ │ ├── UserSearchCriteria.java # Critères de recherche
|
||||
│ │ └── UserSearchResultDTO.java # Résultat de recherche paginé
|
||||
│ ├── role/
|
||||
│ │ ├── RoleDTO.java # DTO rôle
|
||||
│ │ └── RoleAssignmentDTO.java # Assignation rôle → utilisateur
|
||||
│ └── audit/
|
||||
│ └── AuditLogDTO.java # Log d'audit
|
||||
├── enums/
|
||||
│ ├── user/
|
||||
│ │ └── StatutUser.java # ACTIF, INACTIF, SUSPENDU, etc.
|
||||
│ └── role/
|
||||
│ └── TypeRole.java # REALM_ROLE, CLIENT_ROLE
|
||||
├── service/
|
||||
│ ├── UserService.java # Interface CRUD utilisateurs
|
||||
│ ├── RoleService.java # Interface gestion rôles
|
||||
│ ├── AuditService.java # Interface consultation audit
|
||||
│ └── SyncService.java # Interface synchronisation
|
||||
└── validation/
|
||||
└── ValidationConstants.java # Constantes de validation
|
||||
```
|
||||
|
||||
### Module server-impl-quarkus
|
||||
|
||||
```
|
||||
lions-user-manager-server-impl-quarkus/
|
||||
└── src/main/java/dev/lions/user/manager/server/
|
||||
├── resource/
|
||||
│ ├── UserResource.java # GET/POST/PUT/DELETE /api/users
|
||||
│ ├── RoleResource.java # GET/POST/DELETE /api/roles
|
||||
│ ├── AuditResource.java # GET /api/audit
|
||||
│ └── HealthResource.java # /health/ready, /health/live
|
||||
├── service/
|
||||
│ ├── UserServiceImpl.java # Impl UserService
|
||||
│ ├── RoleServiceImpl.java # Impl RoleService
|
||||
│ ├── AuditServiceImpl.java # Impl AuditService
|
||||
│ └── SyncServiceImpl.java # Impl SyncService
|
||||
├── client/
|
||||
│ ├── KeycloakAdminClient.java # Interface centralisée Keycloak Admin API
|
||||
│ └── KeycloakAdminClientImpl.java # Implémentation avec retry/circuit breaker
|
||||
├── security/
|
||||
│ ├── KeycloakService.java # Gestion tokens service account
|
||||
│ └── SecurityConfig.java # Configuration sécurité Quarkus
|
||||
├── entity/ # Optionnel: audit local
|
||||
│ └── AuditLog.java # Entité JPA audit
|
||||
└── repository/ # Optionnel: audit local
|
||||
└── AuditLogRepository.java # Repository Panache
|
||||
```
|
||||
|
||||
### Module client-quarkus-primefaces-freya
|
||||
|
||||
```
|
||||
lions-user-manager-client-quarkus-primefaces-freya/
|
||||
└── src/main/
|
||||
├── java/dev/lions/user/manager/client/
|
||||
│ ├── service/
|
||||
│ │ ├── UserService.java # REST Client (@RegisterRestClient)
|
||||
│ │ ├── RoleService.java # REST Client
|
||||
│ │ └── AuditService.java # REST Client
|
||||
│ ├── dto/
|
||||
│ │ ├── UserDTO.java # DTO client simplifié
|
||||
│ │ ├── RoleDTO.java # DTO rôle client
|
||||
│ │ └── AuditLogDTO.java # DTO audit client
|
||||
│ ├── view/
|
||||
│ │ ├── UserRechercheBean.java # Bean recherche utilisateurs
|
||||
│ │ ├── UserListeBean.java # Bean liste utilisateurs
|
||||
│ │ ├── UserProfilBean.java # Bean profil utilisateur
|
||||
│ │ ├── RoleGestionBean.java # Bean gestion rôles
|
||||
│ │ └── AuditConsultationBean.java # Bean consultation audit
|
||||
│ └── security/
|
||||
│ ├── JwtTokenManager.java # Gestion tokens JWT
|
||||
│ ├── AuthenticationFilter.java # Filtre authentification
|
||||
│ └── PermissionChecker.java # Vérification permissions
|
||||
└── resources/
|
||||
├── application.properties # Configuration client
|
||||
└── META-INF/resources/pages/
|
||||
├── users-search.xhtml # Page recherche utilisateurs
|
||||
├── users-list.xhtml # Page liste utilisateurs
|
||||
├── user-profile.xhtml # Page profil utilisateur
|
||||
├── roles-management.xhtml # Page gestion rôles
|
||||
└── audit-logs.xhtml # Page consultation audit
|
||||
```
|
||||
|
||||
## ⚙️ Configuration
|
||||
|
||||
### application.properties (server-impl)
|
||||
|
||||
```properties
|
||||
# Application
|
||||
quarkus.application.name=Lions User Manager Server
|
||||
quarkus.application.version=1.0.0
|
||||
|
||||
# HTTP
|
||||
quarkus.http.port=8080
|
||||
quarkus.http.host=0.0.0.0
|
||||
|
||||
# CORS
|
||||
quarkus.http.cors=true
|
||||
quarkus.http.cors.origins=http://localhost:8081
|
||||
quarkus.http.cors.methods=GET,POST,PUT,DELETE,OPTIONS
|
||||
|
||||
# OIDC
|
||||
quarkus.oidc.auth-server-url=https://security.lions.dev/realms/btpxpress
|
||||
quarkus.oidc.client-id=lions-user-manager-server
|
||||
quarkus.oidc.credentials.secret=${OIDC_CLIENT_SECRET}
|
||||
quarkus.oidc.application-type=service
|
||||
|
||||
# Keycloak Admin Client
|
||||
lions.user.manager.keycloak.server-url=${KEYCLOAK_SERVER_URL:http://localhost:8180}
|
||||
lions.user.manager.keycloak.realm=${KEYCLOAK_REALM:master}
|
||||
lions.user.manager.keycloak.client-id=${KEYCLOAK_CLIENT_ID:lions-user-manager}
|
||||
lions.user.manager.keycloak.client-secret=${KEYCLOAK_CLIENT_SECRET}
|
||||
lions.user.manager.keycloak.connection-timeout=5000
|
||||
lions.user.manager.keycloak.read-timeout=30000
|
||||
|
||||
# Feature Toggles
|
||||
lions.user.manager.keycloak.write.enabled=true
|
||||
|
||||
# Database (optionnel pour audit)
|
||||
%prod.quarkus.datasource.db-kind=postgresql
|
||||
%prod.quarkus.datasource.jdbc.url=${DATABASE_URL}
|
||||
%prod.quarkus.datasource.username=${DATABASE_USER}
|
||||
%prod.quarkus.datasource.password=${DATABASE_PASSWORD}
|
||||
%prod.quarkus.hibernate-orm.database.generation=none
|
||||
%prod.quarkus.flyway.migrate-at-start=true
|
||||
|
||||
# OpenAPI
|
||||
quarkus.smallrye-openapi.path=/q/openapi
|
||||
quarkus.swagger-ui.always-include=true
|
||||
quarkus.swagger-ui.path=/q/swagger-ui
|
||||
|
||||
# Health
|
||||
quarkus.smallrye-health.root-path=/health
|
||||
|
||||
# Metrics
|
||||
quarkus.micrometer.export.prometheus.enabled=true
|
||||
quarkus.micrometer.export.prometheus.path=/metrics
|
||||
|
||||
# Logging
|
||||
quarkus.log.level=INFO
|
||||
quarkus.log.category."dev.lions.user.manager".level=DEBUG
|
||||
```
|
||||
|
||||
### application.properties (client)
|
||||
|
||||
```properties
|
||||
# Application
|
||||
quarkus.application.name=Lions User Manager Client
|
||||
quarkus.application.version=1.0.0
|
||||
|
||||
# HTTP
|
||||
quarkus.http.port=8081
|
||||
quarkus.http.host=0.0.0.0
|
||||
|
||||
# OIDC
|
||||
quarkus.oidc.auth-server-url=https://security.lions.dev/realms/btpxpress
|
||||
quarkus.oidc.client-id=lions-user-manager-client
|
||||
quarkus.oidc.credentials.secret=${OIDC_CLIENT_SECRET}
|
||||
quarkus.oidc.application-type=web-app
|
||||
quarkus.oidc.authentication.redirect-path=/
|
||||
quarkus.oidc.authentication.restore-path-after-redirect=true
|
||||
|
||||
# PrimeFaces
|
||||
primefaces.THEME=freya
|
||||
primefaces.FONT_AWESOME=true
|
||||
primefaces.CLIENT_SIDE_VALIDATION=true
|
||||
|
||||
# REST Client
|
||||
lions.user.manager.backend.url=${BACKEND_URL:http://localhost:8080}
|
||||
quarkus.rest-client."lions-user-manager-api".url=${lions.user.manager.backend.url}
|
||||
quarkus.rest-client."lions-user-manager-api".scope=jakarta.inject.Singleton
|
||||
quarkus.rest-client."lions-user-manager-api".connect-timeout=5000
|
||||
quarkus.rest-client."lions-user-manager-api".read-timeout=30000
|
||||
|
||||
# Logging
|
||||
quarkus.log.level=INFO
|
||||
quarkus.log.category."dev.lions.user.manager.client".level=DEBUG
|
||||
```
|
||||
|
||||
## 🔑 Provisioning Keycloak
|
||||
|
||||
### Script de création du client service account
|
||||
|
||||
Voir `scripts/kcadm-provision.sh`:
|
||||
### 1. Démarrer l'infrastructure
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Keycloak
|
||||
docker run -d --name keycloak -p 8180:8080 \
|
||||
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
|
||||
-e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
|
||||
quay.io/keycloak/keycloak:26.0.4 start-dev
|
||||
|
||||
# Configuration
|
||||
KEYCLOAK_URL="${KEYCLOAK_URL:-http://localhost:8180}"
|
||||
ADMIN_USER="${ADMIN_USER:-admin}"
|
||||
ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin}"
|
||||
REALM="${REALM:-master}"
|
||||
CLIENT_ID="lions-user-manager"
|
||||
|
||||
# Login admin
|
||||
kcadm.sh config credentials --server "$KEYCLOAK_URL" \\
|
||||
--realm master --user "$ADMIN_USER" --password "$ADMIN_PASSWORD"
|
||||
|
||||
# Créer le client service account
|
||||
kcadm.sh create clients -r "$REALM" -f - <<EOF
|
||||
{
|
||||
"clientId": "$CLIENT_ID",
|
||||
"enabled": true,
|
||||
"serviceAccountsEnabled": true,
|
||||
"standardFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"publicClient": false,
|
||||
"protocol": "openid-connect"
|
||||
}
|
||||
EOF
|
||||
|
||||
# Récupérer le client UUID
|
||||
CLIENT_UUID=$(kcadm.sh get clients -r "$REALM" --fields id,clientId | \\
|
||||
jq -r ".[] | select(.clientId==\"$CLIENT_ID\") | .id")
|
||||
|
||||
# Assigner les rôles admin realm
|
||||
kcadm.sh add-roles -r "$REALM" --uusername "service-account-$CLIENT_ID" \\
|
||||
--rolename admin
|
||||
|
||||
# Récupérer le client secret
|
||||
kcadm.sh get "clients/$CLIENT_UUID/client-secret" -r "$REALM"
|
||||
# PostgreSQL
|
||||
docker run -d --name postgres -p 5432:5432 \
|
||||
-e POSTGRES_USER=skyfile \
|
||||
-e POSTGRES_PASSWORD=skyfile \
|
||||
-e POSTGRES_DB=lions_user_manager_dev \
|
||||
postgres:16
|
||||
```
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
### Tests unitaires
|
||||
### 2. Configurer Keycloak
|
||||
|
||||
```bash
|
||||
mvn clean test
|
||||
# Utiliser les scripts dans scripts/
|
||||
pwsh scripts/setup-keycloak-client.ps1
|
||||
```
|
||||
|
||||
### Tests d'intégration (avec Testcontainers)
|
||||
### 3. Compiler le projet
|
||||
|
||||
```bash
|
||||
mvn clean verify
|
||||
mvn clean install -DskipTests
|
||||
```
|
||||
|
||||
### Couverture de code (minimum 80%)
|
||||
|
||||
```bash
|
||||
mvn clean test jacoco:report
|
||||
# Rapport: target/site/jacoco/index.html
|
||||
```
|
||||
|
||||
## 📦 Build & Run
|
||||
|
||||
### Build complet
|
||||
|
||||
```bash
|
||||
mvn clean install
|
||||
```
|
||||
|
||||
### Run server
|
||||
### 4. Lancer le serveur (port 8081)
|
||||
|
||||
```bash
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev
|
||||
mvn quarkus:dev -Dquarkus.profile=dev
|
||||
```
|
||||
|
||||
Accès:
|
||||
- API: http://localhost:8080
|
||||
- OpenAPI: http://localhost:8080/q/swagger-ui
|
||||
- Health: http://localhost:8080/health
|
||||
- Metrics: http://localhost:8080/metrics
|
||||
|
||||
### Run client
|
||||
### 5. Lancer le client (port 8082)
|
||||
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
mvn quarkus:dev -Dquarkus.profile=dev
|
||||
```
|
||||
|
||||
Accès:
|
||||
- UI: http://localhost:8081
|
||||
## Ports
|
||||
|
||||
## 🐳 Docker
|
||||
| Service | Port | URL |
|
||||
|---------|------|-----|
|
||||
| Keycloak | 8180 | http://localhost:8180 |
|
||||
| Serveur API | 8081 | http://localhost:8081 |
|
||||
| Client Web | 8082 | http://localhost:8082 |
|
||||
| Swagger UI | 8081 | http://localhost:8081/q/swagger-ui |
|
||||
| PostgreSQL | 5432 | — |
|
||||
|
||||
### Build images
|
||||
## Configuration
|
||||
|
||||
Chaque module utilise 3 fichiers de configuration Quarkus :
|
||||
|
||||
| Fichier | Rôle |
|
||||
|---------|------|
|
||||
| `application.properties` | Propriétés communes (tous environnements) |
|
||||
| `application-dev.properties` | Surcharges développement (ports, logging verbeux, Keycloak local) |
|
||||
| `application-prod.properties` | Surcharges production (env vars, TLS, logging minimal) |
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
# Server
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn clean package -Dquarkus.package.type=uber-jar
|
||||
docker build -t lions-user-manager-server:1.0.0 .
|
||||
# Tests unitaires seuls
|
||||
mvn test
|
||||
|
||||
# Client
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean package -Dquarkus.package.type=uber-jar
|
||||
docker build -t lions-user-manager-client:1.0.0 .
|
||||
# Tests d'intégration
|
||||
mvn verify
|
||||
|
||||
# Avec couverture JaCoCo
|
||||
mvn verify -Pjacoco
|
||||
```
|
||||
|
||||
## ☸️ Déploiement Kubernetes (Helm)
|
||||
## Production
|
||||
|
||||
### Variables d'environnement requises
|
||||
|
||||
```bash
|
||||
helm install lions-user-manager ./helm \\
|
||||
--set server.image.tag=1.0.0 \\
|
||||
--set client.image.tag=1.0.0 \\
|
||||
--set keycloak.url=https://security.lions.dev \\
|
||||
--set keycloak.clientSecret=$KEYCLOAK_CLIENT_SECRET
|
||||
# Keycloak
|
||||
KEYCLOAK_AUTH_SERVER_URL=https://security.lions.dev/realms/lions-user-manager
|
||||
KEYCLOAK_SERVER_URL=https://security.lions.dev
|
||||
KEYCLOAK_ADMIN_USERNAME=admin
|
||||
KEYCLOAK_ADMIN_PASSWORD=<secret>
|
||||
KEYCLOAK_CLIENT_ID=lions-user-manager-client
|
||||
|
||||
# Base de données
|
||||
DB_HOST=<host>
|
||||
DB_PORT=5432
|
||||
DB_NAME=lions_user_manager
|
||||
DB_USERNAME=<user>
|
||||
DB_PASSWORD=<secret>
|
||||
|
||||
# Sécurité
|
||||
OIDC_ENCRYPTION_SECRET=<32-char-secret>
|
||||
CORS_ORIGINS=https://users.lions.dev
|
||||
|
||||
# Backend URL (pour le client)
|
||||
LIONS_USER_MANAGER_BACKEND_URL=https://api.users.lions.dev
|
||||
```
|
||||
|
||||
## 📊 Métriques & Observabilité
|
||||
### Docker
|
||||
|
||||
### Métriques disponibles (Prometheus format)
|
||||
Chaque module déployable contient un `Dockerfile.prod` :
|
||||
|
||||
- `http_server_requests_total`: Nombre de requêtes HTTP
|
||||
- `keycloak_admin_api_calls_total`: Nombre d'appels Admin API
|
||||
- `keycloak_admin_api_errors_total`: Nombre d'erreurs Admin API
|
||||
- `keycloak_admin_api_duration_seconds`: Latence des appels Admin API
|
||||
```bash
|
||||
# Build natif
|
||||
mvn package -Pnative -DskipTests
|
||||
|
||||
### Health checks
|
||||
# Build Docker
|
||||
docker build -f Dockerfile.prod -t lions-user-manager-server:1.0.0 .
|
||||
```
|
||||
|
||||
- `/health/ready`: Readiness probe
|
||||
- `/health/live`: Liveness probe
|
||||
## Licence
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
Voir dossier `docs/`:
|
||||
- `architecture.md`: Architecture détaillée
|
||||
- `runbook.md`: Guide opérationnel
|
||||
- `security-policy.md`: Politique de sécurité
|
||||
- `integration-guide.md`: Guide d'intégration
|
||||
|
||||
## 🔐 Sécurité
|
||||
|
||||
### Contraintes strictes
|
||||
|
||||
1. **AUCUNE écriture directe dans la DB Keycloak**
|
||||
- Toutes les opérations passent par l'Admin REST API
|
||||
- Les accès DB en lecture sont documentés et désactivables
|
||||
|
||||
2. **Authentification OIDC**
|
||||
- Server: Service account (client credentials)
|
||||
- Client: Authorization code flow
|
||||
|
||||
3. **Délégation multi-realm**
|
||||
- Superadmin global: accès tous realms
|
||||
- Admin de realm: limité à son realm
|
||||
|
||||
4. **Audit complet**
|
||||
- Toutes les actions sensibles sont loggées
|
||||
- Format: qui, quoi, quand, IP, succès/échec
|
||||
|
||||
## 🚧 Statut du Projet
|
||||
|
||||
### ✅ Créé
|
||||
- [x] Structure des répertoires
|
||||
- [x] POMs (parent + 3 modules)
|
||||
- [x] Configuration de base
|
||||
- [x] Documentation README
|
||||
|
||||
### 🔄 À Créer
|
||||
|
||||
#### Module server-api
|
||||
- [ ] BaseDTO.java
|
||||
- [ ] UserDTO.java, UserSearchCriteria.java, UserSearchResultDTO.java
|
||||
- [ ] RoleDTO.java, RoleAssignmentDTO.java
|
||||
- [ ] AuditLogDTO.java
|
||||
- [ ] Enums (StatutUser, TypeRole)
|
||||
- [ ] Interfaces de services (UserService, RoleService, AuditService, SyncService)
|
||||
- [ ] ValidationConstants.java
|
||||
|
||||
#### Module server-impl-quarkus
|
||||
- [ ] UserResource.java, RoleResource.java, AuditResource.java, HealthResource.java
|
||||
- [ ] UserServiceImpl.java, RoleServiceImpl.java, AuditServiceImpl.java, SyncServiceImpl.java
|
||||
- [ ] KeycloakAdminClient.java (interface + impl)
|
||||
- [ ] KeycloakService.java, SecurityConfig.java
|
||||
- [ ] Entité AuditLog.java (optionnel)
|
||||
- [ ] Repository AuditLogRepository.java (optionnel)
|
||||
- [ ] application.properties (dev + prod)
|
||||
- [ ] Migration Flyway (optionnel)
|
||||
|
||||
#### Module client-quarkus-primefaces-freya
|
||||
- [ ] REST Clients (UserService, RoleService, AuditService)
|
||||
- [ ] DTOs client
|
||||
- [ ] Beans JSF (UserRechercheBean, UserListeBean, UserProfilBean, RoleGestionBean, AuditConsultationBean)
|
||||
- [ ] Filtres de sécurité (JwtTokenManager, AuthenticationFilter, PermissionChecker)
|
||||
- [ ] Pages XHTML (users-search.xhtml, users-list.xhtml, user-profile.xhtml, roles-management.xhtml, audit-logs.xhtml)
|
||||
- [ ] application.properties
|
||||
|
||||
#### Infrastructure
|
||||
- [ ] Helm charts (Chart.yaml, values.yaml, templates/)
|
||||
- [ ] Scripts Keycloak (kcadm-provision.sh, rotate-secrets.sh)
|
||||
- [ ] Dockerfiles (server + client)
|
||||
|
||||
#### Tests
|
||||
- [ ] Tests unitaires (UserServiceImplTest, KeycloakAdminClientTest)
|
||||
- [ ] Tests d'intégration (UserResourceIT, RoleResourceIT avec Testcontainers)
|
||||
|
||||
#### Documentation
|
||||
- [ ] docs/architecture.md
|
||||
- [ ] docs/runbook.md
|
||||
- [ ] docs/security-policy.md
|
||||
- [ ] docs/integration-guide.md
|
||||
|
||||
## 📖 Prochaines Étapes
|
||||
|
||||
Pour générer le projet complet, poursuivez dans cet ordre:
|
||||
|
||||
1. **Créer les DTOs et enums du module server-api**
|
||||
2. **Créer les interfaces de services du module server-api**
|
||||
3. **Créer les Resources REST du module server-impl**
|
||||
4. **Créer les Services impl du module server-impl**
|
||||
5. **Créer le KeycloakAdminClient (interface + impl)**
|
||||
6. **Créer les REST Clients du module client**
|
||||
7. **Créer les Beans JSF du module client**
|
||||
8. **Créer les pages XHTML du module client**
|
||||
9. **Créer les tests (unitaires + intégration)**
|
||||
10. **Créer les Helm charts et scripts**
|
||||
|
||||
## 📞 Support
|
||||
|
||||
Pour toute question ou problème, consultez:
|
||||
- Documentation: `docs/`
|
||||
- Issues GitHub: [lien à définir]
|
||||
- Email: support@lions.dev
|
||||
|
||||
---
|
||||
|
||||
**Projet généré avec Claude Code**
|
||||
Propriétaire — Lions Dev Team © 2025
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
# Guide de démarrage - Lions User Manager
|
||||
|
||||
## 🚀 Configuration Keycloak effectuée
|
||||
|
||||
La configuration Keycloak a été effectuée avec succès ! Voici ce qui a été configuré :
|
||||
|
||||
### ✅ Realm dédié
|
||||
- **Nom du realm** : `lions-user-manager`
|
||||
- ✅ Architecture correcte : realm séparé pour l'application (pas `master`)
|
||||
|
||||
### ✅ Client configuré
|
||||
- **Client Frontend** : `lions-user-manager-client`
|
||||
- Secret : `client-secret-lions-2025`
|
||||
- Type : Confidential (Authorization Code Flow + Direct Access)
|
||||
- Redirect URIs : `http://localhost:8080/*`, `http://localhost:8081/*`
|
||||
|
||||
- **Backend** : Pas de client séparé ✅
|
||||
- Utilise directement l'Admin API avec les credentials `admin/admin`
|
||||
- Architecture correcte : pas besoin de service account pour ce cas d'usage
|
||||
|
||||
### ✅ Utilisateur de test
|
||||
- **Username** : `testuser`
|
||||
- **Password** : `test123`
|
||||
- **Email** : test@lions.dev
|
||||
- **Rôles** : `admin`, `user_manager`
|
||||
|
||||
### ✅ Rôles créés
|
||||
- `admin` - Accès complet
|
||||
- `user_manager` - Gestion utilisateurs
|
||||
- `user_viewer` - Lecture seule
|
||||
- `auditor` - Consultation logs
|
||||
- `sync_manager` - Synchronisation
|
||||
|
||||
## 📦 Démarrage de l'application
|
||||
|
||||
### 1. Vérifier que Keycloak tourne
|
||||
|
||||
```bash
|
||||
curl http://localhost:8180/realms/lions-user-manager/.well-known/openid-configuration
|
||||
```
|
||||
|
||||
Si Keycloak ne tourne pas, le démarrer :
|
||||
```bash
|
||||
# Exemple avec Docker
|
||||
docker run -p 8180:8080 \
|
||||
-e KEYCLOAK_ADMIN=admin \
|
||||
-e KEYCLOAK_ADMIN_PASSWORD=admin \
|
||||
quay.io/keycloak/keycloak:latest start-dev
|
||||
```
|
||||
|
||||
### 2. Démarrer le Backend (port 8081)
|
||||
|
||||
```bash
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
**Note** : Le backend utilise directement l'Admin API de Keycloak avec `admin/admin`. OIDC est désactivé car pas nécessaire.
|
||||
|
||||
**Vérification** :
|
||||
```bash
|
||||
# Test de l'API (doit renvoyer une liste vide ou des utilisateurs)
|
||||
curl "http://localhost:8081/api/users?realm=lions-user-manager"
|
||||
```
|
||||
|
||||
### 3. Démarrer le Frontend (port 8080)
|
||||
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
**Configuration OIDC active** pour le frontend (fichier `application-dev.properties`) :
|
||||
```properties
|
||||
quarkus.oidc.auth-server-url=http://localhost:8180/realms/lions-user-manager
|
||||
quarkus.oidc.client-id=lions-user-manager-client
|
||||
quarkus.oidc.credentials.secret=client-secret-lions-2025
|
||||
quarkus.oidc.application-type=web-app
|
||||
```
|
||||
|
||||
### 4. Accéder à l'application
|
||||
|
||||
#### Frontend Web
|
||||
1. Ouvrir : http://localhost:8080
|
||||
2. Vous serez redirigé vers Keycloak pour l'authentification
|
||||
3. Se connecter avec : **testuser** / **test123**
|
||||
4. Vous serez redirigé vers l'application
|
||||
|
||||
#### Backend API
|
||||
- Swagger UI : http://localhost:8081/q/swagger-ui
|
||||
- Health Check : http://localhost:8081/q/health
|
||||
- Metrics : http://localhost:8081/q/metrics
|
||||
|
||||
## 🔧 Résolution des problèmes
|
||||
|
||||
### Problème : "Forbidden" sur http://localhost:8081
|
||||
|
||||
**C'est normal !** Le backend ne sert pas de pages web directement. Utilisez plutôt :
|
||||
- Les endpoints API : http://localhost:8081/api/users?realm=lions-user-manager
|
||||
- Le Swagger UI : http://localhost:8081/q/swagger-ui
|
||||
|
||||
### Problème : "Client not found" sur le frontend
|
||||
|
||||
**Solution** : Relancer le script de configuration :
|
||||
```bash
|
||||
bash setup-keycloak-correct.sh
|
||||
```
|
||||
|
||||
### Problème : Impossible de se connecter avec testuser
|
||||
|
||||
**Vérifications** :
|
||||
1. Vérifier que l'utilisateur existe dans le bon realm :
|
||||
- Admin Console : http://localhost:8180/admin
|
||||
- Realm : `lions-user-manager` (pas `master` !)
|
||||
- Users → testuser
|
||||
|
||||
2. Vérifier le mot de passe : `test123`
|
||||
|
||||
3. Vérifier que le compte est activé (Enabled: ON)
|
||||
|
||||
### Problème : "Unauthorized" sur les API
|
||||
|
||||
Le backend utilise l'Admin API avec `admin/admin`. Vérifiez :
|
||||
```properties
|
||||
# Dans application-dev.properties
|
||||
lions.keycloak.admin-username=admin
|
||||
lions.keycloak.admin-password=admin
|
||||
```
|
||||
|
||||
## 📋 Architecture de l'authentification
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Utilisateur │
|
||||
└────────┬────────┘
|
||||
│
|
||||
│ 1. Accède à http://localhost:8080
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Frontend (port 8080) │ ← OIDC activé
|
||||
│ PrimeFaces + Quarkus │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
│ 2. Redirige vers Keycloak
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ Keycloak (port 8180) │
|
||||
│ Realm: lions-user-manager │
|
||||
│ Client: lions-user-manager-client │
|
||||
└────────┬────────────────────────────┘
|
||||
│
|
||||
│ 3. Login: testuser/test123
|
||||
│ 4. Retourne token
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────┐
|
||||
│ Frontend authentifié │
|
||||
└────────┬────────────────┘
|
||||
│
|
||||
│ 5. Appelle l'API avec token
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────┐
|
||||
│ Backend API (port 8081) │ ← OIDC désactivé
|
||||
│ Utilise Admin API directe │
|
||||
└──────────┬───────────────────┘
|
||||
│
|
||||
│ 6. Auth avec admin/admin
|
||||
│
|
||||
▼
|
||||
┌──────────┐
|
||||
│ Keycloak │
|
||||
│ Admin API│
|
||||
└──────────┘
|
||||
```
|
||||
|
||||
## 🎯 Prochaines étapes
|
||||
|
||||
1. ✅ Keycloak configuré
|
||||
2. ✅ Utilisateur de test créé
|
||||
3. ⏳ Tester l'authentification sur le frontend
|
||||
4. ⏳ Tester les API du backend
|
||||
5. ⏳ Développer les pages manquantes
|
||||
6. ⏳ Implémenter les fonctionnalités métier
|
||||
|
||||
## 📞 Support
|
||||
|
||||
En cas de problème :
|
||||
1. Vérifier les logs des applications
|
||||
2. Vérifier la configuration Keycloak dans l'Admin Console
|
||||
3. Consulter `KEYCLOAK_SETUP.md` pour plus de détails
|
||||
4. Relancer `setup-keycloak-correct.sh` si nécessaire
|
||||
|
||||
---
|
||||
|
||||
**Date de configuration** : 2025-12-04
|
||||
**Realm** : `lions-user-manager`
|
||||
**Credentials test** : `testuser` / `test123`
|
||||
212
README_PORTS.md
212
README_PORTS.md
@@ -1,212 +0,0 @@
|
||||
# Configuration des Ports - Lions User Manager
|
||||
|
||||
## ✅ Problème résolu : Conflit de ports
|
||||
|
||||
**Problème initial** : Les deux applications (frontend et backend) étaient configurées sur le **même port 8081**, ce qui empêchait le backend de démarrer.
|
||||
|
||||
**Solution** : Ports correctement séparés.
|
||||
|
||||
## 🌐 Configuration des Ports
|
||||
|
||||
### Frontend (Interface Web JSF/PrimeFaces)
|
||||
- **Port** : `8080`
|
||||
- **URL** : http://localhost:8080
|
||||
- **Type** : Application web avec OIDC activé
|
||||
- **Fichier** : `lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/application.properties`
|
||||
|
||||
```properties
|
||||
quarkus.http.port=8080
|
||||
```
|
||||
|
||||
### Backend (API REST)
|
||||
- **Port** : `8081`
|
||||
- **URL** : http://localhost:8081
|
||||
- **Type** : API REST (pas de pages web)
|
||||
- **Fichier** : `lions-user-manager-server-impl-quarkus/src/main/resources/application.properties`
|
||||
|
||||
```properties
|
||||
quarkus.http.port=8081
|
||||
```
|
||||
|
||||
### Keycloak (Serveur d'authentification)
|
||||
- **Port** : `8180`
|
||||
- **URL** : http://localhost:8180
|
||||
- **Admin Console** : http://localhost:8180/admin
|
||||
- **Credentials** : admin / admin
|
||||
|
||||
## 🚀 Démarrage des applications
|
||||
|
||||
### 1. Démarrer Keycloak (si nécessaire)
|
||||
```bash
|
||||
# Vérifier si Keycloak tourne
|
||||
curl http://localhost:8180/health
|
||||
|
||||
# Si Keycloak ne tourne pas, le démarrer (exemple avec Docker)
|
||||
docker run -p 8180:8080 \
|
||||
-e KEYCLOAK_ADMIN=admin \
|
||||
-e KEYCLOAK_ADMIN_PASSWORD=admin \
|
||||
quay.io/keycloak/keycloak:latest start-dev
|
||||
```
|
||||
|
||||
### 2. Démarrer le Backend (port 8081)
|
||||
```bash
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn clean quarkus:dev
|
||||
```
|
||||
|
||||
**Vérification** :
|
||||
```bash
|
||||
# Swagger UI
|
||||
curl http://localhost:8081/q/swagger-ui
|
||||
|
||||
# Dev UI
|
||||
curl http://localhost:8081/q/dev
|
||||
|
||||
# Health Check
|
||||
curl http://localhost:8081/q/health
|
||||
```
|
||||
|
||||
### 3. Démarrer le Frontend (port 8080)
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean quarkus:dev
|
||||
```
|
||||
|
||||
**Vérification** :
|
||||
```bash
|
||||
# Page d'accueil
|
||||
curl http://localhost:8080
|
||||
|
||||
# Ou ouvrir dans le navigateur
|
||||
http://localhost:8080
|
||||
```
|
||||
|
||||
## 📋 Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Navigateur Web │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 1. Accès à http://localhost:8080
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ FRONTEND (Port 8080) │
|
||||
│ - Pages web JSF/PrimeFaces │
|
||||
│ - OIDC activé │
|
||||
│ - Redirige vers Keycloak pour login │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 2. Appelle l'API backend
|
||||
│ http://localhost:8081/api/*
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ BACKEND (Port 8081) │
|
||||
│ - API REST │
|
||||
│ - OIDC désactivé (utilise Admin API) │
|
||||
│ - Endpoints: /api/users, /api/roles, etc. │
|
||||
└────────────┬────────────────────────────────┘
|
||||
│
|
||||
│ 3. Gère les utilisateurs via Admin API
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ KEYCLOAK (Port 8180) │
|
||||
│ - Realm: lions-user-manager │
|
||||
│ - Client: lions-user-manager-client │
|
||||
│ - Admin API │
|
||||
└─────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 🔧 Flux d'authentification
|
||||
|
||||
1. **Utilisateur accède au frontend** : http://localhost:8080
|
||||
2. **Frontend redirige vers Keycloak** : http://localhost:8180/realms/lions-user-manager
|
||||
3. **Utilisateur se connecte** : testuser / test123
|
||||
4. **Keycloak retourne un token**
|
||||
5. **Frontend est authentifié** et peut appeler le backend
|
||||
6. **Backend utilise Admin API** pour gérer Keycloak (admin/admin)
|
||||
|
||||
## ❌ Ce qui NE fonctionnera PAS
|
||||
|
||||
### ❌ http://localhost:8081 (racine du backend)
|
||||
**Erreur** : Forbidden ou 404
|
||||
|
||||
**Raison** : Le backend est une API REST, il n'a pas de page d'accueil HTML.
|
||||
|
||||
**Solution** : Utilisez plutôt :
|
||||
- http://localhost:8081/q/swagger-ui (interface graphique API)
|
||||
- http://localhost:8081/q/dev (console dev Quarkus)
|
||||
- http://localhost:8081/api/users?realm=lions-user-manager (endpoint API)
|
||||
|
||||
### ❌ http://localhost:8080/api/users
|
||||
**Erreur** : 404
|
||||
|
||||
**Raison** : Les API sont sur le backend (port 8081), pas le frontend (8080).
|
||||
|
||||
**Solution** : http://localhost:8081/api/users?realm=lions-user-manager
|
||||
|
||||
## ✅ URLs correctes
|
||||
|
||||
### Frontend (8080)
|
||||
- **Accueil** : http://localhost:8080
|
||||
- **Login** : Automatiquement redirigé vers Keycloak
|
||||
- **Pages protégées** : http://localhost:8080/pages/user-manager/users/list.xhtml
|
||||
|
||||
### Backend (8081)
|
||||
- **Swagger UI** : http://localhost:8081/q/swagger-ui
|
||||
- **Dev UI** : http://localhost:8081/q/dev
|
||||
- **Health Check** : http://localhost:8081/q/health
|
||||
- **API Users** : http://localhost:8081/api/users?realm=lions-user-manager
|
||||
- **API Roles** : http://localhost:8081/api/roles/realm?realm=lions-user-manager
|
||||
|
||||
### Keycloak (8180)
|
||||
- **Admin Console** : http://localhost:8180/admin
|
||||
- **Account Console** : http://localhost:8180/realms/lions-user-manager/account
|
||||
|
||||
## 🔍 Diagnostic
|
||||
|
||||
### Le frontend ne démarre pas
|
||||
```bash
|
||||
# Vérifier qu'aucun processus n'utilise le port 8080
|
||||
netstat -ano | findstr :8080
|
||||
|
||||
# Logs du frontend
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
### Le backend ne démarre pas
|
||||
```bash
|
||||
# Vérifier qu'aucun processus n'utilise le port 8081
|
||||
netstat -ano | findstr :8081
|
||||
|
||||
# Logs du backend
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
### Keycloak n'est pas accessible
|
||||
```bash
|
||||
# Vérifier le statut
|
||||
curl http://localhost:8180/health
|
||||
|
||||
# Redémarrer si nécessaire
|
||||
```
|
||||
|
||||
## 📝 Credentials
|
||||
|
||||
- **Keycloak Admin** : admin / admin
|
||||
- **Utilisateur de test** : testuser / test123
|
||||
- **Realm** : lions-user-manager
|
||||
- **Client ID** : lions-user-manager-client
|
||||
- **Client Secret** : client-secret-lions-2025
|
||||
|
||||
---
|
||||
|
||||
**Important** : Toujours démarrer dans cet ordre :
|
||||
1. Keycloak (8180)
|
||||
2. Backend (8081)
|
||||
3. Frontend (8080)
|
||||
@@ -1,245 +0,0 @@
|
||||
# 🔧 Refactoring UserServiceImpl - Gestion des Erreurs de Connexion
|
||||
|
||||
**Date**: 2025-12-18
|
||||
|
||||
---
|
||||
|
||||
## 📋 Problème Initial
|
||||
|
||||
### NullPointerException dans `createUser` (ligne 196)
|
||||
|
||||
**Symptôme** : Lorsque le client REST ne peut pas se connecter au service Keycloak et retourne `null`, une `NullPointerException` se produit à la ligne 196 lors de l'appel à `response.getStatus()`.
|
||||
|
||||
**Cause** : Aucune vérification de nullité pour l'objet `Response` retourné par `usersResource.create(userRep)`.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Solution Implémentée
|
||||
|
||||
### 1. Création d'une Exception Personnalisée
|
||||
|
||||
**Fichier créé** : `lions-user-manager-server-impl-quarkus/src/main/java/dev/lions/user/manager/service/exception/KeycloakServiceException.java`
|
||||
|
||||
**Classes d'exception** :
|
||||
- `KeycloakServiceException` : Exception de base pour les erreurs Keycloak
|
||||
- `KeycloakServiceException.ServiceUnavailableException` : Pour les erreurs de connexion (503, 502)
|
||||
- `KeycloakServiceException.TimeoutException` : Pour les timeouts (504)
|
||||
|
||||
**Avantages** :
|
||||
- ✅ Messages d'erreur clairs et spécifiques
|
||||
- ✅ Codes HTTP préservés pour le debugging
|
||||
- ✅ Hiérarchie d'exceptions pour gestion fine
|
||||
|
||||
---
|
||||
|
||||
### 2. Méthode Utilitaire `validateResponse`
|
||||
|
||||
**Fonction** : Valide une réponse HTTP du service Keycloak.
|
||||
|
||||
**Vérifications** :
|
||||
- ✅ Réponse non null
|
||||
- ✅ Code de statut HTTP attendu
|
||||
- ✅ Gestion des codes d'erreur (400, 401, 403, 404, 409, 500, 502, 503, 504)
|
||||
|
||||
**Utilisation** :
|
||||
```java
|
||||
Response response = usersResource.create(userRep);
|
||||
validateResponse(response, "création de l'utilisateur", Response.Status.CREATED.getStatusCode());
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Méthode Utilitaire `handleConnectionException`
|
||||
|
||||
**Fonction** : Gère les exceptions de connexion et les convertit en `KeycloakServiceException` appropriée.
|
||||
|
||||
**Détection automatique** :
|
||||
- ✅ `ConnectException`
|
||||
- ✅ `SocketTimeoutException`
|
||||
- ✅ Messages contenant "Connection", "timeout", "refused", "Unable to connect"
|
||||
|
||||
**Utilisation** :
|
||||
```java
|
||||
catch (Exception e) {
|
||||
handleConnectionException(e, "création de l'utilisateur");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Refactoring de `createUser`
|
||||
|
||||
**Avant** :
|
||||
```java
|
||||
var response = usersResource.create(userRep);
|
||||
if (response.getStatus() != 201) {
|
||||
throw new RuntimeException("Échec de la création...");
|
||||
}
|
||||
```
|
||||
|
||||
**Après** :
|
||||
```java
|
||||
Response response = usersResource.create(userRep);
|
||||
|
||||
// Vérifier si la réponse est null (erreur de connexion)
|
||||
if (response == null) {
|
||||
throw new KeycloakServiceException.ServiceUnavailableException(
|
||||
"Impossible de se connecter au service Keycloak...");
|
||||
}
|
||||
|
||||
// Vérifier le code de statut HTTP
|
||||
int status = response.getStatus();
|
||||
if (status != Response.Status.CREATED.getStatusCode()) {
|
||||
// Gérer les différents codes d'erreur HTTP
|
||||
if (status == 400) { ... }
|
||||
else if (status == 409) { ... }
|
||||
else if (status == 503 || status == 502) { ... }
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**Améliorations** :
|
||||
- ✅ Vérification de nullité avant `getStatus()`
|
||||
- ✅ Vérification de `getLocation()` avant utilisation
|
||||
- ✅ Gestion spécifique des codes HTTP d'erreur
|
||||
- ✅ Messages d'erreur clairs et actionnables
|
||||
|
||||
---
|
||||
|
||||
### 5. Refactoring des Autres Méthodes
|
||||
|
||||
**Méthodes refactorisées** :
|
||||
- ✅ `createUser` - Vérification Response null + codes HTTP
|
||||
- ✅ `updateUser` - Vérification UserResource et UserRepresentation null
|
||||
- ✅ `deleteUser` - Vérification UserResource et UserRepresentation null
|
||||
- ✅ `activateUser` - Vérification UserResource et UserRepresentation null
|
||||
- ✅ `deactivateUser` - Vérification UserResource et UserRepresentation null
|
||||
- ✅ `sendVerificationEmail` - Vérification UserResource null
|
||||
- ✅ `logoutAllSessions` - Vérification UserResource null + getUserSessions null
|
||||
- ✅ `searchUsers` - Utilisation de `handleConnectionException`
|
||||
- ✅ `getUserByUsername` - Vérification users null
|
||||
- ✅ `getUserByEmail` - Vérification users null
|
||||
- ✅ `getUserById` - Utilisation de `handleConnectionException`
|
||||
- ✅ `setPassword` - Utilisation de `handleConnectionException`
|
||||
|
||||
---
|
||||
|
||||
## 📊 Gestion des Codes HTTP
|
||||
|
||||
### Codes Gérés
|
||||
|
||||
| Code | Exception | Message |
|
||||
|------|-----------|---------|
|
||||
| **400** | `KeycloakServiceException` | "Données invalides" |
|
||||
| **401** | `KeycloakServiceException` | "Non autorisé" |
|
||||
| **403** | `KeycloakServiceException` | "Accès interdit" |
|
||||
| **404** | `KeycloakServiceException` | "Ressource non trouvée" |
|
||||
| **409** | `KeycloakServiceException` | "Conflit" |
|
||||
| **500** | `KeycloakServiceException` | "Erreur serveur interne Keycloak" |
|
||||
| **502** | `ServiceUnavailableException` | "Service Keycloak indisponible" |
|
||||
| **503** | `ServiceUnavailableException` | "Service Keycloak indisponible" |
|
||||
| **504** | `TimeoutException` | "Timeout lors de l'opération" |
|
||||
| **null** | `ServiceUnavailableException` | "Impossible de se connecter au service Keycloak" |
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Détection des Erreurs de Connexion
|
||||
|
||||
### Types d'Exceptions Détectées
|
||||
|
||||
1. **Exceptions Java Standard** :
|
||||
- `ConnectException`
|
||||
- `SocketTimeoutException`
|
||||
|
||||
2. **Messages d'Erreur** :
|
||||
- Contient "Connection"
|
||||
- Contient "timeout"
|
||||
- Contient "refused"
|
||||
- Contient "Unable to connect"
|
||||
|
||||
### Exemple de Détection
|
||||
|
||||
```java
|
||||
catch (Exception e) {
|
||||
String errorMessage = e.getMessage();
|
||||
if (e instanceof ConnectException ||
|
||||
e instanceof SocketTimeoutException ||
|
||||
(errorMessage != null && errorMessage.contains("Connection"))) {
|
||||
throw new KeycloakServiceException.ServiceUnavailableException(...);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Résultat
|
||||
|
||||
### Avant
|
||||
- ❌ `NullPointerException` si Response est null
|
||||
- ❌ Messages d'erreur génériques (`RuntimeException`)
|
||||
- ❌ Pas de distinction entre types d'erreurs
|
||||
- ❌ Pas de gestion des codes HTTP spécifiques
|
||||
|
||||
### Après
|
||||
- ✅ Vérification de nullité systématique
|
||||
- ✅ Exceptions spécifiques avec messages clairs
|
||||
- ✅ Distinction entre erreurs de connexion, validation, autorisation, etc.
|
||||
- ✅ Gestion complète des codes HTTP
|
||||
- ✅ Logs détaillés pour le debugging
|
||||
|
||||
---
|
||||
|
||||
## 📝 Exemple d'Utilisation
|
||||
|
||||
### Cas 1 : Connexion Échouée (Response null)
|
||||
|
||||
```java
|
||||
Response response = usersResource.create(userRep);
|
||||
if (response == null) {
|
||||
throw new KeycloakServiceException.ServiceUnavailableException(
|
||||
"Impossible de se connecter au service Keycloak pour créer l'utilisateur: " + user.getUsername());
|
||||
}
|
||||
```
|
||||
|
||||
### Cas 2 : Code HTTP d'Erreur
|
||||
|
||||
```java
|
||||
int status = response.getStatus();
|
||||
if (status == 409) {
|
||||
throw new IllegalArgumentException("L'utilisateur existe déjà (conflit détecté par Keycloak)");
|
||||
} else if (status == 503) {
|
||||
throw new KeycloakServiceException.ServiceUnavailableException("Service Keycloak indisponible");
|
||||
}
|
||||
```
|
||||
|
||||
### Cas 3 : Exception de Connexion
|
||||
|
||||
```java
|
||||
catch (Exception e) {
|
||||
handleConnectionException(e, "création de l'utilisateur " + user.getUsername());
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Migration des Autres Méthodes
|
||||
|
||||
Toutes les méthodes qui utilisent le client REST Keycloak ont été refactorisées pour :
|
||||
|
||||
1. ✅ Vérifier les objets null retournés
|
||||
2. ✅ Utiliser `handleConnectionException` pour les erreurs
|
||||
3. ✅ Lever des `KeycloakServiceException` au lieu de `RuntimeException`
|
||||
4. ✅ Gérer spécifiquement les codes HTTP d'erreur
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
- [Keycloak Admin Client Documentation](https://www.keycloak.org/docs/latest/server_development/#admin-rest-api)
|
||||
- [JAX-RS Response API](https://jakarta.ee/specifications/restful-ws/3.0/jakarta-restful-ws-spec-3.0.html#response)
|
||||
- [Java Exception Handling Best Practices](https://docs.oracle.com/javase/tutorial/essential/exceptions/)
|
||||
|
||||
---
|
||||
|
||||
*Document créé le: 2025-12-18*
|
||||
|
||||
@@ -1,279 +0,0 @@
|
||||
# ✅ Restructuration des fichiers de configuration - TERMINÉE
|
||||
|
||||
## 📋 Résumé des changements
|
||||
|
||||
La configuration a été complètement restructurée selon les **best practices Quarkus** avec une séparation propre entre les environnements.
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Avant / Après
|
||||
|
||||
### ❌ AVANT (système ancien)
|
||||
|
||||
```
|
||||
application.properties (1 seul fichier avec préfixes %dev. et %prod.)
|
||||
├── Propriétés communes
|
||||
├── %dev.propriété1=valeur
|
||||
├── %dev.propriété2=valeur
|
||||
├── %prod.propriété1=valeur
|
||||
└── %prod.propriété2=valeur
|
||||
```
|
||||
|
||||
**Problèmes** :
|
||||
- Fichier unique très long et difficile à lire
|
||||
- Mélange de configurations dev et prod
|
||||
- Difficile de savoir quelle config est active
|
||||
- Duplication des propriétés communes
|
||||
|
||||
---
|
||||
|
||||
### ✅ APRÈS (système propre)
|
||||
|
||||
```
|
||||
application.properties (configuration commune uniquement)
|
||||
├── Propriétés communes à tous les environnements
|
||||
└── Pas de préfixes %dev. ou %prod.
|
||||
|
||||
application-dev.properties (surcharge développement)
|
||||
├── TOUTES les propriétés spécifiques au dev
|
||||
└── Surcharge les propriétés communes si nécessaire
|
||||
|
||||
application-prod.properties (surcharge production)
|
||||
├── TOUTES les propriétés spécifiques à la prod
|
||||
└── Surcharge les propriétés communes si nécessaire
|
||||
```
|
||||
|
||||
**Avantages** :
|
||||
- ✅ Séparation claire des configurations
|
||||
- ✅ Fichiers plus courts et plus lisibles
|
||||
- ✅ Pas de duplication
|
||||
- ✅ Facile de voir quelle config s'applique
|
||||
- ✅ Best practice Quarkus/Spring Boot
|
||||
|
||||
---
|
||||
|
||||
## 📂 Fichiers modifiés
|
||||
|
||||
### Module CLIENT (lions-user-manager-client-quarkus-primefaces-freya)
|
||||
|
||||
| Fichier | Lignes | Contenu |
|
||||
|---------|--------|---------|
|
||||
| `application.properties` | 116 | Configuration commune (HTTP, MyFaces, PrimeFaces, OIDC base, REST Client, Health) |
|
||||
| `application-dev.properties` | 68 | DEV : Port 8082, Keycloak local, CORS permissif, Logging verbeux |
|
||||
| `application-prod.properties` | 62 | PROD : Port 8080, Keycloak prod, CORS restrictif, TLS requis |
|
||||
|
||||
**Changements majeurs** :
|
||||
- ✅ Suppression de tous les préfixes `%dev.` et `%prod.`
|
||||
- ✅ Configuration OIDC complète dans chaque fichier
|
||||
- ✅ Ports distincts (8082 dev, 8080 prod)
|
||||
- ✅ Backend URL via variable d'environnement en prod
|
||||
|
||||
---
|
||||
|
||||
### Module SERVEUR (lions-user-manager-server-impl-quarkus)
|
||||
|
||||
| Fichier | Lignes | Contenu |
|
||||
|---------|--------|---------|
|
||||
| `application.properties` | 109 | Configuration commune (HTTP base, Logging, Audit, Health, Metrics, Jackson) |
|
||||
| `application-dev.properties` | 98 | **DEV : OIDC DÉSACTIVÉ** (simplifie dev), Keycloak Admin local, Security off |
|
||||
| `application-prod.properties` | 120 | **PROD : OIDC OBLIGATOIRE** (sécurité stricte), DB audit, Performance tuning |
|
||||
|
||||
**Changements majeurs** :
|
||||
- ✅ **OIDC désactivé en DEV** : `quarkus.oidc.enabled=false`
|
||||
- Simplifie énormément le développement
|
||||
- Pas besoin de configurer 2 clients Keycloak
|
||||
- Client JSF reste sécurisé
|
||||
- ✅ **OIDC obligatoire en PROD** : Sécurité maximale
|
||||
- ✅ Configuration Database pour audit en prod
|
||||
- ✅ Thread pool optimisé en prod
|
||||
|
||||
---
|
||||
|
||||
### Module API (lions-user-manager-server-api)
|
||||
|
||||
**Aucun changement** : Ce module ne contient que des DTOs et n'a pas de configuration.
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Architecture de sécurité finale
|
||||
|
||||
### Mode DÉVELOPPEMENT
|
||||
```
|
||||
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||
│ Navigateur │────────▶│ Client JSF │────────▶│ Backend API │
|
||||
│ │ │ Port: 8082 │ │ Port: 8081 │
|
||||
│ │ │ OIDC: ✅ Activé │ │ OIDC: ❌ Désactivé│
|
||||
└─────────────┘ └──────────────────┘ └─────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ Keycloak Local │
|
||||
│ Port: 8180 │
|
||||
│ Realm: lions- │
|
||||
│ user-manager │
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
**Flux d'authentification DEV** :
|
||||
1. Utilisateur se connecte via le Client JSF
|
||||
2. Client valide l'utilisateur avec Keycloak
|
||||
3. Client appelle le Backend API **sans vérification OIDC**
|
||||
4. Backend répond directement (pas de validation de token)
|
||||
|
||||
**Avantages** :
|
||||
- ✅ Pas besoin de configurer `lions-user-manager-backend` dans Keycloak
|
||||
- ✅ Développement rapide
|
||||
- ✅ Client reste sécurisé
|
||||
|
||||
---
|
||||
|
||||
### Mode PRODUCTION
|
||||
```
|
||||
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||
│ Navigateur │────────▶│ Client JSF │────────▶│ Backend API │
|
||||
│ │ │ Port: 8080 │ │ Port: 8080 │
|
||||
│ │ │ OIDC: ✅ Activé │ │ OIDC: ✅ Activé │
|
||||
└─────────────┘ └──────────────────┘ └─────────────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────────────────────────┐
|
||||
│ Keycloak Production │
|
||||
│ https://security.lions.dev │
|
||||
│ Realm: master │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Flux d'authentification PROD** :
|
||||
1. Utilisateur se connecte via le Client JSF
|
||||
2. Client obtient un token de Keycloak
|
||||
3. Client envoie le token au Backend dans le header `Authorization: Bearer <token>`
|
||||
4. Backend **valide le token** avec Keycloak avant de répondre
|
||||
|
||||
**Avantages** :
|
||||
- ✅ Défense en profondeur (double validation)
|
||||
- ✅ Zero-trust (backend ne fait confiance à personne)
|
||||
- ✅ Traçabilité (audit de qui a fait quoi)
|
||||
- ✅ Sécurité maximale
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Comment utiliser
|
||||
|
||||
### Développement
|
||||
|
||||
```bash
|
||||
# Terminal 1 : Backend (OIDC désactivé)
|
||||
cd lions-user-manager/lions-user-manager-server-impl-quarkus
|
||||
mvn quarkus:dev
|
||||
|
||||
# Terminal 2 : Client (OIDC activé vers Keycloak local)
|
||||
cd lions-user-manager/lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn quarkus:dev
|
||||
|
||||
# Accès : http://localhost:8082
|
||||
```
|
||||
|
||||
**Note** : L'erreur **HTTP 405** est maintenant **résolue** ! 🎉
|
||||
|
||||
Le backend accepte toutes les requêtes en DEV, donc pas besoin de configurer Keycloak pour le backend.
|
||||
|
||||
---
|
||||
|
||||
### Production
|
||||
|
||||
```bash
|
||||
# Build avec profil production
|
||||
mvn clean package -Pprod
|
||||
|
||||
# Démarrer avec variables d'environnement
|
||||
export KEYCLOAK_CLIENT_SECRET=<secret>
|
||||
export KEYCLOAK_ADMIN_USERNAME=admin
|
||||
export KEYCLOAK_ADMIN_PASSWORD=<password>
|
||||
export DB_PASSWORD=<db-password>
|
||||
|
||||
java -jar target/quarkus-app/quarkus-run.jar
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Compilation - Résultats
|
||||
|
||||
### ✅ Client
|
||||
```
|
||||
[INFO] Building Lions User Manager - Client (Quarkus + PrimeFaces Freya) 1.0.1
|
||||
[INFO] BUILD SUCCESS
|
||||
[INFO] Total time: 18.362 s
|
||||
```
|
||||
|
||||
### ✅ Serveur
|
||||
```
|
||||
[INFO] Building Lions User Manager - Server Implementation (Quarkus) 1.0.0
|
||||
[INFO] BUILD SUCCESS
|
||||
[INFO] Total time: 8.938 s
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Comparaison des propriétés clés
|
||||
|
||||
| Propriété | Commun | DEV | PROD |
|
||||
|-----------|--------|-----|------|
|
||||
| **Client** | | | |
|
||||
| `quarkus.http.port` | - | 8082 | 8080 |
|
||||
| `quarkus.oidc.enabled` | true | true | true |
|
||||
| `quarkus.oidc.auth-server-url` | - | localhost:8180 | security.lions.dev |
|
||||
| `quarkus.http.session-cookie-secure` | - | false | true |
|
||||
| `quarkus.log.console.level` | INFO | DEBUG | WARN |
|
||||
| **Serveur** | | | |
|
||||
| `quarkus.http.port` | - | 8081 | 8080 |
|
||||
| `quarkus.oidc.enabled` | - | **false** | **true** |
|
||||
| `quarkus.security.auth.enabled` | - | false | true |
|
||||
| `lions.keycloak.server-url` | - | localhost:8180 | security.lions.dev |
|
||||
| `quarkus.http.cors.origins` | - | * | restrictif |
|
||||
|
||||
---
|
||||
|
||||
## 📖 Documentation créée
|
||||
|
||||
| Fichier | Description |
|
||||
|---------|-------------|
|
||||
| `CONFIGURATION_GUIDE.md` | Guide complet de configuration (ce fichier) |
|
||||
| `KEYCLOAK_DEV_SETUP.md` | Instructions pour configurer Keycloak en DEV (si OIDC backend activé) |
|
||||
| `test-keycloak-config.sh` | Script de vérification Linux/Mac |
|
||||
| `test-keycloak-config.ps1` | Script de vérification Windows PowerShell |
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist de vérification
|
||||
|
||||
- [x] Fichiers `application.properties` ne contiennent plus de préfixes `%dev.` ou `%prod.`
|
||||
- [x] Fichiers `application-dev.properties` contiennent TOUTES les propriétés DEV
|
||||
- [x] Fichiers `application-prod.properties` contiennent TOUTES les propriétés PROD
|
||||
- [x] OIDC désactivé sur backend DEV (`quarkus.oidc.enabled=false`)
|
||||
- [x] OIDC obligatoire sur backend PROD (`quarkus.oidc.enabled=true`)
|
||||
- [x] Ports distincts (8082 client DEV, 8081 serveur DEV)
|
||||
- [x] Logging verbeux en DEV, minimal en PROD
|
||||
- [x] CORS permissif en DEV, restrictif en PROD
|
||||
- [x] Variables d'environnement pour secrets en PROD
|
||||
- [x] Compilation réussie pour les 3 modules
|
||||
- [x] Documentation complète créée
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Résultat
|
||||
|
||||
**Erreur HTTP 405 RÉSOLUE** ✅
|
||||
|
||||
La restructuration des fichiers de configuration permet un développement simplifié tout en garantissant une sécurité maximale en production.
|
||||
|
||||
**Prochaine étape** : Démarrer les applications et tester le flux complet !
|
||||
|
||||
```bash
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Date de restructuration** : 2025-12-25
|
||||
**Version** : 1.0.0
|
||||
**Statut** : ✅ TERMINÉ
|
||||
@@ -1,259 +0,0 @@
|
||||
# ✅ REST Clients et Beans JSF Créés - Lions User Manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Statut**: ✅ **REST CLIENTS ET BEANS JSF CRÉÉS**
|
||||
|
||||
---
|
||||
|
||||
## 📊 Résumé
|
||||
|
||||
**Total**:
|
||||
- ✅ **REST Clients**: 4 interfaces
|
||||
- ✅ **Beans JSF**: 5 beans
|
||||
|
||||
---
|
||||
|
||||
## 🔌 REST Clients (4/4 ✅)
|
||||
|
||||
### 1. ✅ **UserServiceClient.java**
|
||||
**Localisation**: `client/service/UserServiceClient.java`
|
||||
|
||||
**Méthodes**:
|
||||
- `searchUsers()` - Recherche d'utilisateurs
|
||||
- `getUserById()` - Récupération par ID
|
||||
- `getAllUsers()` - Liste paginée
|
||||
- `createUser()` - Création
|
||||
- `updateUser()` - Mise à jour
|
||||
- `deleteUser()` - Suppression
|
||||
- `activateUser()` / `deactivateUser()` - Activation/Désactivation
|
||||
- `resetPassword()` - Réinitialisation mot de passe
|
||||
- `sendVerificationEmail()` - Envoi email vérification
|
||||
- `logoutAllSessions()` - Déconnexion sessions
|
||||
- `getActiveSessions()` - Sessions actives
|
||||
|
||||
**Configuration**: `@RegisterRestClient(configKey = "lions-user-manager-api")`
|
||||
|
||||
---
|
||||
|
||||
### 2. ✅ **RoleServiceClient.java**
|
||||
**Localisation**: `client/service/RoleServiceClient.java`
|
||||
|
||||
**Méthodes Realm Roles**:
|
||||
- `createRealmRole()` - Création rôle Realm
|
||||
- `getRealmRoleByName()` - Récupération par nom
|
||||
- `getAllRealmRoles()` - Liste tous les rôles Realm
|
||||
- `updateRealmRole()` - Mise à jour
|
||||
- `deleteRealmRole()` - Suppression
|
||||
|
||||
**Méthodes Client Roles**:
|
||||
- `createClientRole()` - Création rôle Client
|
||||
- `getAllClientRoles()` - Liste tous les rôles Client
|
||||
- `getClientRoleByName()` - Récupération par nom
|
||||
- `deleteClientRole()` - Suppression
|
||||
|
||||
**Méthodes Attribution**:
|
||||
- `assignRoleToUser()` - Attribuer un rôle
|
||||
- `revokeRoleFromUser()` - Révoquer un rôle
|
||||
- `getUserRoles()` - Rôles d'un utilisateur
|
||||
|
||||
**Méthodes Composite**:
|
||||
- `getCompositeRoles()` - Rôles composites
|
||||
- `addCompositeRole()` - Ajouter rôle composite
|
||||
- `removeCompositeRole()` - Retirer rôle composite
|
||||
|
||||
---
|
||||
|
||||
### 3. ✅ **AuditServiceClient.java**
|
||||
**Localisation**: `client/service/AuditServiceClient.java`
|
||||
|
||||
**Méthodes Recherche**:
|
||||
- `searchLogs()` - Recherche avancée
|
||||
- `getLogsByActeur()` - Par acteur
|
||||
- `getLogsByRealm()` - Par realm
|
||||
- `getLogsByRessource()` - Par ressource
|
||||
- `getLogsByAction()` - Par type d'action
|
||||
|
||||
**Méthodes Statistiques**:
|
||||
- `getActionStatistics()` - Statistiques par action
|
||||
- `getUserActivityStatistics()` - Statistiques par utilisateur
|
||||
- `getFailureCount()` - Nombre d'échecs
|
||||
- `getSuccessCount()` - Nombre de succès
|
||||
|
||||
**Méthodes Export**:
|
||||
- `exportLogsToCSV()` - Export CSV
|
||||
|
||||
---
|
||||
|
||||
### 4. ✅ **SyncServiceClient.java**
|
||||
**Localisation**: `client/service/SyncServiceClient.java`
|
||||
|
||||
**Méthodes Health**:
|
||||
- `checkHealth()` - Health check général
|
||||
- `checkKeycloakHealth()` - Health check Keycloak
|
||||
|
||||
**Méthodes Synchronisation**:
|
||||
- `syncUsers()` - Synchroniser utilisateurs
|
||||
- `syncRoles()` - Synchroniser rôles
|
||||
|
||||
**Méthodes Vérification**:
|
||||
- `userExists()` - Vérifier existence utilisateur
|
||||
- `roleExists()` - Vérifier existence rôle
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Beans JSF (5/5 ✅)
|
||||
|
||||
### 1. ✅ **UserListBean.java**
|
||||
**Localisation**: `client/view/UserListBean.java`
|
||||
**Scope**: `@ViewScoped`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Liste paginée des utilisateurs
|
||||
- Recherche simple et avancée
|
||||
- Filtres (realm, statut)
|
||||
- Actions (activate, deactivate, delete, logout sessions)
|
||||
- Navigation vers profil/édition/création
|
||||
|
||||
**Propriétés principales**:
|
||||
- `users`: List<UserDTO>
|
||||
- `searchCriteria`: UserSearchCriteriaDTO
|
||||
- `selectedUser`: UserDTO
|
||||
- Pagination (currentPage, pageSize, totalRecords)
|
||||
|
||||
---
|
||||
|
||||
### 2. ✅ **UserProfilBean.java**
|
||||
**Localisation**: `client/view/UserProfilBean.java`
|
||||
**Scope**: `@ViewScoped`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Affichage profil utilisateur
|
||||
- Mode édition
|
||||
- Réinitialisation mot de passe
|
||||
- Activation/Désactivation
|
||||
- Envoi email vérification
|
||||
- Déconnexion sessions
|
||||
|
||||
**Propriétés principales**:
|
||||
- `user`: UserDTO
|
||||
- `userId`: String
|
||||
- `editMode`: boolean
|
||||
- `newPassword`: String (pour reset)
|
||||
|
||||
---
|
||||
|
||||
### 3. ✅ **UserCreationBean.java**
|
||||
**Localisation**: `client/view/UserCreationBean.java`
|
||||
**Scope**: `@ViewScoped`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Création nouvel utilisateur
|
||||
- Validation mot de passe
|
||||
- Sélection realm
|
||||
- Initialisation valeurs par défaut
|
||||
|
||||
**Propriétés principales**:
|
||||
- `newUser`: UserDTO
|
||||
- `password`: String
|
||||
- `passwordConfirm`: String
|
||||
- `realmName`: String
|
||||
|
||||
---
|
||||
|
||||
### 4. ✅ **RoleGestionBean.java**
|
||||
**Localisation**: `client/view/RoleGestionBean.java`
|
||||
**Scope**: `@ViewScoped`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Liste rôles Realm et Client
|
||||
- Création rôles Realm/Client
|
||||
- Suppression rôles
|
||||
- Attribution/Révocation rôles
|
||||
- Filtres (realm, client, type)
|
||||
|
||||
**Propriétés principales**:
|
||||
- `realmRoles`: List<RoleDTO>
|
||||
- `clientRoles`: List<RoleDTO>
|
||||
- `newRole`: RoleDTO
|
||||
- `selectedRole`: RoleDTO
|
||||
|
||||
---
|
||||
|
||||
### 5. ✅ **AuditConsultationBean.java**
|
||||
**Localisation**: `client/view/AuditConsultationBean.java`
|
||||
**Scope**: `@ViewScoped`
|
||||
|
||||
**Fonctionnalités**:
|
||||
- Consultation logs d'audit
|
||||
- Recherche avancée
|
||||
- Filtres (acteur, date, type action, ressource, succès)
|
||||
- Statistiques (actions, utilisateurs, échecs/succès)
|
||||
- Export CSV
|
||||
|
||||
**Propriétés principales**:
|
||||
- `auditLogs`: List<AuditLogDTO>
|
||||
- `actionStatistics`: Map<TypeActionAudit, Long>
|
||||
- `userActivityStatistics`: Map<String, Long>
|
||||
- Filtres de recherche
|
||||
|
||||
---
|
||||
|
||||
## 📐 Patterns Utilisés
|
||||
|
||||
### REST Clients
|
||||
- ✅ `@RegisterRestClient` avec configKey
|
||||
- ✅ `@Path`, `@GET`, `@POST`, `@PUT`, `@DELETE`
|
||||
- ✅ `@QueryParam`, `@PathParam`
|
||||
- ✅ `@Produces` et `@Consumes` MediaType.APPLICATION_JSON
|
||||
|
||||
### Beans JSF
|
||||
- ✅ `@Named` pour injection CDI
|
||||
- ✅ `@ViewScoped` pour scope de vue
|
||||
- ✅ `@Inject @RestClient` pour injection REST Client
|
||||
- ✅ `@PostConstruct` pour initialisation
|
||||
- ✅ Constantes de navigation (WOU/DRY pattern)
|
||||
- ✅ Gestion messages (success/error)
|
||||
- ✅ Logging avec Logger
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Configuration Requise
|
||||
|
||||
### application.properties
|
||||
|
||||
```properties
|
||||
# URL du backend
|
||||
lions.user.manager.backend.url=http://localhost:8080
|
||||
|
||||
# Configuration REST Client
|
||||
quarkus.rest-client.lions-user-manager-api.url=${lions.user.manager.backend.url}
|
||||
quarkus.rest-client.lions-user-manager-api.scope=jakarta.inject.Singleton
|
||||
quarkus.rest-client.lions-user-manager-api.connect-timeout=5000
|
||||
quarkus.rest-client.lions-user-manager-api.read-timeout=30000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
1. **Gestion d'erreurs**: Tous les beans incluent try-catch avec logging et messages utilisateur
|
||||
2. **Validation**: Validation côté client dans les beans (ex: mot de passe)
|
||||
3. **Pagination**: Support pagination dans UserListBean et AuditConsultationBean
|
||||
4. **TODO**: Certaines méthodes nécessitent l'implémentation de la récupération des realms depuis Keycloak
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines Étapes
|
||||
|
||||
1. ✅ **REST Clients créés** - TERMINÉ
|
||||
2. ✅ **Beans JSF créés** - TERMINÉ
|
||||
3. ⏳ **Pages XHTML** - À créer
|
||||
4. ⏳ **Configuration application.properties** - À compléter
|
||||
5. ⏳ **Intégration unionflow** - À faire
|
||||
|
||||
---
|
||||
|
||||
**Statut**: ✅ **100% COMPLÉTÉ**
|
||||
**Date**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
# 📊 Résumé de l'Analyse - lions-user-manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Statut**: Analyse complétée ✅
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Objectif
|
||||
|
||||
Optimiser **lions-user-manager** pour en faire un **module réutilisable** intégré à l'écosystème **lionsdev** et à **unionflow**, avec des composants réutilisables à l'instar de unionflow.
|
||||
|
||||
---
|
||||
|
||||
## 📋 État Actuel
|
||||
|
||||
### ✅ Points Forts
|
||||
|
||||
1. **Backend API Complet** (60% complété)
|
||||
- Module `server-api` : 100% ✅
|
||||
- Module `server-impl-quarkus` : 60% 🔄
|
||||
- UserService avec 25+ méthodes fonctionnelles
|
||||
- Keycloak Admin Client avec résilience (Circuit Breaker, Retry)
|
||||
|
||||
2. **Architecture Solide**
|
||||
- Architecture multi-modules Maven
|
||||
- Séparation claire API / Impl / Client
|
||||
- ZÉRO accès direct DB Keycloak (Admin API uniquement)
|
||||
|
||||
### ⚠️ Points à Améliorer
|
||||
|
||||
1. **Module Client Inexistant** (0%)
|
||||
- Pas de pages XHTML
|
||||
- Pas de composants réutilisables
|
||||
- Pas d'intégration avec unionflow
|
||||
|
||||
2. **Manque de Réutilisabilité**
|
||||
- Pas de composants UI réutilisables
|
||||
- Pas de patterns WOU/DRY comme unionflow
|
||||
|
||||
3. **Intégration Écosystème**
|
||||
- Pas de dépendance Maven vers unionflow
|
||||
- Pas d'intégration au menu unionflow
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Analyse Comparative avec UnionFlow
|
||||
|
||||
### Patterns Identifiés dans UnionFlow
|
||||
|
||||
UnionFlow utilise une **architecture de composants modulaires** avec:
|
||||
|
||||
```
|
||||
templates/components/
|
||||
├── buttons/ # Boutons réutilisables
|
||||
├── cards/ # Cartes (kpi-card, stat-card)
|
||||
├── columns/ # Colonnes de tableaux
|
||||
├── dialogs/ # Dialogs
|
||||
├── forms/ # Champs de formulaire
|
||||
├── layout/ # Layout (menu, topbar)
|
||||
└── tables/ # Composants de tableaux
|
||||
```
|
||||
|
||||
**Pattern WOU/DRY** (Write Once Use / Don't Repeat Yourself):
|
||||
- Chaque composant est paramétrable via `<ui:param>`
|
||||
- Documentation inline dans chaque composant
|
||||
- Réutilisation maximale
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Plan d'Optimisation
|
||||
|
||||
### Phase 1: Composants Réutilisables ✅ EN COURS
|
||||
|
||||
**Structure créée**:
|
||||
```
|
||||
templates/components/
|
||||
├── user-management/ # Composants spécifiques utilisateurs
|
||||
├── role-management/ # Composants spécifiques rôles
|
||||
├── audit/ # Composants audit
|
||||
└── shared/ # Composants partagés
|
||||
├── buttons/
|
||||
├── cards/
|
||||
├── forms/
|
||||
└── tables/
|
||||
```
|
||||
|
||||
**Premier composant créé**: `user-card.xhtml` ✅
|
||||
|
||||
### Phase 2: Module Client (À FAIRE)
|
||||
|
||||
**Tâches**:
|
||||
- [ ] Compléter POM.xml avec Freya Theme
|
||||
- [ ] Créer REST Clients
|
||||
- [ ] Créer Beans JSF (10+)
|
||||
- [ ] Créer pages XHTML utilisant les composants (15+)
|
||||
|
||||
### Phase 3: Intégration UnionFlow (À FAIRE)
|
||||
|
||||
**Tâches**:
|
||||
- [ ] Ajouter dépendance Maven dans unionflow
|
||||
- [ ] Enrichir le menu unionflow (section "Gestion des Membres")
|
||||
- [ ] Créer pages d'intégration dans unionflow
|
||||
|
||||
### Phase 4: Publication (À FAIRE)
|
||||
|
||||
**Tâches**:
|
||||
- [ ] Publier modules dans repository Maven lionsdev
|
||||
- [ ] Créer guide d'intégration
|
||||
- [ ] Documenter tous les composants
|
||||
|
||||
---
|
||||
|
||||
## 📐 Architecture Cible
|
||||
|
||||
### Structure Modulaire
|
||||
|
||||
```
|
||||
lions-user-manager/
|
||||
├── lions-user-manager-server-api/ # Module API (JAR réutilisable)
|
||||
├── lions-user-manager-server-impl-quarkus/ # Implémentation serveur
|
||||
├── lions-user-manager-client-quarkus-primefaces-freya/ # Client UI
|
||||
│ └── templates/components/ # Composants réutilisables ✅
|
||||
└── docs/
|
||||
└── INTEGRATION_GUIDE.md # Guide d'intégration
|
||||
```
|
||||
|
||||
### Intégration avec UnionFlow
|
||||
|
||||
Le menu unionflow sera enrichi avec:
|
||||
|
||||
```xhtml
|
||||
<!-- Gestion des Membres -->
|
||||
<p:submenu id="m_membres" label="Gestion des Membres" icon="pi pi-users">
|
||||
<!-- Pages UnionFlow existantes -->
|
||||
<p:menuitem ... />
|
||||
|
||||
<!-- NOUVEAU: Gestion Utilisateurs Keycloak -->
|
||||
<p:separator />
|
||||
<p:menuitem id="m_gestion_utilisateurs" value="Gestion Utilisateurs"
|
||||
icon="pi pi-users-cog"
|
||||
outcome="/pages/user-manager/users/list" />
|
||||
<p:menuitem id="m_gestion_roles" value="Gestion Rôles"
|
||||
icon="pi pi-shield"
|
||||
outcome="/pages/user-manager/roles/list" />
|
||||
<p:menuitem id="m_audit_utilisateurs" value="Audit Utilisateurs"
|
||||
icon="pi pi-history"
|
||||
outcome="/pages/user-manager/audit/logs" />
|
||||
</p:submenu>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines Actions Immédiates
|
||||
|
||||
### 1. Créer les Composants Réutilisables (2-3 jours)
|
||||
|
||||
**Priorité**: Composants user-management
|
||||
- [x] Structure créée ✅
|
||||
- [x] `user-card.xhtml` créé ✅
|
||||
- [ ] `user-form.xhtml`
|
||||
- [ ] `user-search-bar.xhtml`
|
||||
- [ ] `user-actions.xhtml`
|
||||
- [ ] `user-role-badge.xhtml`
|
||||
|
||||
### 2. Compléter le Module Client (3-4 jours)
|
||||
|
||||
**Priorité**: REST Clients et Beans JSF
|
||||
- [ ] REST Clients (UserServiceClient, RoleServiceClient, etc.)
|
||||
- [ ] Beans JSF (UserListBean, UserProfilBean, etc.)
|
||||
- [ ] Pages XHTML utilisant les composants
|
||||
|
||||
### 3. Intégrer avec UnionFlow (1-2 jours)
|
||||
|
||||
**Priorité**: Dépendance et menu
|
||||
- [ ] Ajouter dépendance dans `unionflow/pom.xml`
|
||||
- [ ] Enrichir menu unionflow
|
||||
- [ ] Créer pages d'intégration
|
||||
|
||||
---
|
||||
|
||||
## 📊 Métriques de Succès
|
||||
|
||||
### Réutilisabilité
|
||||
- ✅ Composants réutilisables dans au moins 2 projets
|
||||
- ✅ Réduction de 50%+ du code dupliqué
|
||||
- ✅ Temps de développement réduit de 30%+
|
||||
|
||||
### Intégration
|
||||
- ✅ Menu unionflow enrichi
|
||||
- ✅ Pages d'intégration fonctionnelles
|
||||
- ✅ Pas de conflits de dépendances
|
||||
|
||||
---
|
||||
|
||||
## 📝 Documents Créés
|
||||
|
||||
1. **ANALYSE_ET_PLAN_OPTIMISATION.md** ✅
|
||||
- Analyse complète
|
||||
- Plan d'optimisation détaillé
|
||||
- Architecture cible
|
||||
- Checklist complète
|
||||
|
||||
2. **RESUME_ANALYSE.md** (ce document) ✅
|
||||
- Résumé exécutif
|
||||
- Prochaines actions
|
||||
|
||||
3. **Composant `user-card.xhtml`** ✅
|
||||
- Exemple de composant réutilisable
|
||||
- Documentation inline
|
||||
- Pattern WOU/DRY
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Utilisation
|
||||
|
||||
### Pour utiliser lions-user-manager dans un projet:
|
||||
|
||||
```xml
|
||||
<!-- Dans pom.xml -->
|
||||
<dependency>
|
||||
<groupId>dev.lions.user.manager</groupId>
|
||||
<artifactId>lions-user-manager-server-api</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Pour l'UI (si PrimeFaces) -->
|
||||
<dependency>
|
||||
<groupId>dev.lions.user.manager</groupId>
|
||||
<artifactId>lions-user-manager-client-quarkus-primefaces-freya</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
### Utilisation d'un composant:
|
||||
|
||||
```xhtml
|
||||
<ui:include src="/templates/components/user-management/user-card.xhtml">
|
||||
<ui:param name="user" value="#{userBean.selectedUser}" />
|
||||
<ui:param name="showActions" value="true" />
|
||||
<ui:param name="outcome" value="/pages/user-manager/users/profile" />
|
||||
</ui:include>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Document créé le**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
**Statut**: Analyse complétée, optimisation en cours
|
||||
|
||||
@@ -1,441 +0,0 @@
|
||||
# Résumé Complet des Corrections - Lions User Manager
|
||||
|
||||
**Date**: 2025-12-05
|
||||
**Statut**: ✅ Toutes les corrections appliquées et testées
|
||||
|
||||
---
|
||||
|
||||
## 📋 Vue d'Ensemble
|
||||
|
||||
### Problème Initial
|
||||
L'application Lions User Manager était presque complète mais rencontrait plusieurs problèmes critiques empêchant le fonctionnement de l'authentification et de la communication frontend-backend:
|
||||
|
||||
1. ❌ Aucun rôle métier n'existait dans Keycloak
|
||||
2. ❌ Backend plantait au démarrage (erreur bruteForceStrategy)
|
||||
3. ❌ Rôles extraits depuis le mauvais token (id_token au lieu de access_token)
|
||||
4. ❌ Token JWT pas propagé du frontend au backend
|
||||
5. ❌ Backend rejetait les tokens (problème d'audience)
|
||||
|
||||
### Résultat Final
|
||||
✅ Application complètement fonctionnelle avec authentification OIDC sécurisée, gestion des rôles, et communication frontend-backend sans erreur.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Corrections Appliquées
|
||||
|
||||
### Correction 1: Création des Rôles Keycloak
|
||||
|
||||
**Fichier créé**: `create-roles-and-assign.sh`
|
||||
|
||||
**Rôles créés**:
|
||||
1. `admin` - Administrateur système avec accès complet
|
||||
2. `user_manager` - Gestionnaire d'utilisateurs
|
||||
3. `user_viewer` - Visualiseur d'utilisateurs
|
||||
4. `auditor` - Auditeur
|
||||
5. `sync_manager` - Gestionnaire de synchronisation
|
||||
|
||||
**Utilisateur configuré**: `testuser` avec tous les rôles assignés
|
||||
|
||||
**Commande d'exécution**:
|
||||
```bash
|
||||
bash create-roles-and-assign.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Correction 2: Désactivation de KeycloakTestUserConfig
|
||||
|
||||
**Fichier modifié**:
|
||||
```
|
||||
lions-user-manager-server-impl-quarkus/src/main/java/dev/lions/user/manager/config/KeycloakTestUserConfig.java
|
||||
```
|
||||
|
||||
**Ligne**: 62-68
|
||||
|
||||
**Changement**:
|
||||
```java
|
||||
void onStart(@Observes StartupEvent ev) {
|
||||
// DÉSACTIVÉ: Configuration manuelle via script create-roles-and-assign.sh
|
||||
log.info("Configuration automatique de Keycloak DÉSACTIVÉE");
|
||||
return;
|
||||
/* Code original commenté */
|
||||
}
|
||||
```
|
||||
|
||||
**Raison**: La lecture automatique de la représentation du realm causait des erreurs de désérialisation JSON (bruteForceStrategy non reconnu par la version client Keycloak).
|
||||
|
||||
---
|
||||
|
||||
### Correction 3: Extraction des Rôles depuis Access Token
|
||||
|
||||
**Fichier modifié**:
|
||||
```
|
||||
lions-user-manager-client-quarkus-primefaces-freya/src/main/resources/application.properties
|
||||
```
|
||||
|
||||
**Ligne**: 64
|
||||
|
||||
**Propriété ajoutée**:
|
||||
```properties
|
||||
quarkus.oidc.roles.source=accesstoken
|
||||
```
|
||||
|
||||
**Raison**: Keycloak met `realm_access.roles` UNIQUEMENT dans l'access_token, pas dans l'id_token. Par défaut, Quarkus OIDC extrait les rôles depuis l'id_token.
|
||||
|
||||
---
|
||||
|
||||
### Correction 4: Propagation du Token JWT (Critique!)
|
||||
|
||||
Cette correction était la plus importante car elle résolvait le 401 Unauthorized.
|
||||
|
||||
#### 4a. Création du AuthHeaderFactory
|
||||
|
||||
**Fichier créé**:
|
||||
```
|
||||
lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/filter/AuthHeaderFactory.java
|
||||
```
|
||||
|
||||
**Code**:
|
||||
```java
|
||||
@ApplicationScoped
|
||||
public class AuthHeaderFactory implements ClientHeadersFactory {
|
||||
|
||||
@Inject
|
||||
JsonWebToken jwt;
|
||||
|
||||
@Override
|
||||
public MultivaluedMap<String, String> update(
|
||||
MultivaluedMap<String, String> incomingHeaders,
|
||||
MultivaluedMap<String, String> clientOutgoingHeaders) {
|
||||
|
||||
MultivaluedMap<String, String> result = new MultivaluedHashMap<>();
|
||||
|
||||
if (jwt != null && jwt.getRawToken() != null && !jwt.getRawToken().isEmpty()) {
|
||||
result.add("Authorization", "Bearer " + jwt.getRawToken());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Rôle**: Intercepte tous les appels REST Client et ajoute automatiquement le header `Authorization: Bearer {token}`.
|
||||
|
||||
#### 4b. Enregistrement sur les REST Clients
|
||||
|
||||
**Fichiers modifiés**:
|
||||
1. `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/service/UserServiceClient.java:20`
|
||||
2. `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/service/RoleServiceClient.java:19`
|
||||
3. `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/service/AuditServiceClient.java:20`
|
||||
4. `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/service/SyncServiceClient.java:16`
|
||||
|
||||
**Annotation ajoutée**:
|
||||
```java
|
||||
@RegisterClientHeaders(AuthHeaderFactory.class)
|
||||
```
|
||||
|
||||
**Exemple complet** (UserServiceClient):
|
||||
```java
|
||||
@Path("/api/users")
|
||||
@RegisterRestClient(configKey = "lions-user-manager-api")
|
||||
@RegisterClientHeaders(AuthHeaderFactory.class) // ← AJOUTÉ
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface UserServiceClient {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**Raison**: La configuration `bearer-token-propagation=true` ne fonctionne QUE pour les appels backend-to-backend. Pour les appels JSF-to-backend, il faut une injection manuelle via un `ClientHeadersFactory`.
|
||||
|
||||
---
|
||||
|
||||
### Correction 5: Configuration de l'Audience JWT
|
||||
|
||||
**Fichier modifié**:
|
||||
```
|
||||
lions-user-manager-server-impl-quarkus/src/main/resources/application-dev.properties
|
||||
```
|
||||
|
||||
**Ligne**: 25
|
||||
|
||||
**Changement**:
|
||||
```properties
|
||||
# AVANT
|
||||
quarkus.oidc.token.audience=optional
|
||||
|
||||
# APRÈS
|
||||
quarkus.oidc.token.audience=account
|
||||
```
|
||||
|
||||
**Raison**:
|
||||
- Keycloak ajoute automatiquement `"aud": "account"` aux access tokens
|
||||
- `audience=optional` ne désactive PAS la vérification, mais attend littéralement la valeur "optional"
|
||||
- `audience=account` accepte les tokens avec cette audience standard
|
||||
|
||||
---
|
||||
|
||||
## 📁 Fichiers Créés
|
||||
|
||||
1. **create-roles-and-assign.sh** - Script bash pour créer les rôles Keycloak
|
||||
2. **AuthHeaderFactory.java** - Factory pour propagation automatique du token JWT
|
||||
3. **CORRECTIONS_FINALES.md** - Document des corrections appliquées
|
||||
4. **SOLUTION_PROPAGATION_TOKEN.md** - Documentation technique détaillée de la propagation du token
|
||||
5. **INSTRUCTIONS_TEST_FINAL.md** - Instructions de test étape par étape
|
||||
6. **RESUME_CORRECTIONS_COMPLETE.md** - Ce document
|
||||
|
||||
---
|
||||
|
||||
## 📝 Fichiers Modifiés
|
||||
|
||||
### Backend
|
||||
1. `KeycloakTestUserConfig.java:62-68` - Désactivation de la configuration automatique
|
||||
2. `application-dev.properties:25` - Configuration de l'audience JWT
|
||||
|
||||
### Frontend
|
||||
3. `application.properties:64` - Source des rôles (accesstoken)
|
||||
4. `UserServiceClient.java:20` - Enregistrement AuthHeaderFactory
|
||||
5. `RoleServiceClient.java:19` - Enregistrement AuthHeaderFactory
|
||||
6. `AuditServiceClient.java:20` - Enregistrement AuthHeaderFactory
|
||||
7. `SyncServiceClient.java:16` - Enregistrement AuthHeaderFactory
|
||||
|
||||
**Total**: 7 fichiers modifiés + 6 fichiers créés
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests à Effectuer
|
||||
|
||||
Pour valider que tout fonctionne:
|
||||
|
||||
### 1. Redémarrer le Backend
|
||||
```bash
|
||||
cd lions-user-manager-server-impl-quarkus
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
**Vérifier**: Pas d'erreur bruteForceStrategy au démarrage
|
||||
|
||||
### 2. Redémarrer le Frontend
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
**Vérifier**: Compilation réussie, démarre sur port 8080
|
||||
|
||||
### 3. Test d'Authentification Complète
|
||||
1. Accéder à http://localhost:8080
|
||||
2. **Se déconnecter** (important!)
|
||||
3. **Se reconnecter** avec `testuser` / `test123`
|
||||
4. Naviguer vers http://localhost:8080/pages/user-manager/users/list.xhtml
|
||||
5. **Vérifier**: Liste des utilisateurs se charge sans erreur 401
|
||||
|
||||
### 4. Vérifier les Logs
|
||||
|
||||
**Frontend** (doit contenir):
|
||||
```
|
||||
FINE Token Bearer ajouté au header Authorization
|
||||
```
|
||||
|
||||
**Backend** (doit contenir):
|
||||
```
|
||||
DEBUG Token verification succeeded
|
||||
```
|
||||
|
||||
**Backend** (NE DOIT PAS contenir):
|
||||
```
|
||||
❌ Bearer access token is not available
|
||||
❌ Audience (aud) claim doesn't contain an acceptable identifier
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Architecture de la Solution
|
||||
|
||||
### Flux d'Authentification Complet
|
||||
|
||||
```
|
||||
1. Utilisateur → Frontend (http://localhost:8080)
|
||||
2. Frontend redirige → Keycloak (http://localhost:8180)
|
||||
3. Utilisateur entre testuser/test123
|
||||
4. Keycloak valide les credentials
|
||||
5. Keycloak génère tokens JWT:
|
||||
- access_token (contient realm_access.roles et aud: account)
|
||||
- id_token (identité utilisateur)
|
||||
- refresh_token
|
||||
6. Keycloak redirige → Frontend avec authorization code
|
||||
7. Frontend échange code → tokens via PKCE
|
||||
8. Quarkus OIDC stocke les tokens dans session HTTP
|
||||
9. JsonWebToken bean CDI créé avec access_token
|
||||
```
|
||||
|
||||
### Flux d'Appel API Frontend → Backend
|
||||
|
||||
```
|
||||
1. JSF Bean (UserListBean) appelle REST Client
|
||||
↓
|
||||
2. UserServiceClient.searchUsers(criteria)
|
||||
↓
|
||||
3. @RegisterClientHeaders déclenche AuthHeaderFactory
|
||||
↓
|
||||
4. AuthHeaderFactory injecte JsonWebToken
|
||||
↓
|
||||
5. AuthHeaderFactory.update() ajoute:
|
||||
Authorization: Bearer {access_token}
|
||||
↓
|
||||
6. Requête HTTP envoyée → Backend (http://localhost:8081)
|
||||
↓
|
||||
7. Backend BearerAuthenticationMechanism extrait le token
|
||||
↓
|
||||
8. Backend valide le token:
|
||||
- Signature JWT (clé publique Keycloak)
|
||||
- Issuer: http://localhost:8180/realms/lions-user-manager
|
||||
- Audience: account ✅
|
||||
- Expiration: non expiré ✅
|
||||
↓
|
||||
9. Backend extrait rôles depuis realm_access/roles
|
||||
↓
|
||||
10. Backend vérifie autorisations (@RolesAllowed)
|
||||
↓
|
||||
11. Backend exécute la logique métier
|
||||
↓
|
||||
12. Backend retourne les données JSON
|
||||
↓
|
||||
13. Frontend reçoit 200 OK + JSON
|
||||
↓
|
||||
14. JSF Bean met à jour la vue
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💡 Points Techniques Importants
|
||||
|
||||
### Pourquoi bearer-token-propagation ne suffit pas?
|
||||
|
||||
La propriété `quarkus.rest-client.bearer-token-propagation=true` fonctionne uniquement pour:
|
||||
- ✅ Appels Backend → Backend (service-to-service)
|
||||
- ❌ Appels JSF Bean → Backend (notre cas)
|
||||
|
||||
**Raison**: Les managed beans JSF s'exécutent dans un contexte serveur différent où le token OIDC n'est pas automatiquement disponible pour injection dans le REST Client.
|
||||
|
||||
**Solution**: `ClientHeadersFactory` personnalisé qui injecte manuellement le `JsonWebToken` CDI.
|
||||
|
||||
### Pourquoi JsonWebToken et pas SecurityContext?
|
||||
|
||||
- `SecurityContext` ne contient pas le token brut (raw token)
|
||||
- `JsonWebToken` est le bean CDI officiel Quarkus OIDC
|
||||
- Contient `getRawToken()` qui retourne le JWT complet en Base64
|
||||
- Thread-safe et géré par le contexte de requête CDI
|
||||
|
||||
### Pourquoi access_token et pas id_token?
|
||||
|
||||
- **id_token** = Identité utilisateur (claims: name, email, preferred_username, etc.)
|
||||
- **access_token** = Autorisation (claims: realm_access.roles, scope, aud, etc.)
|
||||
- Keycloak met `realm_access.roles` UNIQUEMENT dans l'access_token
|
||||
- Standard OAuth2/OIDC: access_token pour l'autorisation API
|
||||
|
||||
### Audience "account" c'est quoi?
|
||||
|
||||
- Keycloak ajoute automatiquement `"aud": "account"` aux access tokens
|
||||
- "account" = Client Keycloak interne pour la gestion de compte utilisateur
|
||||
- Tous les tokens Keycloak ont cette audience par défaut
|
||||
- On peut ajouter d'autres audiences via mappers, mais pas nécessaire ici
|
||||
|
||||
---
|
||||
|
||||
## 🚨 Pièges à Éviter
|
||||
|
||||
### 1. Ne pas se déconnecter avant de tester
|
||||
❌ **Erreur**: Tester avec l'ancien token qui n'a pas les nouveaux rôles
|
||||
✅ **Solution**: TOUJOURS se déconnecter et reconnecter après changement de configuration
|
||||
|
||||
### 2. Oublier de redémarrer après modifications
|
||||
❌ **Erreur**: Hot reload Quarkus ne détecte pas toujours les nouveaux fichiers
|
||||
✅ **Solution**: `mvn clean compile quarkus:dev` force une recompilation complète
|
||||
|
||||
### 3. Utiliser audience=optional
|
||||
❌ **Erreur**: Penser que "optional" désactive la vérification
|
||||
✅ **Solution**: Utiliser `audience=account` ou l'audience réelle du token
|
||||
|
||||
### 4. Chercher les rôles dans l'id_token
|
||||
❌ **Erreur**: `quarkus.oidc.roles.source=idtoken` (défaut)
|
||||
✅ **Solution**: `quarkus.oidc.roles.source=accesstoken`
|
||||
|
||||
### 5. Supposer que bearer-token-propagation fonctionne partout
|
||||
❌ **Erreur**: Compter uniquement sur la config properties
|
||||
✅ **Solution**: `ClientHeadersFactory` pour appels depuis JSF beans
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références et Documentation
|
||||
|
||||
### Quarkus
|
||||
- [Quarkus OIDC Guide](https://quarkus.io/guides/security-openid-connect)
|
||||
- [Quarkus REST Client](https://quarkus.io/guides/rest-client)
|
||||
- [Token Propagation](https://quarkus.io/guides/security-openid-connect-client-reference#token-propagation)
|
||||
|
||||
### Keycloak
|
||||
- [Keycloak Server Admin](https://www.keycloak.org/docs/latest/server_admin/)
|
||||
- [Securing Applications](https://www.keycloak.org/docs/latest/securing_apps/)
|
||||
- [JWT Structure](https://jwt.io)
|
||||
|
||||
### MicroProfile
|
||||
- [REST Client Spec](https://download.eclipse.org/microprofile/microprofile-rest-client-2.0/microprofile-rest-client-spec-2.0.html)
|
||||
- [JWT RBAC Spec](https://download.eclipse.org/microprofile/microprofile-jwt-auth-2.1/microprofile-jwt-auth-spec-2.1.html)
|
||||
|
||||
---
|
||||
|
||||
## ✅ Checklist de Validation Finale
|
||||
|
||||
### Configuration
|
||||
- [x] 5 rôles métier créés dans Keycloak
|
||||
- [x] testuser possède tous les rôles
|
||||
- [x] KeycloakTestUserConfig désactivé
|
||||
- [x] Backend accepte audience "account"
|
||||
- [x] Frontend extrait rôles depuis access_token
|
||||
- [x] AuthHeaderFactory créé et enregistré
|
||||
|
||||
### Démarrage
|
||||
- [ ] Keycloak démarre sur port 8180
|
||||
- [ ] Backend démarre sur port 8081 sans erreur
|
||||
- [ ] Frontend démarre sur port 8080 sans erreur
|
||||
|
||||
### Authentification
|
||||
- [ ] Déconnexion fonctionne
|
||||
- [ ] Reconnexion avec testuser/test123 fonctionne
|
||||
- [ ] Token contient les 5 rôles métier
|
||||
|
||||
### Intégration
|
||||
- [ ] Liste des utilisateurs se charge sans 401
|
||||
- [ ] Token est propagé au backend
|
||||
- [ ] Backend valide le token avec succès
|
||||
- [ ] Opérations CRUD fonctionnent
|
||||
|
||||
---
|
||||
|
||||
## 🎉 Conclusion
|
||||
|
||||
L'application **Lions User Manager** est maintenant **complètement fonctionnelle** avec:
|
||||
|
||||
✅ **Authentification OIDC sécurisée** avec Keycloak
|
||||
✅ **Gestion des rôles** (5 rôles métier configurés)
|
||||
✅ **Propagation automatique du token JWT** via AuthHeaderFactory
|
||||
✅ **Validation des tokens** côté backend avec vérification de l'audience
|
||||
✅ **Extraction correcte des rôles** depuis l'access_token
|
||||
✅ **Communication frontend-backend** sans erreur 401
|
||||
✅ **CRUD complet** sur les utilisateurs Keycloak
|
||||
|
||||
**Prochaines étapes possibles**:
|
||||
1. Tests unitaires et d'intégration
|
||||
2. Gestion des rôles via l'interface
|
||||
3. Audit et logs détaillés
|
||||
4. Synchronisation multi-realms
|
||||
5. Documentation utilisateur finale
|
||||
6. Déploiement en production
|
||||
|
||||
---
|
||||
|
||||
**Auteur**: Claude Code
|
||||
**Date**: 2025-12-05
|
||||
**Version**: 1.0.0
|
||||
**Statut**: ✅ Production Ready
|
||||
226
RESUME_FINAL.md
226
RESUME_FINAL.md
@@ -1,226 +0,0 @@
|
||||
# 🎉 Résumé Final - Optimisation Lions User Manager
|
||||
|
||||
**Date**: 2025-01-29
|
||||
**Statut**: ✅ **OPTIMISATION COMPLÉTÉE**
|
||||
|
||||
---
|
||||
|
||||
## 📊 Vue d'Ensemble
|
||||
|
||||
Le projet **lions-user-manager** a été **totalement optimisé** pour être un module réutilisable intégré à l'écosystème **lionsdev** et à **unionflow**.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Réalisations Complètes
|
||||
|
||||
### 1. Composants Réutilisables (14 composants) ✅
|
||||
|
||||
#### User Management (5)
|
||||
- ✅ `user-card.xhtml` - Carte utilisateur
|
||||
- ✅ `user-form.xhtml` - Formulaire utilisateur
|
||||
- ✅ `user-search-bar.xhtml` - Barre de recherche
|
||||
- ✅ `user-actions.xhtml` - Actions utilisateur
|
||||
- ✅ `user-role-badge.xhtml` - Badge de rôle
|
||||
|
||||
#### Role Management (3)
|
||||
- ✅ `role-card.xhtml` - Carte rôle
|
||||
- ✅ `role-form.xhtml` - Formulaire rôle
|
||||
- ✅ `role-assignment.xhtml` - Attribution rôles
|
||||
|
||||
#### Audit (2)
|
||||
- ✅ `audit-log-row.xhtml` - Ligne de log
|
||||
- ✅ `audit-stats-card.xhtml` - Carte statistiques
|
||||
|
||||
#### Shared (4)
|
||||
- ✅ `button-user-action.xhtml` - Bouton générique
|
||||
- ✅ `user-stat-card.xhtml` - Carte statistique
|
||||
- ✅ `user-form-field.xhtml` - Champ formulaire
|
||||
- ✅ `user-data-table.xhtml` - Tableau de données
|
||||
|
||||
### 2. REST Clients (4 interfaces) ✅
|
||||
|
||||
- ✅ `UserServiceClient.java` - 12 méthodes
|
||||
- ✅ `RoleServiceClient.java` - 15 méthodes
|
||||
- ✅ `AuditServiceClient.java` - 10 méthodes
|
||||
- ✅ `SyncServiceClient.java` - 6 méthodes
|
||||
|
||||
### 3. Beans JSF (5 beans) ✅
|
||||
|
||||
- ✅ `UserListBean.java` - Liste et recherche
|
||||
- ✅ `UserProfilBean.java` - Profil et édition
|
||||
- ✅ `UserCreationBean.java` - Création
|
||||
- ✅ `RoleGestionBean.java` - Gestion rôles
|
||||
- ✅ `AuditConsultationBean.java` - Consultation audit
|
||||
|
||||
### 4. Pages XHTML (7 pages) ✅
|
||||
|
||||
#### Users (4)
|
||||
- ✅ `list.xhtml` - Liste utilisateurs
|
||||
- ✅ `create.xhtml` - Création utilisateur
|
||||
- ✅ `profile.xhtml` - Profil utilisateur
|
||||
- ✅ `edit.xhtml` - Édition utilisateur
|
||||
|
||||
#### Roles (2)
|
||||
- ✅ `list.xhtml` - Liste rôles
|
||||
- ✅ `assign.xhtml` - Attribution rôles
|
||||
|
||||
#### Audit (1)
|
||||
- ✅ `logs.xhtml` - Journal d'audit
|
||||
|
||||
#### Sync (1)
|
||||
- ✅ `dashboard.xhtml` - Dashboard synchronisation
|
||||
|
||||
### 5. Layout Components (4 composants) ✅
|
||||
|
||||
- ✅ `main-template.xhtml` - Template principal
|
||||
- ✅ `topbar.xhtml` - Barre supérieure
|
||||
- ✅ `footer.xhtml` - Pied de page
|
||||
- ✅ `page-header.xhtml` - En-tête de page
|
||||
- ✅ `menu.xhtml` - Menu navigation
|
||||
|
||||
---
|
||||
|
||||
## 📈 Statistiques
|
||||
|
||||
| Catégorie | Nombre | Statut |
|
||||
|-----------|--------|--------|
|
||||
| **Composants réutilisables** | 14 | ✅ 100% |
|
||||
| **REST Clients** | 4 | ✅ 100% |
|
||||
| **Beans JSF** | 5 | ✅ 100% |
|
||||
| **Pages XHTML** | 7 | ✅ 100% |
|
||||
| **Layout Components** | 4 | ✅ 100% |
|
||||
| **TOTAL** | **34 fichiers** | ✅ **100%** |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Objectifs Atteints
|
||||
|
||||
### ✅ Réutilisabilité
|
||||
- ✅ Composants modulaires avec paramètres configurables
|
||||
- ✅ Pattern WOU/DRY respecté
|
||||
- ✅ Documentation inline complète
|
||||
- ✅ Compatible avec unionflow
|
||||
|
||||
### ✅ Intégration Écosystème
|
||||
- ✅ Structure compatible avec lionsdev
|
||||
- ✅ Patterns alignés avec unionflow
|
||||
- ✅ Prêt pour intégration unionflow
|
||||
|
||||
### ✅ Qualité
|
||||
- ✅ Validation JSF intégrée
|
||||
- ✅ Gestion d'erreurs complète
|
||||
- ✅ Logging structuré
|
||||
- ✅ Messages utilisateur
|
||||
|
||||
---
|
||||
|
||||
## 📂 Structure Finale
|
||||
|
||||
```
|
||||
lions-user-manager-client-quarkus-primefaces-freya/
|
||||
├── src/main/java/dev/lions/user/manager/client/
|
||||
│ ├── service/ # REST Clients (4)
|
||||
│ │ ├── UserServiceClient.java ✅
|
||||
│ │ ├── RoleServiceClient.java ✅
|
||||
│ │ ├── AuditServiceClient.java ✅
|
||||
│ │ └── SyncServiceClient.java ✅
|
||||
│ └── view/ # Beans JSF (5)
|
||||
│ ├── UserListBean.java ✅
|
||||
│ ├── UserProfilBean.java ✅
|
||||
│ ├── UserCreationBean.java ✅
|
||||
│ ├── RoleGestionBean.java ✅
|
||||
│ └── AuditConsultationBean.java ✅
|
||||
└── src/main/resources/META-INF/resources/
|
||||
├── templates/
|
||||
│ ├── components/ # Composants réutilisables (14)
|
||||
│ │ ├── user-management/ (5) ✅
|
||||
│ │ ├── role-management/ (3) ✅
|
||||
│ │ ├── audit/ (2) ✅
|
||||
│ │ ├── shared/ (4) ✅
|
||||
│ │ └── layout/ (4) ✅
|
||||
│ └── main-template.xhtml ✅
|
||||
└── pages/user-manager/ # Pages XHTML (7)
|
||||
├── users/ (4) ✅
|
||||
├── roles/ (2) ✅
|
||||
├── audit/ (1) ✅
|
||||
└── sync/ (1) ✅
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines Étapes
|
||||
|
||||
### Phase 1: Configuration (À faire)
|
||||
- [ ] Compléter `application.properties` avec configuration REST Client
|
||||
- [ ] Créer `faces-config.xml` pour navigation
|
||||
- [ ] Configurer Freya Theme dans POM.xml
|
||||
|
||||
### Phase 2: Intégration UnionFlow (À faire)
|
||||
- [ ] Ajouter dépendance Maven dans unionflow
|
||||
- [ ] Enrichir menu unionflow (section "Gestion des Membres")
|
||||
- [ ] Créer pages d'intégration dans unionflow
|
||||
|
||||
### Phase 3: Tests (À faire)
|
||||
- [ ] Tests unitaires Beans JSF
|
||||
- [ ] Tests d'intégration REST Clients
|
||||
- [ ] Tests UI (pages XHTML)
|
||||
|
||||
---
|
||||
|
||||
## 📝 Documents Créés
|
||||
|
||||
1. ✅ `ANALYSE_ET_PLAN_OPTIMISATION.md` - Plan complet
|
||||
2. ✅ `RESUME_ANALYSE.md` - Résumé exécutif
|
||||
3. ✅ `COMPOSANTS_CREES.md` - Liste composants
|
||||
4. ✅ `REST_CLIENTS_ET_BEANS_CREES.md` - REST Clients et Beans
|
||||
5. ✅ `PAGES_XHTML_CREES.md` - Pages XHTML
|
||||
6. ✅ `RESUME_FINAL.md` - Ce document
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Caractéristiques Techniques
|
||||
|
||||
### Patterns
|
||||
- ✅ **WOU/DRY** (Write Once Use / Don't Repeat Yourself)
|
||||
- ✅ **Template Pattern** pour pages XHTML
|
||||
- ✅ **Component Pattern** pour composants réutilisables
|
||||
- ✅ **REST Client Pattern** pour communication API
|
||||
|
||||
### Technologies
|
||||
- ✅ **PrimeFaces 14.0.5** - Composants UI
|
||||
- ✅ **Quarkus PrimeFaces 3.13.3** - Intégration Quarkus
|
||||
- ✅ **Freya Theme** - Thème PrimeFaces
|
||||
- ✅ **MicroProfile REST Client** - Clients REST
|
||||
- ✅ **JSF 4.0** - Framework web
|
||||
|
||||
### Qualité
|
||||
- ✅ Documentation inline complète
|
||||
- ✅ Validation JSF
|
||||
- ✅ Gestion d'erreurs
|
||||
- ✅ Logging structuré
|
||||
- ✅ Messages utilisateur
|
||||
|
||||
---
|
||||
|
||||
## 🏆 Résultat Final
|
||||
|
||||
**lions-user-manager** est maintenant un **module réutilisable complet** avec:
|
||||
|
||||
- ✅ **14 composants réutilisables** prêts à l'emploi
|
||||
- ✅ **4 REST Clients** pour communication API
|
||||
- ✅ **5 Beans JSF** pour logique métier
|
||||
- ✅ **7 pages XHTML** utilisant les composants
|
||||
- ✅ **4 composants layout** pour structure
|
||||
|
||||
**Le module est prêt pour:**
|
||||
- ✅ Utilisation dans lions-user-manager
|
||||
- ✅ Intégration avec unionflow
|
||||
- ✅ Réutilisation dans d'autres projets lionsdev
|
||||
|
||||
---
|
||||
|
||||
**Statut**: ✅ **OPTIMISATION 100% COMPLÉTÉE**
|
||||
**Date**: 2025-01-29
|
||||
**Version**: 1.0.0
|
||||
**Auteur**: Auto (Cursor AI)
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
# 📋 Résumé de la Réorganisation de la Configuration
|
||||
|
||||
## ✅ Problème résolu : Suppression des doublons
|
||||
|
||||
### Avant (Problème)
|
||||
- ❌ Configuration OIDC dupliquée dans `application.properties` (avec `%dev.`) ET `application-dev.properties` (sans préfixe)
|
||||
- ❌ Confusion sur quelle valeur est utilisée
|
||||
- ❌ Maintenance difficile
|
||||
|
||||
### Après (Solution)
|
||||
- ✅ Configuration OIDC principale dans `application.properties` avec préfixes `%dev.` et `%prod.`
|
||||
- ✅ `application-dev.properties` contient UNIQUEMENT les surcharges spécifiques (logging, CORS, etc.)
|
||||
- ✅ `application-prod.properties` documenté et prêt pour des surcharges spécifiques
|
||||
- ✅ Pas de doublons
|
||||
|
||||
## 📁 Organisation finale
|
||||
|
||||
### `application.properties`
|
||||
**Rôle** : Configuration de base + sections DEV et PROD
|
||||
- Configuration HTTP, MyFaces, PrimeFaces (tous profils)
|
||||
- Configuration OIDC de base (tous profils)
|
||||
- Section `%dev.*` : Configuration OIDC pour développement (lignes 73-81)
|
||||
- Section `%prod.*` : Configuration OIDC pour production (lignes 86-94)
|
||||
|
||||
### `application-dev.properties`
|
||||
**Rôle** : Surcharges spécifiques au développement
|
||||
- Logging détaillé (DEBUG, TRACE)
|
||||
- MyFaces en mode Development
|
||||
- Backend URL locale
|
||||
- CORS permissif
|
||||
- **Surcharge de `encryption-secret`** (ligne 45) pour garantir qu'elle soit chargée
|
||||
|
||||
### `application-prod.properties`
|
||||
**Rôle** : Surcharges spécifiques à la production (actuellement vide, prêt pour usage futur)
|
||||
|
||||
## 🔑 Propriété `encryption-secret`
|
||||
|
||||
### Définie à deux endroits (pour garantir le chargement) :
|
||||
1. **`application.properties` ligne 81** : `%dev.quarkus.oidc.token-state-manager.encryption-secret=...` (64 caractères)
|
||||
2. **`application-dev.properties` ligne 45** : `quarkus.oidc.token-state-manager.encryption-secret=...` (64 caractères)
|
||||
|
||||
**Pourquoi les deux ?**
|
||||
- `application.properties` avec `%dev.` : Configuration principale, visible pour tous
|
||||
- `application-dev.properties` : Surcharge pour garantir que Quarkus charge bien la valeur
|
||||
|
||||
**Valeur** : `NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKONTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO` (64 caractères)
|
||||
|
||||
## 📝 Règles de priorité Quarkus
|
||||
|
||||
1. Variables d'environnement (priorité la plus haute)
|
||||
2. `application-{profile}.properties` (ex: `application-dev.properties`)
|
||||
3. `%{profile}.property` dans `application.properties` (ex: `%dev.quarkus.oidc.enabled`)
|
||||
4. `property` dans `application.properties` (priorité la plus basse)
|
||||
|
||||
## ✅ Avantages de cette organisation
|
||||
|
||||
1. **Clarté** : On sait où chercher chaque configuration
|
||||
2. **Pas de doublons** : Chaque propriété est définie une seule fois (sauf `encryption-secret` pour garantir le chargement)
|
||||
3. **Maintenabilité** : Facile d'ajouter/modifier des configurations
|
||||
4. **Comparaison** : Facile de comparer dev vs prod dans `application.properties`
|
||||
|
||||
## 🎯 Prochaines étapes
|
||||
|
||||
1. Redémarrer le client avec `mvn clean quarkus:dev`
|
||||
2. Vérifier que l'erreur `encryption-secret` est résolue
|
||||
3. Si l'erreur persiste, vérifier les logs de debug OIDC pour voir quelle valeur est chargée
|
||||
|
||||
@@ -1,301 +0,0 @@
|
||||
# Solution: Propagation du Token JWT depuis JSF vers Backend
|
||||
|
||||
**Date**: 2025-12-05
|
||||
**Problème**: 401 Unauthorized lors des appels frontend → backend malgré authentification OIDC réussie
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Analyse du Problème
|
||||
|
||||
### Symptômes Observés
|
||||
1. **Frontend** (Port 8080):
|
||||
- ✅ Authentification OIDC réussie avec PKCE
|
||||
- ✅ Token JWT reçu avec tous les rôles dans `realm_access.roles`
|
||||
- ❌ Erreur: `Received: 'Unauthorized, status code 401'` lors des appels API
|
||||
|
||||
2. **Backend** (Port 8081):
|
||||
- ✅ Démarre sans erreur
|
||||
- ❌ Logs: `Bearer access token is not available`
|
||||
- ❌ Rejette les requêtes avec 401 Unauthorized
|
||||
|
||||
### Configuration Initiale (Insuffisante)
|
||||
```properties
|
||||
# application.properties:56
|
||||
quarkus.rest-client."lions-user-manager-api".bearer-token-propagation=true
|
||||
```
|
||||
|
||||
### Pourquoi ça ne fonctionnait pas ?
|
||||
La propriété `bearer-token-propagation=true` ne fonctionne QUE pour:
|
||||
- ✅ Appels **backend → backend** (service-to-service)
|
||||
- ❌ Appels **JSF managed bean → backend** (notre cas)
|
||||
|
||||
**Raison technique**: Les managed beans JSF s'exécutent dans un contexte serveur différent où le token OIDC n'est pas automatiquement injecté dans les appels REST Client.
|
||||
|
||||
---
|
||||
|
||||
## ✅ Solution Implémentée
|
||||
|
||||
### 1. Création de `AuthHeaderFactory`
|
||||
Factory personnalisé qui intercepte TOUS les appels REST Client et ajoute automatiquement le header Authorization avec le token JWT.
|
||||
|
||||
**Fichier**: `lions-user-manager-client-quarkus-primefaces-freya/src/main/java/dev/lions/user/manager/client/filter/AuthHeaderFactory.java`
|
||||
|
||||
```java
|
||||
@ApplicationScoped
|
||||
public class AuthHeaderFactory implements ClientHeadersFactory {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(AuthHeaderFactory.class.getName());
|
||||
|
||||
@Inject
|
||||
JsonWebToken jwt;
|
||||
|
||||
@Override
|
||||
public MultivaluedMap<String, String> update(
|
||||
MultivaluedMap<String, String> incomingHeaders,
|
||||
MultivaluedMap<String, String> clientOutgoingHeaders) {
|
||||
|
||||
MultivaluedMap<String, String> result = new MultivaluedHashMap<>();
|
||||
|
||||
try {
|
||||
// Vérifier si le JWT est disponible et non expiré
|
||||
if (jwt != null && jwt.getRawToken() != null && !jwt.getRawToken().isEmpty()) {
|
||||
String token = jwt.getRawToken();
|
||||
result.add("Authorization", "Bearer " + token);
|
||||
LOGGER.fine("Token Bearer ajouté au header Authorization");
|
||||
} else {
|
||||
LOGGER.warning("Token JWT non disponible ou vide");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.severe("Erreur lors de l'ajout du token Bearer: " + e.getMessage());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Points clés**:
|
||||
- `@ApplicationScoped` - Bean CDI singleton
|
||||
- `@Inject JsonWebToken jwt` - Injecte le token OIDC actuel
|
||||
- `jwt.getRawToken()` - Récupère le token brut (chaîne Base64)
|
||||
- Ajoute `Authorization: Bearer {token}` à chaque requête
|
||||
|
||||
### 2. Enregistrement sur tous les REST Clients
|
||||
Ajout de l'annotation `@RegisterClientHeaders(AuthHeaderFactory.class)` sur chaque interface REST Client.
|
||||
|
||||
#### UserServiceClient
|
||||
```java
|
||||
@Path("/api/users")
|
||||
@RegisterRestClient(configKey = "lions-user-manager-api")
|
||||
@RegisterClientHeaders(AuthHeaderFactory.class) // ← AJOUTÉ
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface UserServiceClient {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### Autres REST Clients modifiés
|
||||
- `RoleServiceClient.java:19`
|
||||
- `AuditServiceClient.java:20`
|
||||
- `SyncServiceClient.java:16`
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Test de la Solution
|
||||
|
||||
### 1. Recompiler le Frontend
|
||||
```bash
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn compile
|
||||
```
|
||||
|
||||
**Résultat attendu**: BUILD SUCCESS ✅
|
||||
|
||||
### 2. Redémarrer le Frontend (si nécessaire)
|
||||
Si le frontend ne recharge pas automatiquement les changements:
|
||||
```bash
|
||||
# Arrêter le frontend actuel (Ctrl+C)
|
||||
mvn quarkus:dev
|
||||
```
|
||||
|
||||
### 3. Test Complet
|
||||
1. Accéder à http://localhost:8080
|
||||
2. **Se déconnecter** (important pour obtenir un nouveau token)
|
||||
3. **Se reconnecter** avec `testuser` / `test123`
|
||||
4. Naviguer vers http://localhost:8080/pages/user-manager/users/list.xhtml
|
||||
5. **Vérifier**: La liste des utilisateurs se charge sans erreur 401
|
||||
|
||||
### 4. Vérification des Logs
|
||||
|
||||
#### Frontend - Token propagé
|
||||
```
|
||||
FINE Token Bearer ajouté au header Authorization
|
||||
```
|
||||
|
||||
#### Backend - Token reçu et validé
|
||||
```
|
||||
DEBUG [io.qu.oi.ru.BearerAuthenticationMechanism] Token validation succeeded
|
||||
```
|
||||
|
||||
Si vous voyez encore `Bearer access token is not available` → le token n'est toujours pas propagé (problème de contexte CDI ou hot reload).
|
||||
|
||||
---
|
||||
|
||||
## 📊 Comparaison Avant/Après
|
||||
|
||||
### AVANT (avec bearer-token-propagation uniquement)
|
||||
```
|
||||
Frontend JSF Bean → REST Client → Backend
|
||||
↓
|
||||
❌ Pas de token
|
||||
↓
|
||||
401 Unauthorized
|
||||
```
|
||||
|
||||
### APRÈS (avec AuthHeaderFactory)
|
||||
```
|
||||
Frontend JSF Bean → REST Client → AuthHeaderFactory
|
||||
↓
|
||||
@Inject JsonWebToken
|
||||
↓
|
||||
Authorization: Bearer {token}
|
||||
↓
|
||||
Backend
|
||||
↓
|
||||
✅ Token validé
|
||||
↓
|
||||
200 OK + Données
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Architecture Technique
|
||||
|
||||
### Flux d'exécution complet
|
||||
|
||||
1. **Utilisateur s'authentifie** via OIDC (Keycloak)
|
||||
- PKCE flow avec S256
|
||||
- Redirection vers Keycloak → Retour avec code → Échange contre tokens
|
||||
|
||||
2. **Quarkus OIDC reçoit les tokens**
|
||||
- `access_token` (contient `realm_access.roles`)
|
||||
- `id_token` (identité utilisateur)
|
||||
- `refresh_token` (renouvellement)
|
||||
|
||||
3. **Token injecté dans contexte CDI**
|
||||
- `JsonWebToken` bean disponible via `@Inject`
|
||||
- Contient toutes les claims du token
|
||||
|
||||
4. **JSF Bean appelle REST Client**
|
||||
- Ex: `userServiceClient.searchUsers(criteria)`
|
||||
|
||||
5. **AuthHeaderFactory intercepte l'appel**
|
||||
- Méthode `update()` appelée avant l'envoi HTTP
|
||||
- Injecte `Authorization: Bearer {access_token}`
|
||||
|
||||
6. **Backend reçoit la requête**
|
||||
- `BearerAuthenticationMechanism` extrait le token
|
||||
- Valide la signature JWT avec clé publique Keycloak
|
||||
- Extrait les rôles depuis `realm_access.roles`
|
||||
- Autorise l'accès si rôles suffisants
|
||||
|
||||
7. **Backend retourne les données**
|
||||
- HTTP 200 OK + JSON response
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Points Importants
|
||||
|
||||
### Pourquoi JsonWebToken et pas d'autres solutions ?
|
||||
1. ✅ **Native Quarkus** - Fait partie du stack OIDC standard
|
||||
2. ✅ **Thread-safe** - Géré par CDI avec contexte de requête
|
||||
3. ✅ **Type-safe** - Interface fortement typée
|
||||
4. ✅ **Validation automatique** - Token déjà validé par Quarkus OIDC
|
||||
|
||||
### Alternatives (non retenues)
|
||||
- ❌ `SecurityContext` - Ne contient pas le token brut
|
||||
- ❌ `OidcSession` - Trop couplé à la session HTTP
|
||||
- ❌ Header manuel dans chaque méthode - Code dupliqué et fragile
|
||||
- ❌ Filter JAX-RS - Plus complexe, moins naturel avec REST Client
|
||||
|
||||
### Avantages de cette solution
|
||||
1. **Automatique** - Aucun code dans les beans JSF
|
||||
2. **Centralisé** - Une seule classe factory
|
||||
3. **Réutilisable** - Fonctionne pour tous les REST Clients
|
||||
4. **Maintenable** - Facile à déboguer et à tester
|
||||
5. **Performant** - Aucune copie du token, juste une référence
|
||||
|
||||
---
|
||||
|
||||
## 📝 Checklist de Validation
|
||||
|
||||
Après implémentation de cette solution:
|
||||
|
||||
### Frontend
|
||||
- [x] `AuthHeaderFactory.java` créé dans `client/filter/`
|
||||
- [x] Tous les REST Clients annotés avec `@RegisterClientHeaders`
|
||||
- [x] Compilation Maven réussie
|
||||
- [x] Aucune erreur de hot reload
|
||||
|
||||
### Runtime
|
||||
- [ ] Se déconnecter puis reconnecter pour obtenir nouveau token
|
||||
- [ ] Naviguer vers la liste des utilisateurs
|
||||
- [ ] Vérifier logs frontend: "Token Bearer ajouté au header Authorization"
|
||||
- [ ] Vérifier logs backend: "Token validation succeeded"
|
||||
- [ ] Liste des utilisateurs s'affiche sans erreur 401
|
||||
|
||||
### Backend
|
||||
- [ ] Backend accepte les requêtes avec token
|
||||
- [ ] Rôles correctement extraits et appliqués
|
||||
- [ ] Pas de logs "Bearer access token is not available"
|
||||
|
||||
---
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### Problème: Token toujours pas propagé après changements
|
||||
**Cause**: Hot reload Quarkus n'a pas détecté les changements de factory
|
||||
|
||||
**Solution**:
|
||||
```bash
|
||||
# Arrêter le frontend (Ctrl+C)
|
||||
cd lions-user-manager-client-quarkus-primefaces-freya
|
||||
mvn clean compile quarkus:dev
|
||||
```
|
||||
|
||||
### Problème: "Token JWT non disponible ou vide"
|
||||
**Cause**: Contexte CDI ne trouve pas le JsonWebToken
|
||||
|
||||
**Solution**:
|
||||
1. Vérifier que l'utilisateur est authentifié
|
||||
2. Se déconnecter et reconnecter
|
||||
3. Vérifier logs OIDC: token doit être présent
|
||||
|
||||
### Problème: 401 sur certaines pages mais pas d'autres
|
||||
**Cause**: Chemins publics mal configurés
|
||||
|
||||
**Solution**: Vérifier `application.properties`:
|
||||
```properties
|
||||
quarkus.http.auth.permission.public.paths=/,/index.xhtml,...
|
||||
quarkus.http.auth.permission.authenticated.paths=/pages/user-manager/*
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Références
|
||||
|
||||
### Quarkus Documentation
|
||||
- [Quarkus OIDC Token Propagation](https://quarkus.io/guides/security-openid-connect-client-reference#token-propagation)
|
||||
- [Quarkus REST Client](https://quarkus.io/guides/rest-client)
|
||||
- [ClientHeadersFactory](https://download.eclipse.org/microprofile/microprofile-rest-client-2.0/microprofile-rest-client-spec-2.0.html#_clientheadersfactory)
|
||||
|
||||
### Keycloak
|
||||
- [JWT Token Structure](https://www.keycloak.org/docs/latest/securing_apps/#_token-exchange)
|
||||
- [Realm Roles vs Client Roles](https://www.keycloak.org/docs/latest/server_admin/#realm-roles)
|
||||
|
||||
---
|
||||
|
||||
**Auteur**: Claude Code
|
||||
**Date**: 2025-12-05
|
||||
**Version**: 1.0.0
|
||||
@@ -1,100 +0,0 @@
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
✅ LIONS USER MANAGER - LANDING PAGE
|
||||
IMPLÉMENTATION TERMINÉE
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
🎨 DESIGN: Freya Blue Template (Variant 1) - #4F8EEC
|
||||
📊 QUALITÉ: Enterprise Grade AAA (35/35 points)
|
||||
⚡ PERFORMANCE: 32KB, 4 requests, vanilla JS
|
||||
📱 RESPONSIVE: Mobile, Tablet, Desktop
|
||||
🎯 MÉTIER: B2B IAM avec vocabulaire technique
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
TESTS DE VALIDATION
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
✅ Page accessible HTTP/1.1 200 OK
|
||||
✅ Freya Blue branding "FREYA BLUE" trouvé
|
||||
✅ Couleur #4F8EEC 3 occurrences
|
||||
✅ Aucune trace violet 0 rgba(139,92,246)
|
||||
✅ Shadows bleues Freya 8 rgba(79,142,236)
|
||||
✅ Alert session expirée Message affiché
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
SECTIONS IMPLÉMENTÉES
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
1️⃣ NAVBAR Glassmorphism + Logo bleu
|
||||
2️⃣ HERO Badge + H1 gradient + 2 CTA
|
||||
3️⃣ STATS 4 compteurs animés
|
||||
4️⃣ FEATURES 6 cartes métier IAM
|
||||
5️⃣ CTA FINAL Gradient bleu + bouton
|
||||
6️⃣ FOOTER Copyright + badges
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
FICHIERS CRÉÉS
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
📄 index.html Page principale (32KB)
|
||||
📝 PAGE_ACCUEIL_FREYA_BLUE_FINAL.md Documentation technique
|
||||
📝 IMPLEMENTATION_COMPLETE.md Résumé final
|
||||
⚙️ application.properties Config redirect session
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
PALETTE FREYA BLUE
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
🔵 Primary: #4F8EEC (base)
|
||||
🔷 Hover: #387FE9 (au survol)
|
||||
⬛ Active: #2C6DCC (cliqué)
|
||||
⬛ Dark: #2159A8 (gradients foncés)
|
||||
|
||||
Shadow RGB: rgba(79, 142, 236, 0.35)
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
FLUX UTILISATEUR
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Premier accès: http://localhost:8082 → Landing page
|
||||
↓ Clique "Se connecter"
|
||||
→ dashboard.xhtml → Keycloak → Dashboard
|
||||
|
||||
Session expirée: ViewExpiredException détectée
|
||||
→ /index.html?expired=true
|
||||
→ Alerte rouge affichée
|
||||
→ Re-connexion Keycloak
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
SCORE FINAL
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Design Freya Blue: ⭐⭐⭐⭐⭐ (5/5)
|
||||
Performance: ⭐⭐⭐⭐⭐ (5/5)
|
||||
Responsive: ⭐⭐⭐⭐⭐ (5/5)
|
||||
Accessibilité: ⭐⭐⭐⭐⭐ (5/5)
|
||||
Code Quality (DRY): ⭐⭐⭐⭐⭐ (5/5)
|
||||
WOW Factor: ⭐⭐⭐⭐⭐ (5/5)
|
||||
Métier/Business: ⭐⭐⭐⭐⭐ (5/5)
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
TOTAL: 35/35 = PARFAIT ✅
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
🎉 CONCLUSION
|
||||
|
||||
La page d'accueil Lions User Manager est 100% PRÊTE pour la production
|
||||
avec les couleurs officielles du template Freya Blue acheté.
|
||||
|
||||
Le template a été parfaitement capitalisé ! 🚀
|
||||
|
||||
═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
URL de test:
|
||||
• Landing page: http://localhost:8082
|
||||
• Session expirée: http://localhost:8082/?expired=true
|
||||
• Dashboard: http://localhost:8082/pages/user-manager/dashboard.xhtml
|
||||
|
||||
Documentation:
|
||||
• lions-user-manager/PAGE_ACCUEIL_FREYA_BLUE_FINAL.md
|
||||
• lions-user-manager/IMPLEMENTATION_COMPLETE.md
|
||||
• lions-user-manager/SUMMARY_VISUAL.txt
|
||||
@@ -1,67 +0,0 @@
|
||||
# Tests Créés - Résumé Complet
|
||||
|
||||
## ✅ Tests Créés avec Succès
|
||||
|
||||
### Server-API (139 tests au total)
|
||||
- ✅ UserSearchCriteriaDTOTest (10 tests)
|
||||
- ✅ RoleAssignmentDTOTest (11 tests)
|
||||
- ✅ AuditLogDTOTest (5 tests)
|
||||
- ✅ StatutUserTest (4 tests)
|
||||
- ✅ TypeRoleTest (4 tests)
|
||||
- ✅ TypeActionAuditTest (4 tests)
|
||||
- ✅ RealmAssignmentDTOTest (12 tests - corrigé)
|
||||
|
||||
### Server-Impl-Quarkus (243 tests au total)
|
||||
- ✅ JacksonConfigTest (2 tests)
|
||||
- ✅ KeycloakTestUserConfigTest (3 tests)
|
||||
- ✅ DevSecurityContextProducerTest (3 tests)
|
||||
- ✅ RealmResourceAdditionalTest (3 tests)
|
||||
- ✅ RoleMapperAdditionalTest (4 tests)
|
||||
- ✅ AuditServiceImplAdditionalTest (9 tests)
|
||||
|
||||
### Client-Quarkus-Primefaces-Freya
|
||||
- ✅ RestClientExceptionMapperTest
|
||||
- ✅ AuthHeaderFactoryTest
|
||||
|
||||
## 📊 Couverture JaCoCo Actuelle
|
||||
|
||||
D'après le dernier rapport généré :
|
||||
- **Instructions** : 54% (amélioration possible)
|
||||
- **Branches** : 40% (amélioration possible)
|
||||
- **Lines** : 54% (amélioration possible)
|
||||
- **Methods** : 75% (bon niveau)
|
||||
- **Classes** : 90% (excellent niveau)
|
||||
|
||||
## 🎯 Objectif Atteint
|
||||
|
||||
- ✅ Tous les tests passent (243 tests dans server-impl-quarkus)
|
||||
- ✅ Tests créés pour les packages critiques
|
||||
- ✅ Rapport JaCoCo généré avec succès
|
||||
- ✅ Couverture améliorée significativement
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
Les tests supplémentaires créés ont amélioré la couverture, notamment pour :
|
||||
- Les DTOs et Enums (100% de couverture)
|
||||
- Les Mappers (99% de couverture)
|
||||
- Les Resources (84% de couverture)
|
||||
- Les Config et Security (tests créés)
|
||||
|
||||
Pour atteindre 100% de couverture, il faudrait créer des tests pour :
|
||||
- Les cas limites dans les services
|
||||
- Les méthodes privées via des tests d'intégration
|
||||
- Les classes de configuration avancées
|
||||
|
||||
## 🚀 Commandes Utiles
|
||||
|
||||
```bash
|
||||
# Exécuter tous les tests
|
||||
mvn clean test
|
||||
|
||||
# Générer le rapport JaCoCo
|
||||
mvn jacoco:report
|
||||
|
||||
# Voir le rapport
|
||||
# Ouvrir: lions-user-manager-server-impl-quarkus/target/site/jacoco/index.html
|
||||
```
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
# Rapport Final - Tests et Couverture JaCoCo
|
||||
|
||||
## ✅ Résultats des Tests
|
||||
|
||||
### Tests Exécutés avec Succès
|
||||
|
||||
**Server-API** : 139 tests - ✅ Tous passent
|
||||
**Server-Impl-Quarkus** : 263 tests - ✅ Tous passent
|
||||
**Client-Quarkus-Primefaces-Freya** : Tests créés et validés
|
||||
|
||||
### Tests Créés
|
||||
|
||||
#### Server-API
|
||||
- ✅ UserSearchCriteriaDTOTest (10 tests)
|
||||
- ✅ RoleAssignmentDTOTest (11 tests)
|
||||
- ✅ AuditLogDTOTest (5 tests)
|
||||
- ✅ StatutUserTest (4 tests)
|
||||
- ✅ TypeRoleTest (4 tests)
|
||||
- ✅ TypeActionAuditTest (4 tests)
|
||||
- ✅ RealmAssignmentDTOTest (12 tests - corrigé)
|
||||
|
||||
#### Server-Impl-Quarkus
|
||||
- ✅ JacksonConfigTest (2 tests)
|
||||
- ✅ KeycloakTestUserConfigTest (3 tests)
|
||||
- ✅ DevSecurityContextProducerTest (3 tests - corrigé)
|
||||
- ✅ RealmResourceAdditionalTest (3 tests)
|
||||
- ✅ RoleMapperAdditionalTest (4 tests)
|
||||
- ✅ AuditServiceImplAdditionalTest (9 tests)
|
||||
- ✅ RoleServiceImplExtendedTest (10 tests) - **NOUVEAU**
|
||||
- ✅ UserServiceImplExtendedTest (10 tests) - **NOUVEAU**
|
||||
|
||||
#### Client-Quarkus-Primefaces-Freya
|
||||
- ✅ RestClientExceptionMapperTest
|
||||
- ✅ AuthHeaderFactoryTest
|
||||
|
||||
## 📊 Couverture JaCoCo
|
||||
|
||||
D'après le dernier rapport généré :
|
||||
- **Instructions** : 54% (amélioration possible)
|
||||
- **Branches** : 40% (amélioration possible)
|
||||
- **Lines** : 54% (amélioration possible)
|
||||
- **Methods** : 75% (bon niveau)
|
||||
- **Classes** : 90% (excellent niveau)
|
||||
|
||||
### Couverture par Package
|
||||
|
||||
1. **dev.lions.user.manager.mapper** : 99% ✅
|
||||
2. **dev.lions.user.manager.resource** : 84% ✅
|
||||
3. **dev.lions.user.manager.service.impl** : 40% ⚠️ (amélioré avec les nouveaux tests)
|
||||
4. **dev.lions.user.manager.client** : 36% ⚠️
|
||||
5. **dev.lions.user.manager.config** : 11% ⚠️ (tests créés)
|
||||
6. **dev.lions.user.manager.security** : 0% → Tests créés ✅
|
||||
|
||||
## 🎯 Améliorations Réalisées
|
||||
|
||||
1. ✅ **Tous les tests passent** (263 tests dans server-impl-quarkus)
|
||||
2. ✅ **Tests créés pour les packages critiques** (security, config, services)
|
||||
3. ✅ **Couverture améliorée** pour les méthodes importantes :
|
||||
- `userHasRole`, `roleExists`, `countUsersWithRole` dans RoleServiceImpl
|
||||
- `deactivateUser`, `resetPassword`, `sendVerificationEmail`, `logoutAllSessions`, `getActiveSessions` dans UserServiceImpl
|
||||
3. ✅ **Rapport JaCoCo généré avec succès**
|
||||
|
||||
## 📝 Notes
|
||||
|
||||
Pour atteindre 100% de couverture, il faudrait :
|
||||
- Créer des tests d'intégration pour les cas limites
|
||||
- Tester les méthodes privées via des tests d'intégration
|
||||
- Améliorer la couverture des branches conditionnelles
|
||||
- Tester les cas d'erreur complexes
|
||||
|
||||
## 🚀 Commandes
|
||||
|
||||
```bash
|
||||
# Exécuter tous les tests
|
||||
mvn clean test
|
||||
|
||||
# Générer le rapport JaCoCo
|
||||
mvn jacoco:report
|
||||
|
||||
# Voir le rapport
|
||||
# Ouvrir: lions-user-manager-server-impl-quarkus/target/site/jacoco/index.html
|
||||
```
|
||||
|
||||
## 📈 Statistiques Finales
|
||||
|
||||
- **Total tests** : 402+ tests (139 + 263)
|
||||
- **Tests qui passent** : 402/402 (100%)
|
||||
- **Tests qui échouent** : 0
|
||||
- **Couverture Instructions** : 54%
|
||||
- **Couverture Branches** : 40%
|
||||
- **Couverture Methods** : 75%
|
||||
- **Couverture Classes** : 90%
|
||||
|
||||
119
TESTS_SUMMARY.md
119
TESTS_SUMMARY.md
@@ -1,119 +0,0 @@
|
||||
# Résumé des Tests Créés pour 100% de Couverture JaCoCo
|
||||
|
||||
## Tests Créés et Corrigés
|
||||
|
||||
### Server-API (lions-user-manager-server-api)
|
||||
|
||||
#### DTOs
|
||||
- ✅ **UserSearchCriteriaDTOTest.java** - Tests complets (10 tests)
|
||||
- ✅ **RoleAssignmentDTOTest.java** - Tests complets (11 tests)
|
||||
- ✅ **AuditLogDTOTest.java** - Tests complets (5 tests)
|
||||
- ⚠️ **RealmAssignmentDTOTest.java** - 1 test échoue (testIsExpired_Expired)
|
||||
|
||||
#### Enums
|
||||
- ✅ **StatutUserTest.java** - Tests complets (4 tests)
|
||||
- ✅ **TypeRoleTest.java** - Tests complets (4 tests)
|
||||
- ✅ **TypeActionAuditTest.java** - Tests complets (4 tests)
|
||||
|
||||
### Server-Impl-Quarkus (lions-user-manager-server-impl-quarkus)
|
||||
|
||||
#### Mappers
|
||||
- ✅ **UserMapperAdditionalTest.java** - Tests supplémentaires
|
||||
- ✅ **RoleMapperAdditionalTest.java** - Tests supplémentaires
|
||||
|
||||
#### Resources
|
||||
- ✅ **RealmResourceAdditionalTest.java** - Tests supplémentaires
|
||||
- ✅ **UserResourceAdditionalTest.java** - Tests supplémentaires
|
||||
|
||||
#### Services
|
||||
- ✅ **UserServiceImplAdditionalTest.java** - Tests supplémentaires
|
||||
- ✅ **RoleServiceImplAdditionalTest.java** - Tests supplémentaires
|
||||
- ✅ **AuditServiceImplAdditionalTest.java** - Tests supplémentaires
|
||||
- ✅ **SyncServiceImplAdditionalTest.java** - Tests supplémentaires
|
||||
|
||||
#### Clients
|
||||
- ✅ **KeycloakAdminClientImplAdditionalTest.java** - Tests supplémentaires
|
||||
|
||||
#### Config
|
||||
- ✅ **JacksonConfigTest.java** - Tests complets
|
||||
|
||||
### Client-Quarkus-Primefaces-Freya
|
||||
|
||||
#### Services/Filters
|
||||
- ✅ **RestClientExceptionMapperTest.java** - Tests complets
|
||||
- ✅ **AuthHeaderFactoryTest.java** - Tests complets
|
||||
|
||||
## Tests Existant Déjà
|
||||
|
||||
### Server-API
|
||||
- BaseDTOTest.java
|
||||
- RoleDTOTest.java
|
||||
- UserDTOTest.java
|
||||
- UserSearchResultDTOTest.java
|
||||
- HealthStatusDTOTest.java
|
||||
- SyncResultDTOTest.java
|
||||
- ValidationConstantsTest.java
|
||||
|
||||
### Server-Impl-Quarkus
|
||||
- UserMapperTest.java
|
||||
- RoleMapperTest.java
|
||||
- UserServiceImplTest.java
|
||||
- RoleServiceImplTest.java
|
||||
- AuditServiceImplTest.java
|
||||
- SyncServiceImplTest.java
|
||||
- UserResourceTest.java
|
||||
- RoleResourceTest.java
|
||||
- AuditResourceTest.java
|
||||
- SyncResourceTest.java
|
||||
- HealthResourceEndpointTest.java
|
||||
- KeycloakAdminClientImplTest.java
|
||||
- RealmResourceTest.java
|
||||
- RealmAssignmentResourceTest.java
|
||||
- RealmAuthorizationServiceImplTest.java
|
||||
- KeycloakTestUserConfigTest.java
|
||||
|
||||
### Client-Quarkus-Primefaces-Freya
|
||||
- UserProfilBeanTest.java
|
||||
- UserCreationBeanTest.java
|
||||
- RoleGestionBeanTest.java
|
||||
- UserListBeanTest.java
|
||||
- AuditConsultationBeanTest.java
|
||||
- DashboardBeanTest.java
|
||||
- UserSessionBeanTest.java
|
||||
- SettingsBeanTest.java
|
||||
- RealmAssignmentBeanTest.java
|
||||
- GuestPreferencesTest.java
|
||||
|
||||
## Problèmes Identifiés
|
||||
|
||||
1. **RealmAssignmentDTOTest.testIsExpired_Expired** - Test échoue (expected: <true> but was: <false>)
|
||||
- Nécessite de vérifier la logique de `isExpired()` dans RealmAssignmentDTO
|
||||
|
||||
## Prochaines Étapes
|
||||
|
||||
1. ✅ Corriger le test RealmAssignmentDTOTest.testIsExpired_Expired
|
||||
2. ✅ Exécuter tous les tests pour vérifier qu'ils passent
|
||||
3. ✅ Générer le rapport JaCoCo pour vérifier la couverture
|
||||
4. ✅ Créer des tests supplémentaires pour les classes non couvertes
|
||||
5. ✅ Atteindre 100% de couverture JaCoCo
|
||||
|
||||
## Statistiques
|
||||
|
||||
- **Total tests créés** : ~30+ nouveaux fichiers de tests
|
||||
- **Tests existants** : ~20+ fichiers de tests
|
||||
- **Tests qui passent** : 132/133 (99.2%)
|
||||
- **Tests qui échouent** : 1/133 (0.8%)
|
||||
|
||||
## Commandes Utiles
|
||||
|
||||
```bash
|
||||
# Exécuter tous les tests
|
||||
mvn clean test
|
||||
|
||||
# Générer le rapport JaCoCo
|
||||
mvn jacoco:report
|
||||
|
||||
# Voir le rapport (ouvrir dans navigateur)
|
||||
# target/site/jacoco/index.html
|
||||
```
|
||||
|
||||
106
TEST_BACKEND.md
106
TEST_BACKEND.md
@@ -1,106 +0,0 @@
|
||||
# Test du Backend - Lions User Manager
|
||||
|
||||
## ⚠️ Important : Le port 8081 ne sert PAS de pages web !
|
||||
|
||||
Le message "Forbidden" sur `http://localhost:8081/` est **NORMAL**.
|
||||
|
||||
Le backend est une **API REST** uniquement, il n'a pas de page d'accueil HTML.
|
||||
|
||||
## ✅ URLs à tester à la place :
|
||||
|
||||
### 1. Swagger UI (Interface de documentation API)
|
||||
```
|
||||
http://localhost:8081/q/swagger-ui
|
||||
```
|
||||
C'est l'interface graphique pour tester toutes les API.
|
||||
|
||||
### 2. Health Check
|
||||
```
|
||||
http://localhost:8081/q/health
|
||||
```
|
||||
Vérifie que l'application tourne correctement.
|
||||
|
||||
### 3. Metrics
|
||||
```
|
||||
http://localhost:8081/q/metrics
|
||||
```
|
||||
Statistiques de l'application.
|
||||
|
||||
### 4. API Users (endpoint principal)
|
||||
```bash
|
||||
# Lister les utilisateurs du realm lions-user-manager
|
||||
curl "http://localhost:8081/api/users?realm=lions-user-manager"
|
||||
|
||||
# Ou dans votre navigateur :
|
||||
http://localhost:8081/api/users?realm=lions-user-manager
|
||||
```
|
||||
|
||||
### 5. Dev UI (Console de développement Quarkus)
|
||||
```
|
||||
http://localhost:8081/q/dev
|
||||
```
|
||||
|
||||
## 🔧 Test complet avec curl
|
||||
|
||||
```bash
|
||||
# 1. Health check
|
||||
curl http://localhost:8081/q/health
|
||||
|
||||
# 2. Lister les utilisateurs
|
||||
curl "http://localhost:8081/api/users?realm=lions-user-manager"
|
||||
|
||||
# 3. Lister les rôles
|
||||
curl "http://localhost:8081/api/roles/realm?realm=lions-user-manager"
|
||||
|
||||
# 4. Health check Keycloak
|
||||
curl http://localhost:8081/api/health/keycloak
|
||||
```
|
||||
|
||||
## 🌐 Pour l'interface WEB, utilisez le frontend :
|
||||
|
||||
L'interface web JSF/PrimeFaces est sur le **port 8080** :
|
||||
```
|
||||
http://localhost:8080
|
||||
```
|
||||
|
||||
C'est là que vous verrez les pages XHTML et pourrez vous connecter avec `testuser/test123`.
|
||||
|
||||
## 📊 Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────┐
|
||||
│ Frontend (8080) │ ← Pages web XHTML/PrimeFaces
|
||||
│ Interface utilisateur
|
||||
└──────────┬──────────┘
|
||||
│
|
||||
│ Appelle les API
|
||||
│
|
||||
▼
|
||||
┌─────────────────────┐
|
||||
│ Backend (8081) │ ← API REST uniquement (pas de pages web)
|
||||
│ Endpoints REST │ C'est pour ça que / retourne Forbidden
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
## ❓ Pourquoi "Forbidden" ?
|
||||
|
||||
Le backend Quarkus est configuré avec :
|
||||
```properties
|
||||
quarkus.oidc.enabled=false
|
||||
quarkus.security.jaxrs.deny-unannotated-endpoints=false
|
||||
```
|
||||
|
||||
Mais il n'y a **aucun endpoint** défini pour `/` (la racine).
|
||||
|
||||
Les seuls endpoints disponibles sont :
|
||||
- `/api/*` - API REST
|
||||
- `/q/*` - Endpoints Quarkus (dev UI, health, metrics, swagger)
|
||||
|
||||
## ✅ Solution
|
||||
|
||||
**Utilisez Swagger UI** pour tester l'API :
|
||||
```
|
||||
http://localhost:8081/q/swagger-ui
|
||||
```
|
||||
|
||||
Ou testez directement les endpoints API avec curl ou votre navigateur.
|
||||
@@ -1,155 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script de configuration Keycloak pour corriger l'authentification frontend
|
||||
set -e
|
||||
|
||||
KEYCLOAK_URL="http://localhost:8180"
|
||||
REALM="lions-user-manager"
|
||||
CLIENT_ID="lions-user-manager-client"
|
||||
CLIENT_SECRET="client-secret-lions-2025"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Configuration Keycloak pour Frontend"
|
||||
echo "=========================================="
|
||||
|
||||
# 1. Obtenir le token admin
|
||||
echo "1. Récupération du token admin..."
|
||||
TOKEN=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=admin" \
|
||||
-d "password=admin" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=admin-cli" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "❌ Erreur: Impossible d'obtenir le token admin"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Token obtenu"
|
||||
|
||||
# 2. Vérifier si le client existe
|
||||
echo ""
|
||||
echo "2. Vérification du client ${CLIENT_ID}..."
|
||||
CLIENTS=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
# Extraire l'ID interne du client
|
||||
INTERNAL_CLIENT_ID=$(echo "$CLIENTS" | grep -B 5 "\"clientId\":\"${CLIENT_ID}\"" | grep '"id"' | head -1 | grep -o '"id":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$INTERNAL_CLIENT_ID" ]; then
|
||||
echo "⚠️ Client ${CLIENT_ID} n'existe pas, création..."
|
||||
|
||||
# Créer le client
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"clientId\": \"${CLIENT_ID}\",
|
||||
\"enabled\": true,
|
||||
\"protocol\": \"openid-connect\",
|
||||
\"publicClient\": false,
|
||||
\"secret\": \"${CLIENT_SECRET}\",
|
||||
\"redirectUris\": [\"http://localhost:8080/*\"],
|
||||
\"webOrigins\": [\"http://localhost:8080\"],
|
||||
\"standardFlowEnabled\": true,
|
||||
\"directAccessGrantsEnabled\": true,
|
||||
\"serviceAccountsEnabled\": false,
|
||||
\"implicitFlowEnabled\": false,
|
||||
\"fullScopeAllowed\": true
|
||||
}"
|
||||
|
||||
echo "✅ Client créé"
|
||||
|
||||
# Récupérer l'ID après création
|
||||
CLIENTS=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
INTERNAL_CLIENT_ID=$(echo "$CLIENTS" | grep -B 5 "\"clientId\":\"${CLIENT_ID}\"" | grep '"id"' | head -1 | grep -o '"id":"[^"]*' | cut -d'"' -f4)
|
||||
else
|
||||
echo "✅ Client existe (ID: ${INTERNAL_CLIENT_ID})"
|
||||
fi
|
||||
|
||||
# 3. Mettre à jour la configuration du client
|
||||
echo ""
|
||||
echo "3. Mise à jour de la configuration du client..."
|
||||
curl -s -X PUT "${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${INTERNAL_CLIENT_ID}" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"clientId\": \"${CLIENT_ID}\",
|
||||
\"enabled\": true,
|
||||
\"protocol\": \"openid-connect\",
|
||||
\"publicClient\": false,
|
||||
\"redirectUris\": [\"http://localhost:8080/*\"],
|
||||
\"webOrigins\": [\"+\"],
|
||||
\"standardFlowEnabled\": true,
|
||||
\"directAccessGrantsEnabled\": true,
|
||||
\"serviceAccountsEnabled\": false,
|
||||
\"implicitFlowEnabled\": false,
|
||||
\"fullScopeAllowed\": true,
|
||||
\"attributes\": {
|
||||
\"access.token.lifespan\": \"3600\",
|
||||
\"use.refresh.tokens\": \"true\"
|
||||
}
|
||||
}"
|
||||
|
||||
echo "✅ Configuration mise à jour"
|
||||
|
||||
# 4. Définir le secret du client
|
||||
echo ""
|
||||
echo "4. Configuration du secret client..."
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${INTERNAL_CLIENT_ID}/client-secret" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"value\": \"${CLIENT_SECRET}\"}"
|
||||
|
||||
echo "✅ Secret configuré"
|
||||
|
||||
# 5. Vérifier les utilisateurs
|
||||
echo ""
|
||||
echo "5. Vérification des utilisateurs..."
|
||||
USERS=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/users" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
USER_COUNT=$(echo "$USERS" | grep -c '"username"' || echo "0")
|
||||
echo "✅ Utilisateurs trouvés: ${USER_COUNT}"
|
||||
|
||||
if [ "$USER_COUNT" -eq "0" ]; then
|
||||
echo "⚠️ Aucun utilisateur trouvé, création de testuser..."
|
||||
|
||||
# Créer l'utilisateur testuser
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/users" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "testuser",
|
||||
"enabled": true,
|
||||
"emailVerified": true,
|
||||
"firstName": "Test",
|
||||
"lastName": "User",
|
||||
"email": "testuser@lions.dev",
|
||||
"credentials": [{
|
||||
"type": "password",
|
||||
"value": "test123",
|
||||
"temporary": false
|
||||
}]
|
||||
}'
|
||||
|
||||
echo "✅ Utilisateur testuser créé"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "✅ Configuration Keycloak terminée!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Informations de connexion:"
|
||||
echo " Realm: ${REALM}"
|
||||
echo " Client ID: ${CLIENT_ID}"
|
||||
echo " Client Secret: ${CLIENT_SECRET}"
|
||||
echo " Test User: testuser / test123"
|
||||
echo ""
|
||||
echo "URLs:"
|
||||
echo " Frontend: http://localhost:8080"
|
||||
echo " Backend: http://localhost:8081"
|
||||
echo " Keycloak: http://localhost:8180"
|
||||
echo ""
|
||||
@@ -1,179 +0,0 @@
|
||||
# Script PowerShell de configuration Keycloak - Utilisateur de test
|
||||
# Utilise l'API Admin REST de Keycloak pour créer l'utilisateur et les rôles
|
||||
|
||||
$KEYCLOAK_URL = "http://localhost:8180"
|
||||
$ADMIN_USER = "admin"
|
||||
$ADMIN_PASSWORD = "admin"
|
||||
$REALM = "lions-user-manager"
|
||||
$TEST_USER = "test-user"
|
||||
$TEST_PASSWORD = "test123"
|
||||
$TEST_EMAIL = "test@lions.dev"
|
||||
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host "Configuration Keycloak - Utilisateur Test" -ForegroundColor Cyan
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# 1. Obtenir le token d'administration
|
||||
Write-Host "1. Authentification admin..." -ForegroundColor Yellow
|
||||
$tokenParams = "username=$ADMIN_USER&password=$ADMIN_PASSWORD&grant_type=password&client_id=admin-cli"
|
||||
$tokenResponse = Invoke-RestMethod -Uri "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" -Method Post -ContentType "application/x-www-form-urlencoded" -Body $tokenParams
|
||||
|
||||
$ACCESS_TOKEN = $tokenResponse.access_token
|
||||
|
||||
if (-not $ACCESS_TOKEN) {
|
||||
Write-Host "ERREUR: Impossible d'obtenir le token d'administration" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✓ Token obtenu" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# 2. Vérifier/Créer le realm
|
||||
Write-Host "2. Vérification du realm '$REALM'..." -ForegroundColor Yellow
|
||||
$headers = @{Authorization = "Bearer $ACCESS_TOKEN"}
|
||||
try {
|
||||
$realmCheck = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM" -Method Get -Headers $headers -ErrorAction Stop
|
||||
Write-Host "✓ Realm existe déjà" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host "Création du realm '$REALM'..." -ForegroundColor Yellow
|
||||
$realmBody = @{
|
||||
realm = $REALM
|
||||
enabled = $true
|
||||
} | ConvertTo-Json
|
||||
|
||||
$headersWithContent = @{Authorization = "Bearer $ACCESS_TOKEN"; "Content-Type" = "application/json"}
|
||||
Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms" -Method Post -Headers $headersWithContent -Body $realmBody | Out-Null
|
||||
Write-Host "✓ Realm créé" -ForegroundColor Green
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# 3. Créer les rôles realm
|
||||
Write-Host "3. Création des rôles realm..." -ForegroundColor Yellow
|
||||
$ROLES = @("admin", "user_manager", "user_viewer", "role_manager", "role_viewer", "auditor", "sync_manager")
|
||||
|
||||
foreach ($ROLE in $ROLES) {
|
||||
Write-Host " - Vérification du rôle '$ROLE'..." -ForegroundColor Gray
|
||||
try {
|
||||
$roleCheck = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/roles/$ROLE" -Method Get -Headers $headers -ErrorAction Stop
|
||||
Write-Host " ✓ Rôle '$ROLE' existe déjà" -ForegroundColor Green
|
||||
} catch {
|
||||
$roleBody = @{
|
||||
name = $ROLE
|
||||
description = "Rôle $ROLE pour lions-user-manager"
|
||||
} | ConvertTo-Json
|
||||
|
||||
$headersWithContent = @{Authorization = "Bearer $ACCESS_TOKEN"; "Content-Type" = "application/json"}
|
||||
Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/roles" -Method Post -Headers $headersWithContent -Body $roleBody | Out-Null
|
||||
Write-Host " ✓ Rôle '$ROLE' créé" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# 4. Créer l'utilisateur de test
|
||||
Write-Host "4. Création de l'utilisateur '$TEST_USER'..." -ForegroundColor Yellow
|
||||
$users = $null
|
||||
try {
|
||||
$users = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/users?username=$TEST_USER" -Method Get -Headers $headers -ErrorAction Stop
|
||||
} catch {
|
||||
$users = $null
|
||||
}
|
||||
|
||||
if ($users -and $users.Count -gt 0) {
|
||||
$USER_ID = $users[0].id
|
||||
Write-Host " ✓ Utilisateur existe déjà (ID: $USER_ID)" -ForegroundColor Green
|
||||
} else {
|
||||
$userBody = @{
|
||||
username = $TEST_USER
|
||||
email = $TEST_EMAIL
|
||||
firstName = "Test"
|
||||
lastName = "User"
|
||||
enabled = $true
|
||||
emailVerified = $true
|
||||
} | ConvertTo-Json
|
||||
|
||||
$headersWithContent = @{Authorization = "Bearer $ACCESS_TOKEN"; "Content-Type" = "application/json"}
|
||||
Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/users" -Method Post -Headers $headersWithContent -Body $userBody | Out-Null
|
||||
|
||||
$users = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/users?username=$TEST_USER" -Method Get -Headers $headers
|
||||
$USER_ID = $users[0].id
|
||||
|
||||
Write-Host " ✓ Utilisateur créé (ID: $USER_ID)" -ForegroundColor Green
|
||||
|
||||
$passwordBody = @{
|
||||
type = "password"
|
||||
value = $TEST_PASSWORD
|
||||
temporary = $false
|
||||
} | ConvertTo-Json
|
||||
|
||||
Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/users/$USER_ID/reset-password" -Method Put -Headers $headersWithContent -Body $passwordBody | Out-Null
|
||||
Write-Host " ✓ Mot de passe défini" -ForegroundColor Green
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# 5. Assigner les rôles à l'utilisateur
|
||||
Write-Host "5. Attribution des rôles à l'utilisateur..." -ForegroundColor Yellow
|
||||
|
||||
$roleRepresentations = @()
|
||||
foreach ($ROLE in $ROLES) {
|
||||
$roleRep = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/roles/$ROLE" -Method Get -Headers $headers
|
||||
$roleRepresentations += $roleRep
|
||||
}
|
||||
|
||||
$headersWithContent = @{Authorization = "Bearer $ACCESS_TOKEN"; "Content-Type" = "application/json"}
|
||||
Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/users/$USER_ID/role-mappings/realm" -Method Post -Headers $headersWithContent -Body ($roleRepresentations | ConvertTo-Json) | Out-Null
|
||||
|
||||
Write-Host " ✓ Rôles assignés" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# 6. Vérifier le client et le mapper de rôles
|
||||
Write-Host "6. Vérification du client 'lions-user-manager-client'..." -ForegroundColor Yellow
|
||||
try {
|
||||
$clients = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/clients?clientId=lions-user-manager-client" -Method Get -Headers $headers
|
||||
|
||||
if ($clients.Count -gt 0) {
|
||||
$CLIENT_ID = $clients[0].id
|
||||
Write-Host " ✓ Client trouvé (ID: $CLIENT_ID)" -ForegroundColor Green
|
||||
|
||||
$mappers = Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/clients/$CLIENT_ID/protocol-mappers/models" -Method Get -Headers $headers
|
||||
$mapperExists = $mappers | Where-Object { $_.name -eq "realm roles" }
|
||||
|
||||
if (-not $mapperExists) {
|
||||
Write-Host " Création du mapper 'realm roles'..." -ForegroundColor Yellow
|
||||
$mapperBody = @{
|
||||
name = "realm roles"
|
||||
protocol = "openid-connect"
|
||||
protocolMapper = "oidc-usermodel-realm-role-mapper"
|
||||
config = @{
|
||||
"claim.name" = "realm_access.roles"
|
||||
"access.token.claim" = "true"
|
||||
"id.token.claim" = "true"
|
||||
"userinfo.token.claim" = "true"
|
||||
}
|
||||
} | ConvertTo-Json -Depth 10
|
||||
|
||||
Invoke-RestMethod -Uri "$KEYCLOAK_URL/admin/realms/$REALM/clients/$CLIENT_ID/protocol-mappers/models" -Method Post -Headers $headersWithContent -Body $mapperBody | Out-Null
|
||||
Write-Host " ✓ Mapper créé" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " ✓ Mapper existe déjà" -ForegroundColor Green
|
||||
}
|
||||
} else {
|
||||
Write-Host " ⚠ Client 'lions-user-manager-client' non trouvé" -ForegroundColor Yellow
|
||||
Write-Host " Veuillez créer le client manuellement dans Keycloak" -ForegroundColor Yellow
|
||||
}
|
||||
} catch {
|
||||
Write-Host " ⚠ Erreur lors de la vérification du client: $_" -ForegroundColor Yellow
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host "Configuration terminée !" -ForegroundColor Green
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Informations de connexion:" -ForegroundColor Yellow
|
||||
Write-Host " Username: $TEST_USER"
|
||||
Write-Host " Password: $TEST_PASSWORD"
|
||||
Write-Host " Email: $TEST_EMAIL"
|
||||
Write-Host ""
|
||||
Write-Host "Rôles assignés: $($ROLES -join ', ')" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
@@ -1,211 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script de configuration Keycloak - Utilisateur de test
|
||||
# Utilise l'API Admin REST de Keycloak pour créer l'utilisateur et les rôles
|
||||
|
||||
KEYCLOAK_URL="http://localhost:8180"
|
||||
ADMIN_USER="admin"
|
||||
ADMIN_PASSWORD="admin"
|
||||
REALM="lions-user-manager"
|
||||
TEST_USER="test-user"
|
||||
TEST_PASSWORD="test123"
|
||||
TEST_EMAIL="test@lions.dev"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Configuration Keycloak - Utilisateur Test"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# 1. Obtenir le token d'administration
|
||||
echo "1. Authentification admin..."
|
||||
TOKEN_RESPONSE=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=${ADMIN_USER}" \
|
||||
-d "password=${ADMIN_PASSWORD}" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=admin-cli")
|
||||
|
||||
ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$ACCESS_TOKEN" ]; then
|
||||
echo "ERREUR: Impossible d'obtenir le token d'administration"
|
||||
echo "Réponse: $TOKEN_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ Token obtenu"
|
||||
echo ""
|
||||
|
||||
# 2. Vérifier/Créer le realm
|
||||
echo "2. Vérification du realm '${REALM}'..."
|
||||
REALM_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-X GET "${KEYCLOAK_URL}/admin/realms/${REALM}" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}")
|
||||
|
||||
if [ "$REALM_EXISTS" != "200" ]; then
|
||||
echo "Création du realm '${REALM}'..."
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"realm\": \"${REALM}\",
|
||||
\"enabled\": true
|
||||
}"
|
||||
echo "✓ Realm créé"
|
||||
else
|
||||
echo "✓ Realm existe déjà"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 3. Créer les rôles realm
|
||||
echo "3. Création des rôles realm..."
|
||||
ROLES=("admin" "user_manager" "user_viewer" "role_manager" "role_viewer" "auditor" "sync_manager")
|
||||
|
||||
for ROLE in "${ROLES[@]}"; do
|
||||
echo " - Vérification du rôle '${ROLE}'..."
|
||||
ROLE_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/roles/${ROLE}" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}")
|
||||
|
||||
if [ "$ROLE_EXISTS" != "200" ]; then
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/roles" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"name\": \"${ROLE}\",
|
||||
\"description\": \"Rôle ${ROLE} pour lions-user-manager\"
|
||||
}"
|
||||
echo " ✓ Rôle '${ROLE}' créé"
|
||||
else
|
||||
echo " ✓ Rôle '${ROLE}' existe déjà"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
# 4. Créer l'utilisateur de test
|
||||
echo "4. Création de l'utilisateur '${TEST_USER}'..."
|
||||
USER_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||
-X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/users?username=${TEST_USER}" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}")
|
||||
|
||||
if [ "$USER_EXISTS" != "200" ]; then
|
||||
# Créer l'utilisateur
|
||||
USER_ID=$(curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/users" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"username\": \"${TEST_USER}\",
|
||||
\"email\": \"${TEST_EMAIL}\",
|
||||
\"firstName\": \"Test\",
|
||||
\"lastName\": \"User\",
|
||||
\"enabled\": true,
|
||||
\"emailVerified\": true
|
||||
}" | grep -o '"id":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$USER_ID" ]; then
|
||||
# Récupérer l'ID de l'utilisateur existant
|
||||
USER_ID=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/users?username=${TEST_USER}" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" | grep -o '"id":"[^"]*' | cut -d'"' -f4 | head -1)
|
||||
fi
|
||||
|
||||
if [ -z "$USER_ID" ]; then
|
||||
echo "ERREUR: Impossible de créer ou récupérer l'utilisateur"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo " ✓ Utilisateur créé (ID: ${USER_ID})"
|
||||
|
||||
# Définir le mot de passe
|
||||
curl -s -X PUT "${KEYCLOAK_URL}/admin/realms/${REALM}/users/${USER_ID}/reset-password" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"type\": \"password\",
|
||||
\"value\": \"${TEST_PASSWORD}\",
|
||||
\"temporary\": false
|
||||
}"
|
||||
echo " ✓ Mot de passe défini"
|
||||
else
|
||||
# Récupérer l'ID de l'utilisateur existant
|
||||
USER_ID=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/users?username=${TEST_USER}" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" | grep -o '"id":"[^"]*' | cut -d'"' -f4 | head -1)
|
||||
echo " ✓ Utilisateur existe déjà (ID: ${USER_ID})"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 5. Assigner les rôles à l'utilisateur
|
||||
echo "5. Attribution des rôles à l'utilisateur..."
|
||||
|
||||
# Récupérer les représentations des rôles
|
||||
ROLE_REPRESENTATIONS="["
|
||||
for i in "${!ROLES[@]}"; do
|
||||
ROLE="${ROLES[$i]}"
|
||||
ROLE_REP=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/roles/${ROLE}" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}")
|
||||
|
||||
if [ $i -gt 0 ]; then
|
||||
ROLE_REPRESENTATIONS+=","
|
||||
fi
|
||||
ROLE_REPRESENTATIONS+="${ROLE_REP}"
|
||||
done
|
||||
ROLE_REPRESENTATIONS+="]"
|
||||
|
||||
# Assigner tous les rôles
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/users/${USER_ID}/role-mappings/realm" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "${ROLE_REPRESENTATIONS}"
|
||||
|
||||
echo " ✓ Rôles assignés"
|
||||
echo ""
|
||||
|
||||
# 6. Vérifier le client et le mapper de rôles
|
||||
echo "6. Vérification du client 'lions-user-manager-client'..."
|
||||
CLIENT_ID=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/clients?clientId=lions-user-manager-client" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" | grep -o '"id":"[^"]*' | cut -d'"' -f4 | head -1)
|
||||
|
||||
if [ -z "$CLIENT_ID" ]; then
|
||||
echo " ⚠ Client 'lions-user-manager-client' non trouvé"
|
||||
echo " Veuillez créer le client manuellement dans Keycloak"
|
||||
else
|
||||
echo " ✓ Client trouvé (ID: ${CLIENT_ID})"
|
||||
|
||||
# Vérifier le mapper de rôles realm
|
||||
MAPPER_EXISTS=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${CLIENT_ID}/protocol-mappers/models" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" | grep -o '"name":"realm roles"')
|
||||
|
||||
if [ -z "$MAPPER_EXISTS" ]; then
|
||||
echo " Création du mapper 'realm roles'..."
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${CLIENT_ID}/protocol-mappers/models" \
|
||||
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"name\": \"realm roles\",
|
||||
\"protocol\": \"openid-connect\",
|
||||
\"protocolMapper\": \"oidc-usermodel-realm-role-mapper\",
|
||||
\"config\": {
|
||||
\"claim.name\": \"realm_access.roles\",
|
||||
\"access.token.claim\": \"true\",
|
||||
\"id.token.claim\": \"true\",
|
||||
\"userinfo.token.claim\": \"true\"
|
||||
}
|
||||
}"
|
||||
echo " ✓ Mapper créé"
|
||||
else
|
||||
echo " ✓ Mapper existe déjà"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "Configuration terminée !"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Informations de connexion:"
|
||||
echo " Username: ${TEST_USER}"
|
||||
echo " Password: ${TEST_PASSWORD}"
|
||||
echo " Email: ${TEST_EMAIL}"
|
||||
echo ""
|
||||
echo "Rôles assignés: ${ROLES[*]}"
|
||||
echo ""
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
KEYCLOAK_URL="http://localhost:8180"
|
||||
REALM="lions-user-manager"
|
||||
USER_ID="672833b5-0c4c-451e-8fe9-86cdae19fb5c"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Creation des roles et assignation"
|
||||
echo "=========================================="
|
||||
|
||||
# 1. Obtenir le token admin
|
||||
echo "1. Recuperation du token admin..."
|
||||
TOKEN=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=admin" \
|
||||
-d "password=admin" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=admin-cli" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "Erreur: Impossible d'obtenir le token admin"
|
||||
exit 1
|
||||
fi
|
||||
echo "Token obtenu"
|
||||
|
||||
# 2. Creer les roles
|
||||
echo ""
|
||||
echo "2. Creation des roles..."
|
||||
|
||||
echo " - Creation role: admin"
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/roles" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"admin","description":"System administrator with full access"}'
|
||||
|
||||
echo " - Creation role: user_manager"
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/roles" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"user_manager","description":"User manager"}'
|
||||
|
||||
echo " - Creation role: user_viewer"
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/roles" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"user_viewer","description":"User viewer"}'
|
||||
|
||||
echo " - Creation role: auditor"
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/roles" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"auditor","description":"Auditor"}'
|
||||
|
||||
echo " - Creation role: sync_manager"
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/roles" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"sync_manager","description":"Sync manager"}'
|
||||
|
||||
echo "Roles crees"
|
||||
|
||||
# 3. Recuperer les IDs des roles
|
||||
echo ""
|
||||
echo "3. Recuperation des IDs des roles..."
|
||||
ROLES=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/roles" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
ADMIN_ID=$(echo "$ROLES" | grep -o '"id":"[^"]*","name":"admin"' | grep -o '"id":"[^"]*' | cut -d'"' -f4)
|
||||
USER_MANAGER_ID=$(echo "$ROLES" | grep -o '"id":"[^"]*","name":"user_manager"' | grep -o '"id":"[^"]*' | cut -d'"' -f4)
|
||||
USER_VIEWER_ID=$(echo "$ROLES" | grep -o '"id":"[^"]*","name":"user_viewer"' | grep -o '"id":"[^"]*' | cut -d'"' -f4)
|
||||
AUDITOR_ID=$(echo "$ROLES" | grep -o '"id":"[^"]*","name":"auditor"' | grep -o '"id":"[^"]*' | cut -d'"' -f4)
|
||||
SYNC_MANAGER_ID=$(echo "$ROLES" | grep -o '"id":"[^"]*","name":"sync_manager"' | grep -o '"id":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
echo "IDs recuperes:"
|
||||
echo " admin: $ADMIN_ID"
|
||||
echo " user_manager: $USER_MANAGER_ID"
|
||||
echo " user_viewer: $USER_VIEWER_ID"
|
||||
echo " auditor: $AUDITOR_ID"
|
||||
echo " sync_manager: $SYNC_MANAGER_ID"
|
||||
|
||||
# 4. Assigner les roles a testuser
|
||||
echo ""
|
||||
echo "4. Assignation des roles a testuser..."
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/users/${USER_ID}/role-mappings/realm" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "[
|
||||
{\"id\":\"${ADMIN_ID}\",\"name\":\"admin\"},
|
||||
{\"id\":\"${USER_MANAGER_ID}\",\"name\":\"user_manager\"},
|
||||
{\"id\":\"${USER_VIEWER_ID}\",\"name\":\"user_viewer\"},
|
||||
{\"id\":\"${AUDITOR_ID}\",\"name\":\"auditor\"},
|
||||
{\"id\":\"${SYNC_MANAGER_ID}\",\"name\":\"sync_manager\"}
|
||||
]"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Configuration terminee!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Roles assignes a testuser:"
|
||||
echo " - admin"
|
||||
echo " - user_manager"
|
||||
echo " - user_viewer"
|
||||
echo " - auditor"
|
||||
echo " - sync_manager"
|
||||
echo ""
|
||||
@@ -1,49 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script pour récupérer le secret du client Keycloak
|
||||
|
||||
KEYCLOAK_URL="http://localhost:8180"
|
||||
REALM="lions-user-manager"
|
||||
|
||||
# 1. Obtenir le token admin
|
||||
TOKEN=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=admin" \
|
||||
-d "password=admin" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=admin-cli" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "Erreur: Impossible d'obtenir le token"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 2. Récupérer tous les clients
|
||||
CLIENTS=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
# 3. Extraire l'ID du client
|
||||
CLIENT_ID=$(echo "$CLIENTS" | grep -B 5 '"clientId":"lions-user-manager-client"' | grep '"id"' | head -1 | grep -o '"id":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$CLIENT_ID" ]; then
|
||||
echo "Erreur: Client non trouvé"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Client ID interne: $CLIENT_ID"
|
||||
|
||||
# 4. Récupérer le secret du client
|
||||
SECRET=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${CLIENT_ID}/client-secret" \
|
||||
-H "Authorization: Bearer ${TOKEN}" | grep -o '"value":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$SECRET" ]; then
|
||||
echo "Erreur: Secret non trouvé"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Secret du client lions-user-manager-client ==="
|
||||
echo "Secret: $SECRET"
|
||||
echo ""
|
||||
echo "Mettre à jour dans application-dev.properties:"
|
||||
echo "quarkus.oidc.credentials.secret=$SECRET"
|
||||
@@ -1,110 +0,0 @@
|
||||
# Script d'intégration de PrimeFaces Freya Extension dans Lions User Manager
|
||||
# Usage: .\integrate-freya-extension.ps1
|
||||
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host " Intégration Freya Extension" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Chemins
|
||||
$WORKSPACE = "C:\Users\dadyo\PersonalProjects\lions-workspace"
|
||||
$FREYA_EXT_PATH = "$WORKSPACE\primefaces-freya-extension"
|
||||
$USER_MANAGER_PATH = "$WORKSPACE\lions-user-manager"
|
||||
|
||||
# Étape 1 : Vérifier que primefaces-freya-extension existe
|
||||
Write-Host "[1/5] Vérification de primefaces-freya-extension..." -ForegroundColor Yellow
|
||||
if (-Not (Test-Path $FREYA_EXT_PATH)) {
|
||||
Write-Host "❌ ERREUR: primefaces-freya-extension introuvable à $FREYA_EXT_PATH" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host "✅ primefaces-freya-extension trouvé" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# Étape 2 : Compiler et installer primefaces-freya-extension
|
||||
Write-Host "[2/5] Compilation et installation de primefaces-freya-extension..." -ForegroundColor Yellow
|
||||
Set-Location $FREYA_EXT_PATH
|
||||
|
||||
Write-Host "Exécution de: mvn clean install -DskipTests" -ForegroundColor Gray
|
||||
$result = mvn clean install -DskipTests 2>&1
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "❌ ERREUR lors de la compilation de primefaces-freya-extension" -ForegroundColor Red
|
||||
Write-Host $result -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✅ primefaces-freya-extension compilé et installé dans le repository Maven local" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# Étape 3 : Vérifier l'installation dans le repository Maven local
|
||||
Write-Host "[3/5] Vérification de l'installation dans le repository Maven local..." -ForegroundColor Yellow
|
||||
$M2_REPO = "$env:USERPROFILE\.m2\repository\dev\lions\primefaces-freya-extension-runtime\1.0.0-SNAPSHOT"
|
||||
|
||||
if (Test-Path $M2_REPO) {
|
||||
Write-Host "✅ Artefact trouvé dans: $M2_REPO" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "⚠️ ATTENTION: Artefact non trouvé dans le repository Maven local" -ForegroundColor Yellow
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# Étape 4 : Sauvegarder les pom.xml originaux
|
||||
Write-Host "[4/5] Sauvegarde des pom.xml originaux..." -ForegroundColor Yellow
|
||||
Set-Location $USER_MANAGER_PATH
|
||||
|
||||
$PARENT_POM = "$USER_MANAGER_PATH\pom.xml"
|
||||
$CLIENT_POM = "$USER_MANAGER_PATH\lions-user-manager-client-quarkus-primefaces-freya\pom.xml"
|
||||
|
||||
if (Test-Path $PARENT_POM) {
|
||||
Copy-Item $PARENT_POM "$PARENT_POM.backup" -Force
|
||||
Write-Host "✅ Sauvegarde créée: pom.xml.backup" -ForegroundColor Green
|
||||
}
|
||||
|
||||
if (Test-Path $CLIENT_POM) {
|
||||
Copy-Item $CLIENT_POM "$CLIENT_POM.backup" -Force
|
||||
Write-Host "✅ Sauvegarde créée: lions-user-manager-client-quarkus-primefaces-freya/pom.xml.backup" -ForegroundColor Green
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# Étape 5 : Instructions manuelles
|
||||
Write-Host "[5/5] Prochaines étapes manuelles..." -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "📝 Vous devez maintenant modifier les fichiers pom.xml :" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "1️⃣ Éditer: $PARENT_POM" -ForegroundColor White
|
||||
Write-Host " Ajouter dans <properties>:" -ForegroundColor Gray
|
||||
Write-Host " <primefaces-freya-extension.version>1.0.0-SNAPSHOT</primefaces-freya-extension.version>" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
Write-Host " Ajouter dans <dependencyManagement><dependencies>:" -ForegroundColor Gray
|
||||
Write-Host " <dependency>" -ForegroundColor DarkGray
|
||||
Write-Host " <groupId>dev.lions</groupId>" -ForegroundColor DarkGray
|
||||
Write-Host " <artifactId>primefaces-freya-extension-runtime</artifactId>" -ForegroundColor DarkGray
|
||||
Write-Host " <version>`${primefaces-freya-extension.version}</version>" -ForegroundColor DarkGray
|
||||
Write-Host " </dependency>" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
Write-Host "2️⃣ Éditer: $CLIENT_POM" -ForegroundColor White
|
||||
Write-Host " Ajouter dans <dependencies>:" -ForegroundColor Gray
|
||||
Write-Host " <dependency>" -ForegroundColor DarkGray
|
||||
Write-Host " <groupId>dev.lions</groupId>" -ForegroundColor DarkGray
|
||||
Write-Host " <artifactId>primefaces-freya-extension-runtime</artifactId>" -ForegroundColor DarkGray
|
||||
Write-Host " </dependency>" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
Write-Host "3️⃣ Dans vos fichiers .xhtml, ajouter le namespace:" -ForegroundColor White
|
||||
Write-Host " xmlns:fr=`"http://primefaces.org/freya`"" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
Write-Host "4️⃣ Remplacer les composants PrimeFaces par les composants Freya:" -ForegroundColor White
|
||||
Write-Host " Avant: <div class=`"field`"><p:outputLabel>...</p:outputLabel><p:inputText>...</p:inputText></div>" -ForegroundColor DarkGray
|
||||
Write-Host " Après: <fr:fieldInput label=`"...`" value=`"#{...}`" />" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host " Intégration terminée !" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "📚 Documentation complète: $USER_MANAGER_PATH\INTEGRATION_FREYA_EXTENSION.md" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "🚀 Pour tester:" -ForegroundColor Yellow
|
||||
Write-Host " cd $USER_MANAGER_PATH" -ForegroundColor Gray
|
||||
Write-Host " mvn clean install" -ForegroundColor Gray
|
||||
Write-Host " cd lions-user-manager-client-quarkus-primefaces-freya" -ForegroundColor Gray
|
||||
Write-Host " mvn quarkus:dev" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
# Script de migration automatique de toutes les pages XHTML vers Freya Extension
|
||||
# Date: 2025-12-26
|
||||
# Description: Migre tous les composants PrimeFaces vers Freya Extension
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Migration XHTML vers Freya Extension" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Chemin de base
|
||||
$basePath = "lions-user-manager-client-quarkus-primefaces-freya\src\main\resources\META-INF\resources"
|
||||
|
||||
# Liste des fichiers XHTML à migrer
|
||||
$xhtmlFiles = @(
|
||||
"$basePath\pages\user-manager\users\edit.xhtml",
|
||||
"$basePath\pages\user-manager\users\view.xhtml",
|
||||
"$basePath\pages\user-manager\users\profile.xhtml",
|
||||
"$basePath\pages\user-manager\roles\list.xhtml",
|
||||
"$basePath\pages\user-manager\roles\assign.xhtml",
|
||||
"$basePath\pages\user-manager\dashboard.xhtml",
|
||||
"$basePath\pages\user-manager\settings.xhtml",
|
||||
"$basePath\pages\user-manager\audit\logs.xhtml",
|
||||
"$basePath\pages\user-manager\sync\dashboard.xhtml",
|
||||
"$basePath\pages\user-manager\users.xhtml",
|
||||
"$basePath\pages\user-manager\roles.xhtml"
|
||||
)
|
||||
|
||||
# Patterns de remplacement
|
||||
$replacements = @(
|
||||
# Ajout du namespace Freya si absent
|
||||
@{
|
||||
Pattern = '(<ui:composition[^>]*xmlns:p="http://primefaces.org/ui")'
|
||||
Replacement = '$1`n xmlns:fr="http://primefaces.org/freya"'
|
||||
Description = "Ajout namespace Freya"
|
||||
},
|
||||
|
||||
# Migration des messages vers growl
|
||||
@{
|
||||
Pattern = '<p:messages\s+id="([^"]+)"\s+showDetail="true"\s+closable="true">\s*<p:autoUpdate\s*/>\s*</p:messages>'
|
||||
Replacement = '<fr:growl id="$1" />'
|
||||
Description = "Migration p:messages vers fr:growl"
|
||||
},
|
||||
|
||||
# Migration des commandButton avec styleClass p-button-success
|
||||
@{
|
||||
Pattern = '<p:commandButton([^>]*)styleClass="([^"]*p-button-success[^"]*)"'
|
||||
Replacement = '<fr:commandButton$1severity="success"'
|
||||
Description = "Migration commandButton success"
|
||||
},
|
||||
|
||||
# Migration des commandButton avec styleClass p-button-secondary
|
||||
@{
|
||||
Pattern = '<p:commandButton([^>]*)styleClass="([^"]*p-button-secondary[^"]*)"'
|
||||
Replacement = '<fr:commandButton$1severity="secondary"'
|
||||
Description = "Migration commandButton secondary"
|
||||
},
|
||||
|
||||
# Migration des commandButton avec styleClass p-button-info
|
||||
@{
|
||||
Pattern = '<p:commandButton([^>]*)styleClass="([^"]*p-button-info[^"]*)"'
|
||||
Replacement = '<fr:commandButton$1severity="info"'
|
||||
Description = "Migration commandButton info"
|
||||
},
|
||||
|
||||
# Migration des commandButton avec styleClass p-button-primary
|
||||
@{
|
||||
Pattern = '<p:commandButton([^>]*)styleClass="([^"]*p-button-primary[^"]*)"'
|
||||
Replacement = '<fr:commandButton$1severity="primary"'
|
||||
Description = "Migration commandButton primary"
|
||||
},
|
||||
|
||||
# Migration des commandButton avec styleClass p-button-warning
|
||||
@{
|
||||
Pattern = '<p:commandButton([^>]*)styleClass="([^"]*p-button-warning[^"]*)"'
|
||||
Replacement = '<fr:commandButton$1severity="warning"'
|
||||
Description = "Migration commandButton warning"
|
||||
},
|
||||
|
||||
# Migration des commandButton avec styleClass p-button-danger
|
||||
@{
|
||||
Pattern = '<p:commandButton([^>]*)styleClass="([^"]*p-button-danger[^"]*)"'
|
||||
Replacement = '<fr:commandButton$1severity="danger"'
|
||||
Description = "Migration commandButton danger"
|
||||
},
|
||||
|
||||
# Migration des commandButton avec styleClass p-button-outlined
|
||||
@{
|
||||
Pattern = '<p:commandButton([^>]*)styleClass="([^"]*p-button-outlined[^"]*)"'
|
||||
Replacement = '<fr:commandButton$1outlined="true"'
|
||||
Description = "Migration commandButton outlined"
|
||||
},
|
||||
|
||||
# Migration des commandButton avec styleClass p-button-text
|
||||
@{
|
||||
Pattern = '<p:commandButton([^>]*)styleClass="([^"]*p-button-text[^"]*)"'
|
||||
Replacement = '<fr:commandButton$1text="true"'
|
||||
Description = "Migration commandButton text"
|
||||
},
|
||||
|
||||
# Migration des tags
|
||||
@{
|
||||
Pattern = '<p:tag\s+'
|
||||
Replacement = '<fr:tag '
|
||||
Description = "Migration p:tag vers fr:tag"
|
||||
},
|
||||
|
||||
# Migration des dataTable
|
||||
@{
|
||||
Pattern = '<p:dataTable\s+'
|
||||
Replacement = '<fr:dataTable '
|
||||
Description = "Migration p:dataTable vers fr:dataTable"
|
||||
},
|
||||
|
||||
# Fermeture des dataTable
|
||||
@{
|
||||
Pattern = '</p:dataTable>'
|
||||
Replacement = '</fr:dataTable>'
|
||||
Description = "Fermeture fr:dataTable"
|
||||
}
|
||||
)
|
||||
|
||||
# Compteurs
|
||||
$totalFiles = 0
|
||||
$migratedFiles = 0
|
||||
$errors = 0
|
||||
|
||||
# Migration des fichiers
|
||||
foreach ($file in $xhtmlFiles) {
|
||||
if (Test-Path $file) {
|
||||
$totalFiles++
|
||||
Write-Host "Migration de: $file" -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
# Lecture du contenu
|
||||
$content = Get-Content $file -Raw -Encoding UTF8
|
||||
$originalContent = $content
|
||||
|
||||
# Application des remplacements
|
||||
$replacementCount = 0
|
||||
foreach ($replacement in $replacements) {
|
||||
$matches = [regex]::Matches($content, $replacement.Pattern)
|
||||
if ($matches.Count -gt 0) {
|
||||
$content = $content -replace $replacement.Pattern, $replacement.Replacement
|
||||
$replacementCount += $matches.Count
|
||||
Write-Host " ✓ $($replacement.Description): $($matches.Count) remplacement(s)" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
|
||||
# Sauvegarde si des modifications ont été faites
|
||||
if ($content -ne $originalContent) {
|
||||
Set-Content $file -Value $content -Encoding UTF8 -NoNewline
|
||||
$migratedFiles++
|
||||
Write-Host " ✓ Fichier migré avec succès ($replacementCount modifications)" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " ℹ Aucune modification nécessaire" -ForegroundColor Gray
|
||||
}
|
||||
}
|
||||
catch {
|
||||
$errors++
|
||||
Write-Host " ✗ Erreur: $_" -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
}
|
||||
}
|
||||
|
||||
# Résumé
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Résumé de la migration" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host "Fichiers traités: $totalFiles" -ForegroundColor White
|
||||
Write-Host "Fichiers migrés: $migratedFiles" -ForegroundColor Green
|
||||
Write-Host "Erreurs: $errors" -ForegroundColor $(if ($errors -gt 0) { "Red" } else { "Green" })
|
||||
Write-Host ""
|
||||
|
||||
if ($migratedFiles -gt 0) {
|
||||
Write-Host "✓ Migration terminée avec succès !" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Prochaines étapes:" -ForegroundColor Cyan
|
||||
Write-Host "1. Compiler le projet: mvn clean install -DskipTests" -ForegroundColor White
|
||||
Write-Host "2. Tester l'application" -ForegroundColor White
|
||||
} else {
|
||||
Write-Host "ℹ Aucun fichier n'a nécessité de migration" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
52
pom.xml
52
pom.xml
@@ -19,16 +19,17 @@
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
|
||||
<!-- Quarkus & Dependencies -->
|
||||
<quarkus.version>3.15.1</quarkus.version>
|
||||
<quarkus.version>3.17.8</quarkus.version>
|
||||
<quarkus-primefaces.version>3.15.1</quarkus-primefaces.version>
|
||||
<primefaces.version>14.0.5</primefaces.version>
|
||||
<primefaces-freya-extension.version>1.0.0</primefaces-freya-extension.version>
|
||||
<keycloak.version>26.0.4</keycloak.version>
|
||||
<keycloak.version>26.0.7</keycloak.version>
|
||||
<lombok.version>1.18.30</lombok.version>
|
||||
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
||||
|
||||
<!-- Testing -->
|
||||
<junit.version>5.10.1</junit.version>
|
||||
<mockito.version>5.11.0</mockito.version>
|
||||
<testcontainers.version>1.19.3</testcontainers.version>
|
||||
<rest-assured.version>5.4.0</rest-assured.version>
|
||||
|
||||
@@ -107,9 +108,56 @@
|
||||
<version>${rest-assured.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>dev</id>
|
||||
<activation>
|
||||
<activeByDefault>true</activeByDefault>
|
||||
</activation>
|
||||
<properties>
|
||||
<quarkus.profile>dev</quarkus.profile>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>prod</id>
|
||||
<properties>
|
||||
<quarkus.profile>prod</quarkus.profile>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>native</id>
|
||||
<properties>
|
||||
<quarkus.profile>prod</quarkus.profile>
|
||||
<quarkus.package.jar.type>native</quarkus.package.jar.type>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
|
||||
16
script/.env.example
Normal file
16
script/.env.example
Normal file
@@ -0,0 +1,16 @@
|
||||
# Base de données
|
||||
DB_NAME=lions_user_manager
|
||||
DB_USER=lions
|
||||
DB_PASSWORD=lions
|
||||
DB_PORT=5432
|
||||
|
||||
# Keycloak
|
||||
KC_ADMIN=admin
|
||||
KC_ADMIN_PASSWORD=admin
|
||||
KC_PORT=8180
|
||||
|
||||
# Serveur API
|
||||
SERVER_PORT=8080
|
||||
|
||||
# Client Web
|
||||
CLIENT_PORT=8082
|
||||
4
script/build-all.bat
Normal file
4
script/build-all.bat
Normal file
@@ -0,0 +1,4 @@
|
||||
@echo off
|
||||
REM Build des modules server-impl et client (sans tests)
|
||||
cd /d "%~dp0\.."
|
||||
mvn clean package -DskipTests -pl lions-user-manager-server-impl-quarkus,lions-user-manager-client-quarkus-primefaces-freya -am
|
||||
6
script/build-all.sh
Normal file
6
script/build-all.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build des modules server-impl et client (sans tests)
|
||||
set -e
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR/.."
|
||||
mvn clean package -DskipTests -pl lions-user-manager-server-impl-quarkus,lions-user-manager-client-quarkus-primefaces-freya -am
|
||||
69
script/docker/docker-compose.yml
Normal file
69
script/docker/docker-compose.yml
Normal file
@@ -0,0 +1,69 @@
|
||||
# Stack complète Lions User Manager : Postgres, Keycloak, Serveur API, Client Web
|
||||
# Usage: depuis la racine lions-user-manager : docker-compose -f script/docker/docker-compose.yml up -d
|
||||
# Build préalable : script/build-all.sh (ou build-all.bat)
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:15
|
||||
environment:
|
||||
POSTGRES_DB: ${DB_NAME:-lions_user_manager}
|
||||
POSTGRES_USER: ${DB_USER:-lions}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-lions}
|
||||
ports:
|
||||
- "${DB_PORT:-5432}:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-lions} -d ${DB_NAME:-lions_user_manager}"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
keycloak:
|
||||
image: quay.io/keycloak/keycloak:26.3.3
|
||||
command: start-dev
|
||||
environment:
|
||||
KC_DB: postgres
|
||||
KC_DB_URL: jdbc:postgresql://postgres:5432/${DB_NAME:-lions_user_manager}
|
||||
KC_DB_USERNAME: ${DB_USER:-lions}
|
||||
KC_DB_PASSWORD: ${DB_PASSWORD:-lions}
|
||||
KC_BOOTSTRAP_ADMIN_USERNAME: ${KC_ADMIN:-admin}
|
||||
KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_ADMIN_PASSWORD:-admin}
|
||||
ports:
|
||||
- "${KC_PORT:-8180}:8080"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
||||
lions-user-manager-server:
|
||||
build:
|
||||
context: ../../lions-user-manager-server-impl-quarkus
|
||||
dockerfile: src/main/docker/Dockerfile.jvm
|
||||
ports:
|
||||
- "${SERVER_PORT:-8080}:8080"
|
||||
environment:
|
||||
QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://postgres:5432/${DB_NAME:-lions_user_manager}
|
||||
QUARKUS_DATASOURCE_USERNAME: ${DB_USER:-lions}
|
||||
QUARKUS_DATASOURCE_PASSWORD: ${DB_PASSWORD:-lions}
|
||||
KEYCLOAK_SERVER_URL: http://keycloak:8080
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
keycloak:
|
||||
condition: service_started
|
||||
|
||||
lions-user-manager-client:
|
||||
build:
|
||||
context: ../../lions-user-manager-client-quarkus-primefaces-freya
|
||||
dockerfile: src/main/docker/Dockerfile.jvm
|
||||
ports:
|
||||
- "${CLIENT_PORT:-8082}:8082"
|
||||
environment:
|
||||
KEYCLOAK_SERVER_URL: http://keycloak:8080
|
||||
LIONS_USER_MANAGER_API_URL: http://lions-user-manager-server:8080
|
||||
depends_on:
|
||||
- keycloak
|
||||
- lions-user-manager-server
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
5
script/start-all.bat
Normal file
5
script/start-all.bat
Normal file
@@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
REM Demarre la stack complete (postgres, keycloak, server, client)
|
||||
REM Executer script/build-all.bat avant la premiere fois
|
||||
cd /d "%~dp0\.."
|
||||
docker-compose -f script/docker/docker-compose.yml up -d
|
||||
7
script/start-all.sh
Normal file
7
script/start-all.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# Démarre la stack complète (postgres, keycloak, server, client)
|
||||
# Exécuter script/build-all.sh avant la première fois
|
||||
set -e
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
cd "$SCRIPT_DIR/.."
|
||||
docker-compose -f script/docker/docker-compose.yml up -d
|
||||
@@ -1,166 +0,0 @@
|
||||
# Script de configuration du client Keycloak pour Lions User Manager
|
||||
# Usage: .\setup-keycloak-client.ps1
|
||||
|
||||
Write-Host "=============================================" -ForegroundColor Cyan
|
||||
Write-Host "Configuration Client Keycloak" -ForegroundColor Cyan
|
||||
Write-Host "=============================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Configuration
|
||||
$keycloakUrl = "http://localhost:8180"
|
||||
$realm = "lions-user-manager"
|
||||
$clientId = "lions-user-manager-client"
|
||||
$clientSecret = "NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO"
|
||||
$redirectUri = "http://localhost:8082/*"
|
||||
|
||||
# Étape 1 : Vérifier Keycloak
|
||||
Write-Host "[1/5] Vérification de Keycloak..." -ForegroundColor Yellow
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri "$keycloakUrl" -Method GET -UseBasicParsing -TimeoutSec 3 -ErrorAction Stop
|
||||
Write-Host " ✅ Keycloak accessible" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host " ❌ Keycloak inaccessible sur $keycloakUrl" -ForegroundColor Red
|
||||
Write-Host " Démarrez Keycloak avant de continuer" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Étape 2 : Obtenir un token admin
|
||||
Write-Host "[2/5] Authentification admin..." -ForegroundColor Yellow
|
||||
try {
|
||||
$tokenParams = @{
|
||||
Uri = "$keycloakUrl/realms/master/protocol/openid-connect/token"
|
||||
Method = "POST"
|
||||
Body = @{
|
||||
client_id = "admin-cli"
|
||||
grant_type = "password"
|
||||
username = "admin"
|
||||
password = "admin"
|
||||
}
|
||||
ContentType = "application/x-www-form-urlencoded"
|
||||
}
|
||||
$tokenResponse = Invoke-RestMethod @tokenParams
|
||||
$adminToken = $tokenResponse.access_token
|
||||
Write-Host " ✅ Token admin obtenu" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host " ❌ Échec authentification admin" -ForegroundColor Red
|
||||
Write-Host " Vérifiez les identifiants admin/admin" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Étape 3 : Vérifier si le realm existe
|
||||
Write-Host "[3/5] Vérification du realm '$realm'..." -ForegroundColor Yellow
|
||||
try {
|
||||
$headers = @{
|
||||
Authorization = "Bearer $adminToken"
|
||||
Accept = "application/json"
|
||||
}
|
||||
$realmResponse = Invoke-RestMethod -Uri "$keycloakUrl/admin/realms/$realm" -Headers $headers -Method GET -ErrorAction Stop
|
||||
Write-Host " ✅ Realm '$realm' existe" -ForegroundColor Green
|
||||
} catch {
|
||||
if ($_.Exception.Response.StatusCode -eq 404) {
|
||||
Write-Host " ⚠️ Realm '$realm' n'existe pas" -ForegroundColor Yellow
|
||||
Write-Host " Créez le realm manuellement via la console Keycloak:" -ForegroundColor Yellow
|
||||
Write-Host " 1. Accédez à $keycloakUrl" -ForegroundColor Gray
|
||||
Write-Host " 2. Administration Console > Create Realm" -ForegroundColor Gray
|
||||
Write-Host " 3. Realm name: $realm" -ForegroundColor Gray
|
||||
exit 1
|
||||
}
|
||||
Write-Host " ❌ Erreur vérification realm: $_" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Étape 4 : Vérifier si le client existe
|
||||
Write-Host "[4/5] Vérification du client '$clientId'..." -ForegroundColor Yellow
|
||||
try {
|
||||
$clientsResponse = Invoke-RestMethod -Uri "$keycloakUrl/admin/realms/$realm/clients?clientId=$clientId" -Headers $headers -Method GET
|
||||
|
||||
if ($clientsResponse.Count -eq 0) {
|
||||
Write-Host " ⚠️ Client '$clientId' n'existe pas" -ForegroundColor Yellow
|
||||
Write-Host " Création du client..." -ForegroundColor Yellow
|
||||
|
||||
# Créer le client
|
||||
$clientData = @{
|
||||
clientId = $clientId
|
||||
enabled = $true
|
||||
protocol = "openid-connect"
|
||||
publicClient = $false
|
||||
standardFlowEnabled = $true
|
||||
directAccessGrantsEnabled = $true
|
||||
serviceAccountsEnabled = $false
|
||||
implicitFlowEnabled = $false
|
||||
redirectUris = @($redirectUri, "http://localhost:8082/auth/callback")
|
||||
webOrigins = @("http://localhost:8082")
|
||||
attributes = @{
|
||||
"pkce.code.challenge.method" = "S256"
|
||||
}
|
||||
secret = $clientSecret
|
||||
} | ConvertTo-Json -Depth 10
|
||||
|
||||
$createHeaders = @{
|
||||
Authorization = "Bearer $adminToken"
|
||||
"Content-Type" = "application/json"
|
||||
}
|
||||
|
||||
Invoke-RestMethod -Uri "$keycloakUrl/admin/realms/$realm/clients" -Headers $createHeaders -Method POST -Body $clientData
|
||||
Write-Host " ✅ Client créé avec succès" -ForegroundColor Green
|
||||
|
||||
# Récupérer l'ID du client nouvellement créé
|
||||
Start-Sleep -Seconds 1
|
||||
$clientsResponse = Invoke-RestMethod -Uri "$keycloakUrl/admin/realms/$realm/clients?clientId=$clientId" -Headers $headers -Method GET
|
||||
$client = $clientsResponse[0]
|
||||
|
||||
# Configurer le secret
|
||||
$secretData = @{
|
||||
type = "secret"
|
||||
value = $clientSecret
|
||||
} | ConvertTo-Json
|
||||
|
||||
Invoke-RestMethod -Uri "$keycloakUrl/admin/realms/$realm/clients/$($client.id)/client-secret" -Headers $createHeaders -Method POST -Body $secretData
|
||||
Write-Host " ✅ Secret configuré" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " ✅ Client '$clientId' existe déjà" -ForegroundColor Green
|
||||
$client = $clientsResponse[0]
|
||||
|
||||
# Vérifier les redirect URIs
|
||||
Write-Host " Vérification des redirect URIs..." -ForegroundColor Gray
|
||||
$clientDetails = Invoke-RestMethod -Uri "$keycloakUrl/admin/realms/$realm/clients/$($client.id)" -Headers $headers -Method GET
|
||||
|
||||
if ($clientDetails.redirectUris -notcontains $redirectUri) {
|
||||
Write-Host " ⚠️ Redirect URI manquant, mise à jour..." -ForegroundColor Yellow
|
||||
$clientDetails.redirectUris += $redirectUri
|
||||
$clientDetails.redirectUris += "http://localhost:8082/auth/callback"
|
||||
|
||||
$updateData = $clientDetails | ConvertTo-Json -Depth 10
|
||||
$updateHeaders = @{
|
||||
Authorization = "Bearer $adminToken"
|
||||
"Content-Type" = "application/json"
|
||||
}
|
||||
Invoke-RestMethod -Uri "$keycloakUrl/admin/realms/$realm/clients/$($client.id)" -Headers $updateHeaders -Method PUT -Body $updateData
|
||||
Write-Host " ✅ Redirect URIs mis à jour" -ForegroundColor Green
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Host " ❌ Erreur configuration client: $_" -ForegroundColor Red
|
||||
Write-Host " $($_.Exception.Message)" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Étape 5 : Résumé
|
||||
Write-Host ""
|
||||
Write-Host "[5/5] Configuration terminée" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "=============================================" -ForegroundColor Cyan
|
||||
Write-Host "Résumé de la Configuration" -ForegroundColor Cyan
|
||||
Write-Host "=============================================" -ForegroundColor Cyan
|
||||
Write-Host "Realm: $realm" -ForegroundColor White
|
||||
Write-Host "Client ID: $clientId" -ForegroundColor White
|
||||
Write-Host "Client Secret: $clientSecret" -ForegroundColor White
|
||||
Write-Host "Redirect URI: $redirectUri" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Write-Host "✅ Le client est configuré et prêt" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Prochaines étapes:" -ForegroundColor Cyan
|
||||
Write-Host "1. Redémarrez le client JSF si nécessaire (Ctrl+C puis mvn quarkus:dev)" -ForegroundColor Gray
|
||||
Write-Host "2. Supprimez les cookies du navigateur pour localhost:8082" -ForegroundColor Gray
|
||||
Write-Host "3. Accédez à http://localhost:8082" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
@@ -1,177 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script de configuration Keycloak pour lions-user-manager
|
||||
# Configuration CORRECTE avec realm dédié et client uniquement pour le frontend
|
||||
|
||||
KEYCLOAK_URL="http://localhost:8180"
|
||||
MASTER_REALM="master"
|
||||
APP_REALM="lions-user-manager"
|
||||
ADMIN_USER="admin"
|
||||
ADMIN_PASS="admin"
|
||||
|
||||
echo "=== Configuration Keycloak pour lions-user-manager ==="
|
||||
echo ""
|
||||
|
||||
# 1. Obtenir le token d'administration
|
||||
echo "1. Connexion à Keycloak (realm master)..."
|
||||
TOKEN_RESPONSE=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=${ADMIN_USER}" \
|
||||
-d "password=${ADMIN_PASS}" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=admin-cli")
|
||||
|
||||
TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "❌ Erreur: Impossible d'obtenir le token d'accès"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Connexion réussie"
|
||||
|
||||
# 2. Créer le realm dédié pour l'application
|
||||
echo ""
|
||||
echo "2. Création du realm dédié '${APP_REALM}'..."
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${KEYCLOAK_URL}/admin/realms" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"realm\": \"${APP_REALM}\",
|
||||
\"displayName\": \"Lions User Manager\",
|
||||
\"enabled\": true,
|
||||
\"sslRequired\": \"none\",
|
||||
\"registrationAllowed\": false,
|
||||
\"loginWithEmailAllowed\": true,
|
||||
\"duplicateEmailsAllowed\": false,
|
||||
\"resetPasswordAllowed\": true,
|
||||
\"editUsernameAllowed\": false,
|
||||
\"bruteForceProtected\": true,
|
||||
\"accessTokenLifespan\": 3600,
|
||||
\"ssoSessionIdleTimeout\": 1800,
|
||||
\"ssoSessionMaxLifespan\": 36000
|
||||
}")
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||
if [ "$HTTP_CODE" == "201" ] || [ "$HTTP_CODE" == "409" ]; then
|
||||
echo "✅ Realm '${APP_REALM}' créé ou existe déjà"
|
||||
else
|
||||
echo "⚠️ Statut HTTP: $HTTP_CODE"
|
||||
fi
|
||||
|
||||
# 3. Créer UNIQUEMENT le client frontend
|
||||
echo ""
|
||||
echo "3. Création du client frontend 'lions-user-manager-client'..."
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${KEYCLOAK_URL}/admin/realms/${APP_REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"clientId": "lions-user-manager-client",
|
||||
"name": "Lions User Manager Client",
|
||||
"description": "Interface web pour la gestion des utilisateurs",
|
||||
"enabled": true,
|
||||
"protocol": "openid-connect",
|
||||
"publicClient": false,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": true,
|
||||
"serviceAccountsEnabled": false,
|
||||
"authorizationServicesEnabled": false,
|
||||
"secret": "client-secret-lions-2025",
|
||||
"redirectUris": [
|
||||
"http://localhost:8080/*",
|
||||
"http://localhost:8081/*"
|
||||
],
|
||||
"webOrigins": ["*"],
|
||||
"attributes": {
|
||||
"access.token.lifespan": "3600",
|
||||
"pkce.code.challenge.method": "S256"
|
||||
}
|
||||
}')
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||
if [ "$HTTP_CODE" == "201" ] || [ "$HTTP_CODE" == "409" ]; then
|
||||
echo "✅ Client frontend créé ou existe déjà"
|
||||
else
|
||||
echo "⚠️ Statut HTTP: $HTTP_CODE"
|
||||
fi
|
||||
|
||||
# 4. Créer les rôles realm dans le nouveau realm
|
||||
echo ""
|
||||
echo "4. Création des rôles dans le realm '${APP_REALM}'..."
|
||||
for role in admin user_manager user_viewer auditor sync_manager; do
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${APP_REALM}/roles" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"name\": \"${role}\", \"description\": \"Rôle ${role}\"}" > /dev/null 2>&1
|
||||
echo " ✅ Rôle '${role}' créé"
|
||||
done
|
||||
|
||||
# 5. Créer un utilisateur de test dans le nouveau realm
|
||||
echo ""
|
||||
echo "5. Création d'un utilisateur de test dans le realm '${APP_REALM}'..."
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${KEYCLOAK_URL}/admin/realms/${APP_REALM}/users" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "testuser",
|
||||
"email": "test@lions.dev",
|
||||
"firstName": "Test",
|
||||
"lastName": "User",
|
||||
"enabled": true,
|
||||
"emailVerified": true,
|
||||
"credentials": [{
|
||||
"type": "password",
|
||||
"value": "test123",
|
||||
"temporary": false
|
||||
}]
|
||||
}')
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||
if [ "$HTTP_CODE" == "201" ] || [ "$HTTP_CODE" == "409" ]; then
|
||||
echo "✅ Utilisateur 'testuser' créé (mot de passe: test123)"
|
||||
else
|
||||
echo "⚠️ Statut HTTP: $HTTP_CODE"
|
||||
fi
|
||||
|
||||
# 6. Récupérer et attribuer les rôles
|
||||
echo ""
|
||||
echo "6. Attribution des rôles à l'utilisateur..."
|
||||
USER_RESPONSE=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${APP_REALM}/users?username=testuser" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
USER_ID=$(echo "$USER_RESPONSE" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4)
|
||||
|
||||
if [ -n "$USER_ID" ]; then
|
||||
for role in admin user_manager; do
|
||||
ROLE_DATA=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${APP_REALM}/roles/${role}" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${APP_REALM}/users/${USER_ID}/role-mappings/realm" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "[${ROLE_DATA}]" > /dev/null 2>&1
|
||||
|
||||
echo " ✅ Rôle '${role}' attribué à testuser"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Configuration terminée ==="
|
||||
echo ""
|
||||
echo "📋 Récapitulatif:"
|
||||
echo " • Realm dédié: ${APP_REALM}"
|
||||
echo " • Client Frontend: client_id=lions-user-manager-client, secret=client-secret-lions-2025"
|
||||
echo " • Backend: Utilise directement l'Admin API avec admin/admin (pas de client séparé)"
|
||||
echo " • Utilisateur de test: testuser / test123"
|
||||
echo " • Rôles créés: admin, user_manager, user_viewer, auditor, sync_manager"
|
||||
echo ""
|
||||
echo "🌐 Accès:"
|
||||
echo " • Backend: http://localhost:8081"
|
||||
echo " • Frontend: http://localhost:8080"
|
||||
echo " • Keycloak: http://localhost:8180"
|
||||
echo " • Admin Console: http://localhost:8180/admin (admin/admin)"
|
||||
echo ""
|
||||
echo "⚙️ Prochaines étapes:"
|
||||
echo " 1. Mettre à jour application-dev.properties avec realm=${APP_REALM}"
|
||||
echo " 2. Redémarrer les applications"
|
||||
echo ""
|
||||
@@ -1,177 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script de configuration Keycloak pour lions-user-manager (sans jq)
|
||||
# Usage: ./setup-keycloak-simple.sh
|
||||
|
||||
KEYCLOAK_URL="http://localhost:8180"
|
||||
REALM="master"
|
||||
ADMIN_USER="admin"
|
||||
ADMIN_PASS="admin"
|
||||
|
||||
echo "=== Configuration Keycloak pour lions-user-manager ==="
|
||||
echo ""
|
||||
|
||||
# 1. Obtenir le token d'administration
|
||||
echo "1. Connexion à Keycloak..."
|
||||
TOKEN_RESPONSE=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=${ADMIN_USER}" \
|
||||
-d "password=${ADMIN_PASS}" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=admin-cli")
|
||||
|
||||
# Extraire le token sans jq
|
||||
TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
if [ -z "$TOKEN" ]; then
|
||||
echo "❌ Erreur: Impossible d'obtenir le token d'accès"
|
||||
echo "Réponse: $TOKEN_RESPONSE"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Connexion réussie"
|
||||
|
||||
# 2. Créer le client backend (lions-user-manager)
|
||||
echo ""
|
||||
echo "2. Création du client backend 'lions-user-manager'..."
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"clientId": "lions-user-manager",
|
||||
"name": "Lions User Manager Backend",
|
||||
"description": "Service backend pour la gestion des utilisateurs",
|
||||
"enabled": true,
|
||||
"protocol": "openid-connect",
|
||||
"publicClient": false,
|
||||
"serviceAccountsEnabled": true,
|
||||
"standardFlowEnabled": false,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"authorizationServicesEnabled": false,
|
||||
"secret": "sD8hT13lG6c79WOWQk3dVzya5pfPhzw3",
|
||||
"redirectUris": ["http://localhost:8081/*"],
|
||||
"webOrigins": ["http://localhost:8081", "http://localhost:8080"],
|
||||
"attributes": {
|
||||
"access.token.lifespan": "3600"
|
||||
}
|
||||
}')
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||
if [ "$HTTP_CODE" == "201" ] || [ "$HTTP_CODE" == "409" ]; then
|
||||
echo "✅ Client backend créé ou existe déjà"
|
||||
else
|
||||
echo "⚠️ Statut HTTP: $HTTP_CODE"
|
||||
fi
|
||||
|
||||
# 3. Créer le client frontend (lions-user-manager-client)
|
||||
echo ""
|
||||
echo "3. Création du client frontend 'lions-user-manager-client'..."
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"clientId": "lions-user-manager-client",
|
||||
"name": "Lions User Manager Client",
|
||||
"description": "Interface web pour la gestion des utilisateurs",
|
||||
"enabled": true,
|
||||
"protocol": "openid-connect",
|
||||
"publicClient": false,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": true,
|
||||
"authorizationServicesEnabled": false,
|
||||
"secret": "client-secret-lions-2025",
|
||||
"redirectUris": [
|
||||
"http://localhost:8080/*",
|
||||
"http://localhost:8081/*"
|
||||
],
|
||||
"webOrigins": ["*"],
|
||||
"attributes": {
|
||||
"access.token.lifespan": "3600",
|
||||
"pkce.code.challenge.method": "S256"
|
||||
}
|
||||
}')
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||
if [ "$HTTP_CODE" == "201" ] || [ "$HTTP_CODE" == "409" ]; then
|
||||
echo "✅ Client frontend créé ou existe déjà"
|
||||
else
|
||||
echo "⚠️ Statut HTTP: $HTTP_CODE"
|
||||
fi
|
||||
|
||||
# 4. Créer les rôles realm
|
||||
echo ""
|
||||
echo "4. Création des rôles..."
|
||||
for role in admin user_manager user_viewer auditor sync_manager; do
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/roles" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"name\": \"${role}\", \"description\": \"Rôle ${role}\"}" > /dev/null 2>&1
|
||||
echo " ✅ Rôle '${role}' créé ou existe déjà"
|
||||
done
|
||||
|
||||
# 5. Créer un utilisateur de test
|
||||
echo ""
|
||||
echo "5. Création d'un utilisateur de test..."
|
||||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/users" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "testuser",
|
||||
"email": "test@lions.dev",
|
||||
"firstName": "Test",
|
||||
"lastName": "User",
|
||||
"enabled": true,
|
||||
"emailVerified": true,
|
||||
"credentials": [{
|
||||
"type": "password",
|
||||
"value": "test123",
|
||||
"temporary": false
|
||||
}]
|
||||
}')
|
||||
|
||||
HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
|
||||
if [ "$HTTP_CODE" == "201" ] || [ "$HTTP_CODE" == "409" ]; then
|
||||
echo "✅ Utilisateur 'testuser' créé ou existe déjà (mot de passe: test123)"
|
||||
else
|
||||
echo "⚠️ Statut HTTP: $HTTP_CODE"
|
||||
fi
|
||||
|
||||
# 6. Récupérer et attribuer les rôles
|
||||
echo ""
|
||||
echo "6. Attribution des rôles à l'utilisateur..."
|
||||
USER_RESPONSE=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/users?username=testuser" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
USER_ID=$(echo "$USER_RESPONSE" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4)
|
||||
|
||||
if [ -n "$USER_ID" ]; then
|
||||
for role in admin user_manager; do
|
||||
ROLE_DATA=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/roles/${role}" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/users/${USER_ID}/role-mappings/realm" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "[${ROLE_DATA}]" > /dev/null 2>&1
|
||||
|
||||
echo " ✅ Rôle '${role}' attribué à testuser"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Configuration terminée ==="
|
||||
echo ""
|
||||
echo "📋 Récapitulatif:"
|
||||
echo " • Backend: client_id=lions-user-manager, secret=sD8hT13lG6c79WOWQk3dVzya5pfPhzw3"
|
||||
echo " • Frontend: client_id=lions-user-manager-client, secret=client-secret-lions-2025"
|
||||
echo " • Utilisateur de test: testuser / test123"
|
||||
echo " • Rôles créés: admin, user_manager, user_viewer, auditor, sync_manager"
|
||||
echo ""
|
||||
echo "🌐 Accès:"
|
||||
echo " • Backend: http://localhost:8081"
|
||||
echo " • Frontend: http://localhost:8080"
|
||||
echo " • Keycloak: http://localhost:8180"
|
||||
echo ""
|
||||
echo "⚠️ N'oubliez pas de redémarrer les applications si elles tournent déjà!"
|
||||
echo ""
|
||||
@@ -1,157 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script de configuration Keycloak pour lions-user-manager
|
||||
# Usage: ./setup-keycloak.sh
|
||||
|
||||
KEYCLOAK_URL="http://localhost:8180"
|
||||
REALM="master"
|
||||
ADMIN_USER="admin"
|
||||
ADMIN_PASS="admin"
|
||||
|
||||
echo "=== Configuration Keycloak pour lions-user-manager ==="
|
||||
echo ""
|
||||
|
||||
# 1. Obtenir le token d'administration
|
||||
echo "1. Connexion à Keycloak..."
|
||||
TOKEN=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=${ADMIN_USER}" \
|
||||
-d "password=${ADMIN_PASS}" \
|
||||
-d "grant_type=password" \
|
||||
-d "client_id=admin-cli" | jq -r '.access_token')
|
||||
|
||||
if [ -z "$TOKEN" ] || [ "$TOKEN" == "null" ]; then
|
||||
echo "❌ Erreur: Impossible d'obtenir le token d'accès"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ Connexion réussie"
|
||||
|
||||
# 2. Créer le client backend (lions-user-manager)
|
||||
echo ""
|
||||
echo "2. Création du client backend 'lions-user-manager'..."
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"clientId": "lions-user-manager",
|
||||
"name": "Lions User Manager Backend",
|
||||
"description": "Service backend pour la gestion des utilisateurs",
|
||||
"enabled": true,
|
||||
"protocol": "openid-connect",
|
||||
"publicClient": false,
|
||||
"serviceAccountsEnabled": true,
|
||||
"standardFlowEnabled": false,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": false,
|
||||
"authorizationServicesEnabled": false,
|
||||
"secret": "sD8hT13lG6c79WOWQk3dVzya5pfPhzw3",
|
||||
"redirectUris": ["http://localhost:8081/*"],
|
||||
"webOrigins": ["http://localhost:8081", "http://localhost:8080"],
|
||||
"attributes": {
|
||||
"access.token.lifespan": "3600"
|
||||
}
|
||||
}' 2>&1
|
||||
|
||||
echo "✅ Client backend créé"
|
||||
|
||||
# 3. Créer le client frontend (lions-user-manager-client)
|
||||
echo ""
|
||||
echo "3. Création du client frontend 'lions-user-manager-client'..."
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/clients" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"clientId": "lions-user-manager-client",
|
||||
"name": "Lions User Manager Client",
|
||||
"description": "Interface web pour la gestion des utilisateurs",
|
||||
"enabled": true,
|
||||
"protocol": "openid-connect",
|
||||
"publicClient": false,
|
||||
"standardFlowEnabled": true,
|
||||
"implicitFlowEnabled": false,
|
||||
"directAccessGrantsEnabled": true,
|
||||
"authorizationServicesEnabled": false,
|
||||
"secret": "client-secret-lions-2025",
|
||||
"redirectUris": [
|
||||
"http://localhost:8080/*",
|
||||
"http://localhost:8081/*"
|
||||
],
|
||||
"webOrigins": ["*"],
|
||||
"attributes": {
|
||||
"access.token.lifespan": "3600",
|
||||
"pkce.code.challenge.method": "S256"
|
||||
}
|
||||
}' 2>&1
|
||||
|
||||
echo "✅ Client frontend créé"
|
||||
|
||||
# 4. Créer les rôles realm
|
||||
echo ""
|
||||
echo "4. Création des rôles..."
|
||||
for role in admin user_manager user_viewer auditor sync_manager; do
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/roles" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"name\": \"${role}\", \"description\": \"Rôle ${role}\"}" 2>&1
|
||||
echo " ✅ Rôle '${role}' créé"
|
||||
done
|
||||
|
||||
# 5. Créer un utilisateur de test
|
||||
echo ""
|
||||
echo "5. Création d'un utilisateur de test..."
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/users" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "testuser",
|
||||
"email": "test@lions.dev",
|
||||
"firstName": "Test",
|
||||
"lastName": "User",
|
||||
"enabled": true,
|
||||
"emailVerified": true,
|
||||
"credentials": [{
|
||||
"type": "password",
|
||||
"value": "test123",
|
||||
"temporary": false
|
||||
}]
|
||||
}' 2>&1
|
||||
|
||||
echo "✅ Utilisateur 'testuser' créé (mot de passe: test123)"
|
||||
|
||||
# 6. Récupérer l'ID de l'utilisateur
|
||||
USER_ID=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/users?username=testuser" \
|
||||
-H "Authorization: Bearer ${TOKEN}" | jq -r '.[0].id')
|
||||
|
||||
if [ -n "$USER_ID" ] && [ "$USER_ID" != "null" ]; then
|
||||
echo ""
|
||||
echo "6. Attribution des rôles à l'utilisateur..."
|
||||
|
||||
# Récupérer les IDs des rôles
|
||||
for role in admin user_manager; do
|
||||
ROLE_DATA=$(curl -s -X GET "${KEYCLOAK_URL}/admin/realms/${REALM}/roles/${role}" \
|
||||
-H "Authorization: Bearer ${TOKEN}")
|
||||
|
||||
# Attribuer le rôle
|
||||
curl -s -X POST "${KEYCLOAK_URL}/admin/realms/${REALM}/users/${USER_ID}/role-mappings/realm" \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "[${ROLE_DATA}]" 2>&1
|
||||
|
||||
echo " ✅ Rôle '${role}' attribué à testuser"
|
||||
done
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=== Configuration terminée ==="
|
||||
echo ""
|
||||
echo "📋 Récapitulatif:"
|
||||
echo " • Backend: client_id=lions-user-manager, secret=sD8hT13lG6c79WOWQk3dVzya5pfPhzw3"
|
||||
echo " • Frontend: client_id=lions-user-manager-client, secret=client-secret-lions-2025"
|
||||
echo " • Utilisateur de test: testuser / test123"
|
||||
echo " • Rôles créés: admin, user_manager, user_viewer, auditor, sync_manager"
|
||||
echo ""
|
||||
echo "🌐 Accès:"
|
||||
echo " • Backend: http://localhost:8081"
|
||||
echo " • Frontend: http://localhost:8080"
|
||||
echo " • Keycloak: http://localhost:8180"
|
||||
echo ""
|
||||
14
test-auth.sh
14
test-auth.sh
@@ -1,14 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Test d'authentification avec le client lions-user-manager-client"
|
||||
echo ""
|
||||
|
||||
curl -X POST "http://localhost:8180/realms/lions-user-manager/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=lions-user-manager-client" \
|
||||
-d "client_secret=client-secret-lions-2025" \
|
||||
-d "username=testuser" \
|
||||
-d "password=test123" \
|
||||
-d "grant_type=password"
|
||||
|
||||
echo ""
|
||||
@@ -1,159 +0,0 @@
|
||||
# Script de test de la configuration Keycloak pour lions-user-manager
|
||||
# Usage: .\test-keycloak-config.ps1
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$KEYCLOAK_URL = "http://localhost:8180"
|
||||
$REALM = "lions-user-manager"
|
||||
$CLIENT_ID = "lions-user-manager-client"
|
||||
$CLIENT_SECRET = "NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO"
|
||||
$USERNAME = "testadmin"
|
||||
$PASSWORD = "admin123"
|
||||
$BACKEND_URL = "http://localhost:8081"
|
||||
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host "Test de configuration Keycloak" -ForegroundColor Cyan
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Test 1: Vérifier que Keycloak est accessible
|
||||
Write-Host "[1/4] Vérification de l'accès à Keycloak..." -ForegroundColor Yellow
|
||||
try {
|
||||
$response = Invoke-WebRequest -Uri $KEYCLOAK_URL -Method GET -UseBasicParsing -ErrorAction Stop
|
||||
Write-Host "✅ Keycloak est accessible sur $KEYCLOAK_URL" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Host "❌ Keycloak n'est pas accessible sur $KEYCLOAK_URL" -ForegroundColor Red
|
||||
Write-Host " Assurez-vous que Keycloak est démarré." -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# Test 2: Obtenir un token
|
||||
Write-Host "[2/4] Obtention d'un token d'accès..." -ForegroundColor Yellow
|
||||
$tokenUrl = "$KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/token"
|
||||
$body = @{
|
||||
client_id = $CLIENT_ID
|
||||
client_secret = $CLIENT_SECRET
|
||||
grant_type = "password"
|
||||
username = $USERNAME
|
||||
password = $PASSWORD
|
||||
scope = "openid profile email roles"
|
||||
}
|
||||
|
||||
try {
|
||||
$tokenResponse = Invoke-RestMethod -Uri $tokenUrl -Method Post -Body $body -ContentType "application/x-www-form-urlencoded" -ErrorAction Stop
|
||||
$ACCESS_TOKEN = $tokenResponse.access_token
|
||||
Write-Host "✅ Token obtenu avec succès" -ForegroundColor Green
|
||||
Write-Host " Token (premiers 50 caractères): $($ACCESS_TOKEN.Substring(0, [Math]::Min(50, $ACCESS_TOKEN.Length)))..." -ForegroundColor Gray
|
||||
} catch {
|
||||
Write-Host "❌ Impossible d'obtenir un token" -ForegroundColor Red
|
||||
Write-Host " Erreur: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Vérifiez que:" -ForegroundColor Yellow
|
||||
Write-Host " - Le realm '$REALM' existe" -ForegroundColor Yellow
|
||||
Write-Host " - Le client '$CLIENT_ID' existe avec le bon secret" -ForegroundColor Yellow
|
||||
Write-Host " - L'utilisateur '$USERNAME' existe avec le mot de passe '$PASSWORD'" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# Test 3: Vérifier le contenu du token
|
||||
Write-Host "[3/4] Vérification du contenu du token..." -ForegroundColor Yellow
|
||||
$tokenParts = $ACCESS_TOKEN.Split('.')
|
||||
$payload = $tokenParts[1]
|
||||
|
||||
# Ajouter padding si nécessaire
|
||||
while ($payload.Length % 4 -ne 0) {
|
||||
$payload += "="
|
||||
}
|
||||
|
||||
try {
|
||||
$payloadBytes = [Convert]::FromBase64String($payload)
|
||||
$payloadJson = [System.Text.Encoding]::UTF8.GetString($payloadBytes)
|
||||
$tokenData = $payloadJson | ConvertFrom-Json
|
||||
|
||||
if ($tokenData.realm_access) {
|
||||
Write-Host "✅ Le token contient les rôles (realm_access)" -ForegroundColor Green
|
||||
$roles = $tokenData.realm_access.roles -join ", "
|
||||
Write-Host " Rôles trouvés: $roles" -ForegroundColor Gray
|
||||
|
||||
if ($tokenData.realm_access.roles -contains "admin" -or $tokenData.realm_access.roles -contains "user_manager") {
|
||||
Write-Host "✅ L'utilisateur a le rôle 'admin' ou 'user_manager'" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "⚠️ L'utilisateur n'a pas le rôle 'admin' ou 'user_manager'" -ForegroundColor Yellow
|
||||
Write-Host " L'endpoint /api/users/search nécessite un de ces rôles" -ForegroundColor Yellow
|
||||
Write-Host " Assignez le rôle 'admin' ou 'user_manager' à l'utilisateur '$USERNAME'" -ForegroundColor Yellow
|
||||
}
|
||||
} else {
|
||||
Write-Host "❌ Le token ne contient pas realm_access.roles" -ForegroundColor Red
|
||||
Write-Host " Vérifiez la configuration du client scope 'roles' dans Keycloak" -ForegroundColor Red
|
||||
}
|
||||
} catch {
|
||||
Write-Host "⚠️ Impossible de décoder le token" -ForegroundColor Yellow
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# Test 4: Tester l'API backend
|
||||
Write-Host "[4/4] Test de l'endpoint /api/users/search..." -ForegroundColor Yellow
|
||||
$apiUrl = "$BACKEND_URL/api/users/search"
|
||||
$headers = @{
|
||||
"Authorization" = "Bearer $ACCESS_TOKEN"
|
||||
"Content-Type" = "application/json"
|
||||
}
|
||||
$searchBody = @{
|
||||
realmName = $REALM
|
||||
page = 0
|
||||
pageSize = 20
|
||||
} | ConvertTo-Json
|
||||
|
||||
try {
|
||||
$apiResponse = Invoke-RestMethod -Uri $apiUrl -Method Post -Headers $headers -Body $searchBody -ErrorAction Stop
|
||||
Write-Host "✅ Endpoint /api/users/search accessible (HTTP 200)" -ForegroundColor Green
|
||||
Write-Host " Nombre d'utilisateurs trouvés: $($apiResponse.totalCount)" -ForegroundColor Gray
|
||||
$success = $true
|
||||
} catch {
|
||||
$statusCode = $_.Exception.Response.StatusCode.value__
|
||||
|
||||
if ($null -eq $statusCode) {
|
||||
Write-Host "❌ Le backend n'est pas accessible sur $BACKEND_URL" -ForegroundColor Red
|
||||
Write-Host " Assurez-vous que lions-user-manager-server est démarré (mvn quarkus:dev)" -ForegroundColor Red
|
||||
} elseif ($statusCode -eq 401) {
|
||||
Write-Host "❌ Erreur 401 Unauthorized" -ForegroundColor Red
|
||||
Write-Host " Le token n'est pas accepté par le backend" -ForegroundColor Red
|
||||
Write-Host " Vérifiez que le serveur utilise le même realm dans application.properties" -ForegroundColor Red
|
||||
} elseif ($statusCode -eq 403) {
|
||||
Write-Host "❌ Erreur 403 Forbidden" -ForegroundColor Red
|
||||
Write-Host " L'utilisateur n'a pas les permissions nécessaires" -ForegroundColor Red
|
||||
Write-Host " Assignez le rôle 'admin' ou 'user_manager' à l'utilisateur" -ForegroundColor Red
|
||||
} elseif ($statusCode -eq 405) {
|
||||
Write-Host "❌ Erreur 405 Method Not Allowed" -ForegroundColor Red
|
||||
Write-Host " C'est l'erreur que vous rencontriez !" -ForegroundColor Red
|
||||
Write-Host " Vérifiez que le serveur backend est bien configuré avec le realm '$REALM'" -ForegroundColor Red
|
||||
} else {
|
||||
Write-Host "⚠️ Réponse HTTP $statusCode" -ForegroundColor Yellow
|
||||
Write-Host " Erreur: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
}
|
||||
$success = $false
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
# Résumé
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host "Résumé du test" -ForegroundColor Cyan
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
if ($success) {
|
||||
Write-Host "🎉 Configuration correcte ! Tout fonctionne." -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Vous pouvez maintenant:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Démarrer le client: cd lions-user-manager-client-quarkus-primefaces-freya && mvn quarkus:dev" -ForegroundColor Gray
|
||||
Write-Host " 2. Accéder à: http://localhost:8082" -ForegroundColor Gray
|
||||
Write-Host " 3. Se connecter avec: $USERNAME / $PASSWORD" -ForegroundColor Gray
|
||||
Write-Host " 4. Naviguer vers: /pages/user-manager/users/list.xhtml" -ForegroundColor Gray
|
||||
} else {
|
||||
Write-Host "❌ La configuration nécessite des ajustements." -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Consultez le fichier KEYCLOAK_DEV_SETUP.md pour les instructions complètes." -ForegroundColor Yellow
|
||||
}
|
||||
Write-Host ""
|
||||
@@ -1,148 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script de test de la configuration Keycloak pour lions-user-manager
|
||||
# Usage: ./test-keycloak-config.sh
|
||||
|
||||
set -e
|
||||
|
||||
KEYCLOAK_URL="http://localhost:8180"
|
||||
REALM="lions-user-manager"
|
||||
CLIENT_ID="lions-user-manager-client"
|
||||
CLIENT_SECRET="NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO"
|
||||
USERNAME="testadmin"
|
||||
PASSWORD="admin123"
|
||||
BACKEND_URL="http://localhost:8081"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Test de configuration Keycloak"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Test 1: Vérifier que Keycloak est accessible
|
||||
echo "[1/4] Vérification de l'accès à Keycloak..."
|
||||
if curl -s -f "$KEYCLOAK_URL" > /dev/null 2>&1; then
|
||||
echo "✅ Keycloak est accessible sur $KEYCLOAK_URL"
|
||||
else
|
||||
echo "❌ Keycloak n'est pas accessible sur $KEYCLOAK_URL"
|
||||
echo " Assurez-vous que Keycloak est démarré."
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test 2: Obtenir un token
|
||||
echo "[2/4] Obtention d'un token d'accès..."
|
||||
TOKEN_RESPONSE=$(curl -s -X POST \
|
||||
"$KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "client_id=$CLIENT_ID" \
|
||||
-d "client_secret=$CLIENT_SECRET" \
|
||||
-d "grant_type=password" \
|
||||
-d "username=$USERNAME" \
|
||||
-d "password=$PASSWORD" \
|
||||
-d "scope=openid profile email roles")
|
||||
|
||||
if echo "$TOKEN_RESPONSE" | grep -q "access_token"; then
|
||||
ACCESS_TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
||||
echo "✅ Token obtenu avec succès"
|
||||
echo " Token (premiers 50 caractères): ${ACCESS_TOKEN:0:50}..."
|
||||
else
|
||||
echo "❌ Impossible d'obtenir un token"
|
||||
echo " Réponse de Keycloak:"
|
||||
echo "$TOKEN_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$TOKEN_RESPONSE"
|
||||
echo ""
|
||||
echo "Vérifiez que:"
|
||||
echo " - Le realm '$REALM' existe"
|
||||
echo " - Le client '$CLIENT_ID' existe avec le bon secret"
|
||||
echo " - L'utilisateur '$USERNAME' existe avec le mot de passe '$PASSWORD'"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test 3: Vérifier le contenu du token
|
||||
echo "[3/4] Vérification du contenu du token..."
|
||||
TOKEN_PAYLOAD=$(echo "$ACCESS_TOKEN" | cut -d'.' -f2)
|
||||
# Ajouter le padding si nécessaire pour base64
|
||||
TOKEN_PAYLOAD_PADDED=$(echo "$TOKEN_PAYLOAD" | awk '{while(length($0) % 4 != 0) $0 = $0 "="; print}')
|
||||
TOKEN_DECODED=$(echo "$TOKEN_PAYLOAD_PADDED" | base64 -d 2>/dev/null || echo "{}")
|
||||
|
||||
echo "$TOKEN_DECODED" | python3 -m json.tool > /tmp/token_decoded.json 2>/dev/null || echo "$TOKEN_DECODED" > /tmp/token_decoded.json
|
||||
|
||||
if grep -q "realm_access" /tmp/token_decoded.json; then
|
||||
echo "✅ Le token contient les rôles (realm_access)"
|
||||
ROLES=$(cat /tmp/token_decoded.json | grep -A 10 "realm_access" | grep -A 5 "roles" || echo "[]")
|
||||
echo " Rôles trouvés: $ROLES"
|
||||
else
|
||||
echo "❌ Le token ne contient pas realm_access.roles"
|
||||
echo " Vérifiez la configuration du client scope 'roles' dans Keycloak"
|
||||
fi
|
||||
|
||||
if grep -q "\"admin\"" /tmp/token_decoded.json || grep -q "\"user_manager\"" /tmp/token_decoded.json; then
|
||||
echo "✅ L'utilisateur a le rôle 'admin' ou 'user_manager'"
|
||||
else
|
||||
echo "⚠️ L'utilisateur n'a pas le rôle 'admin' ou 'user_manager'"
|
||||
echo " L'endpoint /api/users/search nécessite un de ces rôles"
|
||||
echo " Assignez le rôle 'admin' ou 'user_manager' à l'utilisateur '$USERNAME'"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Test 4: Tester l'API backend
|
||||
echo "[4/4] Test de l'endpoint /api/users/search..."
|
||||
API_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST \
|
||||
"$BACKEND_URL/api/users/search" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-d '{
|
||||
"realmName": "'"$REALM"'",
|
||||
"page": 0,
|
||||
"pageSize": 20
|
||||
}' 2>/dev/null)
|
||||
|
||||
HTTP_CODE=$(echo "$API_RESPONSE" | grep "HTTP_CODE:" | cut -d':' -f2)
|
||||
RESPONSE_BODY=$(echo "$API_RESPONSE" | sed '/HTTP_CODE:/d')
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "✅ Endpoint /api/users/search accessible (HTTP 200)"
|
||||
echo " Nombre d'utilisateurs trouvés: $(echo "$RESPONSE_BODY" | grep -o '"totalCount":[0-9]*' | cut -d':' -f2 || echo "?")"
|
||||
elif [ "$HTTP_CODE" = "000" ] || [ -z "$HTTP_CODE" ]; then
|
||||
echo "❌ Le backend n'est pas accessible sur $BACKEND_URL"
|
||||
echo " Assurez-vous que lions-user-manager-server est démarré (mvn quarkus:dev)"
|
||||
elif [ "$HTTP_CODE" = "401" ]; then
|
||||
echo "❌ Erreur 401 Unauthorized"
|
||||
echo " Le token n'est pas accepté par le backend"
|
||||
echo " Vérifiez que le serveur utilise le même realm dans application.properties"
|
||||
elif [ "$HTTP_CODE" = "403" ]; then
|
||||
echo "❌ Erreur 403 Forbidden"
|
||||
echo " L'utilisateur n'a pas les permissions nécessaires"
|
||||
echo " Assignez le rôle 'admin' ou 'user_manager' à l'utilisateur"
|
||||
elif [ "$HTTP_CODE" = "405" ]; then
|
||||
echo "❌ Erreur 405 Method Not Allowed"
|
||||
echo " C'est l'erreur que vous rencontriez !"
|
||||
echo " Vérifiez que le serveur backend est bien configuré avec le realm '$REALM'"
|
||||
else
|
||||
echo "⚠️ Réponse HTTP $HTTP_CODE"
|
||||
echo " Réponse: $RESPONSE_BODY"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Résumé
|
||||
echo "=========================================="
|
||||
echo "Résumé du test"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
if [ "$HTTP_CODE" = "200" ]; then
|
||||
echo "🎉 Configuration correcte ! Tout fonctionne."
|
||||
echo ""
|
||||
echo "Vous pouvez maintenant:"
|
||||
echo " 1. Démarrer le client: cd lions-user-manager-client-quarkus-primefaces-freya && mvn quarkus:dev"
|
||||
echo " 2. Accéder à: http://localhost:8082"
|
||||
echo " 3. Se connecter avec: $USERNAME / $PASSWORD"
|
||||
echo " 4. Naviguer vers: /pages/user-manager/users/list.xhtml"
|
||||
else
|
||||
echo "❌ La configuration nécessite des ajustements."
|
||||
echo ""
|
||||
echo "Consultez le fichier KEYCLOAK_DEV_SETUP.md pour les instructions complètes."
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Cleanup
|
||||
rm -f /tmp/token_decoded.json
|
||||
@@ -1,114 +0,0 @@
|
||||
# Script de test pour vérifier le token JWT Keycloak
|
||||
# Ce script obtient un token et le décode pour vérifier la présence des rôles
|
||||
|
||||
$KEYCLOAK_URL = "http://localhost:8180"
|
||||
$REALM = "lions-user-manager"
|
||||
$CLIENT_ID = "lions-user-manager-client"
|
||||
$CLIENT_SECRET = "NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO"
|
||||
$USERNAME = "test-user"
|
||||
$PASSWORD = "test123"
|
||||
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host "Test Token JWT Keycloak" -ForegroundColor Cyan
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# 1. Obtenir un token
|
||||
Write-Host "1. Obtention du token..." -ForegroundColor Yellow
|
||||
$tokenParams = "username=$USERNAME&password=$PASSWORD&grant_type=password&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&scope=openid profile email roles"
|
||||
$tokenResponse = Invoke-RestMethod -Uri "$KEYCLOAK_URL/realms/$REALM/protocol/openid-connect/token" -Method Post -ContentType "application/x-www-form-urlencoded" -Body $tokenParams
|
||||
|
||||
$ACCESS_TOKEN = $tokenResponse.access_token
|
||||
$ID_TOKEN = $tokenResponse.id_token
|
||||
|
||||
if (-not $ACCESS_TOKEN) {
|
||||
Write-Host "ERREUR: Impossible d'obtenir le token" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✓ Token obtenu" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# 2. Décoder le token (JWT = 3 parties séparées par des points)
|
||||
Write-Host "2. Décodage du token..." -ForegroundColor Yellow
|
||||
$tokenParts = $ACCESS_TOKEN -split '\.'
|
||||
if ($tokenParts.Count -ne 3) {
|
||||
Write-Host "ERREUR: Token JWT invalide (doit avoir 3 parties)" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Décoder le payload (2ème partie)
|
||||
$payload = $tokenParts[1]
|
||||
# Ajouter du padding si nécessaire (Base64URL)
|
||||
while ($payload.Length % 4) {
|
||||
$payload += "="
|
||||
}
|
||||
$payload = $payload -replace '-', '+' -replace '_', '/'
|
||||
|
||||
try {
|
||||
$bytes = [System.Convert]::FromBase64String($payload)
|
||||
$json = [System.Text.Encoding]::UTF8.GetString($bytes)
|
||||
$tokenData = $json | ConvertFrom-Json
|
||||
|
||||
Write-Host "✓ Token décodé" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
# 3. Afficher les informations du token
|
||||
Write-Host "3. Informations du token:" -ForegroundColor Yellow
|
||||
Write-Host " Username: $($tokenData.preferred_username)" -ForegroundColor Gray
|
||||
Write-Host " Email: $($tokenData.email)" -ForegroundColor Gray
|
||||
Write-Host " Subject: $($tokenData.sub)" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
# 4. Vérifier les rôles
|
||||
Write-Host "4. Vérification des rôles:" -ForegroundColor Yellow
|
||||
|
||||
# Vérifier realm_access.roles
|
||||
if ($tokenData.realm_access) {
|
||||
if ($tokenData.realm_access.roles) {
|
||||
Write-Host " ✓ realm_access.roles trouvé:" -ForegroundColor Green
|
||||
$tokenData.realm_access.roles | ForEach-Object {
|
||||
Write-Host " - $_" -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host " ✗ realm_access.roles non trouvé dans realm_access" -ForegroundColor Red
|
||||
}
|
||||
} else {
|
||||
Write-Host " ✗ realm_access non trouvé dans le token" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# Vérifier roles directement
|
||||
if ($tokenData.roles) {
|
||||
Write-Host " ✓ roles trouvé directement:" -ForegroundColor Green
|
||||
$tokenData.roles | ForEach-Object {
|
||||
Write-Host " - $_" -ForegroundColor Gray
|
||||
}
|
||||
} else {
|
||||
Write-Host " ✗ roles non trouvé directement dans le token" -ForegroundColor Yellow
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
|
||||
# 5. Afficher le token complet pour inspection
|
||||
Write-Host "5. Token complet (pour inspection sur jwt.io):" -ForegroundColor Yellow
|
||||
Write-Host $ACCESS_TOKEN -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
# 6. Afficher le JSON complet
|
||||
Write-Host "6. Contenu complet du token (JSON):" -ForegroundColor Yellow
|
||||
$json | ConvertFrom-Json | ConvertTo-Json -Depth 10 | Write-Host -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
} catch {
|
||||
Write-Host "ERREUR lors du décodage: $_" -ForegroundColor Red
|
||||
Write-Host "Payload brut: $payload" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host "Test terminé" -ForegroundColor Cyan
|
||||
Write-Host "==========================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Pour inspecter le token visuellement, allez sur https://jwt.io" -ForegroundColor Yellow
|
||||
Write-Host "et collez le token ci-dessus." -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJhYkxDejZoZ1dEdmU4T3E2UzlxNVduMEF5RkFSZmV6MVlzRm44T05mdkNRIn0.eyJleHAiOjE3NjQ5NTg5MDIsImlhdCI6MTc2NDk1ODg0MiwianRpIjoib25sdHJvOjNhMzE4NzdhLWJhMTUtY2M5Yi01OWYyLWRjMWFjNjZiNmU2NiIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODE4MC9yZWFsbXMvbWFzdGVyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRtaW4tY2xpIiwic2lkIjoiMWE0ODJjYTQtMTE3ZS00MzBlLThhYjItNTE5ZjYzYzcyZDlhIiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIn0.sqKz0m-NN7YvikQ5TRIADBM7ID3zpgUUOFRoF8t6qKepsYLuFWl7aNzQWD4yjd2Kg5Yk7WjadYNhj-uvdXxdlayWSHv_Ij0nR2gNLw0mj5l89tn87OyZf2wRFJBKuDRk-qnWmLBNeIsPrN5sa_2bj23o7LrWkYg6lUf40veXn4XzZZJeAz9La70ciniYzZ2lXRM2ILzO9BEUDzy3S2ozYchPsoRDLZrIIGx0N4eWJzRL0_Lb0rCZtEdALObNmjrzR5WblVLb6d-_zO9LqeOEQ-1oCaPDN-ZbV2pH5ISddXHQHB6BGoIJvSw90DU1-AoCONte3QmTz6oa6ykK-6GjTA","expires_in":60,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzUxMiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJmOGIwYWNkMC00NzAwLTQ3MjAtODgyZS02ZTdmZjBiZWJjMzYifQ.eyJleHAiOjE3NjQ5NjA2NDIsImlhdCI6MTc2NDk1ODg0MiwianRpIjoiZGYyNzBiNzItNzc3ZS00MzRmLWZlYTEtMzhmY2NlZjFlOWNkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MTgwL3JlYWxtcy9tYXN0ZXIiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjgxODAvcmVhbG1zL21hc3RlciIsInR5cCI6IlJlZnJlc2giLCJhenAiOiJhZG1pbi1jbGkiLCJzaWQiOiIxYTQ4MmNhNC0xMTdlLTQzMGUtOGFiMi01MTlmNjNjNzJkOWEiLCJzY29wZSI6ImFjciB3ZWItb3JpZ2lucyBiYXNpYyBlbWFpbCBwcm9maWxlIHJvbGVzIn0.Bw-cBOmA9H0ovNYfIblCPfDVMsEf2gwNUn6kKKRdy4tMPZRldurIdV29-jNoGumHUYw0M-EtqGhu5Oloue3hNA","token_type":"Bearer","not-before-policy":0,"session_state":"1a482ca4-117e-430e-8ab2-519f63c72d9a","scope":"email profile"}
|
||||
@@ -1 +0,0 @@
|
||||
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJhYkxDejZoZ1dEdmU4T3E2UzlxNVduMEF5RkFSZmV6MVlzRm44T05mdkNRIn0.eyJleHAiOjE3NjQ5NTg5MDIsImlhdCI6MTc2NDk1ODg0MiwianRpIjoib25sdHJvOjNhMzE4NzdhLWJhMTUtY2M5Yi01OWYyLWRjMWFjNjZiNmU2NiIsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODE4MC9yZWFsbXMvbWFzdGVyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRtaW4tY2xpIiwic2lkIjoiMWE0ODJjYTQtMTE3ZS00MzBlLThhYjItNTE5ZjYzYzcyZDlhIiwic2NvcGUiOiJlbWFpbCBwcm9maWxlIn0.sqKz0m-NN7YvikQ5TRIADBM7ID3zpgUUOFRoF8t6qKepsYLuFWl7aNzQWD4yjd2Kg5Yk7WjadYNhj-uvdXxdlayWSHv_Ij0nR2gNLw0mj5l89tn87OyZf2wRFJBKuDRk-qnWmLBNeIsPrN5sa_2bj23o7LrWkYg6lUf40veXn4XzZZJeAz9La70ciniYzZ2lXRM2ILzO9BEUDzy3S2ozYchPsoRDLZrIIGx0N4eWJzRL0_Lb0rCZtEdALObNmjrzR5WblVLb6d-_zO9LqeOEQ-1oCaPDN-ZbV2pH5ISddXHQHB6BGoIJvSw90DU1-AoCONte3QmTz6oa6ykK-6GjTA
|
||||
@@ -1,85 +0,0 @@
|
||||
# Script de mise à jour de la configuration du client Keycloak
|
||||
Write-Host "Mise a jour de la configuration client Keycloak..." -ForegroundColor Cyan
|
||||
|
||||
# Obtenir un token admin
|
||||
$tokenResponse = Invoke-RestMethod -Uri "http://localhost:8180/realms/master/protocol/openid-connect/token" -Method POST -Body @{
|
||||
client_id = "admin-cli"
|
||||
grant_type = "password"
|
||||
username = "admin"
|
||||
password = "admin"
|
||||
} -ContentType "application/x-www-form-urlencoded"
|
||||
|
||||
$token = $tokenResponse.access_token
|
||||
Write-Host "✅ Token admin obtenu" -ForegroundColor Green
|
||||
|
||||
# Configuration du client
|
||||
$clientConfig = @{
|
||||
id = "b759720f-2a25-4118-9dc8-f167b79ad532"
|
||||
clientId = "lions-user-manager-client"
|
||||
name = "Lions User Manager Client"
|
||||
description = "Interface web pour la gestion des utilisateurs"
|
||||
rootUrl = "http://localhost:8082"
|
||||
adminUrl = "http://localhost:8082"
|
||||
baseUrl = "/"
|
||||
enabled = $true
|
||||
clientAuthenticatorType = "client-secret"
|
||||
secret = "NTuaQpk5E6qiMqAWTFrCOcIkOABzZzKO"
|
||||
redirectUris = @(
|
||||
"http://localhost:8082/*"
|
||||
"http://localhost:8082/auth/callback"
|
||||
"http://localhost:8082/pages/user-manager/*"
|
||||
)
|
||||
webOrigins = @("http://localhost:8082")
|
||||
bearerOnly = $false
|
||||
consentRequired = $false
|
||||
standardFlowEnabled = $true
|
||||
implicitFlowEnabled = $false
|
||||
directAccessGrantsEnabled = $true
|
||||
serviceAccountsEnabled = $false
|
||||
publicClient = $false
|
||||
frontchannelLogout = $true
|
||||
protocol = "openid-connect"
|
||||
attributes = @{
|
||||
"access.token.lifespan" = "1800"
|
||||
"client.session.idle.timeout" = "1800"
|
||||
"client.session.max.lifespan" = "36000"
|
||||
"pkce.code.challenge.method" = "S256"
|
||||
"backchannel.logout.session.required" = "true"
|
||||
"post.logout.redirect.uris" = "http://localhost:8082/*"
|
||||
}
|
||||
fullScopeAllowed = $true
|
||||
defaultClientScopes = @("web-origins", "acr", "profile", "roles", "basic", "email")
|
||||
optionalClientScopes = @("address", "phone", "offline_access", "microprofile-jwt")
|
||||
}
|
||||
|
||||
$headers = @{
|
||||
Authorization = "Bearer $token"
|
||||
"Content-Type" = "application/json"
|
||||
}
|
||||
|
||||
$body = $clientConfig | ConvertTo-Json -Depth 10
|
||||
|
||||
try {
|
||||
Invoke-RestMethod -Uri "http://localhost:8180/admin/realms/lions-user-manager/clients/b759720f-2a25-4118-9dc8-f167b79ad532" `
|
||||
-Method PUT `
|
||||
-Headers $headers `
|
||||
-Body $body
|
||||
|
||||
Write-Host "✅ Configuration client mise a jour avec succes!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
Write-Host "Corrections appliquees:" -ForegroundColor Cyan
|
||||
Write-Host " - rootUrl: http://localhost:8081 → http://localhost:8082" -ForegroundColor Yellow
|
||||
Write-Host " - adminUrl: → http://localhost:8082" -ForegroundColor Yellow
|
||||
Write-Host " - redirectUris: suppression du wildcard '*'" -ForegroundColor Yellow
|
||||
Write-Host " - webOrigins: * → http://localhost:8082" -ForegroundColor Yellow
|
||||
Write-Host " - Access token lifespan: 3600s → 1800s" -ForegroundColor Yellow
|
||||
Write-Host " - Session timeouts configures" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
Write-Host "Prochaine etape:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Supprimez les cookies du navigateur pour localhost:8082" -ForegroundColor Gray
|
||||
Write-Host " 2. Redemarrez le client JSF si necessaire" -ForegroundColor Gray
|
||||
Write-Host " 3. Testez l'acces a http://localhost:8082" -ForegroundColor Gray
|
||||
|
||||
} catch {
|
||||
Write-Host "❌ Erreur lors de la mise a jour: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
# Verification de la configuration du client Keycloak
|
||||
$tokenResponse = Invoke-RestMethod -Uri "http://localhost:8180/realms/master/protocol/openid-connect/token" -Method POST -Body @{
|
||||
client_id = "admin-cli"
|
||||
grant_type = "password"
|
||||
username = "admin"
|
||||
password = "admin"
|
||||
} -ContentType "application/x-www-form-urlencoded"
|
||||
|
||||
$headers = @{ Authorization = "Bearer $($tokenResponse.access_token)" }
|
||||
|
||||
$client = Invoke-RestMethod -Uri "http://localhost:8180/admin/realms/lions-user-manager/clients/b759720f-2a25-4118-9dc8-f167b79ad532" -Headers $headers
|
||||
|
||||
Write-Host "==================================================" -ForegroundColor Cyan
|
||||
Write-Host "Configuration Client Keycloak - Verification" -ForegroundColor Cyan
|
||||
Write-Host "==================================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Client ID: $($client.clientId)" -ForegroundColor White
|
||||
Write-Host "Root URL: $($client.rootUrl)" -ForegroundColor White
|
||||
Write-Host "Admin URL: $($client.adminUrl)" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Write-Host "Redirect URIs:" -ForegroundColor White
|
||||
$client.redirectUris | ForEach-Object { Write-Host " - $_" -ForegroundColor Gray }
|
||||
Write-Host ""
|
||||
Write-Host "Web Origins:" -ForegroundColor White
|
||||
$client.webOrigins | ForEach-Object { Write-Host " - $_" -ForegroundColor Gray }
|
||||
Write-Host ""
|
||||
Write-Host "Standard Flow: $($client.standardFlowEnabled)" -ForegroundColor White
|
||||
Write-Host "Direct Access Grants: $($client.directAccessGrantsEnabled)" -ForegroundColor White
|
||||
Write-Host "Public Client: $($client.publicClient)" -ForegroundColor White
|
||||
Write-Host "Client Secret: $($client.secret)" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Write-Host "==================================================" -ForegroundColor Cyan
|
||||
|
||||
# Verification
|
||||
$allGood = $true
|
||||
if ($client.rootUrl -ne "http://localhost:8082") {
|
||||
Write-Host "❌ Root URL incorrect: $($client.rootUrl)" -ForegroundColor Red
|
||||
$allGood = $false
|
||||
}
|
||||
if ($client.webOrigins -contains "*") {
|
||||
Write-Host "❌ Web Origins contient wildcard" -ForegroundColor Red
|
||||
$allGood = $false
|
||||
}
|
||||
if ($client.redirectUris -contains "*") {
|
||||
Write-Host "❌ Redirect URIs contient wildcard" -ForegroundColor Red
|
||||
$allGood = $false
|
||||
}
|
||||
|
||||
if ($allGood) {
|
||||
Write-Host "✅ Configuration correcte!" -ForegroundColor Green
|
||||
}
|
||||
Reference in New Issue
Block a user