Skip to content

Commit 6860ebf

Browse files
authored
Merge branch 'develop' into feature/ringus-31
2 parents b61e3a5 + 7b2c454 commit 6860ebf

File tree

19 files changed

+443
-44
lines changed

19 files changed

+443
-44
lines changed

src/main/java/es/princip/ringus/application/auth/service/AuthService.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package es.princip.ringus.application.auth.service;
22

3+
4+
import es.princip.ringus.application.member.service.MemberService;
35
import es.princip.ringus.application.serviceTerm.ServiceTermAgreementService;
4-
import es.princip.ringus.domain.serviceTerm.ServiceTermAgreement;
6+
import es.princip.ringus.domain.email.EmailSessionRepository;
7+
import es.princip.ringus.domain.member.Member;
58
import es.princip.ringus.presentation.auth.dto.request.LoginRequest;
6-
import es.princip.ringus.presentation.auth.dto.response.LoginResponse;
79
import es.princip.ringus.presentation.auth.dto.request.SignUpRequest;
10+
import es.princip.ringus.presentation.auth.dto.response.LoginResponse;
811
import es.princip.ringus.presentation.auth.dto.response.SignUpResponse;
9-
import es.princip.ringus.application.member.service.MemberService;
10-
import es.princip.ringus.domain.member.Member;
1112
import jakarta.servlet.http.HttpSession;
1213
import lombok.RequiredArgsConstructor;
1314
import org.springframework.stereotype.Service;
@@ -24,14 +25,17 @@ public class AuthService {
2425
private final EmailVerificationService verificationService;
2526
private final MemberService memberService;
2627
private final ServiceTermAgreementService serviceTermAgreementService;
28+
private final EmailSessionRepository emailSessionRepository;
2729

2830
@Transactional
29-
public SignUpResponse signUp(SignUpRequest request){
30-
verificationService.verifySession(request.email());
31+
public SignUpResponse signUp(SignUpRequest request, HttpSession session){
32+
String sessionId = session.getId();
33+
34+
verificationService.verifySession(request.email(), session);
3135

32-
Set<ServiceTermAgreement> serviceTerm = serviceTermAgreementService.validateAndCreateAgreements(request.serviceTerms());
36+
Member member = memberService.createMember(request, serviceTermAgreementService.validateAndCreateAgreements(request.serviceTerms()));
3337

34-
Member member = memberService.createMember(request, serviceTerm);
38+
emailSessionRepository.deleteById(sessionId);
3539

3640
return new SignUpResponse(member.getId());
3741
}

src/main/java/es/princip/ringus/application/auth/service/EmailVerificationService.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22

33
import es.princip.ringus.domain.email.EmailSession;
44
import es.princip.ringus.domain.email.EmailSessionRepository;
5-
import es.princip.ringus.domain.email.EmailVerificationRepository;
65
import es.princip.ringus.domain.email.EmailVerification;
6+
import es.princip.ringus.domain.email.EmailVerificationRepository;
77
import es.princip.ringus.domain.exception.EmailErrorCode;
88
import es.princip.ringus.domain.exception.SignUpErrorCode;
99
import es.princip.ringus.domain.member.MemberRepository;
1010
import es.princip.ringus.global.exception.CustomRuntimeException;
11+
import jakarta.annotation.PostConstruct;
12+
import jakarta.servlet.http.HttpSession;
1113
import jakarta.transaction.Transactional;
1214
import lombok.RequiredArgsConstructor;
15+
import org.springframework.beans.factory.annotation.Value;
1316
import org.springframework.stereotype.Service;
1417

18+
import java.util.Objects;
19+
1520
@Service
1621
@RequiredArgsConstructor
1722
public class EmailVerificationService {
@@ -21,6 +26,14 @@ public class EmailVerificationService {
2126
private final MemberRepository memberRepository;
2227
private final EmailSendService emailSendService;
2328

29+
@Value("${verification.max-failed-attempts}")
30+
private int maxFailedAttempts;
31+
32+
@PostConstruct
33+
public void init(){
34+
EmailVerification.setMaxFailedAttempts(maxFailedAttempts);
35+
}
36+
2437
@Transactional
2538
public void generateVerificationCode(String email) {
2639
if(memberRepository.existsByEmail(email)){
@@ -42,7 +55,7 @@ public void generateVerificationCode(String email) {
4255
* @throws CustomRuntimeException
4356
*/
4457
@Transactional
45-
public void verifyCode(String email, String inputCode){
58+
public void verifyCode(String email, String inputCode, HttpSession session){
4659
EmailVerification verification = verificationRepository.findById(email)
4760
.orElseThrow(() -> new CustomRuntimeException(EmailErrorCode.TTL_EXPIRED));
4861

@@ -57,7 +70,11 @@ public void verifyCode(String email, String inputCode){
5770
}
5871

5972
verificationRepository.delete(verification);
60-
sessionRepository.save(EmailSession.of(email));
73+
74+
String sessionId = session.getId();
75+
76+
sessionRepository.save(EmailSession.of(email, sessionId));
77+
6178
}
6279

6380
/**
@@ -66,8 +83,14 @@ public void verifyCode(String email, String inputCode){
6683
* @throws CustomRuntimeException
6784
*/
6885
@Transactional
69-
public void verifySession(String email){
70-
EmailSession emailSession = sessionRepository.findByEmail(email)
86+
public void verifySession(String email, HttpSession session){
87+
EmailSession emailSession = sessionRepository.findById(email)
7188
.orElseThrow(() -> new CustomRuntimeException(EmailErrorCode.TTL_EXPIRED));
89+
90+
if(!Objects.equals(emailSession.getSessionId(), session.getId())){
91+
throw new CustomRuntimeException(EmailErrorCode.SESSION_EMAIL_MISMATCH);
92+
}
93+
94+
sessionRepository.delete(emailSession);
7295
}
7396
}

src/main/java/es/princip/ringus/application/member/service/MemberService.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package es.princip.ringus.application.member.service;
22

3-
import es.princip.ringus.domain.serviceTerm.ServiceTermAgreement;
4-
import es.princip.ringus.presentation.auth.dto.request.SignUpRequest;
3+
import es.princip.ringus.domain.exception.MemberErrorCode;
54
import es.princip.ringus.domain.exception.SignUpErrorCode;
65
import es.princip.ringus.domain.member.Member;
76
import es.princip.ringus.domain.member.MemberRepository;
7+
import es.princip.ringus.domain.serviceTerm.ServiceTermAgreement;
88
import es.princip.ringus.global.exception.CustomRuntimeException;
9+
import es.princip.ringus.global.util.UniversityDomainUtil;
10+
import es.princip.ringus.presentation.auth.dto.request.SignUpRequest;
11+
import es.princip.ringus.presentation.member.dto.MemberResponse;
912
import lombok.RequiredArgsConstructor;
1013
import org.springframework.security.crypto.password.PasswordEncoder;
1114
import org.springframework.stereotype.Service;
@@ -31,14 +34,19 @@ public Member createMember(SignUpRequest request, Set<ServiceTermAgreement> serv
3134
throw new CustomRuntimeException(SignUpErrorCode.DUPLICATE_EMAIL);
3235
}
3336

34-
Member member = Member.of(request.email(), request.password(), passwordEncoder, request.memberType(), serviceTerm);
37+
boolean isUniversityVerified = UniversityDomainUtil.isUniversityVerified(request.email());
38+
39+
Member member = Member.of(request.email(), request.password(), passwordEncoder, request.memberType(), serviceTerm, isUniversityVerified);
40+
3541
memberRepository.save(member);
3642

3743
return member;
3844
}
3945

40-
public Member getByMemberId(Long memberId) {
41-
return memberRepository.findById(memberId).orElseThrow();
42-
}
46+
public MemberResponse getMemberById(Long memberId){
47+
Member member = memberRepository.findById(memberId)
48+
.orElseThrow(() -> new CustomRuntimeException(MemberErrorCode.MEMBER_NOT_FOUND));
4349

50+
return MemberResponse.from(member);
51+
}
4452
}

src/main/java/es/princip/ringus/domain/email/EmailSession.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ public class EmailSession implements Serializable {
1515

1616
@Id
1717
private String email;
18+
private String sessionId;
1819

19-
public static EmailSession of(String email) {
20-
return new EmailSession(email);
20+
public static EmailSession of(String email, String sessionId) {
21+
return new EmailSession(email, sessionId);
2122
}
2223

23-
private EmailSession(String email) {
24+
private EmailSession(String email, String sessionId) {
2425
this.email = email;
26+
this.sessionId = sessionId;
2527
}
2628
}

src/main/java/es/princip/ringus/domain/email/EmailVerification.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.NoArgsConstructor;
66
import org.springframework.data.annotation.Id;
77
import org.springframework.data.redis.core.RedisHash;
8+
89
import java.io.Serializable;
910
import java.util.Random;
1011

@@ -26,6 +27,8 @@ public class EmailVerification implements Serializable {
2627

2728
private int failedAttempts;
2829

30+
private static int maxFailedAttempts;
31+
2932
public static EmailVerification of(String email) {
3033
return new EmailVerification(email, generateVerificationCode());
3134
}
@@ -45,10 +48,14 @@ public void plusFailedAttempts() {
4548
}
4649

4750
public boolean hasVerificationAttemptsLeft() {
48-
return failedAttempts < 5;
51+
return failedAttempts < maxFailedAttempts;
4952
}
5053

5154
public boolean isValid(String inputCode) {
5255
return this.verificationCode.equals(inputCode);
5356
}
57+
58+
public static void setMaxFailedAttempts(int maxFailedAttempts) {
59+
EmailVerification.maxFailedAttempts = maxFailedAttempts;
60+
}
5461
}

src/main/java/es/princip/ringus/domain/exception/EmailErrorCode.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ public enum EmailErrorCode implements ErrorCode {
88
SUCESSS_VALILDATION(HttpStatus.OK, "성공적으로 인증되었습니다"),
99
TTL_EXPIRED(HttpStatus.FORBIDDEN, "TTL 만료"),
1010
ERROR_EXCEEDED_ATTEMPTS(HttpStatus.FORBIDDEN, "인증번호 틀림 횟수 5회 이상, 새로운 인증번호를 발급 받아주세요"),
11-
ERROR_INVALID_CODE(HttpStatus.BAD_REQUEST, "인증번호가 틀립니다");
11+
ERROR_INVALID_CODE(HttpStatus.BAD_REQUEST, "인증번호가 틀립니다"),
12+
SESSION_NOT_FOUND(HttpStatus.NOT_FOUND, "세션을 찾을 수 없음"),
13+
SESSION_EMAIL_MISMATCH(HttpStatus.BAD_REQUEST, "요청된 이메일과 인증된 이메일이 다름");
1214

1315
EmailErrorCode(HttpStatus status, String message) {
1416
this.status = status;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package es.princip.ringus.domain.exception;
2+
3+
import es.princip.ringus.global.exception.ErrorCode;
4+
import org.springframework.http.HttpStatus;
5+
6+
public enum MemberErrorCode implements ErrorCode {
7+
8+
SESSION_EXPIRED(HttpStatus.UNAUTHORIZED, "세션이 거부됨"),
9+
MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "멤버를 찾을 수 없음");
10+
11+
MemberErrorCode(HttpStatus status, String message) {
12+
this.status = status;
13+
this.message = message;
14+
}
15+
16+
private final HttpStatus status;
17+
private final String message;
18+
19+
@Override
20+
public HttpStatus status() {
21+
return this.status;
22+
}
23+
24+
@Override
25+
public String message() {
26+
return this.message;
27+
}
28+
29+
@Override
30+
public String code() {
31+
return this.name();
32+
}
33+
}

src/main/java/es/princip/ringus/domain/member/Member.java

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,33 @@ public class Member extends BaseTimeEntity {
3030
@Enumerated(EnumType.STRING)
3131
private MemberType memberType;
3232

33-
@ElementCollection(fetch = FetchType.EAGER)
33+
@ElementCollection(fetch = FetchType.LAZY)
3434
@CollectionTable(name = "service_term_agreement", joinColumns = @JoinColumn(name = "member_id"))
3535
private Set<ServiceTermAgreement> serviceTerms;
3636

37+
private boolean isFileVerified;
38+
39+
private boolean isProfileRegistered;
40+
41+
private boolean isUniversityVerified;
42+
43+
@OneToOne(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true)
44+
private User user;
45+
3746
public static Member of(
3847
final String email,
3948
final String password,
4049
final PasswordEncoder passwordEncoder,
4150
final String memberType,
42-
final Set<ServiceTermAgreement> serviceTerms
51+
final Set<ServiceTermAgreement> serviceTerms,
52+
final boolean isUniversityVerified
4353
) {
4454
return new Member(
4555
MemberType.valueOf(memberType),
4656
passwordEncoder.encode(password),
4757
email,
48-
serviceTerms
58+
serviceTerms,
59+
isUniversityVerified
4960
);
5061
}
5162

@@ -54,12 +65,27 @@ public Member(
5465
final MemberType memberType,
5566
final String password,
5667
final String email,
57-
final Set<ServiceTermAgreement> serviceTerms
58-
68+
final Set<ServiceTermAgreement> serviceTerms,
69+
final Boolean isUniversityVerified
5970
) {
6071
this.memberType = memberType;
6172
this.password = password;
6273
this.email = email;
6374
this.serviceTerms = serviceTerms;
75+
this.isFileVerified = false;
76+
this.isProfileRegistered = false;
77+
this.isUniversityVerified = isUniversityVerified;
78+
}
79+
80+
public void verifyFile() {
81+
this.isFileVerified = true;
82+
}
83+
84+
public void registerProfile() {
85+
this.isProfileRegistered = true;
86+
}
87+
88+
public void confirmUniversity() {
89+
this.isUniversityVerified = true;
6490
}
6591
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package es.princip.ringus.global.interceptor;
2+
3+
import es.princip.ringus.domain.exception.MemberErrorCode;
4+
import es.princip.ringus.global.exception.CustomRuntimeException;
5+
import es.princip.ringus.global.util.CookieUtil;
6+
import jakarta.servlet.http.HttpServletRequest;
7+
import jakarta.servlet.http.HttpServletResponse;
8+
import jakarta.servlet.http.HttpSession;
9+
import org.springframework.stereotype.Component;
10+
import org.springframework.web.servlet.HandlerInterceptor;
11+
12+
@Component
13+
public class SessionInterceptor implements HandlerInterceptor {
14+
@Override
15+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
16+
HttpSession session = request.getSession(false);
17+
if(session == null){
18+
throw new CustomRuntimeException(MemberErrorCode.SESSION_EXPIRED);
19+
}
20+
CookieUtil.addSessionCookie(response, session.getId());
21+
return true;
22+
}
23+
}

0 commit comments

Comments
 (0)