From e1ebe5a0b7bc2633ff34a37959c15b0583000e0d Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Mon, 11 May 2026 16:22:40 +0800 Subject: [PATCH] Support key-only (null model) entries in nested map structures for groups and users setGroup and setUser now accept a null model value. If the entity already exists it is returned as-is without any updates. If it does not exist, a 404 is returned, since the key-only form is meant to reference an existing entity, not create one. --- .../crowd/service/GroupsServiceImpl.java | 7 +++++++ .../crowd/service/UsersServiceImpl.java | 7 +++++++ .../crowd/service/GroupsServiceTest.java | 18 ++++++++++++++++++ .../crowd/service/UsersServiceTest.java | 18 ++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/GroupsServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/GroupsServiceImpl.java index 4de40518..2212aff7 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/GroupsServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/GroupsServiceImpl.java @@ -108,9 +108,16 @@ public GroupModel setGroup( final Group group = findGroup(directoryId, groupName); if (group == null) { + if (groupModel == null) { + throw new GroupNotFoundException(groupName); + } return createGroup(directoryId, groupModel); } + if (groupModel == null) { + return GroupModelUtil.toGroupModel(group); + } + return updateGroup(directoryId, groupName, groupModel); } diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/UsersServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/UsersServiceImpl.java index 4d0330b7..db0f8492 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/UsersServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/UsersServiceImpl.java @@ -81,9 +81,16 @@ UserModel setUser( final User user = findUser(directoryId, username); if (user == null) { + if (userModel == null) { + throw new UserNotFoundException(username); + } return addUser(directoryId, username, userModel); } + if (userModel == null) { + return UserModelUtil.toUserModel(user); + } + return updateUser(directoryId, user.getName(), userModel); } diff --git a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/GroupsServiceTest.java b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/GroupsServiceTest.java index 9edd6769..dfddafb7 100644 --- a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/GroupsServiceTest.java +++ b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/GroupsServiceTest.java @@ -190,6 +190,24 @@ public void testSetGroups() { verify(spy, times(groupModels.size())).setGroup(anyLong(), any(), any()); } + @Test + public void testSetGroupNullModelAddNew() { + final Group group = getTestGroup(); + assertThrows(GroupNotFoundException.class, () -> + groupsService.setGroup(group.getDirectoryId(), group.getName(), null)); + } + + @Test + public void testSetGroupNullModelExisting() { + final Group group = getTestGroup(); + final GroupsServiceImpl spy = spy(groupsService); + doReturn(group).when(spy).findGroup(group.getDirectoryId(), group.getName()); + + spy.setGroup(group.getDirectoryId(), group.getName(), null); + verify(spy, never()).createGroup(anyLong(), any()); + verify(spy, never()).updateGroup(anyLong(), anyString(), any()); + } + @Test public void testSetGroupsNull() { assertEquals(Collections.emptyMap(), groupsService.setGroups(0L, null)); diff --git a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/UsersServiceTest.java b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/UsersServiceTest.java index 21e5f020..1794f4ee 100644 --- a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/UsersServiceTest.java +++ b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/UsersServiceTest.java @@ -142,6 +142,24 @@ public void testSetUserWithMapKeyUsernameWhenModelUsernameIsNull() { verify(spy).addUser(anyLong(), eq(user.getName()), any(UserModel.class)); } + @Test + public void testSetUserNullModelAddNew() { + final User user = getTestUser(); + assertThrows(UserNotFoundException.class, () -> + usersService.setUser(user.getDirectoryId(), user.getName(), null)); + } + + @Test + public void testSetUserNullModelExisting() throws CrowdException { + final User user = getTestUser(); + final UsersServiceImpl spy = spy(usersService); + doReturn(user).when(spy).findUser(user.getDirectoryId(), user.getName()); + + spy.setUser(user.getDirectoryId(), user.getName(), null); + verify(spy, never()).addUser(anyLong(), anyString(), any()); + verify(spy, never()).updateUser(anyLong(), anyString(), any()); + } + @Test public void testSetUsers() { final User user = getTestUser();