회원관리 관리 수정
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package com.kamco.cd.kamcoback.auth;
|
||||
|
||||
import com.kamco.cd.kamcoback.members.service.AuthService;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class AuthFailureEventListener implements ApplicationListener<AbstractAuthenticationFailureEvent> {
|
||||
|
||||
private final AuthService authService;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(AbstractAuthenticationFailureEvent event) {
|
||||
// 로그인 시도에 사용된 (username)
|
||||
Object principal = event.getAuthentication().getPrincipal();
|
||||
|
||||
if (principal instanceof String username) {
|
||||
// 로그인 실패 카운트 증가 로직 호출
|
||||
authService.loginFail(UUID.fromString(username));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAsyncExecution() {
|
||||
return ApplicationListener.super.supportsAsyncExecution();
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import jakarta.validation.Valid;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
@@ -31,101 +30,81 @@ 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 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 = "회원 탈퇴")
|
||||
@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);
|
||||
return ApiResponseDto.createOK(uuid);
|
||||
}
|
||||
|
||||
@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)
|
||||
})
|
||||
@PatchMapping("/{memberId}/password")
|
||||
public ApiResponseDto<Long> resetPassword(@PathVariable Long memberId) {
|
||||
adminService.resetPassword(memberId);
|
||||
return ApiResponseDto.createOK(memberId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.kamco.cd.kamcoback.auth.JwtTokenProvider;
|
||||
import com.kamco.cd.kamcoback.auth.RefreshTokenService;
|
||||
import com.kamco.cd.kamcoback.config.api.ApiResponseDto;
|
||||
import com.kamco.cd.kamcoback.members.dto.SignInRequest;
|
||||
import com.kamco.cd.kamcoback.members.service.AuthService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Content;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@@ -13,6 +14,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.nio.file.AccessDeniedException;
|
||||
import java.time.Duration;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
@@ -36,6 +38,7 @@ public class AuthController {
|
||||
private final AuthenticationManager authenticationManager;
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final RefreshTokenService refreshTokenService;
|
||||
private final AuthService authService;
|
||||
|
||||
@Value("${token.refresh-cookie-name}")
|
||||
private String refreshCookieName;
|
||||
@@ -47,45 +50,49 @@ 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 = "ID 또는 비밀번호 불일치",
|
||||
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
||||
responseCode = "401",
|
||||
description = "ID 또는 비밀번호 불일치",
|
||||
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
||||
})
|
||||
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 username = authentication.getName(); // UserDetailsService 에서 사용한 username
|
||||
|
||||
// 로그인 시간 저장
|
||||
authService.saveLogin(UUID.fromString(username));
|
||||
|
||||
String accessToken = jwtTokenProvider.createAccessToken(username);
|
||||
String refreshToken = jwtTokenProvider.createRefreshToken(username);
|
||||
|
||||
// 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());
|
||||
|
||||
return ApiResponseDto.ok(new TokenResponse(accessToken, refreshToken));
|
||||
}
|
||||
|
||||
@@ -93,16 +100,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("만료되었거나 유효하지 않은 리프레시 토큰 입니다.");
|
||||
}
|
||||
@@ -120,17 +127,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(newAccessToken, newRefreshToken));
|
||||
@@ -140,12 +147,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 삭제
|
||||
@@ -154,17 +161,19 @@ 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 accessToken, String refreshToken) {}
|
||||
public record TokenResponse(String accessToken, String refreshToken) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,13 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import java.util.UUID;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springdoc.core.annotations.ParameterObject;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -31,41 +31,41 @@ 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 = "회원정보 수정")
|
||||
|
||||
@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)
|
||||
})
|
||||
@PutMapping("/{uuid}")
|
||||
public ApiResponseDto<UUID> updateMember(
|
||||
@PathVariable UUID uuid, @RequestBody MembersDto.UpdateReq updateReq) {
|
||||
// membersService.updateMember(uuid, updateReq);
|
||||
return ApiResponseDto.createOK(uuid);
|
||||
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<Long> resetPassword(@PathVariable Long memberId, @RequestBody @Valid MembersDto.InitReq initReq) {
|
||||
membersService.resetPassword(memberId, initReq);
|
||||
return ApiResponseDto.createOK(memberId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.kamco.cd.kamcoback.members.dto;
|
||||
|
||||
import com.kamco.cd.kamcoback.common.enums.RoleType;
|
||||
import com.kamco.cd.kamcoback.common.utils.interfaces.EnumValid;
|
||||
import com.kamco.cd.kamcoback.common.utils.interfaces.JsonFormatDttm;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
@@ -23,33 +21,47 @@ public class MembersDto {
|
||||
|
||||
private Long id;
|
||||
private UUID uuid;
|
||||
private String employeeNo;
|
||||
private String userRole;
|
||||
private String name;
|
||||
private String email;
|
||||
private String userId;
|
||||
private String employeeNo;
|
||||
private String tempPassword;
|
||||
private String status;
|
||||
private String roleName;
|
||||
@JsonFormatDttm private ZonedDateTime createdDttm;
|
||||
@JsonFormatDttm private ZonedDateTime updatedDttm;
|
||||
@JsonFormatDttm
|
||||
private ZonedDateTime createdDttm;
|
||||
@JsonFormatDttm
|
||||
private ZonedDateTime updatedDttm;
|
||||
@JsonFormatDttm
|
||||
private ZonedDateTime firstLoginDttm;
|
||||
@JsonFormatDttm
|
||||
private ZonedDateTime lastLoginDttm;
|
||||
|
||||
public Basic(
|
||||
Long id,
|
||||
UUID uuid,
|
||||
String employeeNo,
|
||||
String name,
|
||||
String email,
|
||||
String status,
|
||||
String roleName,
|
||||
ZonedDateTime createdDttm,
|
||||
ZonedDateTime updatedDttm) {
|
||||
Long id,
|
||||
UUID uuid,
|
||||
String userRole,
|
||||
String name,
|
||||
String userId,
|
||||
String employeeNo,
|
||||
String tempPassword,
|
||||
String status,
|
||||
ZonedDateTime createdDttm,
|
||||
ZonedDateTime updatedDttm,
|
||||
ZonedDateTime firstLoginDttm,
|
||||
ZonedDateTime lastLoginDttm
|
||||
) {
|
||||
this.id = id;
|
||||
this.uuid = uuid;
|
||||
this.employeeNo = employeeNo;
|
||||
this.userRole = userRole;
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.userId = userId;
|
||||
this.employeeNo = employeeNo;
|
||||
this.tempPassword = tempPassword;
|
||||
this.status = status;
|
||||
this.roleName = roleName;
|
||||
this.createdDttm = createdDttm;
|
||||
this.updatedDttm = updatedDttm;
|
||||
this.firstLoginDttm = firstLoginDttm;
|
||||
this.lastLoginDttm = lastLoginDttm;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,21 +71,12 @@ public class MembersDto {
|
||||
@AllArgsConstructor
|
||||
public static class SearchReq {
|
||||
|
||||
@Schema(description = "이름(name), 이메일(email), 사번(employeeNo)", example = "name")
|
||||
private String field;
|
||||
@Schema(description = "전체, 관리자(ROLE_ADMIN), 라벨러(ROLE_LABELER), 검수자(ROLE_REVIEWER)", example = "")
|
||||
private String userRole;
|
||||
|
||||
@Schema(description = "키워드", example = "홍길동")
|
||||
private String keyword;
|
||||
|
||||
@Schema(description = "라벨러 포함 여부", example = "true")
|
||||
private boolean labeler = true;
|
||||
|
||||
@Schema(description = "검수자 포함 여부", example = "true")
|
||||
private boolean reviewer = true;
|
||||
|
||||
@Schema(description = "운영자 포함 여부", example = "true")
|
||||
private boolean admin = true;
|
||||
|
||||
// 페이징 파라미터
|
||||
@Schema(description = "페이지 번호 (0부터 시작) ", example = "0")
|
||||
private int page = 0;
|
||||
@@ -112,7 +115,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;
|
||||
@@ -146,29 +149,10 @@ public class MembersDto {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class RolesDto {
|
||||
public static class InitReq {
|
||||
|
||||
@Schema(description = "UUID", example = "4e89e487-c828-4a34-a7fc-0d5b0e3b53b5")
|
||||
private UUID uuid;
|
||||
|
||||
@Schema(description = "역할 ROLE_ADMIN, ROLE_LABELER, ROLE_REVIEWER", example = "ROLE_ADMIN")
|
||||
@EnumValid(enumClass = RoleType.class)
|
||||
private String roleName;
|
||||
|
||||
public RolesDto(UUID uuid, String roleName) {
|
||||
this.uuid = uuid;
|
||||
this.roleName = roleName;
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public static class StatusDto {
|
||||
|
||||
@Schema(description = "변경할 상태값 ACTIVE, INACTIVE, ARCHIVED", example = "ACTIVE")
|
||||
@NotBlank
|
||||
private String status;
|
||||
@Schema(description = "패스워드", example = "")
|
||||
@Size(max = 255)
|
||||
private String password;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package com.kamco.cd.kamcoback.members.service;
|
||||
|
||||
import com.kamco.cd.kamcoback.auth.BCryptSaltGenerator;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.mindrot.jbcrypt.BCrypt;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -17,69 +15,35 @@ public class AdminService {
|
||||
private final MembersCoreService membersCoreService;
|
||||
|
||||
/**
|
||||
* 회원가입
|
||||
* 관리자 계정 등록
|
||||
*
|
||||
* @param addReq
|
||||
* @return
|
||||
*/
|
||||
@Transactional
|
||||
public Long saveMember(MembersDto.AddReq addReq) {
|
||||
// salt 생성, 사번이 salt
|
||||
String salt = BCryptSaltGenerator.generateSaltWithEmployeeNo(addReq.getUserId().trim());
|
||||
|
||||
// 패스워드 암호화, 초기 패스워드 고정
|
||||
String hashedPassword = BCrypt.hashpw(addReq.getTempPassword(), salt);
|
||||
addReq.setTempPassword(hashedPassword);
|
||||
return membersCoreService.saveMembers(addReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 관리자 계정 수정
|
||||
*
|
||||
* @param uuid
|
||||
* @param updateReq
|
||||
*/
|
||||
@Transactional
|
||||
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
|
||||
membersCoreService.updateMembers(uuid, updateReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 역할 추가
|
||||
*
|
||||
* @param rolesDto
|
||||
*/
|
||||
@Transactional
|
||||
public void saveRoles(MembersDto.RolesDto rolesDto) {
|
||||
// membersCoreService.saveRoles(rolesDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 역할 삭제
|
||||
*
|
||||
* @param rolesDto
|
||||
*/
|
||||
public void deleteRoles(MembersDto.RolesDto rolesDto) {
|
||||
// membersCoreService.deleteRoles(rolesDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 역할 수정
|
||||
*
|
||||
* @param statusDto
|
||||
*/
|
||||
public void updateStatus(UUID uuid, MembersDto.StatusDto statusDto) {
|
||||
// membersCoreService.updateStatus(uuid, statusDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 회원 탈퇴
|
||||
* 관리자 계정 미사용 처리
|
||||
*
|
||||
* @param uuid
|
||||
*/
|
||||
@Transactional
|
||||
public void deleteAccount(UUID uuid) {
|
||||
// membersCoreService.deleteAccount(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 패스워드 초기화
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
public void resetPassword(Long id) {
|
||||
// membersCoreService.resetPassword(id);
|
||||
membersCoreService.deleteAccount(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.kamco.cd.kamcoback.members.service;
|
||||
|
||||
import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional(readOnly = true)
|
||||
public class AuthService {
|
||||
|
||||
private final MembersCoreService membersCoreService;
|
||||
|
||||
/**
|
||||
* 로그인 일시 저장
|
||||
*
|
||||
* @param uuid
|
||||
*/
|
||||
@Transactional
|
||||
public void saveLogin(UUID uuid) {
|
||||
membersCoreService.saveLogin(uuid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 로그인 실패 저장
|
||||
*
|
||||
* @param uuid
|
||||
*/
|
||||
@Transactional
|
||||
public void loginFail(UUID uuid) {
|
||||
membersCoreService.loginFail(uuid);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.kamco.cd.kamcoback.members.service;
|
||||
|
||||
import com.kamco.cd.kamcoback.common.exception.CustomApiException;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
|
||||
import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -23,38 +25,22 @@ public class MembersService {
|
||||
* @return
|
||||
*/
|
||||
public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
|
||||
return null; // membersCoreService.findByMembers(searchReq);
|
||||
return membersCoreService.findByMembers(searchReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 회원정보 수정
|
||||
* 패스워드 사용자 변경
|
||||
*
|
||||
* @param uuid
|
||||
* @param updateReq
|
||||
* @param id
|
||||
* @param initReq
|
||||
*/
|
||||
// public void updateMember(UUID uuid, MembersDto.UpdateReq updateReq) {
|
||||
//
|
||||
// if (StringUtils.isNotBlank(updateReq.getPassword())) {
|
||||
//
|
||||
// if (!this.isValidPassword(updateReq.getPassword())) {
|
||||
// throw new CustomApiException("WRONG_PASSWORD", HttpStatus.BAD_REQUEST);
|
||||
// }
|
||||
//
|
||||
// if (StringUtils.isBlank(updateReq.getEmployeeNo())) {
|
||||
// throw new CustomApiException("BAD_REQUEST", HttpStatus.BAD_REQUEST);
|
||||
// }
|
||||
//
|
||||
// // salt 생성, 사번이 salt
|
||||
// String salt =
|
||||
// BCryptSaltGenerator.generateSaltWithEmployeeNo(updateReq.getEmployeeNo().trim());
|
||||
//
|
||||
// // 패스워드 암호화, 초기 패스워드 고정
|
||||
// String hashedPassword = BCrypt.hashpw(updateReq.getPassword(), salt);
|
||||
// updateReq.setPassword(hashedPassword);
|
||||
// }
|
||||
//
|
||||
// membersCoreService.updateMembers(uuid, updateReq);
|
||||
// }
|
||||
@Transactional
|
||||
public void resetPassword(Long id, MembersDto.InitReq initReq) {
|
||||
if (!isValidPassword(initReq.getPassword())) {
|
||||
throw new CustomApiException("WRONG_PASSWORD", HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
membersCoreService.resetPassword(id, initReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 대문자 1개 이상 소문자 1개 이상 숫자 1개 이상 특수문자(!@#$) 1개 이상
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
package com.kamco.cd.kamcoback.postgres.core;
|
||||
|
||||
import com.kamco.cd.kamcoback.auth.BCryptSaltGenerator;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto.AddReq;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
|
||||
import com.kamco.cd.kamcoback.members.exception.MemberException.DuplicateMemberException;
|
||||
import com.kamco.cd.kamcoback.members.exception.MemberException.DuplicateMemberException.Field;
|
||||
import com.kamco.cd.kamcoback.members.exception.MemberException.MemberNotFoundException;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.members.MembersArchivedRepository;
|
||||
import com.kamco.cd.kamcoback.postgres.repository.members.MembersRepository;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.mindrot.jbcrypt.BCrypt;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@@ -18,10 +22,9 @@ import org.springframework.stereotype.Service;
|
||||
public class MembersCoreService {
|
||||
|
||||
private final MembersRepository membersRepository;
|
||||
private final MembersArchivedRepository memberArchivedRepository;
|
||||
|
||||
/**
|
||||
* 회원가입
|
||||
* 관리자 계정 등록
|
||||
*
|
||||
* @param addReq
|
||||
* @return
|
||||
@@ -30,11 +33,17 @@ public class MembersCoreService {
|
||||
if (membersRepository.existsByUserId(addReq.getUserId())) {
|
||||
throw new DuplicateMemberException(Field.USER_ID, addReq.getUserId());
|
||||
}
|
||||
|
||||
// salt 생성, 사번이 salt
|
||||
String salt = BCryptSaltGenerator.generateSaltWithEmployeeNo(addReq.getUserId().trim());
|
||||
// 패스워드 암호화, 초기 패스워드 고정
|
||||
String hashedPassword = BCrypt.hashpw(addReq.getTempPassword(), salt);
|
||||
|
||||
MemberEntity memberEntity = new MemberEntity();
|
||||
memberEntity.setUserId(addReq.getUserId());
|
||||
memberEntity.setUserRole(addReq.getUserRole());
|
||||
memberEntity.setTempPassword(addReq.getTempPassword());
|
||||
memberEntity.setPassword(addReq.getTempPassword());
|
||||
memberEntity.setTempPassword(addReq.getTempPassword()); // 임시 패스워드는 암호화 하지 않음
|
||||
memberEntity.setPassword(hashedPassword);
|
||||
memberEntity.setName(addReq.getName());
|
||||
memberEntity.setEmployeeNo(addReq.getEmployeeNo());
|
||||
|
||||
@@ -42,22 +51,22 @@ public class MembersCoreService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 회원정보 수정
|
||||
* 관리자 계정 수정
|
||||
*
|
||||
* @param uuid
|
||||
* @param updateReq
|
||||
*/
|
||||
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());
|
||||
}
|
||||
|
||||
// 임시 패스워드는 암호화 하지 않음
|
||||
if (StringUtils.isNotBlank(updateReq.getTempPassword())) {
|
||||
memberEntity.setTempPassword(updateReq.getTempPassword());
|
||||
memberEntity.setPassword(updateReq.getTempPassword());
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(memberEntity.getEmployeeNo())) {
|
||||
@@ -66,123 +75,42 @@ public class MembersCoreService {
|
||||
|
||||
membersRepository.save(memberEntity);
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * 역할 추가
|
||||
// *
|
||||
// * @param rolesDto
|
||||
// */
|
||||
// public void saveRoles(MembersDto.RolesDto rolesDto) {
|
||||
//
|
||||
// MemberEntity memberEntity =
|
||||
// membersRepository
|
||||
// .findByUUID(rolesDto.getUuid())
|
||||
// .orElseThrow(() -> new MemberNotFoundException());
|
||||
//
|
||||
// if (memberRoleRepository.findByUuidAndRoleName(rolesDto)) {
|
||||
// throw new MemberException.DuplicateMemberException(
|
||||
// MemberException.DuplicateMemberException.Field.DEFAULT, "중복된 역할이 있습니다.");
|
||||
// }
|
||||
//
|
||||
// MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
|
||||
// memberRoleEntityId.setMemberUuid(rolesDto.getUuid());
|
||||
// memberRoleEntityId.setRoleName(rolesDto.getRoleName());
|
||||
//
|
||||
// MemberRoleEntity memberRoleEntity = new MemberRoleEntity();
|
||||
// memberRoleEntity.setId(memberRoleEntityId);
|
||||
// memberRoleEntity.setMemberUuid(memberEntity);
|
||||
// memberRoleEntity.setCreatedDttm(ZonedDateTime.now());
|
||||
// memberRoleRepository.save(memberRoleEntity);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 역할 삭제
|
||||
// *
|
||||
// * @param rolesDto
|
||||
// */
|
||||
// public void deleteRoles(MembersDto.RolesDto rolesDto) {
|
||||
// MemberEntity memberEntity =
|
||||
// membersRepository
|
||||
// .findByUUID(rolesDto.getUuid())
|
||||
// .orElseThrow(() -> new MemberNotFoundException());
|
||||
//
|
||||
// MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
|
||||
// memberRoleEntityId.setMemberUuid(rolesDto.getUuid());
|
||||
// memberRoleEntityId.setRoleName(rolesDto.getRoleName());
|
||||
//
|
||||
// MemberRoleEntity memberRoleEntity = new MemberRoleEntity();
|
||||
// memberRoleEntity.setId(memberRoleEntityId);
|
||||
// memberRoleEntity.setMemberUuid(memberEntity);
|
||||
//
|
||||
// memberRoleRepository.delete(memberRoleEntity);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 상태 수정
|
||||
// *
|
||||
// * @param statusDto
|
||||
// */
|
||||
// public void updateStatus(UUID uuid, MembersDto.StatusDto statusDto) {
|
||||
// MemberEntity memberEntity =
|
||||
// membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
|
||||
//
|
||||
// memberEntity.setStatus(statusDto.getStatus());
|
||||
// memberEntity.setUpdatedDttm(ZonedDateTime.now());
|
||||
// membersRepository.save(memberEntity);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 회원 탈퇴
|
||||
// *
|
||||
// * @param uuid
|
||||
// */
|
||||
// public void deleteAccount(UUID uuid) {
|
||||
// MemberEntity memberEntity =
|
||||
// membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
|
||||
//
|
||||
// MemberArchivedEntityId memberArchivedEntityId = new MemberArchivedEntityId();
|
||||
// memberArchivedEntityId.setUserId(memberEntity.getId());
|
||||
// memberArchivedEntityId.setUuid(memberEntity.getUuid());
|
||||
//
|
||||
// MemberArchivedEntity memberArchivedEntity = new MemberArchivedEntity();
|
||||
// memberArchivedEntity.setId(memberArchivedEntityId);
|
||||
// memberArchivedEntity.setEmployeeNo(memberEntity.getEmployeeNo());
|
||||
// memberArchivedEntity.setName(memberEntity.getName());
|
||||
// memberArchivedEntity.setPassword(memberEntity.getPassword());
|
||||
// memberArchivedEntity.setEmail(memberEntity.getEmail());
|
||||
// memberArchivedEntity.setStatus(memberEntity.getStatus());
|
||||
// memberArchivedEntity.setCreatedDttm(memberEntity.getCreatedDttm());
|
||||
// memberArchivedEntity.setArchivedDttm(ZonedDateTime.now());
|
||||
// memberArchivedRepository.save(memberArchivedEntity);
|
||||
//
|
||||
// memberEntity.setStatus("ARCHIVED");
|
||||
// memberEntity.setName("**********");
|
||||
// memberEntity.setEmployeeNo("**********");
|
||||
// memberEntity.setPassword("**********");
|
||||
// memberEntity.setEmail("**********");
|
||||
// memberEntity.setUpdatedDttm(ZonedDateTime.now());
|
||||
// membersRepository.save(memberEntity);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 패스워드 초기화
|
||||
// *
|
||||
// * @param id
|
||||
// */
|
||||
// public void resetPassword(Long id) {
|
||||
// MemberEntity memberEntity =
|
||||
// membersRepository.findById(id).orElseThrow(() -> new MemberNotFoundException());
|
||||
//
|
||||
// String salt =
|
||||
// BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
|
||||
// // 패스워드 암호화, 초기 패스워드 고정
|
||||
// String hashedPassword = BCrypt.hashpw(password, salt);
|
||||
//
|
||||
// memberEntity.setPassword(hashedPassword);
|
||||
// memberEntity.setStatus("INACTIVE");
|
||||
// memberEntity.setUpdatedDttm(ZonedDateTime.now());
|
||||
// membersRepository.save(memberEntity);
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* 관리자 계정 미사용 처리
|
||||
*
|
||||
* @param uuid
|
||||
*/
|
||||
public void deleteAccount(UUID uuid) {
|
||||
MemberEntity memberEntity =
|
||||
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
|
||||
|
||||
memberEntity.setStatus("INACTIVE");
|
||||
memberEntity.setUpdatedDttm(ZonedDateTime.now());
|
||||
membersRepository.save(memberEntity);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 패스워드 변경
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
public void resetPassword(Long id, MembersDto.InitReq initReq) {
|
||||
MemberEntity memberEntity =
|
||||
membersRepository.findById(id).orElseThrow(() -> new MemberNotFoundException());
|
||||
|
||||
String salt =
|
||||
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
|
||||
// 패스워드 암호화
|
||||
String hashedPassword = BCrypt.hashpw(initReq.getPassword(), salt);
|
||||
|
||||
memberEntity.setPassword(hashedPassword);
|
||||
memberEntity.setStatus("ACTIVE");
|
||||
memberEntity.setUpdatedDttm(ZonedDateTime.now());
|
||||
membersRepository.save(memberEntity);
|
||||
}
|
||||
//
|
||||
|
||||
/**
|
||||
@@ -191,7 +119,42 @@ public class MembersCoreService {
|
||||
* @param searchReq
|
||||
* @return
|
||||
*/
|
||||
// public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
|
||||
// return membersRepository.findByMembers(searchReq);
|
||||
// }
|
||||
public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
|
||||
return membersRepository.findByMembers(searchReq);
|
||||
}
|
||||
|
||||
/**
|
||||
* 최초 로그인 저장 마지막 로그인 저장
|
||||
*
|
||||
* @param uuid
|
||||
*/
|
||||
public void saveLogin(UUID uuid) {
|
||||
MemberEntity memberEntity =
|
||||
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
|
||||
|
||||
if (memberEntity.getFirstLoginDttm() == null) {
|
||||
memberEntity.setFirstLoginDttm(ZonedDateTime.now());
|
||||
}
|
||||
memberEntity.setLastLoginDttm(ZonedDateTime.now());
|
||||
memberEntity.setLoginFailCount(0);
|
||||
membersRepository.save(memberEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 로그인 실패시 상태 저장
|
||||
*
|
||||
* @param uuid
|
||||
*/
|
||||
public void loginFail(UUID uuid) {
|
||||
MemberEntity memberEntity =
|
||||
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
|
||||
|
||||
int failCnt = memberEntity.getLoginFailCount() + 1;
|
||||
if (failCnt >= 5) {
|
||||
memberEntity.setStatus("INACTIVE");
|
||||
}
|
||||
|
||||
memberEntity.setLoginFailCount(failCnt);
|
||||
membersRepository.save(memberEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,4 +73,14 @@ public class MemberEntity {
|
||||
@ColumnDefault("now()")
|
||||
@Column(name = "updated_dttm")
|
||||
private ZonedDateTime updatedDttm = ZonedDateTime.now();
|
||||
|
||||
@Column(name = "first_login_dttm")
|
||||
private ZonedDateTime firstLoginDttm;
|
||||
|
||||
@Column(name = "last_login_dttm")
|
||||
private ZonedDateTime lastLoginDttm;
|
||||
|
||||
@Column(name = "login_fail_count")
|
||||
@ColumnDefault("0")
|
||||
private Integer loginFailCount = 0;
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.members;
|
||||
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.springframework.data.domain.Page;
|
||||
|
||||
public interface MembersRepositoryCustom {
|
||||
|
||||
boolean existsByUserId(String userId);
|
||||
|
||||
Optional<MemberEntity> findByUserId(String employeeNo);
|
||||
Optional<MemberEntity> findByUserId(String userId);
|
||||
|
||||
Optional<MemberEntity> findByUUID(UUID uuid);
|
||||
//
|
||||
// Page<Basic> findByMembers(MembersDto.SearchReq searchReq);
|
||||
//
|
||||
|
||||
//
|
||||
// Optional<MemberEntity> findByEmployeeNo(String employeeNo);
|
||||
Page<Basic> findByMembers(MembersDto.SearchReq searchReq);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
package com.kamco.cd.kamcoback.postgres.repository.members;
|
||||
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||
import com.kamco.cd.kamcoback.members.dto.MembersDto.Basic;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.MemberEntity;
|
||||
import com.kamco.cd.kamcoback.postgres.entity.QMemberEntity;
|
||||
import com.querydsl.core.BooleanBuilder;
|
||||
import com.querydsl.core.types.Projections;
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
@@ -24,96 +33,95 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 사용자 조회 user id
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
@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());
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 회원정보 목록 조회
|
||||
// *
|
||||
// * @param searchReq
|
||||
// * @return
|
||||
// */
|
||||
// @Override
|
||||
// public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
|
||||
// Pageable pageable = searchReq.toPageable();
|
||||
// BooleanBuilder builder = new BooleanBuilder();
|
||||
// BooleanBuilder leftBuilder = new BooleanBuilder();
|
||||
//
|
||||
// if (StringUtils.isNotBlank(searchReq.getField())) {
|
||||
// switch (searchReq.getField()) {
|
||||
// case "name" ->
|
||||
// builder.and(memberEntity.name.containsIgnoreCase(searchReq.getKeyword().trim()));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// List<String> roles = new ArrayList<>();
|
||||
// // 라벨러
|
||||
// if (searchReq.isLabeler()) {
|
||||
// roles.add(RoleType.ROLE_LABELER.getId());
|
||||
// }
|
||||
//
|
||||
// // 시스템 전체 관리자
|
||||
// if (searchReq.isAdmin()) {
|
||||
// roles.add(RoleType.ROLE_ADMIN.getId());
|
||||
// }
|
||||
//
|
||||
// // 검수자
|
||||
// if (searchReq.isReviewer()) {
|
||||
// roles.add(RoleType.ROLE_REVIEWER.getId());
|
||||
// }
|
||||
//
|
||||
// // 역할 in 조건 추가
|
||||
// if (!roles.isEmpty()) {
|
||||
// leftBuilder.and(memberRoleEntity.id.roleName.in(roles));
|
||||
// }
|
||||
//
|
||||
// List<MembersDto.Basic> content =
|
||||
// queryFactory
|
||||
// .select(
|
||||
// Projections.constructor(
|
||||
// MembersDto.Basic.class,
|
||||
// memberEntity.id,
|
||||
// memberEntity.uuid,
|
||||
// memberEntity.employeeNo,
|
||||
// memberEntity.name,
|
||||
// null,
|
||||
// memberEntity.status,
|
||||
// memberRoleEntity.id.roleName,
|
||||
// memberEntity.createdDttm,
|
||||
// memberEntity.updatedDttm))
|
||||
// .from(memberEntity)
|
||||
// .leftJoin(memberRoleEntity)
|
||||
// .on(memberRoleEntity.memberUuid.uuid.eq(memberEntity.uuid).and(leftBuilder))
|
||||
// .where(builder)
|
||||
// .offset(pageable.getOffset())
|
||||
// .limit(pageable.getPageSize())
|
||||
// .orderBy(memberEntity.createdDttm.desc())
|
||||
// .fetch();
|
||||
//
|
||||
// long total =
|
||||
// queryFactory
|
||||
// .select(memberEntity)
|
||||
// .from(memberEntity)
|
||||
// .leftJoin(memberRoleEntity)
|
||||
// .on(memberRoleEntity.memberUuid.uuid.eq(memberEntity.uuid).and(leftBuilder))
|
||||
// .fetchCount();
|
||||
//
|
||||
// return new PageImpl<>(content, pageable, total);
|
||||
// }
|
||||
//
|
||||
/**
|
||||
* 회원정보 목록 조회
|
||||
*
|
||||
* @param searchReq
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Page<Basic> findByMembers(MembersDto.SearchReq searchReq) {
|
||||
Pageable pageable = searchReq.toPageable();
|
||||
BooleanBuilder builder = new BooleanBuilder();
|
||||
|
||||
// 검색어
|
||||
if (StringUtils.isNotBlank(searchReq.getKeyword())) {
|
||||
String contains = "%" + searchReq.getKeyword() + "%";
|
||||
|
||||
builder.and(
|
||||
memberEntity.name.likeIgnoreCase(contains)
|
||||
.or(memberEntity.userId.likeIgnoreCase(contains))
|
||||
.or(memberEntity.employeeNo.likeIgnoreCase(contains))
|
||||
);
|
||||
}
|
||||
|
||||
// 권한
|
||||
if (StringUtils.isNotBlank(searchReq.getUserRole())) {
|
||||
builder.and(memberEntity.userRole.eq(searchReq.getUserRole()));
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
long total =
|
||||
queryFactory
|
||||
.select(memberEntity)
|
||||
.from(memberEntity)
|
||||
.fetchCount();
|
||||
|
||||
return new PageImpl<>(content, pageable, total);
|
||||
}
|
||||
|
||||
/**
|
||||
* 사용자 ID 조회 UUID
|
||||
*
|
||||
* @param uuid
|
||||
* @return
|
||||
*/
|
||||
@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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user