spotlessApply 적용

This commit is contained in:
2025-12-11 13:47:57 +09:00
parent ec19cf533a
commit d798dc16f9
14 changed files with 261 additions and 279 deletions

View File

@@ -28,9 +28,9 @@ public class CustomAuthenticationProvider implements AuthenticationProvider {
// 1. 유저 조회
MemberEntity member =
membersRepository
.findByUserId(username)
.orElseThrow(() -> new CustomApiException(AuthErrorCode.LOGIN_ID_NOT_FOUND));
membersRepository
.findByUserId(username)
.orElseThrow(() -> new CustomApiException(AuthErrorCode.LOGIN_ID_NOT_FOUND));
// 2. jBCrypt + 커스텀 salt 로 저장된 패스워드 비교
if (!BCrypt.checkpw(rawPassword, member.getPassword())) {

View File

@@ -219,7 +219,7 @@ public class CommonCodeApiController {
// .map(Clazzes::new)
// .toList();
//변화탐지 clazz API : enum -> 공통코드로 변경
// 변화탐지 clazz API : enum -> 공통코드로 변경
List<CommonCodeDto.Clazzes> list =
commonCodeUtil.getChildCodesByParentCode("0000").stream()
.map(

View File

@@ -8,17 +8,11 @@ import org.springframework.http.HttpStatus;
public enum AuthErrorCode implements ErrorCode {
// 🔐 로그인 관련
LOGIN_ID_NOT_FOUND(
"LOGIN_ID_NOT_FOUND",
HttpStatus.UNAUTHORIZED),
LOGIN_ID_NOT_FOUND("LOGIN_ID_NOT_FOUND", HttpStatus.UNAUTHORIZED),
LOGIN_PASSWORD_MISMATCH(
"LOGIN_PASSWORD_MISMATCH",
HttpStatus.UNAUTHORIZED),
LOGIN_PASSWORD_MISMATCH("LOGIN_PASSWORD_MISMATCH", HttpStatus.UNAUTHORIZED),
LOGIN_PASSWORD_EXCEEDED(
"LOGIN_PASSWORD_EXCEEDED",
HttpStatus.UNAUTHORIZED);
LOGIN_PASSWORD_EXCEEDED("LOGIN_PASSWORD_EXCEEDED", HttpStatus.UNAUTHORIZED);
private final String code;
private final HttpStatus status;

View File

@@ -30,33 +30,33 @@ public class SecurityConfig {
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.csrf(csrf -> csrf.disable()) // CSRF 보안 기능 비활성화
.sessionManagement(
sm ->
sm.sessionCreationPolicy(
SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음, 요청은 JWT 인증
.formLogin(form -> form.disable()) // react에서 로그인 요청 관리
.httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용
.logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음
.authenticationProvider(
customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용
.authorizeHttpRequests(
auth ->
auth.requestMatchers(HttpMethod.OPTIONS, "/**")
.permitAll() // preflight 허용
.requestMatchers(
"/api/auth/signin",
"/api/auth/refresh",
"/swagger-ui/**",
"/api/members/{memberId}/password",
"/v3/api-docs/**")
.permitAll()
.anyRequest()
.authenticated())
.addFilterBefore(
jwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter
.class) // 요청 들어오면 먼저 JWT 토큰 검사 후 security context 에 사용자 정보 저장.
.csrf(csrf -> csrf.disable()) // CSRF 보안 기능 비활성화
.sessionManagement(
sm ->
sm.sessionCreationPolicy(
SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음, 요청은 JWT 인증
.formLogin(form -> form.disable()) // react에서 로그인 요청 관리
.httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용
.logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음
.authenticationProvider(
customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용
.authorizeHttpRequests(
auth ->
auth.requestMatchers(HttpMethod.OPTIONS, "/**")
.permitAll() // preflight 허용
.requestMatchers(
"/api/auth/signin",
"/api/auth/refresh",
"/swagger-ui/**",
"/api/members/{memberId}/password",
"/v3/api-docs/**")
.permitAll()
.anyRequest()
.authenticated())
.addFilterBefore(
jwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter
.class) // 요청 들어오면 먼저 JWT 토큰 검사 후 security context 에 사용자 정보 저장.
;
return http.build();
@@ -64,7 +64,7 @@ public class SecurityConfig {
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration)
throws Exception {
throws Exception {
return configuration.getAuthenticationManager();
}

View File

@@ -20,11 +20,9 @@ public class ApiResponseDto<T> {
@JsonInclude(JsonInclude.Include.NON_NULL)
private T errorData;
@JsonIgnore
private HttpStatus httpStatus;
@JsonIgnore private HttpStatus httpStatus;
@JsonIgnore
private Long errorLogUid;
@JsonIgnore private Long errorLogUid;
public ApiResponseDto(T data) {
this.data = data;
@@ -49,7 +47,7 @@ public class ApiResponseDto<T> {
}
public ApiResponseDto(
ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
this.error = new Error(code.getId(), message);
this.httpStatus = httpStatus;
this.errorLogUid = errorLogUid;
@@ -90,17 +88,17 @@ public class ApiResponseDto<T> {
}
public static ApiResponseDto<String> createException(
ApiResponseCode code, String message, HttpStatus httpStatus) {
ApiResponseCode code, String message, HttpStatus httpStatus) {
return new ApiResponseDto<>(code, message, httpStatus);
}
public static ApiResponseDto<String> createException(
ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
ApiResponseCode code, String message, HttpStatus httpStatus, Long errorLogUid) {
return new ApiResponseDto<>(code, message, httpStatus, errorLogUid);
}
public static <T> ApiResponseDto<T> createException(
ApiResponseCode code, String message, T data) {
ApiResponseCode code, String message, T data) {
return new ApiResponseDto<>(code, message, data);
}
@@ -116,9 +114,7 @@ public class ApiResponseDto<T> {
}
}
/**
* Error가 아닌 Business상 성공이거나 실패인 경우, 메세지 함께 전달하기 위한 object
*/
/** Error가 아닌 Business상 성공이거나 실패인 경우, 메세지 함께 전달하기 위한 object */
@Getter
public static class ResponseObj {

View File

@@ -30,78 +30,78 @@ public class AdminApiController {
@Operation(summary = "관리자 계정 등록", description = "관리자 계정 등록")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "등록 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "등록 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PostMapping("/join")
public ApiResponseDto<Long> saveMember(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "관리자 계정 등록",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.AddReq.class)))
@RequestBody
@Valid
MembersDto.AddReq addReq) {
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "관리자 계정 등록",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.AddReq.class)))
@RequestBody
@Valid
MembersDto.AddReq addReq) {
return ApiResponseDto.createOK(adminService.saveMember(addReq));
}
@Operation(summary = "관리자 계정 수정", description = "관리자 계정 수정")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "수정 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "수정 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PutMapping("/{uuid}")
public ApiResponseDto<UUID> updateMembers(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "관리자 계정 수정",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.UpdateReq.class)))
@PathVariable
UUID uuid,
@RequestBody @Valid MembersDto.UpdateReq updateReq) {
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "관리자 계정 수정",
required = true,
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = MembersDto.UpdateReq.class)))
@PathVariable
UUID uuid,
@RequestBody @Valid MembersDto.UpdateReq updateReq) {
adminService.updateMembers(uuid, updateReq);
return ApiResponseDto.createOK(UUID.randomUUID());
}
@Operation(summary = "관리자 계정 미사용 처리", description = "관리자 계정 미사용 처리")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "관리자 계정 미사용 처리",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "관리자 계정 미사용 처리",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = UUID.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@DeleteMapping("/delete/{uuid}")
public ApiResponseDto<UUID> deleteAccount(@PathVariable UUID uuid) {
adminService.deleteAccount(uuid);

View File

@@ -50,57 +50,59 @@ public class AuthController {
@Operation(summary = "로그인", description = "사번으로 로그인하여 액세스/리프레시 토큰을 발급.")
@ApiResponses({
@ApiResponse(
responseCode = "200",
description = "로그인 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
responseCode = "200",
description = "로그인 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
@ApiResponse(
responseCode = "401",
description = "로그인 실패 (아이디/비밀번호 오류, 계정잠금 등)",
content =
@Content(
schema = @Schema(implementation = ErrorResponse.class),
examples = {
@ExampleObject(
name = "아이디 입력 오류",
description = "존재하지 않는 아이디",
value = """
responseCode = "401",
description = "로그인 실패 (아이디/비밀번호 오류, 계정잠금 등)",
content =
@Content(
schema = @Schema(implementation = ErrorResponse.class),
examples = {
@ExampleObject(
name = "아이디 입력 오류",
description = "존재하지 않는 아이디",
value =
"""
{
"code": "LOGIN_ID_NOT_FOUND",
"message": "아이디를 잘못 입력하셨습니다."
}
"""),
@ExampleObject(
name = "비밀번호 입력 오류 (4회 이하)",
description = "아이디는 정상, 비밀번호를 여러 번 틀린 경우",
value = """
@ExampleObject(
name = "비밀번호 입력 오류 (4회 이하)",
description = "아이디는 정상, 비밀번호를 여러 번 틀린 경우",
value =
"""
{
"code": "LOGIN_PASSWORD_MISMATCH",
"message": "비밀번호를 잘못 입력하셨습니다."
}
"""),
@ExampleObject(
name = "비밀번호 오류 횟수 초과",
description = "비밀번호 5회 이상 오류로 계정 잠김",
value = """
@ExampleObject(
name = "비밀번호 오류 횟수 초과",
description = "비밀번호 5회 이상 오류로 계정 잠김",
value =
"""
{
"code": "LOGIN_PASSWORD_EXCEEDED",
"message": "비밀번호 오류 횟수를 초과하여 이용하실 수 없습니다. 로그인 오류에 대해 관리자에게 문의하시기 바랍니다."
}
""")
}
))
}))
})
public ApiResponseDto<TokenResponse> signin(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "로그인 요청 정보",
required = true)
@RequestBody
SignInRequest request,
HttpServletResponse response) {
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "로그인 요청 정보",
required = true)
@RequestBody
SignInRequest request,
HttpServletResponse response) {
Authentication authentication =
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword()));
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword()));
String status = authService.getUserStatus(request);
@@ -116,17 +118,17 @@ public class AuthController {
// Redis에 RefreshToken 저장 (TTL = 7일)
refreshTokenService.save(
username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
// HttpOnly + Secure 쿠키에 RefreshToken 저장
ResponseCookie cookie =
ResponseCookie.from(refreshCookieName, refreshToken)
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
.sameSite("Strict")
.build();
ResponseCookie.from(refreshCookieName, refreshToken)
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
.sameSite("Strict")
.build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
@@ -137,16 +139,16 @@ public class AuthController {
@Operation(summary = "토큰 재발급", description = "리프레시 토큰으로 새로운 액세스/리프레시 토큰을 재발급합니다.")
@ApiResponses({
@ApiResponse(
responseCode = "200",
description = "재발급 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
responseCode = "200",
description = "재발급 성공",
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
@ApiResponse(
responseCode = "401",
description = "만료되었거나 유효하지 않은 리프레시 토큰",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
responseCode = "401",
description = "만료되었거나 유효하지 않은 리프레시 토큰",
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
})
public ResponseEntity<TokenResponse> refresh(String refreshToken, HttpServletResponse response)
throws AccessDeniedException {
throws AccessDeniedException {
if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) {
throw new AccessDeniedException("만료되었거나 유효하지 않은 리프레시 토큰 입니다.");
}
@@ -164,17 +166,17 @@ public class AuthController {
// Redis 갱신
refreshTokenService.save(
username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
// 쿠키 갱신
ResponseCookie cookie =
ResponseCookie.from(refreshCookieName, newRefreshToken)
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
.sameSite("Strict")
.build();
ResponseCookie.from(refreshCookieName, newRefreshToken)
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
.sameSite("Strict")
.build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
return ResponseEntity.ok(new TokenResponse("ACTIVE", newAccessToken, newRefreshToken));
@@ -184,12 +186,12 @@ public class AuthController {
@Operation(summary = "로그아웃", description = "현재 사용자의 토큰을 무효화(리프레시 토큰 삭제)합니다.")
@ApiResponses({
@ApiResponse(
responseCode = "200",
description = "로그아웃 성공",
content = @Content(schema = @Schema(implementation = Void.class)))
responseCode = "200",
description = "로그아웃 성공",
content = @Content(schema = @Schema(implementation = Void.class)))
})
public ApiResponseDto<ResponseEntity<Object>> logout(
Authentication authentication, HttpServletResponse response) {
Authentication authentication, HttpServletResponse response) {
if (authentication != null) {
String username = authentication.getName();
// Redis에서 RefreshToken 삭제
@@ -198,19 +200,17 @@ public class AuthController {
// 쿠키 삭제 (Max-Age=0)
ResponseCookie cookie =
ResponseCookie.from(refreshCookieName, "")
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(0)
.sameSite("Strict")
.build();
ResponseCookie.from(refreshCookieName, "")
.httpOnly(true)
.secure(refreshCookieSecure)
.path("/")
.maxAge(0)
.sameSite("Strict")
.build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
return ApiResponseDto.createOK(ResponseEntity.noContent().build());
}
public record TokenResponse(String status, String accessToken, String refreshToken) {
}
public record TokenResponse(String status, String accessToken, String refreshToken) {}
}

View File

@@ -34,43 +34,43 @@ public class MembersApiController {
@Operation(summary = "회원정보 목록", description = "회원정보 조회")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "200",
description = "검색 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Page.class))),
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "200",
description = "검색 성공",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Page.class))),
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@GetMapping
public ApiResponseDto<Page<Basic>> getMemberList(
@ParameterObject MembersDto.SearchReq searchReq) {
@ParameterObject MembersDto.SearchReq searchReq) {
return ApiResponseDto.ok(membersService.findByMembers(searchReq));
}
@Operation(summary = "사용자 비밀번호 변경", description = "사용자 비밀번호 변경")
@ApiResponses(
value = {
@ApiResponse(
responseCode = "201",
description = "사용자 비밀번호 변경",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
value = {
@ApiResponse(
responseCode = "201",
description = "사용자 비밀번호 변경",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Long.class))),
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
})
@PatchMapping("/{memberId}/password")
public ApiResponseDto<String> resetPassword(@PathVariable String memberId, @RequestBody @Valid MembersDto.InitReq initReq) {
public ApiResponseDto<String> resetPassword(
@PathVariable String memberId, @RequestBody @Valid MembersDto.InitReq initReq) {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(memberId, initReq.getTempPassword()));
new UsernamePasswordAuthenticationToken(memberId, initReq.getTempPassword()));
membersService.resetPassword(memberId, initReq);
return ApiResponseDto.createOK(memberId);

View File

@@ -32,31 +32,26 @@ public class MembersDto {
private String tempPassword;
private String status;
private String statusName;
@JsonFormatDttm
private ZonedDateTime createdDttm;
@JsonFormatDttm
private ZonedDateTime updatedDttm;
@JsonFormatDttm
private ZonedDateTime firstLoginDttm;
@JsonFormatDttm
private ZonedDateTime lastLoginDttm;
@JsonFormatDttm private ZonedDateTime createdDttm;
@JsonFormatDttm private ZonedDateTime updatedDttm;
@JsonFormatDttm private ZonedDateTime firstLoginDttm;
@JsonFormatDttm private ZonedDateTime lastLoginDttm;
public Basic(
Long id,
UUID uuid,
String userRole,
String userRoleName,
String name,
String userId,
String employeeNo,
String tempPassword,
String status,
String statusName,
ZonedDateTime createdDttm,
ZonedDateTime updatedDttm,
ZonedDateTime firstLoginDttm,
ZonedDateTime lastLoginDttm
) {
Long id,
UUID uuid,
String userRole,
String userRoleName,
String name,
String userId,
String employeeNo,
String tempPassword,
String status,
String statusName,
ZonedDateTime createdDttm,
ZonedDateTime updatedDttm,
ZonedDateTime firstLoginDttm,
ZonedDateTime lastLoginDttm) {
this.id = id;
this.uuid = uuid;
this.userRole = userRole;
@@ -82,7 +77,6 @@ public class MembersDto {
StatusType type = EnumType.fromId(StatusType.class, status);
return type.getText();
}
}
@Getter
@@ -91,7 +85,9 @@ public class MembersDto {
@AllArgsConstructor
public static class SearchReq {
@Schema(description = "전체, 관리자(ROLE_ADMIN), 라벨러(ROLE_LABELER), 검수자(ROLE_REVIEWER)", example = "")
@Schema(
description = "전체, 관리자(ROLE_ADMIN), 라벨러(ROLE_LABELER), 검수자(ROLE_REVIEWER)",
example = "")
private String userRole;
@Schema(description = "키워드", example = "홍길동")
@@ -135,7 +131,7 @@ public class MembersDto {
private String employeeNo;
public AddReq(
String userRole, String name, String userId, String tempPassword, String employeeNo) {
String userRole, String name, String userId, String tempPassword, String employeeNo) {
this.userRole = userRole;
this.name = name;
this.userId = userId;

View File

@@ -36,7 +36,6 @@ public class AdminService {
membersCoreService.updateMembers(uuid, updateReq);
}
/**
* 관리자 계정 미사용 처리
*

View File

@@ -51,7 +51,7 @@ public class MembersService {
*/
private boolean isValidPassword(String password) {
String passwordPattern =
"^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-\\[\\]{};':\"\\\\|,.<>/?]).{8,20}$";
"^(?=.*[A-Za-z])(?=.*\\d)(?=.*[!@#$%^&*()_+\\-\\[\\]{};':\"\\\\|,.<>/?]).{8,20}$";
return Pattern.matches(passwordPattern, password);
}
}

View File

@@ -59,7 +59,7 @@ public class MembersCoreService {
*/
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(MemberNotFoundException::new);
membersRepository.findByUUID(uuid).orElseThrow(MemberNotFoundException::new);
if (StringUtils.isNotBlank(updateReq.getName())) {
memberEntity.setName(updateReq.getName());
@@ -77,7 +77,6 @@ public class MembersCoreService {
membersRepository.save(memberEntity);
}
/**
* 관리자 계정 미사용 처리
*
@@ -85,14 +84,13 @@ public class MembersCoreService {
*/
public void deleteAccount(UUID uuid) {
MemberEntity memberEntity =
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
memberEntity.setStatus("INACTIVE");
memberEntity.setUpdatedDttm(ZonedDateTime.now());
membersRepository.save(memberEntity);
}
/**
* 패스워드 변경
*
@@ -100,10 +98,10 @@ public class MembersCoreService {
*/
public void resetPassword(String id, MembersDto.InitReq initReq) {
MemberEntity memberEntity =
membersRepository.findByUserId(id).orElseThrow(() -> new MemberNotFoundException());
membersRepository.findByUserId(id).orElseThrow(() -> new MemberNotFoundException());
String salt =
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
// 패스워드 암호화
String hashedPassword = BCrypt.hashpw(initReq.getPassword(), salt);
@@ -112,6 +110,7 @@ public class MembersCoreService {
memberEntity.setUpdatedDttm(ZonedDateTime.now());
membersRepository.save(memberEntity);
}
//
/**
@@ -131,7 +130,10 @@ public class MembersCoreService {
* @return
*/
public String getUserStatus(SignInRequest request) {
MemberEntity memberEntity = membersRepository.findByUserId(request.getUsername()).orElseThrow(MemberNotFoundException::new);
MemberEntity memberEntity =
membersRepository
.findByUserId(request.getUsername())
.orElseThrow(MemberNotFoundException::new);
return memberEntity.getStatus();
}
}

View File

@@ -61,8 +61,7 @@ public class CommonCodeRepositoryImpl implements CommonCodeRepositoryCustom {
.on(child.deleted.isFalse().or(child.deleted.isNull()))
.where(
commonCodeEntity.parent.isNull(),
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull())
)
commonCodeEntity.deleted.isFalse().or(commonCodeEntity.deleted.isNull()))
.orderBy(commonCodeEntity.order.asc(), child.order.asc())
.fetch();
}

View File

@@ -33,11 +33,11 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
@Override
public boolean existsByUserId(String userId) {
return queryFactory
.selectOne()
.from(memberEntity)
.where(memberEntity.userId.eq(userId))
.fetchFirst()
!= null;
.selectOne()
.from(memberEntity)
.where(memberEntity.userId.eq(userId))
.fetchFirst()
!= null;
}
/**
@@ -49,7 +49,7 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
@Override
public Optional<MemberEntity> findByUserId(String userId) {
return Optional.ofNullable(
queryFactory.selectFrom(memberEntity).where(memberEntity.userId.eq(userId)).fetchOne());
queryFactory.selectFrom(memberEntity).where(memberEntity.userId.eq(userId)).fetchOne());
}
/**
@@ -68,10 +68,11 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
String contains = "%" + searchReq.getKeyword() + "%";
builder.and(
memberEntity.name.likeIgnoreCase(contains)
.or(memberEntity.userId.likeIgnoreCase(contains))
.or(memberEntity.employeeNo.likeIgnoreCase(contains))
);
memberEntity
.name
.likeIgnoreCase(contains)
.or(memberEntity.userId.likeIgnoreCase(contains))
.or(memberEntity.employeeNo.likeIgnoreCase(contains)));
}
// 권한
@@ -80,35 +81,30 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
}
List<MembersDto.Basic> content =
queryFactory
.select(
Projections.constructor(
MembersDto.Basic.class,
memberEntity.id,
memberEntity.uuid,
memberEntity.userRole,
memberEntity.name,
memberEntity.userId,
memberEntity.employeeNo,
memberEntity.tempPassword,
memberEntity.status,
memberEntity.createdDttm,
memberEntity.updatedDttm,
memberEntity.firstLoginDttm,
memberEntity.lastLoginDttm
))
.from(memberEntity)
.where(builder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(memberEntity.createdDttm.desc())
.fetch();
queryFactory
.select(
Projections.constructor(
MembersDto.Basic.class,
memberEntity.id,
memberEntity.uuid,
memberEntity.userRole,
memberEntity.name,
memberEntity.userId,
memberEntity.employeeNo,
memberEntity.tempPassword,
memberEntity.status,
memberEntity.createdDttm,
memberEntity.updatedDttm,
memberEntity.firstLoginDttm,
memberEntity.lastLoginDttm))
.from(memberEntity)
.where(builder)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(memberEntity.createdDttm.desc())
.fetch();
long total =
queryFactory
.select(memberEntity)
.from(memberEntity)
.fetchCount();
long total = queryFactory.select(memberEntity).from(memberEntity).fetchCount();
return new PageImpl<>(content, pageable, total);
}
@@ -122,6 +118,6 @@ public class MembersRepositoryImpl implements MembersRepositoryCustom {
@Override
public Optional<MemberEntity> findByUUID(UUID uuid) {
return Optional.ofNullable(
queryFactory.selectFrom(memberEntity).where(memberEntity.uuid.eq(uuid)).fetchOne());
queryFactory.selectFrom(memberEntity).where(memberEntity.uuid.eq(uuid)).fetchOne());
}
}