Skip to content

Commit

Permalink
Merge pull request #101 from Tico-Corp/feature-be/TICO-372-update-use…
Browse files Browse the repository at this point in the history
…r-domain

[REFACTOR] User 도메인 개편 및 필드명 수정 (TICO-372)
  • Loading branch information
bu119 authored Feb 7, 2025
2 parents df7a750 + cfe1456 commit 54b4584
Show file tree
Hide file tree
Showing 20 changed files with 229 additions and 231 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package com.tico.pomoro_do.domain.user.dto;
package com.tico.pomoro_do.domain.auth.dto;

import lombok.Builder;
import lombok.Getter;

@Getter
public class GoogleUserInfoDTO {
public class GoogleUserInfo {

private String userId;
private String email;
private String name;
private String pictureUrl;

@Builder
public GoogleUserInfoDTO(String userId, String email, String name, String pictureUrl) {
public GoogleUserInfo(String userId, String email, String name, String pictureUrl) {
this.userId = userId;
this.email = email;
this.name = name;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.tico.pomoro_do.domain.auth.service;


import com.tico.pomoro_do.domain.user.dto.GoogleUserInfoDTO;
import com.tico.pomoro_do.domain.auth.dto.GoogleUserInfo;
import com.tico.pomoro_do.domain.auth.dto.response.TokenResponse;
import com.tico.pomoro_do.domain.user.entity.User;
import com.tico.pomoro_do.global.enums.ProfileImageType;
Expand All @@ -23,7 +23,7 @@ public interface AuthService {
* @throws IOException IO 예외
* @throws CustomException 구글 ID 토큰이 유효하지 않은 경우 예외
*/
GoogleUserInfoDTO verifyGoogleIdToken(String idToken) throws GeneralSecurityException, IOException, IllegalArgumentException;
GoogleUserInfo verifyGoogleIdToken(String idToken) throws GeneralSecurityException, IOException, IllegalArgumentException;

/**
* 구글 ID 토큰으로 로그인 처리
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
import com.tico.pomoro_do.domain.auth.dto.response.TokenResponse;
import com.tico.pomoro_do.domain.category.entity.Category;
import com.tico.pomoro_do.domain.category.service.CategoryService;
import com.tico.pomoro_do.domain.user.dto.GoogleUserInfoDTO;
import com.tico.pomoro_do.domain.auth.dto.GoogleUserInfo;
import com.tico.pomoro_do.domain.user.entity.SocialLogin;
import com.tico.pomoro_do.domain.user.entity.User;
import com.tico.pomoro_do.domain.user.repository.SocialLoginRepository;
import com.tico.pomoro_do.domain.user.repository.UserRepository;
import com.tico.pomoro_do.domain.user.service.ImageService;
import com.tico.pomoro_do.domain.user.service.UserService;
import com.tico.pomoro_do.global.auth.jwt.JWTUtil;
import com.tico.pomoro_do.global.code.ErrorCode;
import com.tico.pomoro_do.global.common.constants.CategoryConstants;
Expand Down Expand Up @@ -46,14 +47,15 @@ public class AuthServiceImpl implements AuthService {
private final JWTUtil jwtUtil;
private final UserRepository userRepository;
private final SocialLoginRepository socialLoginRepository;
private final UserService userService;
private final TokenService tokenService;
private final ImageService imageService;
private final CategoryService categoryService;


// 구글 ID 토큰 무결성 검사
@Override
public GoogleUserInfoDTO verifyGoogleIdToken(String idToken) throws GeneralSecurityException, IOException, IllegalArgumentException {
public GoogleUserInfo verifyGoogleIdToken(String idToken) throws GeneralSecurityException, IOException, IllegalArgumentException {
NetHttpTransport transport = new NetHttpTransport();
JsonFactory jsonFactory = new GsonFactory();
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
Expand All @@ -63,7 +65,7 @@ public GoogleUserInfoDTO verifyGoogleIdToken(String idToken) throws GeneralSecur
GoogleIdToken googleIdToken = verifier.verify(idToken); // 검증 실패시 IllegalArgumentException를 던짐
if (googleIdToken != null) {
GoogleIdToken.Payload payload = googleIdToken.getPayload();
return GoogleUserInfoDTO.builder()
return GoogleUserInfo.builder()
.userId(payload.getSubject())
.email(payload.getEmail())
.name((String) payload.get("name"))
Expand All @@ -84,9 +86,9 @@ public TokenResponse googleLogin(String idTokenHeader, String deviceId) throws G
// 토큰 추출
String idToken = jwtUtil.extractToken(idTokenHeader, TokenType.GOOGLE);
// 구글 토큰 유효성 검증
GoogleUserInfoDTO userInfo = verifyGoogleIdToken(idToken);
GoogleUserInfo userInfo = verifyGoogleIdToken(idToken);
// 회원 가입 여부 판단 -> 회원 가입 x -> 에러 발생
validateUserExists(userInfo.getEmail());
userService.validateEmailExists(userInfo.getEmail());
// 회원 가입되어 있으면 토큰 발급
return tokenService.createAuthTokens(userInfo.getEmail(), String.valueOf(UserRole.USER), deviceId);
}
Expand All @@ -102,9 +104,9 @@ public TokenResponse googleJoin(String idTokenHeader, String deviceId, String ni
// 구글 idToken 유효성 검사 및 추출
String idToken = jwtUtil.extractToken(idTokenHeader, TokenType.GOOGLE);
// 구글 id 토큰 검증
GoogleUserInfoDTO userInfo = verifyGoogleIdToken(idToken);
GoogleUserInfo userInfo = verifyGoogleIdToken(idToken);
// 사용자의 이메일 중복 체크
checkIfUserAlreadyRegistered(userInfo.getEmail());
userService.isEmailRegistered(userInfo.getEmail());

// 알맞는 profileImage url 가져오기 (null 가능)
String profileImageUrl = determineProfileImageUrl(imageType, profileImage, userInfo);
Expand Down Expand Up @@ -138,30 +140,6 @@ private void joinValidateInputs(String deviceId, String nickname) {
ValidationUtils.validateNickname(nickname);
}

/**
* 사용자 등록 여부 확인 메서드
*
* @param email 사용자 이메일
*/
private void validateUserExists(String email) {
if (!userRepository.existsByUsername(email)) {
log.error("사용자 등록되지 않음: 이메일 = {}", email);
throw new CustomException(ErrorCode.USER_NOT_FOUND);
}
}

/**
* 사용자가 이미 등록되어 있는지 확인합니다.
*
* @param email 사용자의 이메일
*/
private void checkIfUserAlreadyRegistered(String email) {
if (userRepository.existsByUsername(email)) {
log.error("이미 등록된 사용자: 이메일 = {}", email);
throw new CustomException(ErrorCode.USER_ALREADY_REGISTERED);
}
}

/**
* 프로필 이미지 URL을 결정합니다.
*
Expand All @@ -172,7 +150,7 @@ private void checkIfUserAlreadyRegistered(String email) {
* GOOGLE 유형인 경우 구글 프로필 이미지 URL을 반환하며,
* DEFAULT 유형인 경우 null을 반환합니다.
*/
private String determineProfileImageUrl(ProfileImageType imageType, MultipartFile profileImage, GoogleUserInfoDTO userInfo) {
private String determineProfileImageUrl(ProfileImageType imageType, MultipartFile profileImage, GoogleUserInfo userInfo) {
return switch (imageType) {
case FILE -> imageService.imageUpload(profileImage, S3Folder.PROFILES.getFolderName());
case GOOGLE -> userInfo.getPictureUrl();
Expand All @@ -183,17 +161,17 @@ private String determineProfileImageUrl(ProfileImageType imageType, MultipartFil

// User 생성
@Override
public User createUser(String username, String nickname, String profileImageUrl, UserRole role) {
public User createUser(String email, String nickname, String profileImageUrl, UserRole role) {

User user = User.builder()
.username(username)
.email(email)
.nickname(nickname)
.profileImageUrl(profileImageUrl)
.role(role)
.build();
userRepository.save(user);

log.info("사용자 저장 성공: 이메일 = {}", username);
log.info("사용자 저장 성공: 이메일 = {}", email);
return user;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ public class CustomUserDetailsService implements UserDetailsService {
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

// DB에서 조회
Optional<User> userData = userRepository.findByUsername(username);
Optional<User> userData = userRepository.findByEmail(username);

// 데이터가 있으면 검증 진행
if (userData.isPresent()) {
User user = userData.get();
AuthUser authUser = AuthUser.builder()
.email(user.getUsername())
.email(user.getEmail())
.role(String.valueOf(user.getRole()))
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ public ResponseEntity<SuccessResponseDTO<String>> createCategory(
@AuthenticationPrincipal CustomUserDetails customUserDetails,
@Valid @RequestBody CategoryCreationDTO request
){
String username = customUserDetails.getUsername();
categoryService.createCategory(username, request);
String email = customUserDetails.getUsername();
categoryService.createCategory(email, request);

SuccessResponseDTO<String> successResponse = SuccessResponseDTO.<String>builder()
.status(SuccessCode.CATEGORY_CREATION_SUCCESS.getHttpStatus().value())
Expand All @@ -82,8 +82,8 @@ public ResponseEntity<SuccessResponseDTO<String>> createCategory(
public ResponseEntity<SuccessResponseDTO<CategoryDTO>> getCategories(
@AuthenticationPrincipal CustomUserDetails customUserDetails
) {
String username = customUserDetails.getUsername();
CategoryDTO categoryDTO = categoryService.getCategories(username);
String email = customUserDetails.getUsername();
CategoryDTO categoryDTO = categoryService.getCategories(email);

SuccessResponseDTO<CategoryDTO> successResponse = SuccessResponseDTO.<CategoryDTO>builder()
.status(SuccessCode.CATEGORY_FETCH_SUCCESS.getHttpStatus().value())
Expand All @@ -102,8 +102,8 @@ public ResponseEntity<SuccessResponseDTO<CategoryDTO>> getCategories(
public ResponseEntity<SuccessResponseDTO<List<GeneralCategoryDTO>>> getGeneralCategories(
@AuthenticationPrincipal CustomUserDetails customUserDetails
) {
String username = customUserDetails.getUsername();
User user = userService.findByUsername(username);
String email = customUserDetails.getUsername();
User user = userService.findByEmail(email);
List<GeneralCategoryDTO> categories = categoryService.getGeneralCategories(user);

SuccessResponseDTO<List<GeneralCategoryDTO>> successResponse = SuccessResponseDTO.<List<GeneralCategoryDTO>>builder()
Expand All @@ -123,8 +123,8 @@ public ResponseEntity<SuccessResponseDTO<List<GeneralCategoryDTO>>> getGeneralCa
public ResponseEntity<SuccessResponseDTO<List<GroupCategoryDTO>>> getGroupCategories(
@AuthenticationPrincipal CustomUserDetails customUserDetails
) {
String username = customUserDetails.getUsername();
User user = userService.findByUsername(username);
String email = customUserDetails.getUsername();
User user = userService.findByEmail(email);
List<GroupCategoryDTO> categories = categoryService.getGroupCategories(user);

SuccessResponseDTO<List<GroupCategoryDTO>> successResponse = SuccessResponseDTO.<List<GroupCategoryDTO>>builder()
Expand All @@ -144,8 +144,8 @@ public ResponseEntity<SuccessResponseDTO<List<GroupCategoryDTO>>> getGroupCatego
public ResponseEntity<SuccessResponseDTO<List<InvitedGroupDTO>>> getInvitedGroupCategories(
@AuthenticationPrincipal CustomUserDetails customUserDetails
) {
String username = customUserDetails.getUsername();
User user = userService.findByUsername(username);
String email = customUserDetails.getUsername();
User user = userService.findByEmail(email);
List<InvitedGroupDTO> groupCategories = categoryService.getInvitedGroupCategories(user);

SuccessResponseDTO<List<InvitedGroupDTO>> successResponse = SuccessResponseDTO.<List<InvitedGroupDTO>>builder()
Expand All @@ -166,8 +166,8 @@ public ResponseEntity<SuccessResponseDTO<CategoryDetailDTO>> getCategoryDetail(
@PathVariable Long categoryId,
@AuthenticationPrincipal CustomUserDetails customUserDetails
) {
String username = customUserDetails.getUsername();
CategoryDetailDTO categoryDetailDTO = categoryService.getCategoryDetail(categoryId, username);
String email = customUserDetails.getUsername();
CategoryDetailDTO categoryDetailDTO = categoryService.getCategoryDetail(categoryId, email);

SuccessResponseDTO<CategoryDetailDTO> successResponse = SuccessResponseDTO.<CategoryDetailDTO>builder()
.status(SuccessCode.CATEGORY_DETAIL_FETCH_SUCCESS.getHttpStatus().value())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ public class CategoryServiceImpl implements CategoryService {
/**
* 카테고리 생성
*
* @param hostName 카테고리를 생성하는 호스트 유저의 이름
* @param hostEmail 카테고리를 생성하는 호스트 유저의 이메일
* @param categoryCreationDTO 생성할 카테고리의 정보가 담긴 DTO
*/
@Override
@Transactional
public void createCategory(String hostName, CategoryCreationDTO categoryCreationDTO){
public void createCategory(String hostEmail, CategoryCreationDTO categoryCreationDTO){

User host = userService.findByUsername(hostName);
User host = userService.findByEmail(hostEmail);

// 일반/그룹 카테고리 생성
Category category = createNewCategory(
Expand Down Expand Up @@ -139,13 +139,13 @@ public void createGroupMember(Category category, User member, GroupInvitationSta
/**
* 주어진 사용자 이름을 기반으로 사용자의 일반, 그룹, 초대받은 카테고리를 조회
*
* @param username 사용자의 이름
* @param email 사용자의 이메일
* @return 사용자에 해당하는 일반 카테고리, 그룹 카테고리, 초대받은 그룹 카테고리를 포함하는 CategoryDTO 객체
*/
@Override
public CategoryDTO getCategories(String username) {
public CategoryDTO getCategories(String email) {
// 사용자 조회
User user = userService.findByUsername(username);
User user = userService.findByEmail(email);

// 일반 카테고리
List<GeneralCategoryDTO> generalCategories = getGeneralCategories(user);
Expand Down Expand Up @@ -250,11 +250,11 @@ private Map<Category, Long> calculateMemberCounts(List<Category> groupCategories
* 카테고리 상세 조회
*
* @param categoryId 카테고리 ID
* @param username 조회한 유저 이메일
* @param email 조회한 유저 이메일
* @return CategoryDetailDTO 객체
*/
@Override
public CategoryDetailDTO getCategoryDetail(Long categoryId, String username){
public CategoryDetailDTO getCategoryDetail(Long categoryId, String email){
Category category = findByCategoryId(categoryId);
List<GroupMemberDTO> groupMemberDTOList = new ArrayList<>();
// 그룹 멤버 조회
Expand All @@ -277,7 +277,7 @@ public CategoryDetailDTO getCategoryDetail(Long categoryId, String username){
.categoryId(categoryId)
.title(category.getTitle())
.hostNickname(category.getHost().getNickname())
.hostStatus(category.getHost().getUsername().equals(username))
.hostStatus(category.getHost().getEmail().equals(email))
.type(category.getType())
.visibility(category.getVisibility())
.members(groupMemberDTOList)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.tico.pomoro_do.domain.user.controller;

import com.tico.pomoro_do.domain.auth.dto.response.TokenResponse;
import com.tico.pomoro_do.domain.user.dto.request.AdminDTO;
import com.tico.pomoro_do.domain.user.dto.request.AdminRequest;
import com.tico.pomoro_do.domain.user.service.AdminService;
import com.tico.pomoro_do.global.code.SuccessCode;
import com.tico.pomoro_do.global.response.SuccessResponseDTO;
Expand Down Expand Up @@ -33,7 +33,7 @@ public class AdminController {
/**
* 관리자 회원가입 API
*
* @param adminDTO AdminDTO 객체
* @param adminRequest AdminDTO 객체
* @param profileImage 관리자 프로필 이미지 파일
* @return 성공 시 TokenDTO를 포함하는 SuccessResponseDTO
*/
Expand All @@ -50,17 +50,17 @@ public class AdminController {
})
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<SuccessResponseDTO<TokenResponse>> adminJoin(
@Valid @RequestPart AdminDTO adminDTO,
@Valid @RequestPart AdminRequest adminRequest,
@RequestPart(value = "profileImage", required = false) MultipartFile profileImage
) {

TokenResponse jwtResponse = adminService.adminJoin(adminDTO, profileImage);
TokenResponse jwtResponse = adminService.adminJoin(adminRequest, profileImage);
SuccessResponseDTO<TokenResponse> successResponse = SuccessResponseDTO.<TokenResponse>builder()
.status(SuccessCode.ADMIN_SIGNUP_SUCCESS.getHttpStatus().value())
.message(SuccessCode.ADMIN_SIGNUP_SUCCESS.getMessage())
.data(jwtResponse)
.build();
log.info("관리자 회원가입 성공: {}", adminDTO.getUsername());
log.info("관리자 회원가입 성공: {}", adminRequest.getEmail());
return ResponseEntity.status(HttpStatus.CREATED).body(successResponse);
}

Expand All @@ -83,16 +83,16 @@ public ResponseEntity<SuccessResponseDTO<TokenResponse>> adminJoin(
})
@PostMapping("/login")
public ResponseEntity<SuccessResponseDTO<TokenResponse>> adminLogin(
@Valid @RequestBody AdminDTO request
@Valid @RequestBody AdminRequest request
) {
log.info("관리자 로그인 요청: {}", request.getUsername());
log.info("관리자 로그인 요청: {}", request.getEmail());
TokenResponse jwtResponse = adminService.adminLogin(request);
SuccessResponseDTO<TokenResponse> successResponse = SuccessResponseDTO.<TokenResponse>builder()
.status(SuccessCode.ADMIN_LOGIN_SUCCESS.getHttpStatus().value())
.message(SuccessCode.ADMIN_LOGIN_SUCCESS.getMessage())
.data(jwtResponse)
.build();
log.info("관리자 로그인 성공: {}", request.getUsername());
log.info("관리자 로그인 성공: {}", request.getEmail());
return ResponseEntity.ok(successResponse);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.tico.pomoro_do.domain.user.controller;

import com.tico.pomoro_do.domain.user.dto.response.ImageDTO;
import com.tico.pomoro_do.domain.user.dto.response.ImageResponse;
import com.tico.pomoro_do.domain.user.service.ImageService;
import com.tico.pomoro_do.global.code.SuccessCode;
import com.tico.pomoro_do.global.enums.S3Folder;
Expand Down Expand Up @@ -45,20 +45,20 @@ public class ImageController {
@ApiResponse(responseCode = "400", description = "유효하지 않은 이미지 파일"),
})
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<SuccessResponseDTO<ImageDTO>> imageUpload(
public ResponseEntity<SuccessResponseDTO<ImageResponse>> imageUpload(
@RequestParam("image") MultipartFile image
) {

String imageUrl = imageService.imageUpload(image, S3Folder.IMAGES.getFolderName());

ImageDTO imageDTO = ImageDTO.builder()
ImageResponse imageResponse = ImageResponse.builder()
.imageUrl(imageUrl)
.build();

SuccessResponseDTO<ImageDTO> response = SuccessResponseDTO.<ImageDTO>builder()
SuccessResponseDTO<ImageResponse> response = SuccessResponseDTO.<ImageResponse>builder()
.status(SuccessCode.IMAGE_UPLOAD_SUCCESS.getHttpStatus().value())
.message(SuccessCode.IMAGE_UPLOAD_SUCCESS.getMessage())
.data(imageDTO)
.data(imageResponse)
.build();

return ResponseEntity.ok(response);
Expand Down
Loading

0 comments on commit 54b4584

Please sign in to comment.