package de.ph87.tools.user; import de.ph87.tools.group.GroupDto; import de.ph87.tools.group.GroupMapper; import jakarta.annotation.Nullable; import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletResponse; import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.server.ResponseStatusException; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; import static de.ph87.tools.UserArgumentResolver.USER_UUID_COOKIE_NAME; @Slf4j @Service @Transactional @EnableScheduling @RequiredArgsConstructor public class UserService { private final UserRepository userRepository; private final UserPrivateMapper userPrivateMapper; private final UserPublicMapper userPublicMapper; private final GroupMapper groupMapper; @NonNull public User getUserByPrivateUuidOrElseCreate(@Nullable final String privateUuid, @NonNull final HttpServletResponse response) { final User user = Optional.ofNullable(privateUuid).map(userRepository::findByPrivateUuid).filter(Optional::isPresent).map(Optional::get).orElseGet(this::createUnchecked); writeUserUuidCookie(response, user); return user; } @Nullable public UserPrivateDto getUserByPrivateUuidOrNull(@Nullable final String privateUuid, final @NonNull HttpServletResponse response) { if (privateUuid == null || privateUuid.isEmpty()) { return null; } final User user = userRepository.findByPrivateUuid(privateUuid).orElse(null); writeUserUuidCookie(response, user); return userPrivateMapper.toPrivateDtoOrNull(user); } @NonNull public UserPrivateDto changeName(@NonNull final String privateUuid, @NonNull final String name) { return modify(privateUuid, user -> { user.setName(name); log.info("User name changed: user={}", user); }); } @NonNull public UserCommonDto getCommonByUuid(@NonNull final String privateUuid, @NonNull final String targetUuid) { final User principal = getByPrivateUuidOrThrow(privateUuid); final User target = getByPublicUuid(targetUuid); final Set commonGroups = groupMapper.findAllCommonGroups(principal, target); return new UserCommonDto(target, commonGroups); } public void delete(@NonNull final String privateUuid, final @NonNull HttpServletResponse response) { final User user = userRepository.findByPrivateUuid(privateUuid).orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST)); deleteUnchecked(response, user); } /* CREATE, MODIFY, DELETE ----------------------------------------------------------------------- */ @NonNull private User createUnchecked() { final User user = userRepository.save(new User()); log.info("User CREATED: {}", user); return user; } @NonNull private UserPrivateDto modify(@NonNull final String privateUuid, @NonNull Consumer modifier) { final User user = getByPrivateUuidOrThrow(privateUuid); modifier.accept(user); userPublicMapper.publish(user); userPrivateMapper.publish(user); return userPrivateMapper.toPrivateDto(user); } private void deleteUnchecked(final HttpServletResponse response, final User user) { userRepository.delete(user); log.info("User DELETED: {}", user); writeUserUuidCookie(response, null); } /* GETTERS & FINDERS ---------------------------------------------------------------------------- */ @NonNull public User getByPrivateUuidOrThrow(@NonNull final String privateUuid) { return userRepository.findByPrivateUuid(privateUuid).orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST)); } @NonNull public User getByPublicUuid(@NonNull final String publicUuid) { return userRepository.findByPublicUuid(publicUuid).orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST)); } @NonNull public Optional findByPrivateUuid(@NonNull final String privateUuid) { return userRepository.findByPrivateUuid(privateUuid); } /* COOKIES -------------------------------------------------------------------------------------- */ private static void writeUserUuidCookie(@NonNull final HttpServletResponse response, @Nullable final User user) { final Cookie cookie = new Cookie(USER_UUID_COOKIE_NAME, ""); if (user != null) { cookie.setValue(user.getPrivateUuid()); } cookie.setMaxAge(10 * 365 * 24 * 60 * 60); cookie.setPath("/"); response.addCookie(cookie); } }