fix(keycloak): gérer 409 User Conflict + bump Lombok + release 21 explicite

- UserServiceImpl.createUser : capture HTTP 409 et récupère l'utilisateur
  existant (searchByEmail/searchByUsername) au lieu de throw brutal
- usernameExists : utilise searchByUsername(exact=true) au lieu de search(query)
  pour match exact sans ambiguïté
- pom.xml : <release>21</release> explicite sur maven-compiler-plugin
- Lombok 1.18.34 → 1.18.36

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
dahoud
2026-04-21 12:45:44 +00:00
parent 8ab1513bf5
commit 86d0dc51b7
2 changed files with 21 additions and 3 deletions

View File

@@ -187,6 +187,7 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <configuration>
<release>21</release>
<annotationProcessorPaths> <annotationProcessorPaths>
<path> <path>
<groupId>org.mapstruct</groupId> <groupId>org.mapstruct</groupId>
@@ -196,7 +197,7 @@
<path> <path>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.34</version> <version>1.18.36</version>
</path> </path>
<path> <path>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>

View File

@@ -215,8 +215,25 @@ public class UserServiceImpl implements UserService {
UsersResource usersResource = keycloakAdminClient.getUsers(realmName); UsersResource usersResource = keycloakAdminClient.getUsers(realmName);
var response = usersResource.create(userRep); var response = usersResource.create(userRep);
if (response.getStatus() == 409) {
// Utilisateur déjà existant — le récupérer par email ou username
log.warn("Utilisateur {} déjà existant dans Keycloak (409), récupération...", user.getUsername());
if (user.getEmail() != null) {
List<UserRepresentation> existing = usersResource.searchByEmail(user.getEmail(), true);
if (!existing.isEmpty()) {
log.info("Utilisateur récupéré par email: {}", user.getEmail());
return UserMapper.toDTO(existing.get(0), realmName);
}
}
List<UserRepresentation> existing = usersResource.searchByUsername(user.getUsername(), true);
if (!existing.isEmpty()) {
log.info("Utilisateur récupéré par username: {}", user.getUsername());
return UserMapper.toDTO(existing.get(0), realmName);
}
throw new RuntimeException("Utilisateur en conflit mais introuvable: " + user.getUsername());
}
if (response.getStatus() != 201) { if (response.getStatus() != 201) {
throw new RuntimeException("Échec de la création de l'utilisateur: " + response.getStatusInfo()); throw new RuntimeException("Échec de la création de l'utilisateur (HTTP " + response.getStatus() + " " + response.getStatusInfo().getReasonPhrase() + ")");
} }
// Récupérer l'ID de l'utilisateur créé // Récupérer l'ID de l'utilisateur créé
@@ -465,7 +482,7 @@ public class UserServiceImpl implements UserService {
public boolean usernameExists(@NotBlank String username, @NotBlank String realmName) { public boolean usernameExists(@NotBlank String username, @NotBlank String realmName) {
try { try {
List<UserRepresentation> users = keycloakAdminClient.getUsers(realmName) List<UserRepresentation> users = keycloakAdminClient.getUsers(realmName)
.search(username, 0, 1, true); .searchByUsername(username, true);
return !users.isEmpty(); return !users.isEmpty();
} catch (Exception e) { } catch (Exception e) {
log.error("Erreur lors de la vérification de l'existence du username {}", username, e); log.error("Erreur lors de la vérification de l'existence du username {}", username, e);