Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: 비밀번호 변경 아이디로 SMS 인증 번호 발급 API 추가 #72

Merged
merged 2 commits into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.readyvery.readyverydemo.security.oauth2.handler.OAuth2LoginFailureHandler;
import com.readyvery.readyverydemo.security.oauth2.handler.OAuth2LoginSuccessHandler;
import com.readyvery.readyverydemo.security.oauth2.service.CustomOAuth2UserService;
import com.readyvery.readyverydemo.src.ceo.CeoServiceFacade;

import lombok.RequiredArgsConstructor;

Expand All @@ -50,6 +51,7 @@ public class SpringSecurityConfig {
private final OAuth2LoginFailureHandler oAuth2LoginFailureHandler;
private final CustomOAuth2UserService customOAuth2UserService;
private final RefreshTokenRepository refreshTokenRepository;
private final CeoServiceFacade ceoServiceFacade;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
Expand Down Expand Up @@ -128,7 +130,7 @@ public PasswordEncoder passwordEncoder() {

@Bean
public LoginSuccessHandler loginSuccessHandler() {
return new LoginSuccessHandler(jwtService, refreshTokenRepository, ceoRepository);
return new LoginSuccessHandler(jwtService, refreshTokenRepository, ceoServiceFacade);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

import com.readyvery.readyverydemo.domain.CeoInfo;
import com.readyvery.readyverydemo.domain.repository.CeoRepository;
import com.readyvery.readyverydemo.redis.dao.RefreshToken;
import com.readyvery.readyverydemo.redis.repository.RefreshTokenRepository;
import com.readyvery.readyverydemo.security.jwt.service.JwtService;
import com.readyvery.readyverydemo.src.ceo.CeoServiceFacade;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
Expand All @@ -21,7 +21,7 @@ public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

private final JwtService jwtService;
private final RefreshTokenRepository refreshTokenRepository;
private final CeoRepository ceoRepository;
private final CeoServiceFacade ceoServiceFacade;

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Expand All @@ -42,8 +42,7 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo

private CeoInfo extractCeoInfo(Authentication authentication) {
UserDetails userDetails = (UserDetails)authentication.getPrincipal();
CeoInfo ceoInfo = ceoRepository.findByEmail(userDetails.getUsername())
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 사용자입니다."));
CeoInfo ceoInfo = ceoServiceFacade.getCeoInfoByEmail(userDetails.getUsername());
return ceoInfo;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,19 @@
import org.springframework.stereotype.Service;

import com.readyvery.readyverydemo.domain.CeoInfo;
import com.readyvery.readyverydemo.domain.repository.CeoRepository;
import com.readyvery.readyverydemo.src.ceo.CeoServiceFacade;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class CustomLoginCeoService implements UserDetailsService {

private final CeoRepository ceoRepository;
private final CeoServiceFacade ceoServiceFacade;

@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
CeoInfo ceoInfo = ceoRepository.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("해당 이메일이 존재하지 않습니다."));
CeoInfo ceoInfo = ceoServiceFacade.getCeoInfoByEmail(email);

return User.builder()
.username(ceoInfo.getEmail())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import com.readyvery.readyverydemo.src.ceo.dto.CeoAuthRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoDuplicateCheckReq;
import com.readyvery.readyverydemo.src.ceo.dto.CeoDuplicateCheckRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoExistEmailReq;
import com.readyvery.readyverydemo.src.ceo.dto.CeoExistEmailRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoFindEmailReq;
import com.readyvery.readyverydemo.src.ceo.dto.CeoFindEmailRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoFindPasswordReq;
Expand Down Expand Up @@ -188,4 +190,16 @@ public CeoFindPasswordRes findCeoPassword(@RequestBody CeoFindPasswordReq ceoFin
return ceoServiceImpl.findCeoPassword(ceoFindPasswordReq);
}

/**
* 패스워드 찾기(이메일 존재 여부 파악)
*/
@Operation(summary = " 패스워드 찾기(이메일 존재 여부 파악) ", description = "사장님의 패스워드 찾습니다.", tags = {"유저 정보"})
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK")
})
@PostMapping("/ceo/find/password/email")
public CeoExistEmailRes findCeoPasswordExistEmail(@RequestBody CeoExistEmailReq ceoExistEmailReq) {
return ceoServiceImpl.findCeoPasswordExistEmail(ceoExistEmailReq.getEmail());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.readyvery.readyverydemo.src.ceo.dto.CeoAuthRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoDuplicateCheckReq;
import com.readyvery.readyverydemo.src.ceo.dto.CeoDuplicateCheckRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoExistEmailRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoFindEmailRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoFindPasswordReq;
import com.readyvery.readyverydemo.src.ceo.dto.CeoFindPasswordRes;
Expand Down Expand Up @@ -38,4 +39,5 @@ public interface CeoService {

CeoFindPasswordRes findCeoPassword(CeoFindPasswordReq ceoFindPasswordReq);

CeoExistEmailRes findCeoPasswordExistEmail(String email);
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ public CeoInfo getCeoInfo(Long id) {
);
}

public CeoInfo getCeoInfoByEmail(String email) {
return ceoRepository.findByEmail(email).orElseThrow(
() -> new BusinessLogicException(ExceptionCode.USER_NOT_FOUND)
);
}

public void changeRoleAndSave(Long userId, Role role) {
CeoInfo ceoInfo = getCeoInfo(userId);
ceoInfo.changeRole(role);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.readyvery.readyverydemo.src.ceo.dto.CeoAuthRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoDuplicateCheckReq;
import com.readyvery.readyverydemo.src.ceo.dto.CeoDuplicateCheckRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoExistEmailRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoFindEmailRes;
import com.readyvery.readyverydemo.src.ceo.dto.CeoFindPasswordReq;
import com.readyvery.readyverydemo.src.ceo.dto.CeoFindPasswordRes;
Expand Down Expand Up @@ -105,6 +106,22 @@ public CeoFindPasswordRes findCeoPassword(CeoFindPasswordReq ceoFindPasswordReq)

}

@Override
public CeoExistEmailRes findCeoPasswordExistEmail(String email) {
CeoInfo ceoInfo = ceoServiceFacade.getCeoInfoByEmail(email);

return CeoExistEmailRes.builder()
.isSuccess(true)
.email(email)
.message(maskPhoneNumber(ceoInfo.getPhone()))
.build();

}

private String maskPhoneNumber(String phoneNumber) {
return phoneNumber.substring(0, 3) + "-****-**" + phoneNumber.substring(phoneNumber.length() - 2);
}

@Override
public CeoLogoutRes removeRefreshTokenInDB(CustomUserDetails userDetails, HttpServletResponse response) {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.readyvery.readyverydemo.src.ceo.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class CeoExistEmailReq {

private String email;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.readyvery.readyverydemo.src.ceo.dto;

import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
public class CeoExistEmailRes {

private boolean isSuccess;
private String email;
private String message;

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ public class CeoEntryApplicationServiceImpl implements CeoEntryApplicationServic
public CeoEntryApplicationRes entryApplication(Long userId, CeoEntryApplicationReq ceoEntryApplicationReq) {
// 1. 유저 정보 확인
CeoInfo ceoInfo = ceoServiceFacade.getCeoInfo(userId);
System.out.println("ceoInfo.getRole() = " + ceoInfo.getRole());
System.out.println("Role = " + Role.USER);

if (!ceoInfo.getRole().equals(Role.USER)) {
throw new BusinessLogicException(ExceptionCode.AUTH_ERROR);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendFindEmailReq;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendFindEmailRes;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendReq;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendRes;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsVerifyReq;
Expand All @@ -29,7 +31,7 @@ public class SmsController {
@PostMapping("/sms/send")
public SmsSendRes sendSms(
@RequestBody SmsSendReq smsSendReq) {
return smsServiceImpl.sendSms(smsSendReq);
return smsServiceImpl.sendSms(smsSendReq.getPhoneNumber());
}

@Operation(summary = "SMS 인증 번호 검증 기능", description = "SMS 인증 번호를 검증합니다.", tags = {"SMS 인증"})
Expand All @@ -42,4 +44,14 @@ public SmsVerifyRes verifySms(
return smsServiceImpl.verifySms(smsVerifyReq);
}

@Operation(summary = "아이디로 SMS 인증 번호 발급 기능", description = "아이디로 SMS 인증 번호를 발급합니다.", tags = {"SMS 인증"})
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK"),
})
@PostMapping("/sms/send/find-email")
public SmsSendFindEmailRes sendFindPasswordSms(
@RequestBody SmsSendFindEmailReq smsSendFindEmailReq) {
return smsServiceImpl.sendFindPasswordSms(smsSendFindEmailReq);
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.readyvery.readyverydemo.src.smsauthentication;

import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendReq;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendFindEmailReq;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendFindEmailRes;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendRes;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsVerifyReq;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsVerifyRes;

public interface SmsService {

SmsSendRes sendSms(SmsSendReq smsSendReq);
SmsSendRes sendSms(String phoneNumber);

SmsVerifyRes verifySms(SmsVerifyReq smsVerifyReq);

SmsSendFindEmailRes sendFindPasswordSms(SmsSendFindEmailReq smsSendFindEmailReq);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import org.springframework.stereotype.Service;

import com.readyvery.readyverydemo.config.SolApiConfig;
import com.readyvery.readyverydemo.domain.CeoInfo;
import com.readyvery.readyverydemo.global.exception.BusinessLogicException;
import com.readyvery.readyverydemo.global.exception.ExceptionCode;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendReq;
import com.readyvery.readyverydemo.src.ceo.CeoServiceFacade;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendFindEmailReq;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendFindEmailRes;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsSendRes;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsVerifyReq;
import com.readyvery.readyverydemo.src.smsauthentication.dto.SmsVerifyRes;
Expand All @@ -22,18 +25,19 @@ public class SmsServiceImpl implements SmsService {
private final SolApiConfig solApiConfig;
private final MessageSendingService messageSendingService;
private final VerificationService verificationService;
private final CeoServiceFacade ceoServiceFacade;

@Override
public SmsSendRes sendSms(SmsSendReq smsSendReq) {
public SmsSendRes sendSms(String phoneNumber) {
// Message 패키지가 중복될 경우 net.nurigo.sdk.message.model.Message로 치환하여 주세요

if (StringUtils.isEmpty(smsSendReq.getPhoneNumber())) {
if (StringUtils.isEmpty(phoneNumber)) {
throw new BusinessLogicException(ExceptionCode.INVALID_INPUT);
}

String code = verificationService.createVerificationCode(smsSendReq.getPhoneNumber(), false);
String code = verificationService.createVerificationCode(phoneNumber, false);
String messageContent = "[Readyvery] 아래의 인증번호를 입력해주세요.\n인증번호 : " + code;
boolean isMessageSent = messageSendingService.sendMessage(smsSendReq.getPhoneNumber(),
boolean isMessageSent = messageSendingService.sendMessage(phoneNumber,
solApiConfig.getPhoneNumber(), messageContent);

if (isMessageSent) {
Expand Down Expand Up @@ -74,4 +78,19 @@ public SmsVerifyRes verifySms(SmsVerifyReq smsVerifyReq) {

}

@Override
public SmsSendFindEmailRes sendFindPasswordSms(SmsSendFindEmailReq smsSendFindEmailReq) {
if (StringUtils.isEmpty(smsSendFindEmailReq.getEmail())) {
throw new BusinessLogicException(ExceptionCode.INVALID_INPUT);
}
CeoInfo ceoInfo = ceoServiceFacade.getCeoInfoByEmail(smsSendFindEmailReq.getEmail());
SmsSendRes sendSms = sendSms(ceoInfo.getPhone());

return SmsSendFindEmailRes.builder()
.isSuccess(sendSms.isSuccess())
.message(sendSms.getSmsMessage())
.build();

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.readyvery.readyverydemo.src.smsauthentication.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class SmsSendFindEmailReq {

private String email;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.readyvery.readyverydemo.src.smsauthentication.dto;

import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
public class SmsSendFindEmailRes {

private boolean isSuccess;
private String message;
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void testSendSms() {
true); // sendMessage의 결과를 모킹

// when
SmsSendRes response = smsService.sendSms(request);
SmsSendRes response = smsService.sendSms(request.getPhoneNumber());

// then
assertTrue(response.isSuccess());
Expand Down
Loading