[api] 테스트 user 커밋

This commit is contained in:
2026-02-24 15:51:13 +09:00
parent 6e734f2b92
commit f293406661
9 changed files with 225 additions and 1 deletions
@@ -60,7 +60,7 @@ public class SecurityConfig {
.accessDeniedHandler(new JwtAccessDeniedHandler()) .accessDeniedHandler(new JwtAccessDeniedHandler())
) )
.authorizeHttpRequests(auth -> auth .authorizeHttpRequests(auth -> auth
.requestMatchers("/", "/actuator/health", "/auth/**", "/api/user/signup").permitAll() .requestMatchers("/", "/actuator/health", "/auth/**", "/api/testUser/signup").permitAll()
.anyRequest().authenticated() .anyRequest().authenticated()
) )
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
@@ -0,0 +1,39 @@
package com.alist.api.modules.testUser;
import com.alist.api.common.response.ApiResponse;
import com.alist.api.common.response.ApiResponseCode;
import com.alist.api.modules.testUser.dto.TestUserDto;
import com.alist.api.modules.testUser.form.TestUserSignupForm;
import com.alist.api.modules.testUser.service.TestUserService;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
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.RestController;
@Slf4j
@RestController
@RequestMapping("/api/testUser")
public class TestUserController {
public final TestUserService testUserService;
public TestUserController(TestUserService testUserService) {
this.testUserService = testUserService;
}
@PostMapping("/signup")
public ResponseEntity<ApiResponse<TestUserDto>> signup(@Valid @RequestBody TestUserSignupForm testUserSignupForm) {
TestUserDto userDto = testUserService.insertTestUserProc(testUserSignupForm.testUserDto());
if (userDto.getResultCode() == 2004) {
return ApiResponse.entity(userDto, ApiResponseCode.CODE_2004, "아이디");
}
return ApiResponse.entity(userDto, ApiResponseCode.CODE_2002, "아이디");
}
}
@@ -0,0 +1,19 @@
package com.alist.api.modules.testUser.dto;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class TestUserDto {
private Integer userIdx;
private String id;
@JsonIgnore
private String newPassword;
@JsonIgnore
private String password;
@JsonIgnore
private int resultCode;
}
@@ -0,0 +1,14 @@
package com.alist.api.modules.testUser.dto;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
public class TestUserTokenDto {
private int userTokenIdx;
private int userIdx;
private String userApiKey;
private String userRole;
private int resultCode;
}
@@ -0,0 +1,40 @@
package com.alist.api.modules.testUser.form;
import com.alist.api.modules.testUser.dto.TestUserDto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;
@Setter
@Getter
@Schema(description = "회원 가입 요청 폼")
public class TestUserSignupForm {
@Schema(
description = "사용자 아이디 (공백 불가)",
example = "test"
)
@NotBlank(message = "아이디를 입력해주세요.")
private String id;
@Schema(
description = "비밀번호 (8~64자, 영문 + 숫자 조합, 공백 불가)",
example = "pass1234"
)
@NotBlank(message = "비밀번호를 입력해주세요.")
@Size(min = 8, max = 64, message = "비밀번호는 8~64자여야 합니다.")
@Pattern(
regexp = "^(?=.*[A-Za-z])(?=.*\\d)\\S+$",
message = "비밀번호는 영문과 숫자를 포함하고 공백이 없어야 합니다."
)
private String password;
public TestUserDto testUserDto() {
TestUserDto testUserDto = new TestUserDto();
testUserDto.setId(id.trim());
testUserDto.setPassword(password);
return testUserDto;
}
}
@@ -0,0 +1,14 @@
package com.alist.api.modules.testUser.mapper;
import com.alist.api.modules.testUser.dto.TestUserDto;
import com.alist.api.modules.testUser.dto.TestUserTokenDto;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TestUserMapper {
int selectDuplicateTestUserCount(TestUserDto testUserDto);
int insertTestUserSignup(TestUserDto testUserDto);
int insertTestUserTokenSignup(TestUserTokenDto testUserTokenDto);
}
@@ -0,0 +1,65 @@
package com.alist.api.modules.testUser.service;
import com.alist.api.common.utils.ApiKeyGenerator;
import com.alist.api.modules.testUser.dto.TestUserDto;
import com.alist.api.modules.testUser.dto.TestUserTokenDto;
import com.alist.api.modules.testUser.mapper.TestUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Service
public class TestUserService {
private final TestUserMapper testUserMapper;
private final PasswordEncoder passwordEncoder;
public TestUserService(TestUserMapper testUserMapper, PasswordEncoder passwordEncoder) {
this.testUserMapper = testUserMapper;
this.passwordEncoder = passwordEncoder;
}
@Transactional
public TestUserDto insertTestUserProc(TestUserDto testUserDto) {
// 중복체크
if (testUserMapper.selectDuplicateTestUserCount(testUserDto) > 0) {
testUserDto.setResultCode(2004);
return testUserDto;
}
// 비밀번호 생성
testUserDto.setNewPassword(passwordEncoder.encode(testUserDto.getPassword()));
// 회원정보 입력
int result = testUserMapper.insertTestUserSignup(testUserDto);
if (result > 0) {
// user_api_key 생성
TestUserTokenDto testUserTokenDto = new TestUserTokenDto();
testUserTokenDto.setUserIdx(testUserDto.getUserIdx());
apiKeyWithRetry(testUserTokenDto);
}
log.info("cnt : " + testUserDto.getUserIdx());
log.info("userIdx : " + testUserDto.getUserIdx());
return testUserDto;
}
@Transactional
public int apiKeyWithRetry(TestUserTokenDto testUserTokenDto) {
for (int i = 0; i < 5; i++) {
testUserTokenDto.setUserApiKey(ApiKeyGenerator.userApiKeyProc());
try {
return testUserMapper.insertTestUserTokenSignup(testUserTokenDto);
} catch (DuplicateKeyException e) {
// 충돌이면 다시 생성
log.warn("Duplicate API key. retrying... userId={}", testUserTokenDto.getUserIdx());
}
}
throw new IllegalStateException("API key generation failed after retries.");
}
}
@@ -0,0 +1,8 @@
package com.alist.api.modules.testUser.vo;
import lombok.Getter;
@Getter
public class TestUserVo {
private String id;
}
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.alist.api.modules.testUser.mapper.TestUserMapper">
<insert id="insertTestUserSignup" useGeneratedKeys="true" keyProperty="userIdx">
/*UserSignupMapper.insertTestUserSignup*/
insert into test_user (id, password, del_yn, create_at, update_at)
value (#{id}, #{newPassword}, 1, now(), now())
</insert>
<insert id="insertTestUserTokenSignup" useGeneratedKeys="true" keyProperty="userTokenIdx">
/*UserSignupMapper.insertTestUserTokenSignup*/
insert into test_user_token (user_idx, user_api_key, user_role, created_at, updated_at)
value (#{userIdx}, #{userApiKey}, 'user', now(), now())
</insert>
<select id="selectDuplicateTestUserCount" resultType="int">
/*UserSignupMapper.selectDuplicateTestUserCount*/
select count(*)
from test_user
where id = #{id}
</select>
</mapper>