diff --git a/src/main/java/UMC/campusNote/auth/controller/AuthController.java b/src/main/java/UMC/campusNote/auth/controller/AuthController.java index 19294d9..b19eff6 100644 --- a/src/main/java/UMC/campusNote/auth/controller/AuthController.java +++ b/src/main/java/UMC/campusNote/auth/controller/AuthController.java @@ -21,17 +21,17 @@ public class AuthController { private final AuthService authService; @PostMapping("/signUp") - public ApiResponse join(@RequestBody @Valid JoinReqDto joinReqDto){ + public ApiResponse join(@RequestBody @Valid AuthRequestDTO.JoinReqDTO joinReqDto){ return ApiResponse.of(USER_JOIN, authService.join(joinReqDto)); } @PostMapping("/login") - public ApiResponse login(@RequestBody @Valid LoginReqDto loginReqDto){ + public ApiResponse login(@RequestBody @Valid AuthRequestDTO.LoginReqDTO loginReqDto){ return ApiResponse.of(USER_LOGIN, authService.login(loginReqDto)); } @PostMapping("/refresh-token") - public ApiResponse refreshToken(HttpServletRequest request, HttpServletResponse response) { + public ApiResponse refreshToken(HttpServletRequest request, HttpServletResponse response) { return ApiResponse.of(ACCESS_TOKEN, authService.refreshToken(request, response)); } diff --git a/src/main/java/UMC/campusNote/auth/converter/AuthConverter.java b/src/main/java/UMC/campusNote/auth/converter/AuthConverter.java new file mode 100644 index 0000000..20ee189 --- /dev/null +++ b/src/main/java/UMC/campusNote/auth/converter/AuthConverter.java @@ -0,0 +1,45 @@ +package UMC.campusNote.auth.converter; + +import UMC.campusNote.auth.dto.AuthRequestDTO; +import UMC.campusNote.auth.dto.AuthResponseDTO; +import UMC.campusNote.user.entity.User; + +import static UMC.campusNote.user.entity.Role.USER; + +public class AuthConverter { + + public static AuthResponseDTO.JoinResDTO toJoinResDTO(Long userId, String accesstoken, String refreshtoken){ + return AuthResponseDTO.JoinResDTO.builder() + .userId(userId) + .accesstoken(accesstoken) + .refreshtoken(refreshtoken) + .build(); + } + + public static AuthResponseDTO.LoginResDTO toLoginResDTO(Long userId, String accessToken, String refreshToken){ + return AuthResponseDTO.LoginResDTO.builder() + .userId(userId) + .accessToken(accessToken) + .refreshToken(refreshToken) + .build(); + } + + public static AuthResponseDTO.RefreshResDTO toRefreshResDTO(String accessToken){ + return AuthResponseDTO.RefreshResDTO.builder() + .accessToken(accessToken) + .build(); + } + + public static User toUser(AuthRequestDTO.JoinReqDTO joinReqDto){ + return User.builder() + .clientId(joinReqDto.getClientId()) + .img(joinReqDto.getImg()) + .name(joinReqDto.getName()) + .role(USER) + .university(joinReqDto.getUniversity()) + .currentSemester(joinReqDto.getSemester()) + .build(); + } + + +} diff --git a/src/main/java/UMC/campusNote/auth/dto/AuthRequestDTO.java b/src/main/java/UMC/campusNote/auth/dto/AuthRequestDTO.java new file mode 100644 index 0000000..2272c0d --- /dev/null +++ b/src/main/java/UMC/campusNote/auth/dto/AuthRequestDTO.java @@ -0,0 +1,46 @@ +package UMC.campusNote.auth.dto; + +import UMC.campusNote.user.entity.User; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import static UMC.campusNote.user.entity.Role.USER; + +public class AuthRequestDTO { + @AllArgsConstructor + @NoArgsConstructor + @Getter + @Builder + public static class JoinReqDTO { + @NotBlank + @Size(max=100) + private String clientId; + @NotBlank + @Size(max=20) + private String name; + @NotBlank + @Size(max=20) + private String university; + @NotBlank + @Size(max=10) + private String semester; + @NotBlank + private String img; + + } + + @AllArgsConstructor + @NoArgsConstructor + @Builder + @Getter + public static class LoginReqDTO { + + @NotBlank + private String clientId; + } + +} diff --git a/src/main/java/UMC/campusNote/auth/dto/AuthResponseDTO.java b/src/main/java/UMC/campusNote/auth/dto/AuthResponseDTO.java new file mode 100644 index 0000000..5e7d2db --- /dev/null +++ b/src/main/java/UMC/campusNote/auth/dto/AuthResponseDTO.java @@ -0,0 +1,39 @@ +package UMC.campusNote.auth.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public class AuthResponseDTO { + @AllArgsConstructor + @Getter + @Builder + public static class JoinResDTO { + private Long userId; + private String accesstoken; + private String refreshtoken; + + } + + @AllArgsConstructor + @Builder + @Getter + @NoArgsConstructor + public static class LoginResDTO { + private Long userId; + private String accessToken; + private String refreshToken; + + } + + @Builder + @AllArgsConstructor + @NoArgsConstructor + @Getter + public static class RefreshResDTO { + + private String accessToken; + + } +} diff --git a/src/main/java/UMC/campusNote/auth/dto/JoinReqDto.java b/src/main/java/UMC/campusNote/auth/dto/JoinReqDto.java deleted file mode 100644 index 15e24eb..0000000 --- a/src/main/java/UMC/campusNote/auth/dto/JoinReqDto.java +++ /dev/null @@ -1,44 +0,0 @@ -package UMC.campusNote.auth.dto; - -import UMC.campusNote.user.entity.User; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import static UMC.campusNote.user.entity.Role.USER; - -@AllArgsConstructor -@NoArgsConstructor -@Getter -@Builder -public class JoinReqDto { - @NotBlank - @Size(max=100) - private String clientId; - @NotBlank - @Size(max=20) - private String name; - @NotBlank - @Size(max=20) - private String university; - @NotBlank - @Size(max=10) - private String semester; - @NotBlank - private String img; - - public User toEntity(){ - return User.builder() - .clientId(clientId) - .img(img) - .name(name) - .role(USER) - .university(university) - .currentSemester(semester) - .build(); - } - -} diff --git a/src/main/java/UMC/campusNote/auth/dto/JoinResDto.java b/src/main/java/UMC/campusNote/auth/dto/JoinResDto.java deleted file mode 100644 index 705f267..0000000 --- a/src/main/java/UMC/campusNote/auth/dto/JoinResDto.java +++ /dev/null @@ -1,21 +0,0 @@ -package UMC.campusNote.auth.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; - -@AllArgsConstructor -@Getter -@Builder -public class JoinResDto { - private Long userId; - private String accesstoken; - private String refreshtoken; - public static JoinResDto fromEntity(Long userId, String accesstoken, String refreshtoken){ - return JoinResDto.builder() - .userId(userId) - .accesstoken(accesstoken) - .refreshtoken(refreshtoken) - .build(); - } -} diff --git a/src/main/java/UMC/campusNote/auth/dto/LoginReqDto.java b/src/main/java/UMC/campusNote/auth/dto/LoginReqDto.java deleted file mode 100644 index 3ff1192..0000000 --- a/src/main/java/UMC/campusNote/auth/dto/LoginReqDto.java +++ /dev/null @@ -1,18 +0,0 @@ -package UMC.campusNote.auth.dto; - -import jakarta.validation.constraints.Max; -import jakarta.validation.constraints.NotBlank; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@AllArgsConstructor -@NoArgsConstructor -@Builder -@Getter -public class LoginReqDto { - - @NotBlank - private String clientId; -} diff --git a/src/main/java/UMC/campusNote/auth/dto/LoginResDto.java b/src/main/java/UMC/campusNote/auth/dto/LoginResDto.java deleted file mode 100644 index 2286d56..0000000 --- a/src/main/java/UMC/campusNote/auth/dto/LoginResDto.java +++ /dev/null @@ -1,24 +0,0 @@ -package UMC.campusNote.auth.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@AllArgsConstructor -@Builder -@Getter -@NoArgsConstructor -public class LoginResDto { - private Long userId; - private String accessToken; - private String refreshToken; - - public static LoginResDto fromEntity(Long userId, String accessToken, String refreshToken){ - return LoginResDto.builder() - .userId(userId) - .accessToken(accessToken) - .refreshToken(refreshToken) - .build(); - } -} diff --git a/src/main/java/UMC/campusNote/auth/dto/RefreshResDto.java b/src/main/java/UMC/campusNote/auth/dto/RefreshResDto.java deleted file mode 100644 index 1a611c6..0000000 --- a/src/main/java/UMC/campusNote/auth/dto/RefreshResDto.java +++ /dev/null @@ -1,22 +0,0 @@ -package UMC.campusNote.auth.dto; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; - - -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Getter -public class RefreshResDto { - - private String accessToken; - - public static RefreshResDto fromEntity(String accessToken){ - return RefreshResDto.builder() - .accessToken(accessToken) - .build(); - } -} diff --git a/src/main/java/UMC/campusNote/auth/service/AuthService.java b/src/main/java/UMC/campusNote/auth/service/AuthService.java index d36070e..cf9280e 100644 --- a/src/main/java/UMC/campusNote/auth/service/AuthService.java +++ b/src/main/java/UMC/campusNote/auth/service/AuthService.java @@ -6,10 +6,10 @@ public interface AuthService { + AuthResponseDTO.JoinResDTO join(AuthRequestDTO.JoinReqDTO joinReqDto); - JoinResDto join(JoinReqDto joinReqDto); + AuthResponseDTO.LoginResDTO login(AuthRequestDTO.LoginReqDTO loginReqDto); - LoginResDto login(LoginReqDto loginReqDto); + AuthResponseDTO.RefreshResDTO refreshToken(HttpServletRequest request, HttpServletResponse response); - RefreshResDto refreshToken(HttpServletRequest request, HttpServletResponse response); } diff --git a/src/main/java/UMC/campusNote/auth/service/AuthServiceImpl.java b/src/main/java/UMC/campusNote/auth/service/AuthServiceImpl.java index 108444b..3bf3fef 100644 --- a/src/main/java/UMC/campusNote/auth/service/AuthServiceImpl.java +++ b/src/main/java/UMC/campusNote/auth/service/AuthServiceImpl.java @@ -1,5 +1,6 @@ package UMC.campusNote.auth.service; +import UMC.campusNote.auth.converter.AuthConverter; import UMC.campusNote.auth.dto.*; import UMC.campusNote.auth.jwt.JwtProvider; import UMC.campusNote.auth.redis.RedisProvider; @@ -30,22 +31,24 @@ public class AuthServiceImpl implements AuthService { @Override @Transactional - public JoinResDto join(JoinReqDto joinReqDto) { + public AuthResponseDTO.JoinResDTO join(AuthRequestDTO.JoinReqDTO joinReqDto) { userRepository.findByClientId(joinReqDto.getClientId()) .ifPresent( user -> { throw new GeneralException(USER_ALREADY_EXIST); }); - User user = joinReqDto.toEntity(); + User user = AuthConverter.toUser(joinReqDto); User savedUser = userRepository.save(user); String accessToken = jwtProvider.generateToken(user); String refreshToken = jwtProvider.generateRefreshToken(user); saveUserToken(savedUser, refreshToken); - return JoinResDto.fromEntity(savedUser.getId(), accessToken, refreshToken); + + return AuthConverter.toJoinResDTO(savedUser.getId(), accessToken, refreshToken); + } @Override @Transactional - public LoginResDto login(LoginReqDto loginReqDto) { + public AuthResponseDTO.LoginResDTO login(AuthRequestDTO.LoginReqDTO loginReqDto) { //log.info("loginReqDto.getClientId() : {}", loginReqDto.getClientId()); User user = userRepository.findByClientId(loginReqDto.getClientId()) .orElseThrow(() -> new GeneralException(USER_NOT_FOUND)); @@ -53,11 +56,13 @@ public LoginResDto login(LoginReqDto loginReqDto) { String refreshToken = jwtProvider.generateRefreshToken(user); revokeAllUserTokens(user); saveUserToken(user, refreshToken); - return LoginResDto.fromEntity(user.getId(), accessToken, refreshToken); + + return AuthConverter.toLoginResDTO(user.getId(), accessToken, refreshToken); + } @Override - public RefreshResDto refreshToken(HttpServletRequest request, HttpServletResponse response) { + public AuthResponseDTO.RefreshResDTO refreshToken(HttpServletRequest request, HttpServletResponse response) { final String authHeader = request.getHeader(HEADER_AUTHORIZATION); final String refreshToken; final String userEmail; @@ -70,7 +75,9 @@ public RefreshResDto refreshToken(HttpServletRequest request, HttpServletRespons .orElseThrow(() -> new GeneralException(USER_NOT_FOUND)); if (jwtProvider.isTokenValid(refreshToken, user)) { String accessToken = jwtProvider.generateToken(user); - return RefreshResDto.fromEntity(accessToken); + + return AuthConverter.toRefreshResDTO(accessToken); + } } return null; diff --git a/src/main/java/UMC/campusNote/common/code/status/ErrorStatus.java b/src/main/java/UMC/campusNote/common/code/status/ErrorStatus.java index e988843..bd57cab 100644 --- a/src/main/java/UMC/campusNote/common/code/status/ErrorStatus.java +++ b/src/main/java/UMC/campusNote/common/code/status/ErrorStatus.java @@ -35,6 +35,9 @@ public enum ErrorStatus implements BaseErrorCode { USER_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "MEMBER4004", "이미 존재하는 사용자입니다."), FRIEND_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "MEMBER4005", "이미 존재하는 친구입니다."), + + FRIEND_NOT_MYSELF(HttpStatus.BAD_REQUEST, "MEMBER4006", "자기 자신과는 친구가 될 수 없습니다."), + // 토큰 관련 에러 TOKEN_NOT_FOUND(HttpStatus.BAD_REQUEST, "TOKEN4001", "토큰이 존재하지 않습니다."), TOKEN_EXPIRED(HttpStatus.BAD_REQUEST, "TOKEN4002", "토큰이 만료되었습니다."), @@ -54,7 +57,6 @@ public enum ErrorStatus implements BaseErrorCode { // 강의 노트 관련 에러 LESSONNOTE_NOT_FOUND(HttpStatus.BAD_REQUEST, "LESSONNOTE4001", "존재하지 않는 강의 노트."); - private final HttpStatus httpStatus; private final String code; private final String message; diff --git a/src/main/java/UMC/campusNote/friend/controller/FriendController.java b/src/main/java/UMC/campusNote/friend/controller/FriendController.java index d87fe7c..3c95172 100644 --- a/src/main/java/UMC/campusNote/friend/controller/FriendController.java +++ b/src/main/java/UMC/campusNote/friend/controller/FriendController.java @@ -1,7 +1,8 @@ package UMC.campusNote.friend.controller; import UMC.campusNote.common.ApiResponse; -import UMC.campusNote.friend.dto.AddFriendReqDto; + +import UMC.campusNote.friend.dto.FriendRequestDTO; import UMC.campusNote.friend.service.FriendService; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -17,7 +18,7 @@ public class FriendController { private final FriendService friendService; @PostMapping - private ApiResponse addFriend(@Valid @RequestBody AddFriendReqDto addFriendReqDto){ + private ApiResponse addFriend(@Valid @RequestBody FriendRequestDTO.AddFriendReqDTO addFriendReqDto){ friendService.addFriend(addFriendReqDto); diff --git a/src/main/java/UMC/campusNote/friend/converter/FriendConverter.java b/src/main/java/UMC/campusNote/friend/converter/FriendConverter.java new file mode 100644 index 0000000..9d4ae3a --- /dev/null +++ b/src/main/java/UMC/campusNote/friend/converter/FriendConverter.java @@ -0,0 +1,13 @@ +package UMC.campusNote.friend.converter; + +import UMC.campusNote.friend.entity.Friend; +import UMC.campusNote.user.entity.User; + +public class FriendConverter { + public static Friend fromEntity(User user1, User user2){ + return Friend.builder() + .user1(user1) + .user2(user2) + .build(); + } +} diff --git a/src/main/java/UMC/campusNote/friend/dto/FriendRequestDTO.java b/src/main/java/UMC/campusNote/friend/dto/FriendRequestDTO.java new file mode 100644 index 0000000..8b6fed7 --- /dev/null +++ b/src/main/java/UMC/campusNote/friend/dto/FriendRequestDTO.java @@ -0,0 +1,18 @@ +package UMC.campusNote.friend.dto; + +import jakarta.validation.constraints.NotNull; +import lombok.*; + +public class FriendRequestDTO { + @AllArgsConstructor + @NoArgsConstructor + @Getter + @Setter + @Builder + public static class AddFriendReqDTO { + @NotNull + private Long inviterUserId; + @NotNull + private Long invitedUserId; + } +} diff --git a/src/main/java/UMC/campusNote/friend/repository/FriendRepository.java b/src/main/java/UMC/campusNote/friend/repository/FriendRepository.java index f0c7a78..6624b6e 100644 --- a/src/main/java/UMC/campusNote/friend/repository/FriendRepository.java +++ b/src/main/java/UMC/campusNote/friend/repository/FriendRepository.java @@ -2,6 +2,7 @@ import UMC.campusNote.friend.entity.Friend; import UMC.campusNote.user.entity.User; +import io.lettuce.core.dynamic.annotation.Param; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @@ -10,6 +11,8 @@ @Repository public interface FriendRepository extends JpaRepository { + @Query("SELECT f FROM Friend f WHERE (f.user1=:user1 AND f.user2=:user2) OR (f.user1=:user2 AND f.user2=:user1)") - Optional findByUser1AndUser2(User user1, User user2); + Optional findByUser1AndUser2(@Param("user1") User user1, @Param("user2") User user2); + } diff --git a/src/main/java/UMC/campusNote/friend/service/FriendService.java b/src/main/java/UMC/campusNote/friend/service/FriendService.java index 94def55..f878872 100644 --- a/src/main/java/UMC/campusNote/friend/service/FriendService.java +++ b/src/main/java/UMC/campusNote/friend/service/FriendService.java @@ -1,7 +1,9 @@ package UMC.campusNote.friend.service; import UMC.campusNote.common.exception.GeneralException; -import UMC.campusNote.friend.dto.AddFriendReqDto; +import UMC.campusNote.friend.converter.FriendConverter; +import UMC.campusNote.friend.dto.FriendRequestDTO; + import UMC.campusNote.friend.entity.Friend; import UMC.campusNote.friend.repository.FriendRepository; import UMC.campusNote.user.entity.User; @@ -9,9 +11,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import static UMC.campusNote.common.code.status.ErrorStatus.*; -import static UMC.campusNote.common.code.status.ErrorStatus.FRIEND_ALREADY_EXIST; -import static UMC.campusNote.common.code.status.ErrorStatus.USER_NOT_FOUND; @Service @RequiredArgsConstructor @@ -19,10 +20,16 @@ public class FriendService { private final FriendRepository friendRepository; private final UserRepository userRepository; - public void addFriend(AddFriendReqDto addFriendReqDto){ - User inviter = userRepository.findById(addFriendReqDto.getInviterUserId()) + public void addFriend(FriendRequestDTO.AddFriendReqDTO addFriendReqDto) { + + Long inviterId = addFriendReqDto.getInviterUserId(); + Long invitedId = addFriendReqDto.getInvitedUserId(); + + if (invitedId.equals(inviterId)) throw new GeneralException(FRIEND_NOT_MYSELF); + + User inviter = userRepository.findById(inviterId) .orElseThrow(() -> new GeneralException(USER_NOT_FOUND)); - User invited = userRepository.findById(addFriendReqDto.getInvitedUserId()) + User invited = userRepository.findById(invitedId) .orElseThrow(() -> new GeneralException(USER_NOT_FOUND)); friendRepository.findByUser1AndUser2(inviter, invited) @@ -30,7 +37,8 @@ public void addFriend(AddFriendReqDto addFriendReqDto){ throw new GeneralException(FRIEND_ALREADY_EXIST); }); - Friend friend = Friend.fromEntity(invited, inviter); + Friend friend = FriendConverter.fromEntity(invited, inviter); + friendRepository.save(friend); } } diff --git a/src/test/java/UMC/campusNote/friend/service/FriendServiceTest.java b/src/test/java/UMC/campusNote/friend/service/FriendServiceTest.java index 16fd6a2..61bf101 100644 --- a/src/test/java/UMC/campusNote/friend/service/FriendServiceTest.java +++ b/src/test/java/UMC/campusNote/friend/service/FriendServiceTest.java @@ -1,29 +1,23 @@ package UMC.campusNote.friend.service; import UMC.campusNote.common.exception.GeneralException; -import UMC.campusNote.friend.dto.AddFriendReqDto; +import UMC.campusNote.friend.dto.FriendRequestDTO; import UMC.campusNote.friend.entity.Friend; import UMC.campusNote.friend.repository.FriendRepository; -import UMC.campusNote.user.entity.Role; import UMC.campusNote.user.entity.User; import UMC.campusNote.user.repository.UserRepository; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; + import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Mockito; + import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit.jupiter.SpringExtension; import java.util.Optional; -import static UMC.campusNote.common.code.status.ErrorStatus.USER_NOT_FOUND; import static org.mockito.Mockito.*; @@ -45,7 +39,8 @@ public class FriendServiceTest { @DisplayName("[addFriend service 성공] Add friend test") public void addFriendTest(){ // 테스트용 데이터 생성 - AddFriendReqDto addFriendReqDto = new AddFriendReqDto(); + FriendRequestDTO.AddFriendReqDTO addFriendReqDto = new FriendRequestDTO.AddFriendReqDTO(); + addFriendReqDto.setInviterUserId(1L); addFriendReqDto.setInvitedUserId(2L); @@ -75,7 +70,8 @@ public void addFriendTest(){ public void addFriendTest_FRIEND_ALREADY_EXIST(){ // 테스트용 데이터 생성 - AddFriendReqDto addFriendReqDto = new AddFriendReqDto(); + FriendRequestDTO.AddFriendReqDTO addFriendReqDto = new FriendRequestDTO.AddFriendReqDTO(); + addFriendReqDto.setInviterUserId(1L); addFriendReqDto.setInvitedUserId(2L);