151 lines
6.4 KiB
Java
151 lines
6.4 KiB
Java
package com.caliverse.admin.domain.service;
|
|
|
|
import com.caliverse.admin.domain.dao.admin.AdminMapper;
|
|
import com.caliverse.admin.domain.dao.admin.TokenMapper;
|
|
import com.caliverse.admin.domain.entity.Admin;
|
|
import com.caliverse.admin.domain.entity.STATUS;
|
|
import com.caliverse.admin.domain.entity.Token;
|
|
import com.caliverse.admin.domain.request.AuthenticateRequest;
|
|
import com.caliverse.admin.domain.response.AuthenticateResponse;
|
|
import com.caliverse.admin.global.common.code.CommonCode;
|
|
import com.caliverse.admin.global.common.code.ErrorCode;
|
|
import com.caliverse.admin.global.common.code.SuccessCode;
|
|
import com.caliverse.admin.global.common.exception.RestApiException;
|
|
import com.caliverse.admin.global.common.utils.CommonUtils;
|
|
import com.caliverse.admin.global.configuration.JwtService;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.security.authentication.AuthenticationManager;
|
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
import org.springframework.security.core.AuthenticationException;
|
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.time.LocalDateTime;
|
|
import java.time.ZoneId;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.temporal.ChronoUnit;
|
|
|
|
@Slf4j
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
public class AuthenticateService{
|
|
|
|
private final AdminMapper userMapper;
|
|
private final TokenMapper tokenMapper;
|
|
private final AuthenticationManager authenticationManager;
|
|
private final JwtService jwtService;
|
|
private final PasswordEncoder passwordEncoder;
|
|
private final HistoryService historyService;
|
|
@Value("${password.expiration-days}")
|
|
private int passwordExpiration;
|
|
|
|
// 로그인
|
|
public AuthenticateResponse login(AuthenticateRequest authenticateRequest) {
|
|
|
|
String email = authenticateRequest.getEmail();
|
|
String pw = authenticateRequest.getPassword();
|
|
// 삭제 계정 여부
|
|
if(!userMapper.existsByEmail(email)){
|
|
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_MATCH_USER.getMessage());
|
|
}
|
|
|
|
try {
|
|
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken( email, pw ));
|
|
}catch (AuthenticationException authException){
|
|
// 인증에 실패하면 예외가 발생 AuthenticationException 떨어짐
|
|
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_FOUND_USER.getMessage());
|
|
}
|
|
|
|
Admin admin = userMapper.findByEmail(authenticateRequest.getEmail())
|
|
.orElseThrow(() -> new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_MATCH_USER.getMessage()));
|
|
|
|
//비번 기간 만료
|
|
if (isPasswordExpired(admin.getPwUpdateDt())){
|
|
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.PWD_EXPIRATION.getMessage()
|
|
+"("+admin.getPwUpdateDt().plus(passwordExpiration,ChronoUnit.DAYS)
|
|
.atZone(ZoneId.of("UTC"))
|
|
.withZoneSameInstant(ZoneId.of("Asia/Seoul"))
|
|
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))+" 종료)");
|
|
}
|
|
|
|
if(admin.getStatus().name().equals("ROLE_NOT_PERMITTED") || admin.getStatus().name().equals("REJECT")){
|
|
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.NOT_PERMITTED.getMessage());
|
|
}
|
|
int tokenCnt = tokenMapper.getCount(admin.getId());
|
|
if(tokenCnt > 1){
|
|
tokenMapper.updateResetToken(admin.getId());
|
|
}
|
|
|
|
var jwtToken = jwtService.generateToken(admin);
|
|
var refreshToken = jwtService.generateRefreshToken(admin);
|
|
revokeAllUserTokens(admin);
|
|
saveUserToken(admin.getId(), jwtToken);
|
|
|
|
log.info("login id: {}, token: {}", admin.getId(), jwtToken);
|
|
|
|
return AuthenticateResponse.builder()
|
|
.status(CommonCode.SUCCESS.getHttpStatus())
|
|
.result(CommonCode.SUCCESS.getResult())
|
|
.authValue(new AuthenticateResponse.AuthValue(jwtToken, refreshToken,String.valueOf(admin.getStatus())))
|
|
.build();
|
|
}
|
|
|
|
//회원가입
|
|
public AuthenticateResponse register(AuthenticateRequest authenticateRequest){
|
|
|
|
if(userMapper.existsByEmail(authenticateRequest.getEmail())){
|
|
throw new RestApiException(CommonCode.ERROR.getHttpStatus(), ErrorCode.DUPLICATED_EMAIL.getMessage());
|
|
}
|
|
|
|
Admin admin = Admin.builder()
|
|
// .status(STATUS.ROLE_NOT_PERMITTED) //2024.08.02 즉시 회원가입되게 변경
|
|
.groupId((long)2)
|
|
.status(STATUS.PERMITTED)
|
|
.name(authenticateRequest.getName())
|
|
.email(authenticateRequest.getEmail())
|
|
.password(passwordEncoder.encode(authenticateRequest.getPassword()))
|
|
.build();
|
|
|
|
userMapper.save(admin);
|
|
log.info("register Sign Up : {}", admin);
|
|
return AuthenticateResponse.builder()
|
|
.status(CommonCode.SUCCESS.getHttpStatus())
|
|
.result(CommonCode.SUCCESS.getResult())
|
|
.authValue(AuthenticateResponse.AuthValue.builder().message(SuccessCode.SAVE.getMessage()).build())
|
|
.build();
|
|
}
|
|
|
|
// 토큰 저장
|
|
private void saveUserToken(Long memberId, String jwtToken) {
|
|
var token = Token.builder()
|
|
.adminId(memberId)
|
|
.token(jwtToken)
|
|
.tokenType(Token.TokenType.BEARER)
|
|
.expired(false)
|
|
.revoked(false)
|
|
.build();
|
|
tokenMapper.save(token);
|
|
}
|
|
|
|
//토큰 삭제
|
|
private void revokeAllUserTokens(Admin member) {
|
|
var validUserTokens = tokenMapper.findAllValidTokenByUser(member.getId()).orElse(null);
|
|
if(validUserTokens!=null){
|
|
validUserTokens.setExpired(true);
|
|
validUserTokens.setRevoked(true);
|
|
tokenMapper.updateToken(validUserTokens);
|
|
}
|
|
}
|
|
|
|
public boolean isPasswordExpired(LocalDateTime lastPasswordChangeDateTime) {
|
|
LocalDateTime currentDateTime = LocalDateTime.now();
|
|
LocalDateTime minusDate = currentDateTime.minusDays(passwordExpiration);
|
|
|
|
boolean isAfter = minusDate.isAfter(lastPasswordChangeDateTime);
|
|
|
|
return isAfter;
|
|
}
|
|
}
|