diff --git a/src/main/java/com/example/namo2/domain/user/application/UserFacade.java b/src/main/java/com/example/namo2/domain/user/application/UserFacade.java index c1a7d86a4..f04782074 100644 --- a/src/main/java/com/example/namo2/domain/user/application/UserFacade.java +++ b/src/main/java/com/example/namo2/domain/user/application/UserFacade.java @@ -1,44 +1,16 @@ package com.example.namo2.domain.user.application; -import static com.example.namo2.global.common.response.BaseResponseStatus.*; - -import java.io.IOException; -import java.math.BigInteger; -import java.net.HttpURLConnection; -import java.security.KeyFactory; -import java.security.NoSuchAlgorithmException; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.RSAPublicKeySpec; -import java.util.Base64; -import java.util.Date; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - -import org.json.simple.JSONObject; -import org.json.simple.parser.JSONParser; -import org.json.simple.parser.ParseException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.stereotype.Component; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.StringUtils; - -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.Jwts; - import com.example.namo2.domain.category.application.converter.CategoryConverter; import com.example.namo2.domain.category.application.impl.CategoryService; import com.example.namo2.domain.category.application.impl.PaletteService; import com.example.namo2.domain.category.domain.Category; - +import com.example.namo2.domain.user.application.converter.TermConverter; import com.example.namo2.domain.user.application.converter.UserConverter; import com.example.namo2.domain.user.application.impl.UserService; +import com.example.namo2.domain.user.domain.Term; import com.example.namo2.domain.user.domain.User; import com.example.namo2.domain.user.ui.dto.UserRequest; import com.example.namo2.domain.user.ui.dto.UserResponse; - import com.example.namo2.global.common.exception.BaseException; import com.example.namo2.global.common.response.BaseResponseStatus; import com.example.namo2.global.utils.JwtUtils; @@ -46,203 +18,238 @@ import com.example.namo2.global.utils.apple.AppleAuthApi; import com.example.namo2.global.utils.apple.AppleResponse; import com.example.namo2.global.utils.apple.AppleResponseConverter; - +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; + +import java.io.IOException; +import java.math.BigInteger; +import java.net.HttpURLConnection; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.RSAPublicKeySpec; +import java.util.Base64; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import static com.example.namo2.global.common.response.BaseResponseStatus.EXPIRATION_REFRESH_TOKEN; +import static com.example.namo2.global.common.response.BaseResponseStatus.MAKE_PUBLIC_KEY_FAILURE; +import static com.example.namo2.global.common.response.BaseResponseStatus.SOCIAL_LOGIN_FAILURE; @Component @Slf4j @RequiredArgsConstructor public class UserFacade { - private final SocialUtils socialUtils; - private final JwtUtils jwtUtils; - private final AppleAuthApi appleAuthApi; - private final RedisTemplate redisTemplate; - - private final UserService userService; - private final PaletteService paletteService; - private final CategoryService categoryService; - - @Value("${spring.security.oauth1.client.registration.apple.client-id}") - private String clientId; - - @Transactional - public UserResponse.SignUpDto signupKakao(UserRequest.SocialSignUpDto signUpDto) { - try { - HttpURLConnection con = socialUtils.connectKakaoResourceServer(signUpDto); - socialUtils.validateSocialAccessToken(con); - - String result = socialUtils.findSocialLoginUsersInfo(con); - - log.debug("result = " + result); - - Map response = socialUtils.findResponseFromKakako(result); - User user = UserConverter.toUser(response); - User savedUser = saveOrNot(user); - UserResponse.SignUpDto signUpRes = jwtUtils.generateTokens(savedUser.getId()); - userService.updateRefreshToken(savedUser.getId(), signUpRes.getRefreshToken()); - return signUpRes; - } catch (IOException e) { - throw new BaseException(SOCIAL_LOGIN_FAILURE); - } - } - - @Transactional - public UserResponse.SignUpDto signupNaver(UserRequest.SocialSignUpDto signUpDto) { - try { - HttpURLConnection con = socialUtils.connectNaverResourceServer(signUpDto); - socialUtils.validateSocialAccessToken(con); - - String result = socialUtils.findSocialLoginUsersInfo(con); - - Map response = socialUtils.findResponseFromNaver(result); - User user = UserConverter.toUser(response); - User savedUser = saveOrNot(user); - UserResponse.SignUpDto signUpRes = jwtUtils.generateTokens(savedUser.getId()); - userService.updateRefreshToken(savedUser.getId(), signUpRes.getRefreshToken()); - return signUpRes; - } catch (IOException e) { - throw new BaseException(SOCIAL_LOGIN_FAILURE); - } - } - - @Transactional - public UserResponse.SignUpDto signupApple(UserRequest.AppleSignUpDto req) { - AppleResponse.ApplePublicKeyListDto applePublicKeys = appleAuthApi.getApplePublicKeys(); - AppleResponse.ApplePublicKeyDto applePublicKey = null; - - try { - JSONParser parser = new JSONParser(); - String[] decodeArr = req.getIdentityToken().split("\\."); - String header = new String(Base64.getDecoder().decode(decodeArr[0])); - JSONObject headerJson = (JSONObject)parser.parse(header); - - Object kid = headerJson.get("kid"); //개발자 계정에서 얻은 10자리 식별자 키 - Object alg = headerJson.get("alg"); //토큰을 암호화하는데 사용되는 암호화 알고리즘 - - //identityToken 검증 - applePublicKey = AppleResponseConverter.toApplePublicKey(applePublicKeys, kid, alg); - } catch (ParseException e) { - e.printStackTrace(); - } - - PublicKey publicKey = getPublicKey(applePublicKey); - validateToken(publicKey, req.getIdentityToken()); - - Claims claims = Jwts.parserBuilder() - .setSigningKey(publicKey) - .build() - .parseClaimsJws(req.getIdentityToken()) - .getBody(); - String appleOauthId = claims.get("sub", String.class); - String appleEmail = claims.get("email", String.class); - log.debug("email: {}, oauthId : {}", appleEmail, appleOauthId); - - User user = UserConverter.toUser(req.getEmail(), req.getUsername()); - User savedUser = saveOrNot(user); - UserResponse.SignUpDto signUpRes = jwtUtils.generateTokens(savedUser.getId()); - userService.updateRefreshToken(savedUser.getId(), signUpRes.getRefreshToken()); - return signUpRes; - } - - private PublicKey getPublicKey(AppleResponse.ApplePublicKeyDto applePublicKey) { - String nStr = applePublicKey.getN(); //RSA public key의 모듈러스 값 - String eStr = applePublicKey.getE(); //RSA public key의 지수 값 - - byte[] nBytes = Base64.getUrlDecoder().decode(nStr); - byte[] eBytes = Base64.getUrlDecoder().decode(eStr); - - BigInteger n = new BigInteger(1, nBytes); - BigInteger e = new BigInteger(1, eBytes); - - try { - RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(n, e); - KeyFactory keyFactory = KeyFactory.getInstance(applePublicKey.getKty()); - return keyFactory.generatePublic(publicKeySpec); - } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) { - throw new BaseException(MAKE_PUBLIC_KEY_FAILURE); - } - - } - - private boolean validateToken(PublicKey publicKey, String token) { - Claims claims = Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token).getBody(); - - String issuer = (String)claims.get("iss"); - if (!"https://appleid.apple.com".equals(issuer)) { - throw new IllegalArgumentException("Invalid issuer"); - } - - String audience = (String)claims.get("aud"); - log.debug("{}", audience); - if (!clientId.equals(audience)) { - throw new IllegalArgumentException("Invalid audience"); - } - - long expiration = claims.getExpiration().getTime(); - log.debug("expriation : {} < now : {}", expiration, (new Date()).getTime()); - if (expiration <= (new Date()).getTime()) { - throw new IllegalArgumentException("Token expired"); - } - return true; - } - - @Transactional - public UserResponse.SignUpDto reissueAccessToken(UserRequest.SignUpDto signUpDto) { - if (!jwtUtils.validateToken(signUpDto.getRefreshToken())) { - throw new BaseException(EXPIRATION_REFRESH_TOKEN); - } - validateLogout(signUpDto); - - User user = userService.getUserByRefreshToken(signUpDto.getRefreshToken()); - UserResponse.SignUpDto signUpRes = jwtUtils.generateTokens(user.getId()); - user.updateRefreshToken(signUpRes.getRefreshToken()); - return signUpRes; - } - - @Transactional - public void logout(UserRequest.LogoutDto logoutDto) { - // AccessToken 만료시 종료 - if (!jwtUtils.validateToken(logoutDto.getAccessToken())) { - throw new BaseException(EXPIRATION_REFRESH_TOKEN); - } - - Long expiration = jwtUtils.getExpiration(logoutDto.getAccessToken()); - redisTemplate.opsForValue().set(logoutDto.getAccessToken(), "logout", expiration, TimeUnit.MILLISECONDS); - } - - private User saveOrNot(User user) { - Optional userByEmail = userService.getUserByEmail(user.getEmail()); - if (userByEmail.isEmpty()) { - User save = userService.createUser(user); - makeBaseCategory(save); - return save; - } - return userByEmail.get(); - } - - private void makeBaseCategory(User save) { - Category baseCategory = CategoryConverter.toCategory( - "기본", - paletteService.getReferenceById(1L), - Boolean.TRUE, - save - ); - Category groupCategory = CategoryConverter.toCategory( - "모임", - paletteService.getReferenceById(4L), - Boolean.TRUE, - save - ); - - categoryService.create(baseCategory); - categoryService.create(groupCategory); - } - - private void validateLogout(UserRequest.SignUpDto signUpDto) { - String blackToken = redisTemplate.opsForValue().get(signUpDto.getAccessToken()); - if (StringUtils.hasText(blackToken)) { - throw new BaseException(BaseResponseStatus.LOGOUT_ERROR); - } - } + private final SocialUtils socialUtils; + private final JwtUtils jwtUtils; + private final AppleAuthApi appleAuthApi; + private final RedisTemplate redisTemplate; + + private final UserService userService; + private final PaletteService paletteService; + private final CategoryService categoryService; + + @Value("${spring.security.oauth1.client.registration.apple.client-id}") + private String clientId; + + @Transactional + public UserResponse.SignUpDto signupKakao(UserRequest.SocialSignUpDto signUpDto) { + try { + HttpURLConnection con = socialUtils.connectKakaoResourceServer(signUpDto); + socialUtils.validateSocialAccessToken(con); + + String result = socialUtils.findSocialLoginUsersInfo(con); + + log.debug("result = " + result); + + Map response = socialUtils.findResponseFromKakako(result); + User user = UserConverter.toUser(response); + User savedUser = saveOrNot(user); + UserResponse.SignUpDto signUpRes = jwtUtils.generateTokens(savedUser.getId()); + userService.updateRefreshToken(savedUser.getId(), signUpRes.getRefreshToken()); + return signUpRes; + } catch (IOException e) { + throw new BaseException(SOCIAL_LOGIN_FAILURE); + } + } + + @Transactional + public UserResponse.SignUpDto signupNaver(UserRequest.SocialSignUpDto signUpDto) { + try { + HttpURLConnection con = socialUtils.connectNaverResourceServer(signUpDto); + socialUtils.validateSocialAccessToken(con); + + String result = socialUtils.findSocialLoginUsersInfo(con); + + Map response = socialUtils.findResponseFromNaver(result); + User user = UserConverter.toUser(response); + User savedUser = saveOrNot(user); + UserResponse.SignUpDto signUpRes = jwtUtils.generateTokens(savedUser.getId()); + userService.updateRefreshToken(savedUser.getId(), signUpRes.getRefreshToken()); + return signUpRes; + } catch (IOException e) { + throw new BaseException(SOCIAL_LOGIN_FAILURE); + } + } + + @Transactional + public UserResponse.SignUpDto signupApple(UserRequest.AppleSignUpDto req) { + AppleResponse.ApplePublicKeyListDto applePublicKeys = appleAuthApi.getApplePublicKeys(); + AppleResponse.ApplePublicKeyDto applePublicKey = null; + + try { + JSONParser parser = new JSONParser(); + String[] decodeArr = req.getIdentityToken().split("\\."); + String header = new String(Base64.getDecoder().decode(decodeArr[0])); + JSONObject headerJson = (JSONObject) parser.parse(header); + + Object kid = headerJson.get("kid"); //개발자 계정에서 얻은 10자리 식별자 키 + Object alg = headerJson.get("alg"); //토큰을 암호화하는데 사용되는 암호화 알고리즘 + + //identityToken 검증 + applePublicKey = AppleResponseConverter.toApplePublicKey(applePublicKeys, kid, alg); + } catch (ParseException e) { + e.printStackTrace(); + } + + PublicKey publicKey = getPublicKey(applePublicKey); + validateToken(publicKey, req.getIdentityToken()); + + Claims claims = Jwts.parserBuilder() + .setSigningKey(publicKey) + .build() + .parseClaimsJws(req.getIdentityToken()) + .getBody(); + String appleOauthId = claims.get("sub", String.class); + String appleEmail = claims.get("email", String.class); + log.debug("email: {}, oauthId : {}", appleEmail, appleOauthId); + + User user = UserConverter.toUser(req.getEmail(), req.getUsername()); + User savedUser = saveOrNot(user); + UserResponse.SignUpDto signUpRes = jwtUtils.generateTokens(savedUser.getId()); + userService.updateRefreshToken(savedUser.getId(), signUpRes.getRefreshToken()); + return signUpRes; + } + + private PublicKey getPublicKey(AppleResponse.ApplePublicKeyDto applePublicKey) { + String nStr = applePublicKey.getN(); //RSA public key의 모듈러스 값 + String eStr = applePublicKey.getE(); //RSA public key의 지수 값 + + byte[] nBytes = Base64.getUrlDecoder().decode(nStr); + byte[] eBytes = Base64.getUrlDecoder().decode(eStr); + + BigInteger n = new BigInteger(1, nBytes); + BigInteger e = new BigInteger(1, eBytes); + + try { + RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(n, e); + KeyFactory keyFactory = KeyFactory.getInstance(applePublicKey.getKty()); + return keyFactory.generatePublic(publicKeySpec); + } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) { + throw new BaseException(MAKE_PUBLIC_KEY_FAILURE); + } + + } + + private boolean validateToken(PublicKey publicKey, String token) { + Claims claims = Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token).getBody(); + + String issuer = (String) claims.get("iss"); + if (!"https://appleid.apple.com".equals(issuer)) { + throw new IllegalArgumentException("Invalid issuer"); + } + + String audience = (String) claims.get("aud"); + log.debug("{}", audience); + if (!clientId.equals(audience)) { + throw new IllegalArgumentException("Invalid audience"); + } + + long expiration = claims.getExpiration().getTime(); + log.debug("expriation : {} < now : {}", expiration, (new Date()).getTime()); + if (expiration <= (new Date()).getTime()) { + throw new IllegalArgumentException("Token expired"); + } + return true; + } + + @Transactional + public UserResponse.SignUpDto reissueAccessToken(UserRequest.SignUpDto signUpDto) { + if (!jwtUtils.validateToken(signUpDto.getRefreshToken())) { + throw new BaseException(EXPIRATION_REFRESH_TOKEN); + } + validateLogout(signUpDto); + + User user = userService.getUserByRefreshToken(signUpDto.getRefreshToken()); + UserResponse.SignUpDto signUpRes = jwtUtils.generateTokens(user.getId()); + user.updateRefreshToken(signUpRes.getRefreshToken()); + return signUpRes; + } + + @Transactional + public void logout(UserRequest.LogoutDto logoutDto) { + // AccessToken 만료시 종료 + if (!jwtUtils.validateToken(logoutDto.getAccessToken())) { + throw new BaseException(EXPIRATION_REFRESH_TOKEN); + } + + Long expiration = jwtUtils.getExpiration(logoutDto.getAccessToken()); + redisTemplate.opsForValue().set(logoutDto.getAccessToken(), "logout", expiration, TimeUnit.MILLISECONDS); + } + + private User saveOrNot(User user) { + Optional userByEmail = userService.getUserByEmail(user.getEmail()); + if (userByEmail.isEmpty()) { + User save = userService.createUser(user); + makeBaseCategory(save); + return save; + } + return userByEmail.get(); + } + + private void makeBaseCategory(User save) { + Category baseCategory = CategoryConverter.toCategory( + "기본", + paletteService.getReferenceById(1L), + Boolean.TRUE, + save + ); + Category groupCategory = CategoryConverter.toCategory( + "모임", + paletteService.getReferenceById(4L), + Boolean.TRUE, + save + ); + + categoryService.create(baseCategory); + categoryService.create(groupCategory); + } + + private void validateLogout(UserRequest.SignUpDto signUpDto) { + String blackToken = redisTemplate.opsForValue().get(signUpDto.getAccessToken()); + if (StringUtils.hasText(blackToken)) { + throw new BaseException(BaseResponseStatus.LOGOUT_ERROR); + } + } + + @Transactional(readOnly = false) + public void createTerm(UserRequest.TermDto termDto, Long userId) { + User user = userService.getUser(userId); + List terms = TermConverter.toTerms(termDto, user); + userService.createTerm(terms); + } } diff --git a/src/main/java/com/example/namo2/domain/user/application/converter/TermConverter.java b/src/main/java/com/example/namo2/domain/user/application/converter/TermConverter.java new file mode 100644 index 000000000..1f9d25753 --- /dev/null +++ b/src/main/java/com/example/namo2/domain/user/application/converter/TermConverter.java @@ -0,0 +1,31 @@ +package com.example.namo2.domain.user.application.converter; + +import com.example.namo2.domain.user.domain.Content; +import com.example.namo2.domain.user.domain.Term; +import com.example.namo2.domain.user.domain.User; +import com.example.namo2.domain.user.ui.dto.UserRequest; + +import java.util.ArrayList; +import java.util.List; + +public class TermConverter { + public static List toTerms(UserRequest.TermDto termDto, User user) { + List terms = new ArrayList<>(); + System.out.println("termOfUse" + termDto.getIsCheckTermOfUse()); + System.out.println("termOfUse" + termDto.getIsCheckPersonalInformationCollection()); + Term termOfUse = toTerm(Content.TERMS_OF_USE, termDto.getIsCheckTermOfUse(), user); + Term termOfPersonal + = toTerm(Content.PERSONAL_INFORMATION_COLLECTION, termDto.getIsCheckPersonalInformationCollection(), user); + terms.add(termOfUse); + terms.add(termOfPersonal); + return terms; + } + + private static Term toTerm(Content content, Boolean isCheck, User user) { + return Term.builder() + .user(user) + .content(content) + .isCheck(isCheck) + .build(); + } +} diff --git a/src/main/java/com/example/namo2/domain/user/application/impl/UserService.java b/src/main/java/com/example/namo2/domain/user/application/impl/UserService.java index 43dcaf403..ee9c556b2 100644 --- a/src/main/java/com/example/namo2/domain/user/application/impl/UserService.java +++ b/src/main/java/com/example/namo2/domain/user/application/impl/UserService.java @@ -4,7 +4,12 @@ import java.util.List; import java.util.Optional; +import java.util.TreeMap; +import com.example.namo2.domain.user.dao.repository.TermRepository; +import com.example.namo2.domain.user.domain.Term; +import com.example.namo2.global.common.response.BaseResponseStatus; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import com.example.namo2.domain.user.dao.repository.UserRepository; @@ -16,34 +21,49 @@ @Service @RequiredArgsConstructor +@Slf4j public class UserService { - private final UserRepository userRepository; + private final UserRepository userRepository; + private final TermRepository termRepository; - public User createUser(User user) { - return userRepository.save(user); - } + public User createUser(User user) { + return userRepository.save(user); + } - public User getUser(Long userId) { - return userRepository.findById(userId) - .orElseThrow(() -> new BaseException(NOT_FOUND_USER_FAILURE)); - } + public User getUser(Long userId) { + return userRepository.findById(userId) + .orElseThrow(() -> new BaseException(NOT_FOUND_USER_FAILURE)); + } - public List getUsers(List users) { - return userRepository.findUsersById(users); - } + public List getUsers(List users) { + return userRepository.findUsersById(users); + } - public Optional getUserByEmail(String email) { - return userRepository.findUserByEmail(email); - } + public Optional getUserByEmail(String email) { + return userRepository.findUserByEmail(email); + } - public User getUserByRefreshToken(String refreshToken) { - return userRepository.findUserByRefreshToken(refreshToken) - .orElseThrow(() -> new BaseException(NOT_FOUND_USER_FAILURE)); - } + public User getUserByRefreshToken(String refreshToken) { + return userRepository.findUserByRefreshToken(refreshToken) + .orElseThrow(() -> new BaseException(NOT_FOUND_USER_FAILURE)); + } - public void updateRefreshToken(Long userId, String refreshToken) { - User user = userRepository.findById(userId).orElseThrow(() -> new BaseException(NOT_FOUND_USER_FAILURE)); - user.updateRefreshToken(refreshToken); - } + public void updateRefreshToken(Long userId, String refreshToken) { + User user = userRepository.findById(userId).orElseThrow(() -> new BaseException(NOT_FOUND_USER_FAILURE)); + user.updateRefreshToken(refreshToken); + } + + public void createTerm(List terms) { + for (Term term : terms) { + if (!term.getIsCheck()) { + throw new BaseException(NOT_CHECK_TERM_ERROR); + } + termRepository.findTermByContentAndUser(term.getContent(), term.getUser()) + .ifPresentOrElse( + savedTerm -> savedTerm.update(), + () -> termRepository.save(term) + ); + } + } } diff --git a/src/main/java/com/example/namo2/domain/user/dao/repository/TermRepository.java b/src/main/java/com/example/namo2/domain/user/dao/repository/TermRepository.java new file mode 100644 index 000000000..df19f46e1 --- /dev/null +++ b/src/main/java/com/example/namo2/domain/user/dao/repository/TermRepository.java @@ -0,0 +1,12 @@ +package com.example.namo2.domain.user.dao.repository; + +import com.example.namo2.domain.user.domain.Content; +import com.example.namo2.domain.user.domain.Term; +import com.example.namo2.domain.user.domain.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface TermRepository extends JpaRepository { + Optional findTermByContentAndUser(Content content, User user); +} diff --git a/src/main/java/com/example/namo2/domain/user/ui/UserController.java b/src/main/java/com/example/namo2/domain/user/ui/UserController.java index 332123eb6..054f144de 100644 --- a/src/main/java/com/example/namo2/domain/user/ui/UserController.java +++ b/src/main/java/com/example/namo2/domain/user/ui/UserController.java @@ -1,12 +1,30 @@ package com.example.namo2.domain.user.ui; +import com.example.namo2.domain.user.application.UserFacade; +import com.example.namo2.domain.user.ui.dto.UserRequest; +import com.example.namo2.global.common.response.BaseResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import io.swagger.v3.oas.annotations.tags.Tag; - @Tag(name = "User", description = "유저 관련 API") @RestController +@RequiredArgsConstructor @RequestMapping("/user") public class UserController { + private final UserFacade userFacade; + + @Operation(summary = "약관을 동의합니다. ", description = "약관 동의 API") + @PostMapping("/term") + public BaseResponse createTerm(@Valid @RequestBody UserRequest.TermDto termDto, HttpServletRequest request) { + userFacade.createTerm(termDto, (Long) request.getAttribute("userId")); + return BaseResponse.ok(); + } + } diff --git a/src/main/java/com/example/namo2/domain/user/ui/dto/UserRequest.java b/src/main/java/com/example/namo2/domain/user/ui/dto/UserRequest.java index a7a2837cc..6bc073282 100644 --- a/src/main/java/com/example/namo2/domain/user/ui/dto/UserRequest.java +++ b/src/main/java/com/example/namo2/domain/user/ui/dto/UserRequest.java @@ -1,48 +1,63 @@ package com.example.namo2.domain.user.ui.dto; import jakarta.validation.constraints.NotBlank; - +import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; public class UserRequest { - private UserRequest() { - throw new IllegalStateException("Utility class"); - } - - @Getter - @AllArgsConstructor - @NoArgsConstructor - public static class LogoutDto { - @NotBlank - private String accessToken; - } - - @Getter - @AllArgsConstructor - @NoArgsConstructor - public static class SignUpDto { - @NotBlank - private String accessToken; - @NotBlank - private String refreshToken; - } - - @Getter - @AllArgsConstructor - @NoArgsConstructor - public static class SocialSignUpDto { - @NotBlank - private String accessToken; - } - - @Getter - public static class AppleSignUpDto { - @NotBlank - private String identityToken; - private String email; - private String username; - } - + private UserRequest() { + throw new IllegalStateException("Utility class"); + } + + @Getter + @AllArgsConstructor + @NoArgsConstructor + public static class LogoutDto { + @NotBlank + private String accessToken; + } + + @Getter + @AllArgsConstructor + @NoArgsConstructor + public static class SignUpDto { + @NotBlank + private String accessToken; + @NotBlank + private String refreshToken; + } + + @Getter + @AllArgsConstructor + @NoArgsConstructor + public static class SocialSignUpDto { + @NotBlank + private String accessToken; + } + + @Getter + public static class AppleSignUpDto { + @NotBlank + private String identityToken; + private String email; + private String username; + } + + @NoArgsConstructor + public static class TermDto { + @NotNull + private boolean isCheckTermOfUse; + @NotNull + private boolean isCheckPersonalInformationCollection; + + public boolean getIsCheckTermOfUse() { + return isCheckTermOfUse; + } + + public boolean getIsCheckPersonalInformationCollection() { + return isCheckPersonalInformationCollection; + } + } } diff --git a/src/main/java/com/example/namo2/global/common/response/BaseResponseStatus.java b/src/main/java/com/example/namo2/global/common/response/BaseResponseStatus.java index 3d24e1c8a..4f5bc8c5d 100644 --- a/src/main/java/com/example/namo2/global/common/response/BaseResponseStatus.java +++ b/src/main/java/com/example/namo2/global/common/response/BaseResponseStatus.java @@ -5,63 +5,64 @@ @Getter public enum BaseResponseStatus { - /** - * 200 : 요청 성공 - */ - SUCCESS(200, "요청 성공"), + /** + * 200 : 요청 성공 + */ + SUCCESS(200, "요청 성공"), - /** - * 400 : Bad Request - */ - MAKE_PUBLIC_KEY_FAILURE(400, "애플 퍼블릭 키를 생성하는데 실패하였습니다"), - //애플 identityToken 오류 - APPLE_REQUEST_ERROR(400, "애플 identityToken이 잘못되었습니다."), + /** + * 400 : Bad Request + */ + MAKE_PUBLIC_KEY_FAILURE(400, "애플 퍼블릭 키를 생성하는데 실패하였습니다"), + //애플 identityToken 오류 + APPLE_REQUEST_ERROR(400, "애플 identityToken이 잘못되었습니다."), - /** - * 401 : 소셜 로그인 오류 - */ - SOCIAL_LOGIN_FAILURE(401, "소셜 로그인에 실패하였습니다."), + /** + * 401 : 소셜 로그인 오류 + */ + SOCIAL_LOGIN_FAILURE(401, "소셜 로그인에 실패하였습니다."), - /** - * 403 : local Access Token 오류 - */ - EMPTY_ACCESS_KEY(403, "AccessToken 이 비어있습니다."), - LOGOUT_ERROR(403, "로그 아웃된 사용자입니다."), - EXPIRATION_ACCESS_TOKEN(403, "Access token 이 만료되었습니다."), - EXPIRATION_REFRESH_TOKEN(403, "RefreshToken 이 만료되었습니다."), + /** + * 403 : local Access Token 오류 + */ + EMPTY_ACCESS_KEY(403, "AccessToken 이 비어있습니다."), + LOGOUT_ERROR(403, "로그 아웃된 사용자입니다."), + EXPIRATION_ACCESS_TOKEN(403, "Access token 이 만료되었습니다."), + EXPIRATION_REFRESH_TOKEN(403, "RefreshToken 이 만료되었습니다."), - /** - * NOT FOUND 오류 - * 404 번오류 - */ - NOT_FOUND_USER_FAILURE(404, "유저를 찾을 수 없습니다."), - NOT_FOUND_SCHEDULE_FAILURE(404, "스케줄을 찾을 수 없습니다."), - NOT_FOUND_CATEGORY_FAILURE(404, "카테고리를 찾을 수 없습니다."), - NOT_FOUND_PALETTE_FAILURE(404, "팔레트를 찾을 수 없습니다."), - NOT_FOUND_DIARY_FAILURE(404, "다이어리를 찾을 수 없습니다."), + /** + * NOT FOUND 오류 + * 404 번오류 + */ + NOT_FOUND_USER_FAILURE(404, "유저를 찾을 수 없습니다."), + NOT_FOUND_SCHEDULE_FAILURE(404, "스케줄을 찾을 수 없습니다."), + NOT_FOUND_CATEGORY_FAILURE(404, "카테고리를 찾을 수 없습니다."), + NOT_FOUND_PALETTE_FAILURE(404, "팔레트를 찾을 수 없습니다."), + NOT_FOUND_DIARY_FAILURE(404, "다이어리를 찾을 수 없습니다."), - NOT_FOUND_MOIM_DIARY_FAILURE(404, "모임 메모 장소를 찾을 수 없습니다."), - NOT_FOUND_MOIM_FAILURE(404, "모임을 찾을 수 없습니다."), - NOT_FOUND_MOIM_AND_USER_FAILURE(404, "그룹 구성원이 아닙니다."), - NOT_FOUND_MOIM_SCHEDULE_AND_USER_FAILURE(404, "그룹 스케줄 구성원이 아닙니다."), - NOT_FOUND_MOIM_MEMO_LOCATION_FAILURE(404, "모임 장소를 찾을 수 없습니다."), - DIARY_EXISTS_FAILURE(404, "이미 존재하는 다이어리 입니다."), - DUPLICATE_PARTICIPATE_FAILURE(404, "이미 가입한 모임입니다."), - DUPLICATE_MOIM_MEMO_FAILURE(404, "이미 모임 메모가 생성되어 있습니다."), - FILE_NAME_EXCEPTION(404, "파일 확장자가 잘못되었습니다."), - S3_FAILURE(404, "파일 업로드 과정에서 오류가 발생하였습니다."), + NOT_FOUND_MOIM_DIARY_FAILURE(404, "모임 메모 장소를 찾을 수 없습니다."), + NOT_FOUND_MOIM_FAILURE(404, "모임을 찾을 수 없습니다."), + NOT_FOUND_MOIM_AND_USER_FAILURE(404, "그룹 구성원이 아닙니다."), + NOT_FOUND_MOIM_SCHEDULE_AND_USER_FAILURE(404, "그룹 스케줄 구성원이 아닙니다."), + NOT_FOUND_MOIM_MEMO_LOCATION_FAILURE(404, "모임 장소를 찾을 수 없습니다."), + NOT_CHECK_TERM_ERROR(404, "약관에 무조건 동의 해야합니다."), + DIARY_EXISTS_FAILURE(404, "이미 존재하는 다이어리 입니다."), + DUPLICATE_PARTICIPATE_FAILURE(404, "이미 가입한 모임입니다."), + DUPLICATE_MOIM_MEMO_FAILURE(404, "이미 모임 메모가 생성되어 있습니다."), + FILE_NAME_EXCEPTION(404, "파일 확장자가 잘못되었습니다."), + S3_FAILURE(404, "파일 업로드 과정에서 오류가 발생하였습니다."), - /** - * 500 : 서버 에러 - */ - INTERNET_SERVER_ERROR(500, "서버 오류"), - JPA_FAILURE(500, "jpa, sql 상에서 오류가 발생했습니다."); + /** + * 500 : 서버 에러 + */ + INTERNET_SERVER_ERROR(500, "서버 오류"), + JPA_FAILURE(500, "jpa, sql 상에서 오류가 발생했습니다."); - private final int code; - private final String message; + private final int code; + private final String message; - private BaseResponseStatus(int code, String message) { - this.code = code; - this.message = message; - } + private BaseResponseStatus(int code, String message) { + this.code = code; + this.message = message; + } }