Do not return an error when moving a group to the current parent
Closes https://github.com/keycloak/keycloak/issues/21242
This commit is contained in:
parent
a5a2753d11
commit
4bc11bdf7f
3 changed files with 48 additions and 33 deletions
|
@ -24,6 +24,7 @@ import org.keycloak.events.admin.ResourceType;
|
||||||
import org.keycloak.models.Constants;
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.GroupModel;
|
import org.keycloak.models.GroupModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.ModelDuplicateException;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.models.utils.ModelToRepresentation;
|
import org.keycloak.models.utils.ModelToRepresentation;
|
||||||
|
@ -31,7 +32,6 @@ import org.keycloak.representations.idm.GroupRepresentation;
|
||||||
import org.keycloak.representations.idm.ManagementPermissionReference;
|
import org.keycloak.representations.idm.ManagementPermissionReference;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.keycloak.services.ErrorResponse;
|
import org.keycloak.services.ErrorResponse;
|
||||||
import org.keycloak.services.Urls;
|
|
||||||
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluator;
|
||||||
import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
|
import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement;
|
||||||
import org.keycloak.services.resources.admin.permissions.AdminPermissions;
|
import org.keycloak.services.resources.admin.permissions.AdminPermissions;
|
||||||
|
@ -156,11 +156,8 @@ public class GroupResource {
|
||||||
if (ObjectUtil.isBlank(groupName)) {
|
if (ObjectUtil.isBlank(groupName)) {
|
||||||
throw ErrorResponse.error("Group name is missing", Response.Status.BAD_REQUEST);
|
throw ErrorResponse.error("Group name is missing", Response.Status.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
boolean childExists = group.getSubGroupsStream().anyMatch(s -> Objects.equals(s.getName(), groupName));
|
|
||||||
if (childExists) {
|
|
||||||
throw ErrorResponse.exists("Sibling group named '" + groupName + "' already exists.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
try {
|
||||||
Response.ResponseBuilder builder = Response.status(204);
|
Response.ResponseBuilder builder = Response.status(204);
|
||||||
GroupModel child = null;
|
GroupModel child = null;
|
||||||
if (rep.getId() != null) {
|
if (rep.getId() != null) {
|
||||||
|
@ -168,7 +165,9 @@ public class GroupResource {
|
||||||
if (child == null) {
|
if (child == null) {
|
||||||
throw new NotFoundException("Could not find child by id");
|
throw new NotFoundException("Could not find child by id");
|
||||||
}
|
}
|
||||||
|
if (!Objects.equals(child.getParentId(), group.getId())) {
|
||||||
realm.moveGroup(child, group);
|
realm.moveGroup(child, group);
|
||||||
|
}
|
||||||
adminEvent.operation(OperationType.UPDATE);
|
adminEvent.operation(OperationType.UPDATE);
|
||||||
} else {
|
} else {
|
||||||
child = realm.createGroup(groupName, group);
|
child = realm.createGroup(groupName, group);
|
||||||
|
@ -189,6 +188,9 @@ public class GroupResource {
|
||||||
|
|
||||||
GroupRepresentation childRep = ModelToRepresentation.toGroupHierarchy(child, true);
|
GroupRepresentation childRep = ModelToRepresentation.toGroupHierarchy(child, true);
|
||||||
return builder.type(MediaType.APPLICATION_JSON_TYPE).entity(childRep).build();
|
return builder.type(MediaType.APPLICATION_JSON_TYPE).entity(childRep).build();
|
||||||
|
} catch (ModelDuplicateException e) {
|
||||||
|
throw ErrorResponse.exists("Sibling group named '" + groupName + "' already exists.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateGroup(GroupRepresentation rep, GroupModel model, RealmModel realm, KeycloakSession session) {
|
public static void updateGroup(GroupRepresentation rep, GroupModel model, RealmModel realm, KeycloakSession session) {
|
||||||
|
|
|
@ -157,7 +157,9 @@ public class GroupsResource {
|
||||||
if (child == null) {
|
if (child == null) {
|
||||||
throw new NotFoundException("Could not find child by id");
|
throw new NotFoundException("Could not find child by id");
|
||||||
}
|
}
|
||||||
|
if (child.getParentId() != null) {
|
||||||
realm.moveGroup(child, null);
|
realm.moveGroup(child, null);
|
||||||
|
}
|
||||||
adminEvent.operation(OperationType.UPDATE).resourcePath(session.getContext().getUri());
|
adminEvent.operation(OperationType.UPDATE).resourcePath(session.getContext().getUri());
|
||||||
} else {
|
} else {
|
||||||
child = realm.createGroup(groupName);
|
child = realm.createGroup(groupName);
|
||||||
|
|
|
@ -183,10 +183,16 @@ public class GroupTest extends AbstractGroupTest {
|
||||||
assertSameNameNotAllowed(response,"Top level group named 'top' already exists.");
|
assertSameNameNotAllowed(response,"Top level group named 'top' already exists.");
|
||||||
response.close();
|
response.close();
|
||||||
|
|
||||||
|
// allow moving the group to top level (nothing is done)
|
||||||
|
response = realm.groups().add(topGroup);
|
||||||
|
assertEquals(Response.Status.NO_CONTENT, response.getStatusInfo());
|
||||||
|
response.close();
|
||||||
|
|
||||||
GroupRepresentation level2Group = new GroupRepresentation();
|
GroupRepresentation level2Group = new GroupRepresentation();
|
||||||
level2Group.setName("level2");
|
level2Group.setName("level2");
|
||||||
response = realm.groups().group(topGroup.getId()).subGroup(level2Group);
|
response = realm.groups().group(topGroup.getId()).subGroup(level2Group);
|
||||||
assertEquals(201, response.getStatus()); // created status
|
assertEquals(201, response.getStatus()); // created status
|
||||||
|
level2Group.setId(ApiUtil.getCreatedId(response));
|
||||||
response.close();
|
response.close();
|
||||||
|
|
||||||
GroupRepresentation anotherlevel2Group = new GroupRepresentation();
|
GroupRepresentation anotherlevel2Group = new GroupRepresentation();
|
||||||
|
@ -194,6 +200,11 @@ public class GroupTest extends AbstractGroupTest {
|
||||||
response = realm.groups().group(topGroup.getId()).subGroup(anotherlevel2Group);
|
response = realm.groups().group(topGroup.getId()).subGroup(anotherlevel2Group);
|
||||||
assertSameNameNotAllowed(response,"Sibling group named 'level2' already exists.");
|
assertSameNameNotAllowed(response,"Sibling group named 'level2' already exists.");
|
||||||
response.close();
|
response.close();
|
||||||
|
|
||||||
|
// allow moving the group to the same parent (nothing is done)
|
||||||
|
response = realm.groups().group(topGroup.getId()).subGroup(level2Group);
|
||||||
|
assertEquals(Response.Status.NO_CONTENT, response.getStatusInfo());
|
||||||
|
response.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in a new issue