refactor(audit): extract createUserForBootstrap() to make null actorId contract explicit
createUserOrUpdate(UUID actorId, ...) is always called from the controller with a real authenticated actor. createUserForBootstrap() handles seeding/test setup without emitting an audit event, making the two contracts unambiguous. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -80,6 +80,34 @@ public class UserService {
|
||||
return saved;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public AppUser createUserForBootstrap(CreateUserRequest request) {
|
||||
log.info("Bootstrap user creation (no audit): {}", request.getEmail());
|
||||
|
||||
Set<UserGroup> groups = new HashSet<>();
|
||||
if (request.getGroupIds() != null && !request.getGroupIds().isEmpty()) {
|
||||
groups.addAll(groupRepository.findAllById(request.getGroupIds()));
|
||||
}
|
||||
|
||||
Optional<AppUser> existingUser = userRepository.findByEmail(request.getEmail());
|
||||
if (existingUser.isPresent()) {
|
||||
AppUser updated = existingUser.get().updateFromRequest(request, passwordEncoder, groups);
|
||||
return userRepository.save(updated);
|
||||
}
|
||||
|
||||
AppUser user = AppUser.builder()
|
||||
.email(request.getEmail())
|
||||
.password(passwordEncoder.encode(request.getInitialPassword()))
|
||||
.groups(groups)
|
||||
.firstName(request.getFirstName())
|
||||
.lastName(request.getLastName())
|
||||
.birthDate(request.getBirthDate())
|
||||
.contact(request.getContact())
|
||||
.enabled(true)
|
||||
.build();
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public AppUser createUser(String email, String rawPassword, String firstName, String lastName, Set<UUID> groupIds) {
|
||||
userRepository.findByEmail(email).ifPresent(existing -> {
|
||||
|
||||
@@ -837,6 +837,26 @@ class UserServiceTest {
|
||||
verify(auditService, never()).logAfterCommit(any(), any(), any(), any());
|
||||
}
|
||||
|
||||
// ─── createUserForBootstrap ───────────────────────────────────────────────
|
||||
|
||||
@Test
|
||||
void createUserForBootstrap_createsUserWithoutAuditEvent() {
|
||||
CreateUserRequest req = new CreateUserRequest();
|
||||
req.setEmail("bootstrap@example.com");
|
||||
req.setInitialPassword("secret");
|
||||
req.setGroupIds(List.of());
|
||||
|
||||
when(userRepository.findByEmail("bootstrap@example.com")).thenReturn(Optional.empty());
|
||||
when(passwordEncoder.encode("secret")).thenReturn("encoded");
|
||||
AppUser saved = AppUser.builder().id(UUID.randomUUID()).email("bootstrap@example.com").build();
|
||||
when(userRepository.save(any())).thenReturn(saved);
|
||||
|
||||
AppUser result = userService.createUserForBootstrap(req);
|
||||
|
||||
assertThat(result).isEqualTo(saved);
|
||||
verify(auditService, never()).logAfterCommit(any(), any(), any(), any());
|
||||
}
|
||||
|
||||
// ─── createGroup ──────────────────────────────────────────────────────────
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user