Tools/src/main/java/de/ph87/tools/group/GroupService.java

125 lines
4.4 KiB
Java

package de.ph87.tools.group;
import de.ph87.tools.user.User;
import de.ph87.tools.user.UserPublicMapper;
import de.ph87.tools.user.UserService;
import jakarta.annotation.Nullable;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
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;
@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class GroupService {
private final GroupRepository groupRepository;
private final UserService userService;
private final GroupMapper groupMapper;
private final UserPublicMapper userPublicMapper;
private final GroupOfUserService groupOfUserService;
@NonNull
public GroupDto create(@Nullable final String privateUuid, @NonNull final HttpServletResponse response) {
final User user = userService.getUserByPrivateUuidOrElseCreate(privateUuid, response);
final Group group = createUnchecked(user);
return doJoinUnchecked(group, user);
}
public boolean canAccess(@Nullable final String privateUuid, @NonNull final String groupUuid) {
if (privateUuid == null) {
return false;
}
return userService.findByPrivateUuid(privateUuid).flatMap(user -> groupOfUserService.findGroupOfUser(groupUuid, user)).isPresent();
}
@NonNull
public GroupDto get(@NonNull final String privateUuid, @NonNull final String groupUuid) {
final GroupOfUserService.GroupOfUser ug = groupOfUserService.accessGroupOfUser(groupUuid, privateUuid);
return groupMapper.toDto(ug.group);
}
@NonNull
public GroupDto join(@NonNull final String privateUuid, @NonNull final GroupJoinRequest request) {
final User user = userService.getByPrivateUuidOrThrow(privateUuid);
final Group group = getByGroupByGroupUuid(request.uuid);
if (!group.getPassword().equals(request.password)) {
log.error("Wrong password: user={}, group={}", user, group);
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
return doJoinUnchecked(group, user);
}
@NonNull
private Group getByGroupByGroupUuid(@NonNull final String groupUuid) {
return groupRepository.findByUuid(groupUuid).orElseThrow(() -> new ResponseStatusException(HttpStatus.BAD_REQUEST));
}
@NonNull
public GroupDto changeTitle(@NonNull final String privateUuid, @NonNull final GroupChangeTitleRequest request) {
final GroupOfUserService.GroupOfUser ug = groupOfUserService.accessGroupOfUser(request.uuid, privateUuid);
if (!ug.group.isOwnedBy(ug.user)) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
ug.group.setTitle(request.title);
return groupMapper.publish(ug.group);
}
@NonNull
public GroupDto changePassword(@NonNull final String privateUuid, @NonNull final GroupChangePasswordInbound request) {
final User user = userService.getByPrivateUuidOrThrow(privateUuid);
final Group group = groupOfUserService.getGroupOfUser(request.uuid, user);
if (!group.isOwnedBy(user)) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
}
group.setPassword(request.password);
return groupMapper.publish(group);
}
public void leave(@NonNull final String privateUuid, @NonNull final String groupUuid) {
final User user = userService.getByPrivateUuidOrThrow(privateUuid);
final Group group = getByGroupByGroupUuid(groupUuid);
doLeaveUnchecked(group, user);
}
/* CREATE, JOIN, LEAVE -------------------------------------------------------------------------- */
@NonNull
private Group createUnchecked(@NonNull final User user) {
final Group group = groupRepository.save(new Group(user));
log.info("Group CREATED: {}", group);
return group;
}
@NonNull
private GroupDto doJoinUnchecked(@NonNull final Group group, @NonNull final User user) {
group.getUsers().add(user);
group.touch();
user.touch();
log.info("User joined Group: user={}, group={}", user, group);
final GroupDto groupDto = groupMapper.publish(group);
userPublicMapper.publish(user);
return groupDto;
}
private void doLeaveUnchecked(final Group group, final User user) {
group.getUsers().remove(user);
group.touch();
user.touch();
log.info("User left Group: user={}, group={}", user, group);
groupMapper.publish(group);
userPublicMapper.publish(user);
}
}