KEYCLOAK-13369 Not possible to move groups in admin console
This commit is contained in:
parent
61fd66e107
commit
3e82473a90
6 changed files with 86 additions and 3 deletions
|
@ -997,7 +997,8 @@ public class RealmCacheSession implements CacheRealmProvider {
|
|||
listInvalidations.add(realm.getId());
|
||||
invalidateGroup(group.getId(), realm.getId(), true);
|
||||
if (toParent != null) invalidateGroup(toParent.getId(), realm.getId(), false); // Queries already invalidated
|
||||
invalidationEvents.add(GroupAddedEvent.create(group.getId(), realm.getId()));
|
||||
String parentId = toParent == null ? null : toParent.getId();
|
||||
invalidationEvents.add(GroupAddedEvent.create(group.getId(), parentId, realm.getId()));
|
||||
return group;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,10 +36,12 @@ public class GroupAddedEvent extends InvalidationEvent implements RealmCacheInva
|
|||
|
||||
private String groupId;
|
||||
private String realmId;
|
||||
private String parentId;
|
||||
|
||||
public static GroupAddedEvent create(String groupId, String realmId) {
|
||||
public static GroupAddedEvent create(String groupId, String parentId, String realmId) {
|
||||
GroupAddedEvent event = new GroupAddedEvent();
|
||||
event.realmId = realmId;
|
||||
event.parentId = parentId;
|
||||
event.groupId = groupId;
|
||||
return event;
|
||||
}
|
||||
|
@ -57,18 +59,23 @@ public class GroupAddedEvent extends InvalidationEvent implements RealmCacheInva
|
|||
@Override
|
||||
public void addInvalidations(RealmCacheManager realmCache, Set<String> invalidations) {
|
||||
realmCache.groupQueriesInvalidations(realmId, invalidations);
|
||||
if (parentId != null) {
|
||||
invalidations.add(parentId);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExternalizerImpl implements Externalizer<GroupAddedEvent> {
|
||||
|
||||
private static final int VERSION_1 = 1;
|
||||
private static final int VERSION_2 = 2;
|
||||
|
||||
@Override
|
||||
public void writeObject(ObjectOutput output, GroupAddedEvent obj) throws IOException {
|
||||
output.writeByte(VERSION_1);
|
||||
output.writeByte(VERSION_2);
|
||||
|
||||
MarshallUtil.marshallString(obj.groupId, output);
|
||||
MarshallUtil.marshallString(obj.realmId, output);
|
||||
MarshallUtil.marshallString(obj.parentId, output);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -76,6 +83,8 @@ public class GroupAddedEvent extends InvalidationEvent implements RealmCacheInva
|
|||
switch (input.readByte()) {
|
||||
case VERSION_1:
|
||||
return readObjectVersion1(input);
|
||||
case VERSION_2:
|
||||
return readObjectVersion2(input);
|
||||
default:
|
||||
throw new IOException("Unknown version");
|
||||
}
|
||||
|
@ -88,5 +97,14 @@ public class GroupAddedEvent extends InvalidationEvent implements RealmCacheInva
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
public GroupAddedEvent readObjectVersion2(ObjectInput input) throws IOException, ClassNotFoundException {
|
||||
GroupAddedEvent res = new GroupAddedEvent();
|
||||
res.groupId = MarshallUtil.unmarshallString(input);
|
||||
res.realmId = MarshallUtil.unmarshallString(input);
|
||||
res.parentId = MarshallUtil.unmarshallString(input);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,6 +158,7 @@ public class GroupResource {
|
|||
if (child == null) {
|
||||
throw new NotFoundException("Could not find child by id");
|
||||
}
|
||||
realm.moveGroup(child, group);
|
||||
adminEvent.operation(OperationType.UPDATE);
|
||||
} else {
|
||||
child = realm.createGroup(rep.getName(), group);
|
||||
|
|
|
@ -150,6 +150,7 @@ public class GroupsResource {
|
|||
if (child == null) {
|
||||
throw new NotFoundException("Could not find child by id");
|
||||
}
|
||||
realm.moveGroup(child, null);
|
||||
adminEvent.operation(OperationType.UPDATE).resourcePath(session.getContext().getUri());
|
||||
} else {
|
||||
child = realm.createGroup(rep.getName());
|
||||
|
|
|
@ -485,6 +485,45 @@ public class GroupTest extends AbstractGroupTest {
|
|||
assertThat(group.getAttributes(), hasEntry(is("attr3"), contains("attrval2")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moveGroups() {
|
||||
RealmResource realm = adminClient.realms().realm("test");
|
||||
|
||||
// Create 2 top level groups "mygroup1" and "mygroup2"
|
||||
GroupRepresentation group = GroupBuilder.create()
|
||||
.name("mygroup1")
|
||||
.build();
|
||||
GroupRepresentation group1 = createGroup(realm, group);
|
||||
|
||||
group = GroupBuilder.create()
|
||||
.name("mygroup2")
|
||||
.build();
|
||||
GroupRepresentation group2 = createGroup(realm, group);
|
||||
|
||||
// Move "mygroup2" as child of "mygroup1" . Assert it was moved
|
||||
Response response = realm.groups().group(group1.getId()).subGroup(group2);
|
||||
Assert.assertEquals(204, response.getStatus());
|
||||
response.close();
|
||||
|
||||
// Assert "mygroup2" was moved
|
||||
group1 = realm.groups().group(group1.getId()).toRepresentation();
|
||||
group2 = realm.groups().group(group2.getId()).toRepresentation();
|
||||
assertNames(group1.getSubGroups(), "mygroup2");
|
||||
Assert.assertEquals("/mygroup1/mygroup2", group2.getPath());
|
||||
|
||||
|
||||
// Move "mygroup2" back under parent
|
||||
response = realm.groups().add(group2);
|
||||
Assert.assertEquals(204, response.getStatus());
|
||||
response.close();
|
||||
|
||||
// Assert "mygroup2" was moved
|
||||
group1 = realm.groups().group(group1.getId()).toRepresentation();
|
||||
group2 = realm.groups().group(group2.getId()).toRepresentation();
|
||||
assertTrue(group1.getSubGroups().isEmpty());
|
||||
Assert.assertEquals("/mygroup2", group2.getPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void groupMembership() {
|
||||
RealmResource realm = adminClient.realms().realm("test");
|
||||
|
|
|
@ -7,6 +7,7 @@ import org.keycloak.admin.client.resource.GroupsResource;
|
|||
import org.keycloak.representations.idm.GroupRepresentation;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.arquillian.ContainerInfo;
|
||||
import org.keycloak.testsuite.util.GroupBuilder;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
@ -17,6 +18,7 @@ import java.util.List;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.keycloak.testsuite.Assert.assertNames;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -131,6 +133,27 @@ public class GroupInvalidationClusterTest extends AbstractInvalidationClusterTes
|
|||
assertEquals(parentGroup.getPath() + "/" + group.getName(), group.getPath());
|
||||
|
||||
verifyEntityUpdateDuringFailover(group, backendFailover);
|
||||
parentGroup = readEntityOnCurrentFailNode(parentGroup);
|
||||
|
||||
// Add new child
|
||||
GroupRepresentation childGroup2 = GroupBuilder.create()
|
||||
.name("childGroup2")
|
||||
.build();
|
||||
r = entityResourceOnCurrentFailNode(parentGroup).subGroup(childGroup2);
|
||||
String childGroup2Id = ApiUtil.getCreatedId(r);
|
||||
childGroup2.setId(childGroup2Id);
|
||||
|
||||
|
||||
parentGroup = readEntityOnCurrentFailNode(parentGroup);
|
||||
verifyEntityUpdateDuringFailover(parentGroup, backendFailover);
|
||||
|
||||
// Verify same child groups on both nodes
|
||||
GroupRepresentation parentGroupOnOtherNode = readEntityOnCurrentFailNode(parentGroup);
|
||||
assertNames(parentGroup.getSubGroups(), group.getName(), "childGroup2");
|
||||
assertNames(parentGroupOnOtherNode.getSubGroups(), group.getName(), "childGroup2");
|
||||
|
||||
// Remove childGroup2
|
||||
deleteEntityOnCurrentFailNode(childGroup2);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue