Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<User> existingUser = loadUserPort.findByEmail(command.email());
if (existingUser.isPresent()) {
promoteToAdminIfNeeded(existingUser.get());
return;
}

Expand All @@ -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();
}
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/com/promsearch/user/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
Loading