Skip to content

Commit

Permalink
Merge pull request #9 from Seasoning-Today/refactor/accountId-nicknam…
Browse files Browse the repository at this point in the history
…e-validation

회원 아이디 조회, 프로필 변경 서비스 로직 리팩토링
  • Loading branch information
csct3434 authored Jan 23, 2024
2 parents 59a57ff + 8df7856 commit 3043a51
Show file tree
Hide file tree
Showing 11 changed files with 282 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,22 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import today.seasoning.seasoning.common.UserPrincipal;
import today.seasoning.seasoning.user.domain.AccountId;
import today.seasoning.seasoning.user.dto.UpdateUserProfileCommand;
import today.seasoning.seasoning.user.dto.UpdateUserProfileDto;
import today.seasoning.seasoning.user.dto.UserProfileDto;
import today.seasoning.seasoning.user.service.FindUserProfileService;
import today.seasoning.seasoning.user.service.UpdateUserProfileService;
import today.seasoning.seasoning.user.service.ValidateAccountIdUsability;
import today.seasoning.seasoning.user.service.VerifyAccountIdService;

@RestController
@RequiredArgsConstructor
@RequestMapping("/user")
public class UserController {

private final FindUserProfileService findUserProfileService;
private final ValidateAccountIdUsability validateAccountIdUsability;
private final UpdateUserProfileService updateUserProfile;
private final VerifyAccountIdService verifyAccountIdService;

// 프로필 조회
@GetMapping("/profile")
Expand Down Expand Up @@ -57,7 +58,7 @@ public ResponseEntity<Void> updateUserProfile(

@GetMapping("/check-account-id")
public ResponseEntity<Void> checkAccountId(@RequestParam("id") String accountId) {
validateAccountIdUsability.doValidate(accountId);
verifyAccountIdService.verify(new AccountId(accountId));
return ResponseEntity.ok().build();
}
}
34 changes: 34 additions & 0 deletions src/main/java/today/seasoning/seasoning/user/domain/AccountId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package today.seasoning.seasoning.user.domain;

import org.springframework.http.HttpStatus;
import today.seasoning.seasoning.common.exception.CustomException;

public class AccountId {

private final String accountId;

public AccountId(String accountId) {
this.accountId = accountId;
selfValidate();
}

/*
[아이디 규칙]
- 5글자 이상, 20글자 이하
- 영문 소문자, 숫자, 밑줄('_') 및 점('.')으로 구성
- 점으로 시작하거나 끝날 수 없습니다.
- 연속된 점은 포함될 수 없습니다.
*/
private void selfValidate() {
String upperCases = ".*[A-Z].*";
String regex = "^(?!.*\\.\\.)(?!.*\\.$)[^\\W][\\w.]{4,19}$";

if (accountId == null || accountId.matches(upperCases) || !accountId.matches(regex)) {
throw new CustomException(HttpStatus.FORBIDDEN, "Invalid ID Format");
}
}

public String get() {
return accountId;
}
}
32 changes: 32 additions & 0 deletions src/main/java/today/seasoning/seasoning/user/domain/Nickname.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package today.seasoning.seasoning.user.domain;

import java.util.regex.Pattern;
import org.springframework.http.HttpStatus;
import today.seasoning.seasoning.common.exception.CustomException;

public class Nickname {

private final String nickname;

public Nickname(String nickname) {
this.nickname = nickname;
selfValidate();
}

/*
[닉네임 규칙]
- 허용 문자 : 영문 소문자 & 대문자, 한글, 숫자
- 허용 길이 : 2글자 이상, 10글자 이하
*/
private void selfValidate() {
String regex = "^[a-zA-Z0-9가-힣]{2,10}$";

if (nickname == null || !Pattern.matches(regex, nickname)) {
throw new CustomException(HttpStatus.FORBIDDEN, "Invalid Nickname");
}
}

public String get() {
return nickname;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public interface UserRepository extends JpaRepository<User, Long> {

@Query("SELECT u FROM User u WHERE u.accountId = :accountId")
Optional<User> findByAccountId(@Param("accountId") String accountId);

boolean existsByAccountId(String accountId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,29 @@

import lombok.Getter;
import org.springframework.web.multipart.MultipartFile;
import today.seasoning.seasoning.user.domain.AccountId;
import today.seasoning.seasoning.user.domain.Nickname;

@Getter
public class UpdateUserProfileCommand {

private final Long userId;
private final String accountId;
private final String nickname;
private final long userId;
private final AccountId accountId;
private final Nickname nickname;
private final MultipartFile profileImage;

public UpdateUserProfileCommand(Long userId, String accountId, String nickname,
MultipartFile profileImage) {
public UpdateUserProfileCommand(long userId, String accountId, String nickname, MultipartFile profileImage) {
this.userId = userId;
this.accountId = accountId;
this.nickname = nickname;
this.accountId = new AccountId(accountId);
this.nickname = new Nickname(nickname);
this.profileImage = profileImage;
}

public String getAccountId() {
return accountId.get();
}

public String getNickname() {
return nickname.get();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package today.seasoning.seasoning.user.service;

import com.github.f4b6a3.tsid.TsidCreator;
import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
Expand All @@ -19,55 +18,43 @@
@RequiredArgsConstructor
public class UpdateUserProfileService {

private final S3Service s3Service;
private final UserRepository userRepository;
private final ValidateAccountIdUsability validateAccountIdUsability;
private final S3Service s3Service;
private final UserRepository userRepository;

@Transactional
public void doUpdate(UpdateUserProfileCommand command) {
User user = userRepository.findById(command.getUserId()).get();
@Transactional
public void doUpdate(UpdateUserProfileCommand command) {
User user = userRepository.findById(command.getUserId()).get();
String oldProfileFilename = user.getProfileImageFilename();

validateNicknameAndAccountId(command, user.getAccountId());
verifyAccountId(command, user.getAccountId());

deleteOldProfileImage(user.getProfileImageFilename());
UploadFileInfo uploadFileInfo = uploadProfileImage(command.getProfileImage());

UploadFileInfo uploadFileInfo = uploadProfileImage(command.getProfileImage());
user.updateProfile(command.getAccountId(),
command.getNickname(),
uploadFileInfo.getFilename(),
uploadFileInfo.getUrl());

user.updateProfile(command.getAccountId(), command.getNickname(),
uploadFileInfo.getFilename(),
uploadFileInfo.getUrl());
userRepository.save(user);

userRepository.save(user);
}
s3Service.deleteFile(oldProfileFilename);
}

private void validateNicknameAndAccountId(UpdateUserProfileCommand command,
String currentAccountId) {
private void verifyAccountId(UpdateUserProfileCommand command, String currentAccountId) {
String newAccountId = command.getAccountId();

validateNicknameFormat(command.getNickname());
if (!newAccountId.equals(currentAccountId) && userRepository.existsByAccountId(newAccountId)) {
throw new CustomException(HttpStatus.CONFLICT, "아이디 중복");
}
}

String newAccountId = command.getAccountId();
if (!newAccountId.equals(currentAccountId)) {
validateAccountIdUsability.doValidate(newAccountId);
}
}
private UploadFileInfo uploadProfileImage(MultipartFile profileImage) {
String uid = TsidCreator.getTsid().encode(62);
String originalFilename = profileImage.getOriginalFilename();
String uploadFileName = "user/profile/" + uid + "/" + originalFilename;

private void validateNicknameFormat(String nickname) {
if (!Pattern.matches("^[a-zA-Z0-9가-힣]{2,10}$", nickname)) {
throw new CustomException(HttpStatus.BAD_REQUEST, "사용할 수 없는 닉네임 입니다.");
}
}
String imageUrl = s3Service.uploadFile(profileImage, uploadFileName);

private UploadFileInfo uploadProfileImage(MultipartFile profileImage) {
String uid = TsidCreator.getTsid().encode(62);
String originalFilename = profileImage.getOriginalFilename();
String uploadFileName = "user/profile/" + uid + "/" + originalFilename;

String imageUrl = s3Service.uploadFile(profileImage, uploadFileName);

return new UploadFileInfo(uploadFileName, imageUrl);
}

private void deleteOldProfileImage(String filename) {
s3Service.deleteFile(filename);
}
return new UploadFileInfo(uploadFileName, imageUrl);
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package today.seasoning.seasoning.user.service;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import today.seasoning.seasoning.common.exception.CustomException;
import today.seasoning.seasoning.user.domain.AccountId;
import today.seasoning.seasoning.user.domain.UserRepository;

@Service
@RequiredArgsConstructor
public class VerifyAccountIdService {

private final UserRepository userRepository;

public void verify(AccountId accountId) {
if(userRepository.existsByAccountId(accountId.get())) {
throw new CustomException(HttpStatus.CONFLICT, "아이디 중복");
}
}
}
Loading

0 comments on commit 3043a51

Please sign in to comment.