feat: Initial lions-user-manager project structure
Phase 1 & 2 Implementation (40% completion) Module server-api (✅ COMPLETED - 15 files): - DTOs complets (User, Role, Audit, Search) - Enums (StatutUser, TypeRole, TypeActionAudit) - Service interfaces (User, Role, Audit, Sync) - ValidationConstants - 100% compilé et testé Module server-impl-quarkus (🔄 EN COURS - 7 files): - KeycloakAdminClient avec Circuit Breaker, Retry, Timeout - UserServiceImpl avec 25+ méthodes - UserResource REST API (12 endpoints) - Health checks Keycloak - Configurations dev/prod séparées - Mappers UserDTO <-> Keycloak UserRepresentation Module client (⏳ À FAIRE - 0 files): - Configuration PrimeFaces Freya à venir - Interface utilisateur JSF à venir Infrastructure: - Maven multi-modules (parent + 3 enfants) - Quarkus 3.15.1 - Keycloak Admin Client 23.0.3 - PrimeFaces 14.0.5 - Documentation complète (README, PROGRESS_REPORT) Contraintes respectées: - ZÉRO accès direct DB Keycloak (Admin API uniquement) - Multi-realm avec délégation - Résilience (Circuit Breaker, Retry) - Sécurité (@RolesAllowed, OIDC) - Observabilité (Health, Metrics) 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
package dev.lions.user.manager.enums.audit;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
|
||||
/**
|
||||
* Type d'action effectuée sur une ressource
|
||||
* Utilisé pour l'audit trail
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
@Schema(description = "Type d'action pour l'audit")
|
||||
public enum TypeActionAudit {
|
||||
|
||||
// Actions Utilisateur
|
||||
USER_CREATE("Création utilisateur", "USER", "CREATE"),
|
||||
USER_UPDATE("Modification utilisateur", "USER", "UPDATE"),
|
||||
USER_DELETE("Suppression utilisateur", "USER", "DELETE"),
|
||||
USER_ACTIVATE("Activation utilisateur", "USER", "ACTIVATE"),
|
||||
USER_DEACTIVATE("Désactivation utilisateur", "USER", "DEACTIVATE"),
|
||||
USER_SUSPEND("Suspension utilisateur", "USER", "SUSPEND"),
|
||||
USER_UNLOCK("Déverrouillage utilisateur", "USER", "UNLOCK"),
|
||||
USER_PASSWORD_RESET("Réinitialisation mot de passe", "USER", "PASSWORD_RESET"),
|
||||
USER_EMAIL_VERIFY("Vérification email", "USER", "EMAIL_VERIFY"),
|
||||
USER_FORCE_LOGOUT("Déconnexion forcée", "USER", "FORCE_LOGOUT"),
|
||||
|
||||
// Actions Rôle
|
||||
ROLE_CREATE("Création rôle", "ROLE", "CREATE"),
|
||||
ROLE_UPDATE("Modification rôle", "ROLE", "UPDATE"),
|
||||
ROLE_DELETE("Suppression rôle", "ROLE", "DELETE"),
|
||||
ROLE_ASSIGN("Attribution rôle", "ROLE", "ASSIGN"),
|
||||
ROLE_REVOKE("Révocation rôle", "ROLE", "REVOKE"),
|
||||
ROLE_ADD_COMPOSITE("Ajout rôle composite", "ROLE", "ADD_COMPOSITE"),
|
||||
ROLE_REMOVE_COMPOSITE("Retrait rôle composite", "ROLE", "REMOVE_COMPOSITE"),
|
||||
|
||||
// Actions Groupe
|
||||
GROUP_CREATE("Création groupe", "GROUP", "CREATE"),
|
||||
GROUP_UPDATE("Modification groupe", "GROUP", "UPDATE"),
|
||||
GROUP_DELETE("Suppression groupe", "GROUP", "DELETE"),
|
||||
GROUP_ADD_MEMBER("Ajout membre groupe", "GROUP", "ADD_MEMBER"),
|
||||
GROUP_REMOVE_MEMBER("Retrait membre groupe", "GROUP", "REMOVE_MEMBER"),
|
||||
|
||||
// Actions Realm
|
||||
REALM_SYNC("Synchronisation realm", "REALM", "SYNC"),
|
||||
REALM_EXPORT("Export realm", "REALM", "EXPORT"),
|
||||
REALM_IMPORT("Import realm", "REALM", "IMPORT"),
|
||||
|
||||
// Actions Session
|
||||
SESSION_CREATE("Création session", "SESSION", "CREATE"),
|
||||
SESSION_DELETE("Suppression session", "SESSION", "DELETE"),
|
||||
SESSION_REVOKE_ALL("Révocation toutes sessions", "SESSION", "REVOKE_ALL"),
|
||||
|
||||
// Actions Système
|
||||
SYSTEM_BACKUP("Sauvegarde système", "SYSTEM", "BACKUP"),
|
||||
SYSTEM_RESTORE("Restauration système", "SYSTEM", "RESTORE"),
|
||||
SYSTEM_CONFIG_CHANGE("Modification configuration", "SYSTEM", "CONFIG_CHANGE");
|
||||
|
||||
private final String libelle;
|
||||
private final String ressourceType;
|
||||
private final String actionType;
|
||||
|
||||
/**
|
||||
* Détermine si l'action concerne un utilisateur
|
||||
*/
|
||||
public boolean isUserAction() {
|
||||
return ressourceType.equals("USER");
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si l'action concerne un rôle
|
||||
*/
|
||||
public boolean isRoleAction() {
|
||||
return ressourceType.equals("ROLE");
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si l'action est une création
|
||||
*/
|
||||
public boolean isCreateAction() {
|
||||
return actionType.equals("CREATE");
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si l'action est une modification
|
||||
*/
|
||||
public boolean isUpdateAction() {
|
||||
return actionType.equals("UPDATE");
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si l'action est une suppression
|
||||
*/
|
||||
public boolean isDeleteAction() {
|
||||
return actionType.equals("DELETE");
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si l'action est critique (nécessite alerte)
|
||||
*/
|
||||
public boolean isCritical() {
|
||||
return this == USER_DELETE
|
||||
|| this == ROLE_DELETE
|
||||
|| this == USER_SUSPEND
|
||||
|| this == SESSION_REVOKE_ALL
|
||||
|| this == SYSTEM_RESTORE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package dev.lions.user.manager.enums.role;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
|
||||
/**
|
||||
* Type de rôle dans Keycloak
|
||||
* Distingue les rôles au niveau Realm vs Client
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
@Schema(description = "Type de rôle Keycloak")
|
||||
public enum TypeRole {
|
||||
|
||||
/**
|
||||
* Rôle global au niveau du Realm
|
||||
* Applicable à tous les clients du realm
|
||||
*/
|
||||
REALM_ROLE("Realm Role", "Rôle global applicable à tous les clients du realm", "realm-role"),
|
||||
|
||||
/**
|
||||
* Rôle spécifique à un client
|
||||
* Limité au scope d'un client particulier
|
||||
*/
|
||||
CLIENT_ROLE("Client Role", "Rôle spécifique à un client particulier", "client-role"),
|
||||
|
||||
/**
|
||||
* Rôle composite (contient d'autres rôles)
|
||||
*/
|
||||
COMPOSITE_ROLE("Composite Role", "Rôle composite contenant d'autres rôles", "composite-role");
|
||||
|
||||
private final String libelle;
|
||||
private final String description;
|
||||
private final String codeKeycloak;
|
||||
|
||||
/**
|
||||
* Détermine si le rôle est au niveau realm
|
||||
* @return true si c'est un realm role
|
||||
*/
|
||||
public boolean isRealmRole() {
|
||||
return this == REALM_ROLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si le rôle est au niveau client
|
||||
* @return true si c'est un client role
|
||||
*/
|
||||
public boolean isClientRole() {
|
||||
return this == CLIENT_ROLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si le rôle est composite
|
||||
* @return true si c'est un composite role
|
||||
*/
|
||||
public boolean isComposite() {
|
||||
return this == COMPOSITE_ROLE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package dev.lions.user.manager.enums.user;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||
|
||||
/**
|
||||
* Statut d'un utilisateur dans Keycloak
|
||||
* Mappé depuis le champ "enabled" et attributs personnalisés
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
@Schema(description = "Statut d'un utilisateur")
|
||||
public enum StatutUser {
|
||||
|
||||
/**
|
||||
* Utilisateur actif et opérationnel
|
||||
*/
|
||||
ACTIF("Actif", "Utilisateur actif avec accès complet", true),
|
||||
|
||||
/**
|
||||
* Utilisateur désactivé temporairement (peut être réactivé)
|
||||
*/
|
||||
INACTIF("Inactif", "Utilisateur désactivé temporairement", false),
|
||||
|
||||
/**
|
||||
* Utilisateur suspendu suite à une action administrative
|
||||
*/
|
||||
SUSPENDU("Suspendu", "Compte suspendu par un administrateur", false),
|
||||
|
||||
/**
|
||||
* Utilisateur en attente de validation
|
||||
*/
|
||||
EN_ATTENTE("En attente", "Compte en attente de validation", false),
|
||||
|
||||
/**
|
||||
* Utilisateur verrouillé suite à des tentatives échouées
|
||||
*/
|
||||
VERROUILLE("Verrouillé", "Compte verrouillé suite à plusieurs échecs d'authentification", false),
|
||||
|
||||
/**
|
||||
* Utilisateur dont le compte a expiré
|
||||
*/
|
||||
EXPIRE("Expiré", "Compte expiré et nécessite une réactivation", false),
|
||||
|
||||
/**
|
||||
* Utilisateur supprimé (soft delete)
|
||||
*/
|
||||
SUPPRIME("Supprimé", "Compte supprimé logiquement", false);
|
||||
|
||||
private final String libelle;
|
||||
private final String description;
|
||||
private final boolean enabled;
|
||||
|
||||
/**
|
||||
* Convertit un statut Keycloak "enabled" en StatutUser
|
||||
* @param enabled état enabled de Keycloak
|
||||
* @return ACTIF si enabled=true, INACTIF sinon
|
||||
*/
|
||||
public static StatutUser fromEnabled(boolean enabled) {
|
||||
return enabled ? ACTIF : INACTIF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si l'utilisateur peut se connecter
|
||||
* @return true si le statut permet la connexion
|
||||
*/
|
||||
public boolean peutSeConnecter() {
|
||||
return this == ACTIF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si l'utilisateur peut être réactivé
|
||||
* @return true si le statut permet la réactivation
|
||||
*/
|
||||
public boolean peutEtreReactive() {
|
||||
return this == INACTIF || this == SUSPENDU || this == EXPIRE;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user