diff --git a/src/main/java/com/tiki/server/external/service/S3Service.java b/src/main/java/com/tiki/server/external/service/S3Service.java index c07eb796..4cded7b7 100644 --- a/src/main/java/com/tiki/server/external/service/S3Service.java +++ b/src/main/java/com/tiki/server/external/service/S3Service.java @@ -12,11 +12,11 @@ public class S3Service { private final S3Handler s3Handler; - public PreSignedUrlResponse getUploadPreSignedUrl(String fileFormat) { + public PreSignedUrlResponse getUploadPreSignedUrl(final String fileFormat) { return s3Handler.getUploadPreSignedUrl(fileFormat); } - public void deleteFile(S3DeleteRequest request) { + public void deleteFile(final S3DeleteRequest request) { s3Handler.deleteFile(request.fileName()); } } diff --git a/src/main/java/com/tiki/server/external/util/S3Handler.java b/src/main/java/com/tiki/server/external/util/S3Handler.java index 69cd42ce..588d21e3 100644 --- a/src/main/java/com/tiki/server/external/util/S3Handler.java +++ b/src/main/java/com/tiki/server/external/util/S3Handler.java @@ -32,7 +32,7 @@ public class S3Handler { @Value("${aws-property.bucket}") private String bucket; - public PreSignedUrlResponse getUploadPreSignedUrl(String fileFormat) { + public PreSignedUrlResponse getUploadPreSignedUrl(final String fileFormat) { try { String fileName = generateFileName(fileFormat); String key = FILE_SAVE_PREFIX + fileName; @@ -46,7 +46,7 @@ public PreSignedUrlResponse getUploadPreSignedUrl(String fileFormat) { } } - public void deleteFile(String request) { + public void deleteFile(final String request) { try { S3Client s3Client = awsConfig.getS3Client(); s3Client.deleteObject((DeleteObjectRequest.Builder builder) -> diff --git a/src/main/java/com/tiki/server/folder/dto/request/FolderNameUpdateRequest.java b/src/main/java/com/tiki/server/folder/dto/request/FolderNameUpdateRequest.java index d6556d67..3fe63e98 100644 --- a/src/main/java/com/tiki/server/folder/dto/request/FolderNameUpdateRequest.java +++ b/src/main/java/com/tiki/server/folder/dto/request/FolderNameUpdateRequest.java @@ -5,4 +5,4 @@ public record FolderNameUpdateRequest( @NonNull String name ) { -} +} \ No newline at end of file diff --git a/src/main/java/com/tiki/server/memberteammanager/controller/MemberTeamManagerController.java b/src/main/java/com/tiki/server/memberteammanager/controller/MemberTeamManagerController.java new file mode 100644 index 00000000..9f99291d --- /dev/null +++ b/src/main/java/com/tiki/server/memberteammanager/controller/MemberTeamManagerController.java @@ -0,0 +1,42 @@ +package com.tiki.server.memberteammanager.controller; + +import com.tiki.server.common.dto.BaseResponse; +import com.tiki.server.memberteammanager.service.MemberTeamManagerService; +import lombok.AllArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.security.Principal; + + +@RestController +@AllArgsConstructor +@RequestMapping("api/v1/teams") +public class MemberTeamManagerController { + + private final MemberTeamManagerService memberTeamManagerService; + + @DeleteMapping("/{teamId}/members/{kickOutMemberId}") + public ResponseEntity kickOutMemberFromTeam( + final Principal principal, + @PathVariable final long teamId, + @PathVariable final long kickOutMemberId + ) { + long memberId = Long.parseLong(principal.getName()); + memberTeamManagerService.kickOutMemberFromTeam(memberId, teamId, kickOutMemberId); + return ResponseEntity.noContent().build(); + } + + @DeleteMapping("/{teamId}/leave") + public ResponseEntity leaveTeam( + final Principal principal, + @PathVariable final long teamId + ) { + long memberId = Long.parseLong(principal.getName()); + memberTeamManagerService.leaveTeam(memberId, teamId); + return ResponseEntity.noContent().build(); + } +} diff --git a/src/main/java/com/tiki/server/memberteammanager/service/MemberTeamManagerService.java b/src/main/java/com/tiki/server/memberteammanager/service/MemberTeamManagerService.java index 5ea3a791..b72e28b2 100644 --- a/src/main/java/com/tiki/server/memberteammanager/service/MemberTeamManagerService.java +++ b/src/main/java/com/tiki/server/memberteammanager/service/MemberTeamManagerService.java @@ -1,19 +1,48 @@ package com.tiki.server.memberteammanager.service; +import com.tiki.server.memberteammanager.adapter.MemberTeamManagerDeleter; import com.tiki.server.memberteammanager.adapter.MemberTeamManagerFinder; +import com.tiki.server.memberteammanager.adapter.MemberTeamManagerSaver; import com.tiki.server.memberteammanager.entity.MemberTeamManager; +import com.tiki.server.note.adapter.NoteFinder; +import com.tiki.server.note.entity.Note; +import com.tiki.server.team.exception.TeamException; import com.tiki.server.memberteammanager.service.dto.response.MemberTeamPositionGetResponse; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; +import java.util.List; + +import static com.tiki.server.common.entity.Position.ADMIN; +import static com.tiki.server.team.message.ErrorCode.INVALID_AUTHORIZATION_DELETE; +import static com.tiki.server.team.message.ErrorCode.TOO_HIGH_AUTHORIZATION; + @Service @RequiredArgsConstructor @Transactional(readOnly = true) public class MemberTeamManagerService { + private final NoteFinder noteFinder; private final MemberTeamManagerFinder memberTeamManagerFinder; + private final MemberTeamManagerDeleter memberTeamManagerDeleter; + private final MemberTeamManagerSaver memberTeamManagerSaver; + + @Transactional + public void kickOutMemberFromTeam(final long memberId, final long teamId, final long kickOutMemberId) { + checkIsAdmin(memberId, teamId); + MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(kickOutMemberId, teamId); + deleteNoteDependency(kickOutMemberId, teamId); + memberTeamManagerDeleter.delete(memberTeamManager); + } + + @Transactional + public void leaveTeam(final long memberId, final long teamId) { + MemberTeamManager memberTeamManager = checkIsNotAdmin(memberId, teamId); + deleteNoteDependency(memberId, teamId); + memberTeamManagerDeleter.delete(memberTeamManager); + } public MemberTeamPositionGetResponse getPosition(final long memberId, final long teamId) { MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); @@ -25,4 +54,24 @@ public void updateTeamMemberName(final long memberId, final long teamId, final S MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); memberTeamManager.updateName(name); } + + private void checkIsAdmin(final long memberId, final long teamId) { + MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); + if (!memberTeamManager.getPosition().equals(ADMIN)) { + throw new TeamException(INVALID_AUTHORIZATION_DELETE); + } + } + + private MemberTeamManager checkIsNotAdmin(final long memberId, final long teamId) { + MemberTeamManager memberTeamManager = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); + if (memberTeamManager.getPosition().equals(ADMIN)) { + throw new TeamException(TOO_HIGH_AUTHORIZATION); + } + return memberTeamManager; + } + + private void deleteNoteDependency(final long memberId, final long teamId) { + List notes = noteFinder.findAllByMemberIdAndTeamId(memberId, teamId); + notes.forEach(Note::deleteMemberDependency); + } } diff --git a/src/main/java/com/tiki/server/note/adapter/NoteFinder.java b/src/main/java/com/tiki/server/note/adapter/NoteFinder.java index 0cf4c97e..fdcf4748 100644 --- a/src/main/java/com/tiki/server/note/adapter/NoteFinder.java +++ b/src/main/java/com/tiki/server/note/adapter/NoteFinder.java @@ -34,6 +34,10 @@ public List findByCreatedAtAfterOrderByModifiedAtAsc( return noteRepository.findByTeamIdAndCreatedAtAfterOrderByCreatedAtAsc(createdAt, pageRequest, teamId); } + public List findAllByMemberIdAndTeamId(final long memberId, final long teamId) { + return noteRepository.findAllByMemberIdAndTeamId(memberId, teamId); + } + public Note findById(final long noteId) { return noteRepository.findById(noteId) .orElseThrow(() -> new NoteException(INVALID_NOTE)); diff --git a/src/main/java/com/tiki/server/note/entity/Note.java b/src/main/java/com/tiki/server/note/entity/Note.java index 1ef479e9..63c75f60 100644 --- a/src/main/java/com/tiki/server/note/entity/Note.java +++ b/src/main/java/com/tiki/server/note/entity/Note.java @@ -87,6 +87,10 @@ public void updateValue( this.noteType = noteType; } + public void deleteMemberDependency() { + this.memberId = null; + } + private void checkAuthor(final long clientId) { if (this.memberId != clientId) { throw new NoteException(UPDATE_ONLY_AUTHOR); diff --git a/src/main/java/com/tiki/server/note/repository/NoteRepository.java b/src/main/java/com/tiki/server/note/repository/NoteRepository.java index 67c1fbdf..043fa4be 100644 --- a/src/main/java/com/tiki/server/note/repository/NoteRepository.java +++ b/src/main/java/com/tiki/server/note/repository/NoteRepository.java @@ -16,4 +16,6 @@ public interface NoteRepository extends JpaRepository { @Query("SELECT n FROM Note n WHERE n.teamId = :teamId AND n.createdAt > :createdAt ORDER BY n.createdAt ASC") List findByTeamIdAndCreatedAtAfterOrderByCreatedAtAsc(@Param("createdAt") LocalDateTime createdAt, Pageable pageable, long teamId); + + List findAllByMemberIdAndTeamId(long memberId, long TeamId); } diff --git a/src/main/java/com/tiki/server/team/message/ErrorCode.java b/src/main/java/com/tiki/server/team/message/ErrorCode.java index 2f90e6b3..3f871892 100644 --- a/src/main/java/com/tiki/server/team/message/ErrorCode.java +++ b/src/main/java/com/tiki/server/team/message/ErrorCode.java @@ -1,19 +1,21 @@ package com.tiki.server.team.message; -import static org.springframework.http.HttpStatus.FORBIDDEN; -import static org.springframework.http.HttpStatus.NOT_FOUND; - import org.springframework.http.HttpStatus; import lombok.AllArgsConstructor; import lombok.Getter; +import static org.springframework.http.HttpStatus.*; + @Getter @AllArgsConstructor public enum ErrorCode { + /* 400 BAD_REQUEST : 잘못된 요청 */ + TOO_HIGH_AUTHORIZATION(BAD_REQUEST, "어드민은 진행할 수 없습니다."), + /* 403 FORBIDDEN : 권한 없음 */ - INVALID_AUTHORIZATION_DELETE(FORBIDDEN, "팀 삭제에 대한 권한이 없습니다."), + INVALID_AUTHORIZATION_DELETE(FORBIDDEN, "권한이 없습니다."), /* 404 NOT_FOUND : 자원을 찾을 수 없음 */ INVALID_TEAM(NOT_FOUND, "유효하지 않은 단체입니다."); diff --git a/src/main/java/com/tiki/server/team/service/TeamService.java b/src/main/java/com/tiki/server/team/service/TeamService.java index 2f9724c7..d06c25e9 100644 --- a/src/main/java/com/tiki/server/team/service/TeamService.java +++ b/src/main/java/com/tiki/server/team/service/TeamService.java @@ -1,7 +1,6 @@ package com.tiki.server.team.service; import static com.tiki.server.common.entity.Position.ADMIN; -import static com.tiki.server.team.message.ErrorCode.INVALID_AUTHORIZATION_DELETE; import java.util.List; @@ -84,6 +83,10 @@ public void deleteTeam(final long memberId, final long teamId) { teamDeleter.deleteById(teamId); } + private Team createTeam(final TeamCreateRequest request, final University univ) { + return Team.of(request, univ); + } + @Transactional public void updateTeamName(final long memberId, final long teamId, final String newTeamName) { checkIsAdmin(memberId, teamId); @@ -107,8 +110,8 @@ public void alterAdmin(final long memberId, final long teamId, final long target newAdmin.updatePositionToAdmin(); } - private Team createTeam(final TeamCreateRequest request, final University univ) { - return Team.of(request, univ); + private MemberTeamManager createMemberTeamManager(final Member member, final Team team, final Position position) { + return MemberTeamManager.of(member, team, position); } private void deleteIconUrl(final Team team) { @@ -117,10 +120,6 @@ private void deleteIconUrl(final Team team) { } } - private MemberTeamManager createMemberTeamManager(final Member member, final Team team, final Position position) { - return MemberTeamManager.of(member, team, position); - } - private MemberTeamManager checkIsAdmin(final long memberId, final long teamId) { MemberTeamManager accessMember = memberTeamManagerFinder.findByMemberIdAndTeamId(memberId, teamId); accessMember.checkMemberAccessible(ADMIN);