Tools/src/main/java/de/ph87/tools/group/owner/GroupOwnerService.java
2024-11-06 14:52:02 +01:00

148 lines
6.0 KiB
Java

package de.ph87.tools.group.owner;
import de.ph87.tools.group.Group;
import de.ph87.tools.group.GroupMapper;
import de.ph87.tools.group.GroupRepository;
import de.ph87.tools.group.access.GroupAccess;
import de.ph87.tools.group.access.GroupAccessService;
import de.ph87.tools.group.dto.GroupDto;
import de.ph87.tools.group.events.GroupDeletedEvent;
import de.ph87.tools.group.member.GroupMemberService;
import de.ph87.tools.group.requests.GroupChangePasswordRequest;
import de.ph87.tools.group.requests.GroupChangeTitleRequest;
import de.ph87.tools.group.requests.GroupUserRequest;
import de.ph87.tools.group.uuid.GroupUuid;
import de.ph87.tools.tools.numbers.NumbersRepository;
import de.ph87.tools.user.User;
import de.ph87.tools.user.UserService;
import de.ph87.tools.user.push.UserPushService;
import de.ph87.tools.user.uuid.UserPrivateUuid;
import jakarta.annotation.Nullable;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.server.ResponseStatusException;
import java.util.function.BiConsumer;
@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class GroupOwnerService {
private final GroupAccessService groupAccessService;
private final GroupRepository groupRepository;
private final UserService userService;
private final GroupMemberService groupMemberService;
private final NumbersRepository numbersRepository;
private final UserPushService userPushService;
private final GroupMapper groupMapper;
@NonNull
public GroupDto create(@Nullable final UserPrivateUuid privateUuid, @NonNull final HttpServletResponse response) {
final User user = userService.getUserByPrivateUuidOrElseCreate(privateUuid, response);
final Group group = _create_unchecked(user);
return groupMemberService._add_user_to_group_unchecked(group, user);
}
public void delete(@NonNull final UserPrivateUuid userPrivateUuid, @NonNull final GroupUuid groupUuid) {
final GroupAccess access = groupAccessService.ownerAccess(userPrivateUuid, groupUuid);
numbersRepository.deleteAllByGroup(access.group);
groupRepository.delete(access.group);
log.info("Group deleted: group={}", access.group);
final GroupDeletedEvent event = new GroupDeletedEvent(access.group);
access.group.getUsers().forEach(user -> userPushService.push(user, event));
}
public void kick(@NonNull final UserPrivateUuid privateUuid, @NonNull final GroupUserRequest request) {
final OwnerRemoveResult result = _removeUser(privateUuid, request, (group, user) -> log.info("User kicked out of group: user={}, group={}", user, group));
groupMapper.push(result.group);
}
public void ban(@NonNull final UserPrivateUuid privateUuid, @NonNull final GroupUserRequest request) {
final OwnerRemoveResult result = _removeUser(privateUuid, request, (group, user) -> log.info("User banned from group: user={}, group={}", user, group));
result.group.getBanned().add(result.kicked);
groupMapper.push(result.group);
}
public void unban(@NonNull final UserPrivateUuid privateUuid, @NonNull final GroupUserRequest request) {
final GroupAccess access = groupAccessService.ownerAccess(privateUuid, request.groupUuid);
final User user = access.group.getBanned().stream().filter(u -> u.getPublicUuid().equals(request.userPublicUuid)).findFirst().orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST));
access.group.getBanned().remove(user);
log.info("User unbanned from group: user={}, group={}", user, access.group);
groupMapper.push(access.group);
}
@NonNull
public GroupDto changeTitle(@NonNull final UserPrivateUuid privateUuid, @NonNull final GroupChangeTitleRequest request) {
final GroupAccess ug = groupAccessService.access(privateUuid, request.groupUuid);
if (!ug.group.isOwnedBy(ug.principal)) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
ug.group.setTitle(request.title);
return groupMapper.push(ug.group);
}
@NonNull
public GroupDto changePassword(@NonNull final UserPrivateUuid privateUuid, @NonNull final GroupChangePasswordRequest request) {
final GroupAccess access = groupAccessService.ownerAccess(privateUuid, request.groupUuid);
access.group.setPassword(request.password);
return groupMapper.push(access.group);
}
/* EXECUTORS ------------------------------------------------------------------------------------ */
@NonNull
private Group _create_unchecked(@NonNull final User user) {
final Group group = groupRepository.save(new Group(user));
log.info("Group CREATED: {}", group);
return group;
}
@NonNull
private OwnerRemoveResult _removeUser(@NonNull final UserPrivateUuid privateUuid, @NonNull final GroupUserRequest request, @NonNull final BiConsumer<Group, User> beforePush) {
final GroupAccess access = groupAccessService.ownerAccess(privateUuid, request.groupUuid);
final User user = access.group.getUsers().stream().filter(u -> u.getPublicUuid().equals(request.userPublicUuid)).findFirst().orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST));
if (user.equals(access.principal)) {
// owner cannot kick itself from group
throw new ResponseStatusException(HttpStatus.BAD_REQUEST);
}
groupMemberService._remove_user_from_group_unchecked(access.group, user, beforePush);
return new OwnerRemoveResult(access, user);
}
/* RESULT CLASSES ------------------------------------------------------------------------------- */
@Getter
@ToString
private static class OwnerRemoveResult {
@NonNull
public final Group group;
@NonNull
public final User kicked;
public OwnerRemoveResult(@NonNull final GroupAccess access, @NonNull final User kicked) {
this.group = access.group;
this.kicked = kicked;
}
}
}