mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
Fix NPE when accessing group concurrently
Closes #40368 Signed-off-by: vramik <vramik@redhat.com>
This commit is contained in:
parent
e92b825a14
commit
332c9b6e4a
@ -271,7 +271,8 @@ public class GroupAdapter implements GroupModel {
|
||||
@Override
|
||||
public Long getSubGroupsCount() {
|
||||
if (isUpdated()) return updated.getSubGroupsCount();
|
||||
return getGroupModel().getSubGroupsCount();
|
||||
GroupModel model = modelSupplier.get();
|
||||
return model == null ? null : model.getSubGroupsCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -58,6 +58,7 @@ public class CachedGroup extends AbstractRevisioned implements InRealm {
|
||||
this.type = group.getType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
||||
@ -98,14 +98,4 @@ public class GroupUtils {
|
||||
rep.setAccess(groupsEvaluator.getAccess(groupTree));
|
||||
return rep;
|
||||
}
|
||||
|
||||
private static boolean groupMatchesSearchOrIsPathElement(GroupModel group, String search) {
|
||||
if (StringUtil.isBlank(search)) {
|
||||
return true;
|
||||
}
|
||||
if (group.getName().contains(search)) {
|
||||
return true;
|
||||
}
|
||||
return group.getSubGroupsStream().findAny().isPresent();
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import jakarta.ws.rs.core.Response.Status;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.keycloak.admin.client.Keycloak;
|
||||
@ -76,6 +77,9 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.anEmptyMap;
|
||||
@ -90,6 +94,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mstrukel@redhat.com">Marko Strukelj</a>
|
||||
@ -109,6 +114,49 @@ public class GroupTest extends AbstractGroupTest {
|
||||
@InjectHttpClient
|
||||
CloseableHttpClient httpClient;
|
||||
|
||||
|
||||
@Test
|
||||
public void createMultiDeleteMultiReadMulti() {
|
||||
// create multiple groups
|
||||
List<String> groupUuuids = new ArrayList<>();
|
||||
IntStream.range(0, 100).forEach(groupIndex -> {
|
||||
GroupRepresentation group = new GroupRepresentation();
|
||||
group.setName("Test Group " + groupIndex);
|
||||
try (Response response = managedRealm.admin().groups().add(group)) {
|
||||
boolean created = response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL;
|
||||
if (created) {
|
||||
final String groupUuid = ApiUtil.getCreatedId(response);
|
||||
groupUuuids.add(groupUuid);
|
||||
} else {
|
||||
fail("Failed to create group: " + response.getStatusInfo().getReasonPhrase());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
AtomicBoolean deletedAll = new AtomicBoolean(false);
|
||||
List<Exception> caughtExceptions = new CopyOnWriteArrayList<>();
|
||||
// read groups in a separate thread
|
||||
new Thread(() -> {
|
||||
while (!deletedAll.get()) {
|
||||
try {
|
||||
// just loading briefs
|
||||
managedRealm.admin().groups().groups(null, 0, Integer.MAX_VALUE, true);
|
||||
} catch (Exception e) {
|
||||
|
||||
caughtExceptions.add(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
// delete groups
|
||||
groupUuuids.forEach(groupUuid -> {
|
||||
managedRealm.admin().groups().group(groupUuid).remove();
|
||||
});
|
||||
deletedAll.set(true);
|
||||
|
||||
assertThat(caughtExceptions, Matchers.empty());
|
||||
}
|
||||
|
||||
// KEYCLOAK-2716 Can't delete client if its role is assigned to a group
|
||||
@Test
|
||||
public void testClientRemoveWithClientRoleGroupMapping() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user