Skip to content

Commit

Permalink
Merge pull request #102 from Central-MakeUs/80-회원-탈퇴를-할-수-있다
Browse files Browse the repository at this point in the history
Feat(#80): 회원 탈퇴 추가
  • Loading branch information
tmddus2 committed Aug 28, 2024
2 parents 858434e + c686219 commit 9b53d18
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,10 @@ public SuccessResponse<List<LikedFilterDto>> getMyPick(Long id) {
public SuccessResponse<DatedFilterDto> getFilterViewHistory(Long id) {
return SuccessResponse.of(filterService.getFilterViewHistory(id));
}

@DeleteMapping
public SuccessResponse deleteUser(Long id) {
userService.deleteUser(id);
return SuccessResponse.of();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ public SuccessResponse deleteReview(
@Operation(summary = "필터 열람 내역을 조회합니다.")
@ApiResponse(responseCode = "200", description = "필터 열람 내역 조회 성공")
public SuccessResponse<DatedFilterDto> getFilterViewHistory(@LoginInfo Long id);

@Operation(summary = "회원 탈퇴를 할 수 있다.")
@ApiResponse(responseCode = "200", description = "회원 탈퇴 성공")
public SuccessResponse deleteUser(@LoginInfo Long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
public enum Provider {
KAKAO("KAKAO"),
APPLE("APPLE"),
PURITHM("PURITHM");
PURITHM("자체 가입");

private final String provider;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.purithm.domain.user.entity;

import java.time.LocalDateTime;
import java.util.Date;

import org.springframework.data.annotation.CreatedDate;
Expand Down Expand Up @@ -55,6 +56,9 @@ public class User {
@Column(updatable = false)
private Date createdAt;

@Column(updatable = false)
private LocalDateTime deletedAt;

public void agreeToTerms() {
this.terms = true;
}
Expand All @@ -69,4 +73,8 @@ public void updateProfile(UserInfoRequestDto userInfo) {
this.username = userInfo.name();
}

public void withdraw() {
this.deletedAt = LocalDateTime.now();
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.example.purithm.domain.user.repository;

import java.util.Optional;
import java.time.LocalDateTime;

import com.example.purithm.domain.user.entity.Provider;
import com.example.purithm.domain.user.entity.User;
Expand All @@ -9,6 +9,7 @@
import org.springframework.data.repository.query.Param;

public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT u FROM User u WHERE u.provider = :provider AND u.providerId = :providerId AND u.deletedAt IS NULL")
User findByProviderAndProviderId(Provider provider, String providerId);

@Query("SELECT COUNT(r) FROM Review r WHERE r.user.id = :userId")
Expand All @@ -20,7 +21,11 @@ public interface UserRepository extends JpaRepository<User, Long> {
@Query("SELECT COUNT(ufl) FROM UserFilterLog ufl WHERE ufl.userId = :userId")
int countLogsByUserId(@Param("userId") Long userId);

boolean existsByProviderId(String id);
@Query("SELECT CASE WHEN COUNT(u) > 0 THEN true ELSE false END FROM User u "
+ "WHERE u.provider = :provider AND u.providerId = :providerId AND u.deletedAt IS NOT NULL AND u.deletedAt >= :sevenDaysAgo")
boolean existsWithdrawnUser(Provider provider, String providerId, LocalDateTime sevenDaysAgo);

Optional<User> findByProviderId(String id);
@Query("SELECT CASE WHEN COUNT(u) > 0 THEN true ELSE false END FROM User u "
+ "WHERE u.id = :userId AND u.deletedAt IS NOT NULL")
boolean existsWithdrawnUserById(Long userId);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.purithm.domain.user.service;

import java.time.LocalDateTime;

import com.example.purithm.domain.filter.entity.Membership;
import com.example.purithm.domain.user.dto.request.UserInfoRequestDto;
import com.example.purithm.domain.user.dto.response.AccountInfoDto;
Expand All @@ -25,28 +27,35 @@ public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;

public Long signUp(SignUpUserInfoDto socialUserInfoDto) {
if (socialUserInfoDto.getProvider().equals(Provider.PURITHM)
&& userRepository.existsByProviderId(socialUserInfoDto.getProviderId())) {
throw CustomException.of(Error.NICKNAME_ALREADY_USED_ERROR);
}

public Long signUp(SignUpUserInfoDto signUpUserInfoDto) {
User existUser = userRepository
.findByProviderAndProviderId(socialUserInfoDto.getProvider(), socialUserInfoDto.getProviderId());
.findByProviderAndProviderId(signUpUserInfoDto.getProvider(), signUpUserInfoDto.getProviderId());

if (existUser != null) {
if (existUser.getProvider().equals(Provider.PURITHM)) {
throw CustomException.of(Error.NICKNAME_ALREADY_USED_ERROR);
}
return existUser.getId();
}

boolean isWithdrawnUser = userRepository.existsWithdrawnUser(
signUpUserInfoDto.getProvider(),
signUpUserInfoDto.getProviderId(),
LocalDateTime.now().minusDays(7));
if (isWithdrawnUser) {
throw CustomException.of(Error.WIRHDRAWN_USER_ERROR);
}

User user = User.builder()
.profile(socialUserInfoDto.getProfile())
.provider(socialUserInfoDto.getProvider())
.providerId(socialUserInfoDto.getProviderId())
.username(socialUserInfoDto.getUsername())
.email(socialUserInfoDto.getEmail())
.profile(signUpUserInfoDto.getProfile())
.provider(signUpUserInfoDto.getProvider())
.providerId(signUpUserInfoDto.getProviderId())
.username(signUpUserInfoDto.getUsername())
.email(signUpUserInfoDto.getEmail())
.terms(false)
.membership(Membership.BASIC)
.password(passwordEncoder.encode(socialUserInfoDto.getPassword()))
.password(passwordEncoder.encode(signUpUserInfoDto.getPassword()))
.deletedAt(null)
.build();

User savedUser = userRepository.save(user);
Expand Down Expand Up @@ -104,12 +113,21 @@ public void updateProfile(UserInfoRequestDto userInfo, Long userId) {
}

public Long getUserId(LoginRequestDto loginRequestDto) {
User user = userRepository.findByProviderId(loginRequestDto.id())
.orElseThrow(() -> CustomException.of(Error.NOT_FOUND_ERROR));
User user = userRepository.findByProviderAndProviderId(Provider.PURITHM, loginRequestDto.id());
if (user == null) {
throw CustomException.of(Error.NOT_FOUND_ERROR);
}

if (!passwordEncoder.matches(loginRequestDto.password(), user.getPassword())) {
throw CustomException.of(Error.INVALID_ID_PASSWORD);
}
return user.getId();
}

public void deleteUser(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> CustomException.of(Error.NOT_FOUND_ERROR));
user.withdraw();
userRepository.save(user);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.purithm.global.auth.argumentresolver;

import com.example.purithm.domain.user.repository.UserRepository;
import com.example.purithm.global.auth.annotation.LoginInfo;
import com.example.purithm.global.exception.CustomException;
import com.example.purithm.global.exception.Error;
Expand All @@ -18,6 +19,7 @@
@Component
@Slf4j
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {
private final UserRepository userRepository;

@Override
public boolean supportsParameter(MethodParameter parameter) {
Expand All @@ -29,14 +31,14 @@ public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer m
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication == null) {
if (authentication == null || authentication.getPrincipal().equals("anonymousUser")) {
throw CustomException.of(Error.INVALID_TOKEN_ERROR);
}

if (authentication.getPrincipal().equals("anonymousUser")) {
throw CustomException.of(Error.INVALID_TOKEN_ERROR);
boolean existsWithdrawnUser = userRepository.existsWithdrawnUserById((Long)authentication.getPrincipal());
if (existsWithdrawnUser) {
throw CustomException.of(Error.NOT_FOUND_ERROR);
}

return authentication.getPrincipal();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public enum Error {

/* 403 */
NOT_AGREED_TERM(HttpStatus.FORBIDDEN, 40300, "이용약관 동의가 필요합니다"),
WIRHDRAWN_USER_ERROR(HttpStatus.FORBIDDEN, 40301, "탈퇴 후 7일이 지나지 않은 재가입 사용자입니다."),

/* 404 */
NOT_FOUND_ERROR(HttpStatus.NOT_FOUND, 40400, "리소스를 찾을 수 없습니다."),
Expand Down

0 comments on commit 9b53d18

Please sign in to comment.