From 0b275dfe81dbe238a51f965cfd0a3331e2ab55b9 Mon Sep 17 00:00:00 2001 From: John Niang Date: Tue, 9 Sep 2025 15:56:27 +0800 Subject: [PATCH] Handle ghost users in user retrieval logic --- .../user/service/impl/UserServiceImpl.java | 10 +++++++- .../service/impl/UserServiceImplTest.java | 24 +++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/run/halo/app/core/user/service/impl/UserServiceImpl.java b/application/src/main/java/run/halo/app/core/user/service/impl/UserServiceImpl.java index 72deab22c..4a2882cd0 100644 --- a/application/src/main/java/run/halo/app/core/user/service/impl/UserServiceImpl.java +++ b/application/src/main/java/run/halo/app/core/user/service/impl/UserServiceImpl.java @@ -105,7 +105,15 @@ public class UserServiceImpl implements UserService { var options = ListOptions.builder() .andQuery(QueryFactory.in("metadata.name", nameSet)) .build(); - return client.listAll(User.class, options, defaultSort()); + return client.listAll(User.class, options, defaultSort()) + .collectMap(u -> u.getMetadata().getName()) + .map(map -> { + var ghost = map.get(GHOST_USER_NAME); + return names.stream() + .map(name -> map.getOrDefault(name, ghost)) + .toList(); + }) + .flatMapMany(Flux::fromIterable); } @Override diff --git a/application/src/test/java/run/halo/app/core/user/service/impl/UserServiceImplTest.java b/application/src/test/java/run/halo/app/core/user/service/impl/UserServiceImplTest.java index 807262d94..0169eecb1 100644 --- a/application/src/test/java/run/halo/app/core/user/service/impl/UserServiceImplTest.java +++ b/application/src/test/java/run/halo/app/core/user/service/impl/UserServiceImplTest.java @@ -22,6 +22,7 @@ import static org.mockito.Mockito.when; import static run.halo.app.extension.GroupVersionKind.fromExtension; import java.util.HashMap; +import java.util.List; import java.util.Set; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -46,6 +47,7 @@ import run.halo.app.core.user.service.RoleService; import run.halo.app.core.user.service.SignUpData; import run.halo.app.core.user.service.UserPostCreatingHandler; import run.halo.app.core.user.service.UserPreCreatingHandler; +import run.halo.app.core.user.service.UserService; import run.halo.app.event.user.PasswordChangedEvent; import run.halo.app.extension.ListOptions; import run.halo.app.extension.Metadata; @@ -108,6 +110,19 @@ class UserServiceImplTest { verify(client, times(1)).get(eq(User.class), eq("faker")); } + @Test + void shouldGetGhostsIfUsersContainDeleted() { + var fakeUser1 = createUser("fake-user1", "fake-password"); + var fakeUser2 = createUser("fake-user2", "fake-password"); + var ghost = createUser(UserService.GHOST_USER_NAME, "fake-password"); + when(client.listAll(eq(User.class), any(ListOptions.class), any(Sort.class))) + .thenReturn(Flux.just(fakeUser1, fakeUser2, ghost)); + userService.getUsersOrGhosts(List.of("fake-user1", "deleted-user", "fake-user2")) + .as(StepVerifier::create) + .expectNext(fakeUser1, ghost, fakeUser2) + .verifyComplete(); + } + @Test void shouldUpdatePasswordIfUserFoundInExtension() { var fakeUser = new User(); @@ -228,16 +243,20 @@ class UserServiceImplTest { } - User createUser(String password) { + User createUser(String username, String password) { var user = new User(); Metadata metadata = new Metadata(); - metadata.setName("fake-user"); + metadata.setName(username); user.setMetadata(metadata); user.setSpec(new User.UserSpec()); user.getSpec().setPassword(password); return user; } + User createUser(String password) { + return createUser("fake-user", password); + } + @Nested class GrantRolesTest { @@ -496,4 +515,5 @@ class UserServiceImplTest { .expectNext(true) .verifyComplete(); } + }