Files
operationSystem-back/src/main/java/com/caliverse/admin/domain/service/AuthenticateService.java
2025-02-12 18:32:21 +09:00

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;
}
}