Skip to content

Commit

Permalink
Merge pull request #151 from kookmin-sw/backend/develop/v3
Browse files Browse the repository at this point in the history
✨ 회원탈퇴 구현
  • Loading branch information
J-Yong99 authored May 14, 2024
2 parents 360e829 + ca08713 commit 469abb7
Show file tree
Hide file tree
Showing 17 changed files with 348 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@
import com.moment.auth.dto.request.UserRequestDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.*;

@FeignClient(name = "core-service")
public interface CoreClient {

@PostMapping("/core/user/register")
ResponseEntity<APIResponse> registerUser(UserRequestDTO.registerUser request);

@DeleteMapping("/core/user/{userId}")
ResponseEntity<APIResponse> deleteUser(@PathVariable Long userId);

@GetMapping("/core/user/test")
ResponseEntity<String> test();
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
package com.moment.auth.controller;

import com.moment.auth.client.CoreClient;
import com.moment.auth.common.APIResponse;
import com.moment.auth.common.code.SuccessCode;
import com.moment.auth.dto.request.AuthRequest;
import com.moment.auth.dto.response.TokenResponseDTO;
import com.moment.auth.service.AuthService;
import com.moment.auth.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.ErrorResponse;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/auth")
@Slf4j
public class AuthController {
private final AuthService authService;
private final UserService userService;
private final CoreClient coreClient;
// 로그인
@PostMapping("/login")
public ResponseEntity<APIResponse<TokenResponseDTO.GetToken>> login(
Expand Down Expand Up @@ -66,4 +73,21 @@ public ResponseEntity<APIResponse> changePassword(
authService.changePassword(changePassword, userId);
return ResponseEntity.ok(APIResponse.of(SuccessCode.UPDATE_SUCCESS));
}

// 회원 탈퇴
@DeleteMapping("/delete")
public ResponseEntity<APIResponse> deleteAccount(
@RequestHeader Long userId
) {
userService.deleteAccount(userId);
return ResponseEntity.ok(APIResponse.of(SuccessCode.DELETE_SUCCESS));
}

// 테스트
@GetMapping("/test")
public ResponseEntity<String> test() {
log.info("test");
coreClient.test();
return new ResponseEntity<>("test", HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.moment.auth.service;

import com.moment.auth.client.CoreClient;
import com.moment.auth.domain.Role;
import com.moment.auth.domain.user.User;
import com.moment.auth.domain.user.UserRepository;
Expand Down Expand Up @@ -120,4 +121,5 @@ public void changePassword(AuthRequest.ChangePassword changePassword, Long userI
user.setPassword(passwordEncoder.encode(changePassword.getNewPassword()));
userService.save(user);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.moment.auth.domain.user.User;
import com.moment.auth.domain.user.UserRepository;
import com.moment.auth.dto.request.UserRequestDTO;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Service;

@Service
Expand Down Expand Up @@ -36,4 +38,18 @@ public void registerUserToCoreServer(User user) {
}

}
@Transactional
public void deleteAccount(Long userId) {
try{
log.info("Core 서버에 유저 삭제를 시도합니다.");
HttpStatusCode statusCode = coreClient.deleteUser(userId).getStatusCode();
if(!statusCode.is2xxSuccessful()){
throw new RuntimeException("Core 서버에 유저 삭제에 실패했습니다.");
}
userRepository.deleteById(userId);

}catch (Exception e){
throw new RuntimeException("Core 서버에 유저 삭제에 실패했습니다.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.moment.auth.dto.request.AuthRequest;
import com.moment.auth.dto.response.TokenResponseDTO;
import com.moment.auth.service.AuthService;
import com.moment.auth.service.UserService;
import io.swagger.v3.core.util.Json;
import jakarta.ws.rs.core.MediaType;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -40,6 +41,9 @@ class AuthControllerTest {
@MockBean
private AuthService authService;

@MockBean
private UserService userService;

@InjectMocks
private AuthController authController;

Expand Down Expand Up @@ -202,4 +206,29 @@ void changePassword() throws Exception {
))
.andDo(print());
}

@Test
void deleteAccount() throws Exception {

Mockito.doNothing().when(userService).deleteAccount(any());

mockMvc.perform(RestDocumentationRequestBuilders.delete("/auth/delete")
.header("userId", 1L))
.andExpect(status().isOk())
.andDo(document("auth/deleteAccount",
Preprocessors.preprocessRequest(Preprocessors.prettyPrint()),
Preprocessors.preprocessResponse(Preprocessors.prettyPrint()),
requestHeaders(
headerWithName("userId").description("Bearer Token")
),
responseFields(
fieldWithPath("status").type(JsonFieldType.NUMBER).description("응답 상태 코드"),
fieldWithPath("code").type(JsonFieldType.STRING).description("응답 코드"),
fieldWithPath("msg").type(JsonFieldType.STRING).description("응답 메시지"),
fieldWithPath("detailMsg").type(JsonFieldType.STRING).description("상세 메시지"),
fieldWithPath("data").type(JsonFieldType.OBJECT).description("데이터 없음")
)
))
.andDo(print());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,20 @@ public ResponseEntity<APIResponse> updateUserSetting(
userService.updateUserSetting(request, userId);
return ResponseEntity.ok(APIResponse.of(SuccessCode.UPDATE_SUCCESS));
}

// 유저 탈퇴
@DeleteMapping("/{userId}")
public ResponseEntity<APIResponse> deleteUser(
@PathVariable Long userId
) {
log.info("delete userId : {}", userId);
userService.deleteUser(userId);
return ResponseEntity.ok(APIResponse.of(SuccessCode.DELETE_SUCCESS));
}
// 테스트
@GetMapping("/test")
public ResponseEntity<String> test() {
log.info("test");
return new ResponseEntity<>("test", HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ public interface AlreadyBookedDateRepository extends JpaRepository<AlreadyBooked
void deleteByUserAndYearDateBetween(User user, LocalDate startDate, LocalDate endDate);

List<AlreadyBookedDate> findAllByUserOrderByYearDate(User user);

void deleteAllByUser(User user);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.moment.core.domain.cardView;

import com.moment.core.domain.tripFile.TripFile;
import com.moment.core.domain.user.User;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;

Expand All @@ -23,4 +24,6 @@ public interface CardViewRepository extends JpaRepository<CardView, Long> {
@Override
@EntityGraph(attributePaths = {"tripFile"})
Optional<CardView> findById(Long id);

void deleteAllByTripFile_User(User user);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.moment.core.domain.imageFile;

import com.moment.core.domain.cardView.CardView;
import com.moment.core.domain.user.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;
Expand All @@ -9,4 +10,8 @@ public interface ImageFileRepository extends JpaRepository<ImageFile, Long> {
List<ImageFile> findAllByCardView_Id(Long cardViewId);

List<ImageFile> findAllByCardView(CardView cardView);



void deleteAllByCardView_TripFile_User(User user);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.moment.core.domain.receipt;

import com.moment.core.domain.trip.Trip;
import com.moment.core.domain.user.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -26,4 +27,6 @@ public interface ReceiptRepository extends PagingAndSortingRepository<Receipt, L
Number countByUser_Id(Long userId);

List<Receipt> findAllByTrip(Trip trip);

void deleteAllByUser(User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.moment.core.domain.user.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;
import java.util.Optional;
Expand All @@ -14,5 +13,5 @@ public interface TripRepository extends JpaRepository<Trip, Long> {
List<Trip> findAllByUserAndIsNotTitledOrderByStartDate(User user, boolean b);



void deleteAllByUser(User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ public interface TripFileRepository extends JpaRepository<TripFile, Long> {
List<TripFile> findByTrip(Trip trip);

List<TripFile> findAllByTrip(Trip trip);

void deleteAllByUser(User user);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.moment.core.service;

import com.moment.core.domain.alreadyBookedDate.AlreadyBookedDateRepository;
import com.moment.core.domain.cardView.CardView;
import com.moment.core.domain.cardView.CardViewRepository;
import com.moment.core.domain.imageFile.ImageFileRepository;
import com.moment.core.domain.receipt.ReceiptRepository;
import com.moment.core.domain.trip.Trip;
import com.moment.core.domain.trip.TripRepository;
import com.moment.core.domain.tripFile.TripFile;
Expand Down Expand Up @@ -29,6 +32,11 @@ public class UserService {
private final EntityManager em;
private final TripFileRepository tripFileRepository;
private final CardViewRepository cardViewRepository;
private final S3Service s3Service;
private final ReceiptRepository receiptRepository;
private final ImageFileRepository imageFileRepository;
private final AlreadyBookedDateRepository alreadyBookedDateRepository;


@Transactional
public User save(UserRequestDTO.registerUser request) {
Expand Down Expand Up @@ -82,4 +90,25 @@ public void updateUserSetting(UserRequestDTO.updateUser request, Long userId) {
user.setFirebaseToken(request.getFirebaseToken());
userRepository.save(user);
}

@Transactional
public void deleteUser(Long userId) {
User user = userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("존재하지 않는 유저입니다."));
// S3 먼저 전부 삭제
// s3Service.deleteFile("", String.valueOf(userId));
// 유저의 영수증 전부 삭제
receiptRepository.deleteAllByUser(user);
// 유저의 imageFile 전부 삭제
imageFileRepository.deleteAllByCardView_TripFile_User(user);
// 카드뷰 전부 삭제
cardViewRepository.deleteAllByTripFile_User(user);
// 여행파일 전부 삭제
tripFileRepository.deleteAllByUser(user);
// 여행 삭제
tripRepository.deleteAllByUser(user);
// alreadyBookedDate 삭제
alreadyBookedDateRepository.deleteAllByUser(user);
// 유저 삭제
userRepository.delete(user);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ public GatewayFilter apply(Config config){
ServerHttpResponse response = exchange.getResponse();
// log.info("global filter baseMessage: {}",config.getBaseMessage());
if (config.isPreLogger()){
log.info("Global Filter Start: request id->{}",request.getId());
log.info("Global Filter Start: request id->{}",request.getLocalAddress());
log.info("Global Filter Start: request path->{}",request.getURI());
log.info("Global Filter Start: request Body->{}",request.getBody());

}
return chain.filter(exchange).then(Mono.fromRunnable(() ->{
if(config.isPreLogger()){
Expand Down
Loading

0 comments on commit 469abb7

Please sign in to comment.