313 lines
7.6 KiB
Java
313 lines
7.6 KiB
Java
package dev.lions.unionflow.server.service;
|
|
|
|
import io.quarkus.oidc.runtime.OidcJwtCallerPrincipal;
|
|
import io.quarkus.security.identity.SecurityIdentity;
|
|
import jakarta.enterprise.context.ApplicationScoped;
|
|
import jakarta.inject.Inject;
|
|
import java.util.Set;
|
|
import org.eclipse.microprofile.jwt.JsonWebToken;
|
|
import org.jboss.logging.Logger;
|
|
|
|
/**
|
|
* Service pour l'intégration avec Keycloak
|
|
*
|
|
* @author UnionFlow Team
|
|
* @version 1.0
|
|
* @since 2025-01-15
|
|
*/
|
|
@ApplicationScoped
|
|
public class KeycloakService {
|
|
|
|
private static final Logger LOG = Logger.getLogger(KeycloakService.class);
|
|
|
|
@Inject SecurityIdentity securityIdentity;
|
|
|
|
@Inject JsonWebToken jwt;
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur actuel est authentifié
|
|
*
|
|
* @return true si l'utilisateur est authentifié
|
|
*/
|
|
public boolean isAuthenticated() {
|
|
return securityIdentity != null && !securityIdentity.isAnonymous();
|
|
}
|
|
|
|
/**
|
|
* Obtient l'ID de l'utilisateur actuel depuis Keycloak
|
|
*
|
|
* @return l'ID de l'utilisateur ou null si non authentifié
|
|
*/
|
|
public String getCurrentUserId() {
|
|
if (!isAuthenticated()) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return jwt.getSubject();
|
|
} catch (Exception e) {
|
|
LOG.warnf("Erreur lors de la récupération de l'ID utilisateur: %s", e.getMessage());
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtient l'email de l'utilisateur actuel
|
|
*
|
|
* @return l'email de l'utilisateur ou null si non authentifié
|
|
*/
|
|
public String getCurrentUserEmail() {
|
|
if (!isAuthenticated()) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return jwt.getClaim("email");
|
|
} catch (Exception e) {
|
|
LOG.warnf("Erreur lors de la récupération de l'email utilisateur: %s", e.getMessage());
|
|
return securityIdentity.getPrincipal().getName();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtient le nom complet de l'utilisateur actuel
|
|
*
|
|
* @return le nom complet ou null si non disponible
|
|
*/
|
|
public String getCurrentUserFullName() {
|
|
if (!isAuthenticated()) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
String firstName = jwt.getClaim("given_name");
|
|
String lastName = jwt.getClaim("family_name");
|
|
|
|
if (firstName != null && lastName != null) {
|
|
return firstName + " " + lastName;
|
|
} else if (firstName != null) {
|
|
return firstName;
|
|
} else if (lastName != null) {
|
|
return lastName;
|
|
}
|
|
|
|
// Fallback sur le nom d'utilisateur
|
|
return jwt.getClaim("preferred_username");
|
|
} catch (Exception e) {
|
|
LOG.warnf("Erreur lors de la récupération du nom utilisateur: %s", e.getMessage());
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtient tous les rôles de l'utilisateur actuel
|
|
*
|
|
* @return les rôles de l'utilisateur
|
|
*/
|
|
public Set<String> getCurrentUserRoles() {
|
|
if (!isAuthenticated()) {
|
|
return Set.of();
|
|
}
|
|
|
|
return securityIdentity.getRoles();
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur actuel a un rôle spécifique
|
|
*
|
|
* @param role le rôle à vérifier
|
|
* @return true si l'utilisateur a le rôle
|
|
*/
|
|
public boolean hasRole(String role) {
|
|
if (!isAuthenticated()) {
|
|
return false;
|
|
}
|
|
|
|
return securityIdentity.hasRole(role);
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur actuel a au moins un des rôles spécifiés
|
|
*
|
|
* @param roles les rôles à vérifier
|
|
* @return true si l'utilisateur a au moins un des rôles
|
|
*/
|
|
public boolean hasAnyRole(String... roles) {
|
|
if (!isAuthenticated()) {
|
|
return false;
|
|
}
|
|
|
|
for (String role : roles) {
|
|
if (securityIdentity.hasRole(role)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur actuel a tous les rôles spécifiés
|
|
*
|
|
* @param roles les rôles à vérifier
|
|
* @return true si l'utilisateur a tous les rôles
|
|
*/
|
|
public boolean hasAllRoles(String... roles) {
|
|
if (!isAuthenticated()) {
|
|
return false;
|
|
}
|
|
|
|
for (String role : roles) {
|
|
if (!securityIdentity.hasRole(role)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Obtient une claim spécifique du JWT
|
|
*
|
|
* @param claimName le nom de la claim
|
|
* @return la valeur de la claim ou null si non trouvée
|
|
*/
|
|
public <T> T getClaim(String claimName) {
|
|
if (!isAuthenticated()) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
return jwt.getClaim(claimName);
|
|
} catch (Exception e) {
|
|
LOG.warnf("Erreur lors de la récupération de la claim %s: %s", claimName, e.getMessage());
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtient toutes les claims du JWT
|
|
*
|
|
* @return toutes les claims ou une map vide si non authentifié
|
|
*/
|
|
public Set<String> getAllClaimNames() {
|
|
if (!isAuthenticated()) {
|
|
return Set.of();
|
|
}
|
|
|
|
try {
|
|
Set<String> names = jwt.getClaimNames();
|
|
return names != null ? names : Set.of();
|
|
} catch (Exception e) {
|
|
LOG.warnf("Erreur lors de la récupération des claims: %s", e.getMessage());
|
|
return Set.of();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtient les informations utilisateur pour les logs
|
|
*
|
|
* @return informations utilisateur formatées
|
|
*/
|
|
public String getUserInfoForLogging() {
|
|
if (!isAuthenticated()) {
|
|
return "Utilisateur non authentifié";
|
|
}
|
|
|
|
String email = getCurrentUserEmail();
|
|
String fullName = getCurrentUserFullName();
|
|
Set<String> roles = getCurrentUserRoles();
|
|
|
|
return String.format(
|
|
"Utilisateur: %s (%s), Rôles: %s",
|
|
fullName != null ? fullName : "N/A", email != null ? email : "N/A", roles);
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur actuel est un administrateur
|
|
*
|
|
* @return true si l'utilisateur est administrateur
|
|
*/
|
|
public boolean isAdmin() {
|
|
return hasRole("ADMIN") || hasRole("admin");
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur actuel peut gérer les membres
|
|
*
|
|
* @return true si l'utilisateur peut gérer les membres
|
|
*/
|
|
public boolean canManageMembers() {
|
|
return hasAnyRole(
|
|
"ADMIN",
|
|
"GESTIONNAIRE_MEMBRE",
|
|
"PRESIDENT",
|
|
"SECRETAIRE",
|
|
"admin",
|
|
"gestionnaire_membre",
|
|
"president",
|
|
"secretaire");
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur actuel peut gérer les finances
|
|
*
|
|
* @return true si l'utilisateur peut gérer les finances
|
|
*/
|
|
public boolean canManageFinances() {
|
|
return hasAnyRole("ADMIN", "TRESORIER", "PRESIDENT", "admin", "tresorier", "president");
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur actuel peut gérer les événements
|
|
*
|
|
* @return true si l'utilisateur peut gérer les événements
|
|
*/
|
|
public boolean canManageEvents() {
|
|
return hasAnyRole(
|
|
"ADMIN",
|
|
"ORGANISATEUR_EVENEMENT",
|
|
"PRESIDENT",
|
|
"SECRETAIRE",
|
|
"admin",
|
|
"organisateur_evenement",
|
|
"president",
|
|
"secretaire");
|
|
}
|
|
|
|
/**
|
|
* Vérifie si l'utilisateur actuel peut gérer les organisations
|
|
*
|
|
* @return true si l'utilisateur peut gérer les organisations
|
|
*/
|
|
public boolean canManageOrganizations() {
|
|
return hasAnyRole("ADMIN", "PRESIDENT", "admin", "president");
|
|
}
|
|
|
|
/** Log les informations de sécurité pour debug */
|
|
public void logSecurityInfo() {
|
|
if (LOG.isDebugEnabled()) {
|
|
LOG.debugf("Informations de sécurité: %s", getUserInfoForLogging());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Obtient le token d'accès brut
|
|
*
|
|
* @return le token JWT brut ou null si non disponible
|
|
*/
|
|
public String getRawAccessToken() {
|
|
if (!isAuthenticated()) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
if (jwt instanceof OidcJwtCallerPrincipal) {
|
|
return ((OidcJwtCallerPrincipal) jwt).getRawToken();
|
|
}
|
|
return jwt.getRawToken();
|
|
} catch (Exception e) {
|
|
LOG.warnf("Erreur lors de la récupération du token brut: %s", e.getMessage());
|
|
return null;
|
|
}
|
|
}
|
|
}
|