diff --git a/src/main/java/com/promsearch/user/application/service/command/UserCommandService.java b/src/main/java/com/promsearch/user/application/service/command/UserCommandService.java index 2d84116..f403b3c 100644 --- a/src/main/java/com/promsearch/user/application/service/command/UserCommandService.java +++ b/src/main/java/com/promsearch/user/application/service/command/UserCommandService.java @@ -26,11 +26,13 @@ import com.promsearch.user.domain.InterestTagSelectionPolicy; import com.promsearch.user.domain.NicknamePolicy; import com.promsearch.user.domain.enums.InterestTagType; +import com.promsearch.user.domain.enums.UserRole; import com.promsearch.user.domain.exception.UserDomainException; import com.promsearch.user.domain.exception.UserErrorCode; import java.time.Instant; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; import lombok.RequiredArgsConstructor; @@ -170,8 +172,10 @@ public void bootstrap(BootstrapAdminAccountCommand command) { log.warn("admin_bootstrap_skipped reason=missing_config"); return; } - if (loadUserPort.existsByEmail(command.email())) { - log.info("admin_bootstrap_skipped reason=already_exists email={}", command.email()); + + Optional existingUser = loadUserPort.findByEmail(command.email()); + if (existingUser.isPresent()) { + promoteToAdminIfNeeded(existingUser.get()); return; } @@ -181,6 +185,16 @@ public void bootstrap(BootstrapAdminAccountCommand command) { log.info("admin_bootstrap_completed userId={}", savedAdmin.getUserId().id()); } + private void promoteToAdminIfNeeded(User user) { + if (user.getRole() == UserRole.ADMIN) { + log.info("admin_bootstrap_skipped reason=already_admin email={}", user.getEmail()); + return; + } + + User promotedAdmin = saveUserPort.update(user.promoteToAdmin()); + log.info("admin_bootstrap_promoted userId={}", promotedAdmin.getUserId().id()); + } + private boolean isBlank(String value) { return value == null || value.isBlank(); } diff --git a/src/main/java/com/promsearch/user/domain/User.java b/src/main/java/com/promsearch/user/domain/User.java index 7f30945..09fcbbf 100644 --- a/src/main/java/com/promsearch/user/domain/User.java +++ b/src/main/java/com/promsearch/user/domain/User.java @@ -257,6 +257,30 @@ public User promoteToOrigin() { .build(); } + /** + * 관리자 권한으로 승급한다. 배포 환경의 관리자 부트스트랩 계정이 일반 가입으로 + * 먼저 생성돼 있던 경우, 재기동 시 이 메서드로 role을 맞춘다. + * + * @return ADMIN 권한으로 변경된 새 사용자 객체 + */ + public User promoteToAdmin() { + return User.builder() + .userId(userId) + .email(email) + .password(password) + .nickname(nickname) + .name(name) + .profileImageUrl(profileImageUrl) + .profileImageObjectKey(profileImageObjectKey) + .point(point) + .role(UserRole.ADMIN) + .grade(grade) + .status(status) + .createdAt(createdAt) + .updatedAt(Instant.now()) + .build(); + } + public User changePassword(String password) { validateRequired(email, password, nickname, point, role, grade, status); diff --git a/src/test/java/com/promsearch/user/application/service/command/UserCommandServiceTest.java b/src/test/java/com/promsearch/user/application/service/command/UserCommandServiceTest.java index 8da3ca1..cb5e210 100644 --- a/src/test/java/com/promsearch/user/application/service/command/UserCommandServiceTest.java +++ b/src/test/java/com/promsearch/user/application/service/command/UserCommandServiceTest.java @@ -218,11 +218,38 @@ void bootstrapCreatesAdminAccountWhenNotExists() { } @Test - void bootstrapSkipsWhenAdminAlreadyExists() { + void bootstrapPromotesExistingUserToAdminWhenRoleIsNotAdmin() { userRepository.save(testUser(1L, "admin@example.com", "old-password", "admin", "admin", null, UserStatus.ACTIVE)); userCommandService.bootstrap(BootstrapAdminAccountCommand.of("admin@example.com", "Admin1234!", "admin")); + assertThat(userRepository.users).hasSize(1); + User promoted = userRepository.users.get(1L); + assertThat(promoted.getRole()).isEqualTo(UserRole.ADMIN); + assertThat(promoted.getPassword()).isEqualTo("old-password"); + } + + @Test + void bootstrapSkipsWhenAdminAlreadyExistsWithAdminRole() { + User existingAdmin = User.reconstruct( + new UserId(1L), + "admin@example.com", + "old-password", + "admin", + "admin", + null, + null, + 0L, + UserRole.ADMIN, + UserGrade.NODE, + UserStatus.ACTIVE, + Instant.now(), + Instant.now() + ); + userRepository.save(existingAdmin); + + userCommandService.bootstrap(BootstrapAdminAccountCommand.of("admin@example.com", "Admin1234!", "admin")); + assertThat(userRepository.users).hasSize(1); assertThat(userRepository.users.get(1L).getPassword()).isEqualTo("old-password"); }