fix #43819 - partial import fails to overwrite existing groups (#43924)

* fix #43819 - partial import fails to overwrite existing groups

- when removal is delayed until insertion of the newly imported group
  this causes a duplicate key constrain violation (`Key (realm_id, parent_group, name)`)
- fixed by flushing group removals

Signed-off-by: Martin Nowak <code@dawg.eu>

* adding a test and using a general fix

Signed-off-by: Steve Hawkins <shawkins@redhat.com>
# Conflicts:
#	services/src/main/java/org/keycloak/partialimport/PartialImportManager.java

---------

Signed-off-by: Martin Nowak <code@dawg.eu>
Signed-off-by: Steve Hawkins <shawkins@redhat.com>
Co-authored-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
dawg 2025-11-25 16:17:51 +01:00 committed by GitHub
parent b57c0d2f88
commit d5a507e90d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 16 additions and 4 deletions

View File

@ -20,6 +20,7 @@ package org.keycloak.partialimport;
import java.util.ArrayList;
import java.util.List;
import org.keycloak.connections.jpa.support.EntityManagers;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.representations.idm.PartialImportRepresentation;
@ -60,6 +61,7 @@ public class PartialImportManager {
for (PartialImport partialImport : partialImports) {
partialImport.removeOverwrites(realm, session);
EntityManagers.flush(session, false);
results.addAllResults(partialImport.doImport(rep, realm, session));
}

View File

@ -143,10 +143,10 @@ public class AbstractPartialImportTest {
piRep.setUsers(users);
}
protected void addGroups() {
protected void addGroups(int numEntities) {
List<GroupRepresentation> groups = new ArrayList<>();
for (int i=0; i < NUM_ENTITIES; i++) {
for (int i=0; i < numEntities; i++) {
GroupRepresentation group = new GroupRepresentation();
group.setName(GROUP_PREFIX + i);
group.setPath("/" + GROUP_PREFIX + i);
@ -156,6 +156,10 @@ public class AbstractPartialImportTest {
piRep.setGroups(groups);
}
protected void addGroups() {
addGroups(NUM_ENTITIES);
}
protected void addClients(boolean withServiceAccounts) {
List<ClientRepresentation> clients = new ArrayList<>();
List<UserRepresentation> serviceAccounts = new ArrayList<>();
@ -294,10 +298,10 @@ public class AbstractPartialImportTest {
protected void testOverwrite(int numberEntities) {
setOverwrite();
PartialImportResults results = doImport();
assertEquals(numberEntities, results.getAdded());
assertEquals(numberEntities, results.getAdded(), results.getErrorMessage());
results = doImport();
assertEquals(numberEntities, results.getOverwritten());
assertEquals(numberEntities, results.getOverwritten(), results.getErrorMessage());
}
private static class PartialImportRealmConfig implements RealmConfig {

View File

@ -48,4 +48,10 @@ public class PartialImportGroupTest extends AbstractPartialImportTest {
addGroups();
testOverwrite();
}
@Test
public void testAddSingleGroupOverwrite() {
addGroups(1);
testOverwrite(1);
}
}