package com.interplug.qcast.biz.login; import com.interplug.qcast.biz.login.dto.JoinUser; import com.interplug.qcast.biz.login.dto.LoginUser; import com.interplug.qcast.biz.login.dto.UserLoginResponse; import com.interplug.qcast.biz.login.dto.UserPassword; import com.interplug.qcast.biz.login.dto.UserResponse; import com.interplug.qcast.config.Exception.ErrorCode; import com.interplug.qcast.config.Exception.QcastException; import com.interplug.qcast.config.message.Messages; import com.interplug.qcast.util.DefaultResponse; import io.swagger.v3.oas.annotations.Operation; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; @Slf4j @RestController @RequestMapping("/api/login") @RequiredArgsConstructor public class LoginController { // @Autowired private LoginService loginService; private final LoginService loginService; @Autowired Messages message; @Value("${qsp.aes256.key}") String loginPasswordAesKey; @Value("${qsp.auto.login.aes256.key}") String autoLoginAesKey; /** * Q.CAST III에 로그인하여 사용자 정보를 획득한다. * * @param loginUser LoginUser * @return UserLoginResponse * @throws Exception */ @Operation(description = "Q.CAST III에 로그인하여 사용자 정보를 획득한다.") @PostMapping("/v1.0/login") @ResponseStatus(HttpStatus.CREATED) public UserLoginResponse login(@RequestBody LoginUser loginUser) throws Exception { return loginService.getLogin(loginUser); } @PostMapping("/v1.0/user") @ResponseStatus(HttpStatus.CREATED) public UserResponse getUser(@RequestBody LoginUser loginUser) { return loginService.getUser(loginUser); } /** * 가입 신청 정보를 등록한다. * * @param joinUser JoinUser * @return DefaultResponse * @throws Exception */ @Operation(description = "가입 신청 정보를 등록한다.") @PostMapping("/v1.0/user/join") @ResponseStatus(HttpStatus.CREATED) public DefaultResponse joinUser(@RequestBody JoinUser joinUser) throws Exception { return loginService.joinUser(joinUser); } /** * 비밀번호를 초기화한다. * * @param userPassword UserPassword * @return DefaultResponse * @throws Exception */ @Operation(description = "비밀번호를 초기화한다.") @PatchMapping("/v1.0/user/init-password") public DefaultResponse initPassword(@RequestBody UserPassword userPassword) throws Exception { return loginService.initPassword(userPassword); } /** * 비밀번호를 변경한다. * * @param userPassword UserPassword * @return DefaultResponse * @throws Exception */ @Operation(description = "비밀번호를 변경한다.") @PatchMapping("/v1.0/user/change-password") public DefaultResponse changePassword(@RequestBody UserPassword userPassword) throws Exception { return loginService.changePassword(userPassword); } /** * 자동 로그인에 사용하는 아이디를 암호화한다. * * @param loginUser LoginUser * @return String * @throws Exception */ @Operation(description = "자동 로그인에 사용하는 아이디를 암호화한다.") @PostMapping("/v1.0/user/login/autoLoginEncryptData") public String getAutoLoginEncryptData(@RequestBody LoginUser loginUser) throws Exception { String loginEncryptId = ""; if ("".equals(loginUser.getLoginId()) || loginUser.getLoginId() == null) { throw new QcastException( ErrorCode.INVALID_INPUT_VALUE, message.getMessage("common.message.required.data", "User Id")); } try { // [0]. AES 암호화 키 : 날짜(YYYYMMDD) + autoLoginAesKey LocalDate today = LocalDate.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); String formattedDate = today.format(formatter); String encryptKey = formattedDate + autoLoginAesKey; // [1]. 암호화 진행 byte[] keyData = loginPasswordAesKey.getBytes(); SecretKey secureKey = new SecretKeySpec(keyData, "AES"); Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init( Cipher.ENCRYPT_MODE, secureKey, new IvParameterSpec(encryptKey.substring(0, 16).getBytes())); byte[] encrypted = c.doFinal(loginUser.getLoginId().getBytes("UTF-8")); // [2]. 암호화 값 셋팅 loginEncryptId = new String(Base64.getEncoder().encode(encrypted)); ; } catch (Exception e) { throw new QcastException( ErrorCode.INTERNAL_SERVER_ERROR, message.getMessage("common.message.error")); } return loginEncryptId; } /** * 자동 로그인에 사용하는 아이디를 복호화한다. * * @param loginUser LoginUser * @return String * @throws Exception */ @Operation(description = "자동 로그인에 사용하는 아이디를 복호화한다.") @PostMapping("/v1.0/user/login/autoLoginDecryptData") public String getAutoLoginDecryptData(@RequestBody LoginUser loginUser) throws Exception { String loginDecryptId = ""; if ("".equals(loginUser.getLoginId()) || loginUser.getLoginId() == null) { throw new QcastException( ErrorCode.INVALID_INPUT_VALUE, message.getMessage("common.message.required.data", "User Id")); } try { // [0]. AES 암호화 키 : 날짜(YYYYMMDD) + autoLoginAesKey LocalDate today = LocalDate.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); String formattedDate = today.format(formatter); String decryptKey = formattedDate + autoLoginAesKey; // [1]. 복호화 진행 byte[] keyData = loginPasswordAesKey.getBytes(); SecretKey secureKey = new SecretKeySpec(keyData, "AES"); Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding"); c.init( Cipher.DECRYPT_MODE, secureKey, new IvParameterSpec(decryptKey.substring(0, 16).getBytes("UTF-8"))); byte[] byteStr = Base64.getDecoder().decode(loginUser.getLoginId().getBytes()); // [2]. 복호화 값 셋팅 loginDecryptId = new String(c.doFinal(byteStr), "UTF-8"); } catch (Exception e) { throw new QcastException( ErrorCode.INTERNAL_SERVER_ERROR, message.getMessage("common.message.error")); } return loginDecryptId; } }