Skip to content

Commit

Permalink
GETP-192 refactor: auth 컴포넌트에서 ErrorCode에 대한 의존성 제거 (#124)
Browse files Browse the repository at this point in the history
* GETP-192 refactor: SignUpService에서 ErrorCode에 대한 의존성 제거

* GETP-192 refactor: AuthService에서 ErrorCode에 대한 의존성 제거

* GETP-192 refactor: VerificationService에서 ErrorCode에 대한 의존성 제거
  • Loading branch information
scv1702 committed Aug 19, 2024
1 parent 1688cc2 commit 841b7de
Show file tree
Hide file tree
Showing 16 changed files with 115 additions and 225 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package es.princip.getp.domain.auth.application;

import es.princip.getp.domain.auth.exception.LoginErrorCode;
import es.princip.getp.domain.auth.exception.IncorrectEmailOrPasswordException;
import es.princip.getp.domain.auth.presentation.dto.request.LoginRequest;
import es.princip.getp.domain.auth.presentation.dto.response.Token;
import es.princip.getp.domain.member.command.domain.model.Member;
import es.princip.getp.infra.exception.BusinessLogicException;
import es.princip.getp.infra.security.details.PrincipalDetails;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -37,8 +36,8 @@ public Token login(final LoginRequest request) {
final Member member = principalDetails.getMember();

return tokenFactory.generateToken(member);
} catch (Exception e) {
throw new BusinessLogicException(LoginErrorCode.INCORRECT_EMAIL_OR_PASSWORD);
} catch (final Exception e) {
throw new IncorrectEmailOrPasswordException();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package es.princip.getp.domain.auth.application;

import es.princip.getp.domain.auth.application.command.SignUpCommand;
import es.princip.getp.domain.auth.exception.SignUpErrorCode;
import es.princip.getp.domain.auth.exception.DuplicatedEmailException;
import es.princip.getp.domain.member.command.application.MemberService;
import es.princip.getp.domain.member.command.application.command.CreateMemberCommand;
import es.princip.getp.domain.member.command.domain.model.Email;
import es.princip.getp.domain.member.command.domain.model.Member;
import es.princip.getp.domain.member.command.domain.model.MemberRepository;
import es.princip.getp.infra.exception.BusinessLogicException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
Expand All @@ -24,18 +23,18 @@ public class SignUpService {
private final PasswordEncoder passwordEncoder;

@Transactional
public void sendEmailVerificationCodeForSignUp(Email email) {
public void sendEmailVerificationCodeForSignUp(final Email email) {
if (memberRepository.existsByEmail(email)) {
throw new BusinessLogicException(SignUpErrorCode.DUPLICATED_EMAIL);
throw new DuplicatedEmailException();
}
emailVerificationService.sendVerificationCode(email);
}

@Transactional
public void signUp(SignUpCommand command) {
public void signUp(final SignUpCommand command) {
emailVerificationService.verifyEmail(command.email(), command.verificationCode());
Long memberId = memberService.create(CreateMemberCommand.from(command));
Member member = memberRepository.findById(memberId).orElseThrow();
final Long memberId = memberService.create(CreateMemberCommand.from(command));
final Member member = memberRepository.findById(memberId).orElseThrow();
member.encodePassword(passwordEncoder);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,52 @@

import es.princip.getp.domain.auth.domain.EmailVerification;
import es.princip.getp.domain.auth.domain.EmailVerificationRepository;
import es.princip.getp.domain.auth.exception.EmailVerificationErrorCode;
import es.princip.getp.domain.auth.exception.IncorrectVerificationCodeException;
import es.princip.getp.domain.auth.exception.NotFoundVerificationException;
import es.princip.getp.domain.member.command.domain.model.Email;
import es.princip.getp.infra.exception.BusinessLogicException;
import es.princip.getp.infra.util.RandomUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@Transactional(readOnly = true)
public class VerificationService {

private final VerificationCodeSender verificationSender;
private final EmailVerificationRepository emailVerificationRepository;
private final EmailVerificationRepository verificationRepository;

private final Long EXPIRATION_TIME;
private final Integer VERIFICATION_CODE_LENGTH;

public VerificationService(
VerificationCodeSender verificationSender,
EmailVerificationRepository emailVerificationRepository,
@Value("${spring.verification-code.expire-time}") Long EXPIRATION_TIME,
@Value("${spring.verification-code.length}") Integer VERIFICATION_CODE_LENGTH
final VerificationCodeSender verificationSender,
final EmailVerificationRepository verificationRepository,
@Value("${spring.verification-code.expire-time}") final Long EXPIRATION_TIME,
@Value("${spring.verification-code.length}") final Integer VERIFICATION_CODE_LENGTH
) {
this.verificationSender = verificationSender;
this.emailVerificationRepository = emailVerificationRepository;
this.verificationRepository = verificationRepository;
this.EXPIRATION_TIME = EXPIRATION_TIME;
this.VERIFICATION_CODE_LENGTH = VERIFICATION_CODE_LENGTH;
}

public Optional<EmailVerification> getByEmail(Email email) {
return emailVerificationRepository.findById(email.getValue());
}

@Transactional
public void sendVerificationCode(Email email) {
if (getByEmail(email).isPresent()) {
emailVerificationRepository.deleteById(email.getValue());
}
String verificationCode = RandomUtil.generateRandomCode(VERIFICATION_CODE_LENGTH);
verificationRepository.deleteById(email.getValue());
final String verificationCode = RandomUtil.generateRandomCode(VERIFICATION_CODE_LENGTH);
verificationSender.send(email, verificationCode);
EmailVerification emailVerification = new EmailVerification(email.getValue(), verificationCode, EXPIRATION_TIME);
emailVerificationRepository.save(emailVerification);
final EmailVerification emailVerification = new EmailVerification(email.getValue(), verificationCode, EXPIRATION_TIME);
verificationRepository.save(emailVerification);
}

@Transactional
public void verifyEmail(Email email, String verificationCode) {
EmailVerification emailVerification = getByEmail(email).orElseThrow(() ->
new BusinessLogicException(EmailVerificationErrorCode.INVALID_EMAIL_VERIFICATION));
if (!emailVerification.verify(verificationCode)) {
throw new BusinessLogicException(
EmailVerificationErrorCode.INCORRECT_EMAIL_VERIFICATION_CODE);
public void verifyEmail(final Email email, final String verificationCode) {
final EmailVerification verification = verificationRepository.findById(email.getValue())
.orElseThrow(NotFoundVerificationException::new);
if (!verification.verify(verificationCode)) {
throw new IncorrectVerificationCodeException();
}
emailVerificationRepository.delete(emailVerification);
verificationRepository.delete(verification);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.auth.exception;

import es.princip.getp.infra.exception.BusinessLogicException;
import es.princip.getp.infra.exception.ErrorDescription;

public class DuplicatedEmailException extends BusinessLogicException {

private static final String code = "DUPLICATED_EMAIL";
private static final String message = "중복된 이메일입니다. 다른 이메일을 사용해주세요.";

public DuplicatedEmailException() {
super(ErrorDescription.of(code, message));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.auth.exception;

import es.princip.getp.infra.exception.BusinessLogicException;
import es.princip.getp.infra.exception.ErrorDescription;

public class IncorrectEmailOrPasswordException extends BusinessLogicException {

private static final String code = "INCORRECT_EMAIL_OR_PASSWORD";
private static final String message = "이메일 또는 비밀번호가 일치하지 않습니다.";

public IncorrectEmailOrPasswordException() {
super(ErrorDescription.of(code, message));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.auth.exception;

import es.princip.getp.infra.exception.BusinessLogicException;
import es.princip.getp.infra.exception.ErrorDescription;

public class IncorrectVerificationCodeException extends BusinessLogicException {

private static final String code = "INCORRECT_VERIFICATION_CODE";
private static final String message = "인증 코드가 일치하지 않습니다.";

public IncorrectVerificationCodeException() {
super(ErrorDescription.of(code, message));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.auth.exception;

import es.princip.getp.infra.exception.ErrorDescription;
import es.princip.getp.infra.exception.NotFoundException;

public class NotFoundVerificationException extends NotFoundException {

private static final String code = "NOT_FOUND_VERIFICATION";
private static final String message = "존재하지 않는 인증입니다. 인증 요청 후 다시 시도해주세요.";

public NotFoundVerificationException() {
super(ErrorDescription.of(code, message));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package es.princip.getp.domain.auth.exception;

import es.princip.getp.infra.exception.BusinessLogicException;
import es.princip.getp.infra.exception.ErrorDescription;

public class NotVerifiedEmailException extends BusinessLogicException {

private static final String code = "NOT_VERIFIED_EMAIL";
private static final String message = "인증되지 않은 이메일입니다. 이메일 인증을 완료해주세요.";

public NotVerifiedEmailException() {
super(ErrorDescription.of(code, message));
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package es.princip.getp.domain.auth.application;

import es.princip.getp.domain.auth.application.command.SignUpCommand;
import es.princip.getp.domain.auth.exception.SignUpErrorCode;
import es.princip.getp.domain.auth.exception.DuplicatedEmailException;
import es.princip.getp.domain.auth.exception.NotVerifiedEmailException;
import es.princip.getp.domain.member.command.application.MemberService;
import es.princip.getp.domain.member.command.application.command.CreateMemberCommand;
import es.princip.getp.domain.member.command.domain.model.Email;
import es.princip.getp.domain.member.command.domain.model.Member;
import es.princip.getp.domain.member.command.domain.model.MemberRepository;
import es.princip.getp.domain.member.command.domain.model.MemberType;
import es.princip.getp.infra.exception.BusinessLogicException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
Expand All @@ -26,8 +26,7 @@
import static es.princip.getp.domain.member.fixture.EmailFixture.email;
import static es.princip.getp.domain.member.fixture.MemberFixture.member;
import static es.princip.getp.domain.member.fixture.PasswordFixture.password;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.*;

Expand Down Expand Up @@ -70,10 +69,8 @@ void sendEmailVerificationCodeForSignUp_WhenEmailIsDuplicated_ShouldThrowExcepti
Email email = Email.of(EMAIL);
given(memberRepository.existsByEmail(email)).willReturn(true);

BusinessLogicException exception =
assertThrows(BusinessLogicException.class,
() -> signUpService.sendEmailVerificationCodeForSignUp(email));
assertThat(exception.getErrorCode()).isEqualTo(SignUpErrorCode.DUPLICATED_EMAIL);
assertThatCode(() -> signUpService.sendEmailVerificationCodeForSignUp(email))
.isInstanceOf(DuplicatedEmailException.class);
}
}

Expand Down Expand Up @@ -103,15 +100,12 @@ void signUp() {
@DisplayName("이메일이 인증되지 않은 경우 실패한다.")
@Test
void signUp_WhenEmailIsNotVerified_ShouldThrowException() {
doThrow(new BusinessLogicException(SignUpErrorCode.NOT_VERIFIED_EMAIL))
doThrow(new NotVerifiedEmailException())
.when(emailVerificationService)
.verifyEmail(command.email(), command.verificationCode());

BusinessLogicException exception =
assertThrows(BusinessLogicException.class,
() -> signUpService.signUp(command));

assertThat(exception.getErrorCode()).isEqualTo(SignUpErrorCode.NOT_VERIFIED_EMAIL);
assertThatCode(() -> signUpService.signUp(command))
.isInstanceOf(NotVerifiedEmailException.class);
}
}
}
Loading

0 comments on commit 841b7de

Please sign in to comment.