KEYCLOAK-9782: Do not allow duplicate group name when updating

This commit is contained in:
Stan Silvert 2020-03-12 14:52:55 -04:00
parent 62f5850731
commit 1f1ed36b71
2 changed files with 68 additions and 3 deletions

View file

@ -50,6 +50,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
@ -97,13 +98,28 @@ public class GroupResource {
*/
@PUT
@Consumes(MediaType.APPLICATION_JSON)
public void updateGroup(GroupRepresentation rep) {
public Response updateGroup(GroupRepresentation rep) {
this.auth.groups().requireManage(group);
for (GroupModel sibling: siblings()) {
if (Objects.equals(sibling.getId(), group.getId())) continue;
if (sibling.getName().equals(rep.getName())) {
return ErrorResponse.exists("Sibling group named '" + rep.getName() + "' already exists.");
}
}
updateGroup(rep, group);
adminEvent.operation(OperationType.UPDATE).resourcePath(session.getContext().getUri()).representation(rep).success();
return Response.noContent().build();
}
private List<GroupModel> siblings() {
if (group.getParentId() == null) {
return realm.getTopLevelGroups();
} else {
return new ArrayList(group.getParent().getSubGroups());
}
}
@DELETE

View file

@ -190,6 +190,55 @@ public class GroupTest extends AbstractGroupTest {
response.close();
assertEquals(409, response.getStatus()); // conflict status 409 - same name not allowed
}
@Test
// KEYCLOAK-11412 Unintended Groups with same names
public void doNotAllowSameGroupNameAtSameLevelWhenUpdatingName() throws Exception {
RealmResource realm = adminClient.realms().realm("test");
GroupRepresentation topGroup = new GroupRepresentation();
topGroup.setName("top1");
topGroup = createGroup(realm, topGroup);
GroupRepresentation anotherTopGroup = new GroupRepresentation();
anotherTopGroup.setName("top2");
anotherTopGroup = createGroup(realm, anotherTopGroup);
anotherTopGroup.setName("top1");
try {
realm.groups().group(anotherTopGroup.getId()).update(anotherTopGroup);
Assert.fail("Expected ClientErrorException");
} catch (ClientErrorException e) {
// conflict status 409 - same name not allowed
assertEquals("HTTP 409 Conflict", e.getMessage());
}
GroupRepresentation level2Group = new GroupRepresentation();
level2Group.setName("level2-1");
addSubGroup(realm, topGroup, level2Group);
GroupRepresentation anotherlevel2Group = new GroupRepresentation();
anotherlevel2Group.setName("level2-2");
addSubGroup(realm, topGroup, anotherlevel2Group);
anotherlevel2Group.setName("level2-1");
try {
realm.groups().group(anotherlevel2Group.getId()).update(anotherlevel2Group);
Assert.fail("Expected ClientErrorException");
} catch (ClientErrorException e) {
// conflict status 409 - same name not allowed
assertEquals("HTTP 409 Conflict", e.getMessage());
}
}
private void addSubGroup(RealmResource realm, GroupRepresentation parent, GroupRepresentation child) {
Response response = realm.groups().add(child);
child.setId(ApiUtil.getCreatedId(response));
response = realm.groups().group(parent.getId()).subGroup(child);
response.close();
}
@Test
public void allowSameGroupNameAtDifferentLevel() throws Exception {