로그인 기능 추가
This commit is contained in:
@@ -26,39 +26,41 @@ public class SecurityConfig {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
// http.csrf(csrf -> csrf.disable()) // CSRF 보안 기능 비활성화
|
/*
|
||||||
// .sessionManagement(
|
http.csrf(csrf -> csrf.disable()) // CSRF 보안 기능 비활성화
|
||||||
// sm ->
|
.sessionManagement(
|
||||||
// sm.sessionCreationPolicy(
|
sm ->
|
||||||
// SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음 요청은 JWT 인증
|
sm.sessionCreationPolicy(
|
||||||
// .formLogin(form -> form.disable()) // react에서 로그인 요청 관리
|
SessionCreationPolicy.STATELESS)) // 서버 세션 만들지 않음, 요청은 JWT 인증
|
||||||
// .httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용
|
.formLogin(form -> form.disable()) // react에서 로그인 요청 관리
|
||||||
// .logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음
|
.httpBasic(basic -> basic.disable()) // 기본 basic 인증 비활성화 JWT 인증사용
|
||||||
// .authenticationProvider(
|
.logout(logout -> logout.disable()) // 기본 로그아웃 비활성화 JWT는 서버 상태가 없으므로 로그아웃 처리 필요 없음
|
||||||
// customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용
|
.authenticationProvider(
|
||||||
// .authorizeHttpRequests(
|
customAuthenticationProvider) // 로그인 패스워드 비교방식 스프링 기본 Provider 사용안함 커스텀 사용
|
||||||
// auth ->
|
.authorizeHttpRequests(
|
||||||
// auth.requestMatchers(
|
auth ->
|
||||||
// "/api/auth/signin",
|
auth.requestMatchers(
|
||||||
// "/api/auth/refresh",
|
"/api/auth/signin",
|
||||||
// "/swagger-ui/**",
|
"/api/auth/refresh",
|
||||||
// "/v3/api-docs/**")
|
"/swagger-ui/**",
|
||||||
// .permitAll()
|
"/v3/api-docs/**")
|
||||||
// .anyRequest()
|
.permitAll()
|
||||||
// .authenticated())
|
.anyRequest()
|
||||||
// .addFilterBefore(
|
.authenticated())
|
||||||
// jwtAuthenticationFilter,
|
.addFilterBefore(
|
||||||
// UsernamePasswordAuthenticationFilter
|
jwtAuthenticationFilter,
|
||||||
// .class) // 요청 들어오면 먼저 JWT 토큰 검사 후 security context 에 사용자 정보 저장.
|
UsernamePasswordAuthenticationFilter
|
||||||
|
.class) // 요청 들어오면 먼저 JWT 토큰 검사 후 security context 에 사용자 정보 저장.
|
||||||
|
*/
|
||||||
http.csrf(csrf -> csrf.disable())
|
http.csrf(csrf -> csrf.disable())
|
||||||
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||||
.formLogin(form -> form.disable())
|
.formLogin(form -> form.disable())
|
||||||
.httpBasic(basic -> basic.disable())
|
.httpBasic(basic -> basic.disable())
|
||||||
.logout(logout -> logout.disable())
|
.logout(logout -> logout.disable())
|
||||||
.authenticationProvider(customAuthenticationProvider)
|
.authenticationProvider(customAuthenticationProvider)
|
||||||
.authorizeHttpRequests(
|
.authorizeHttpRequests(
|
||||||
auth -> auth.anyRequest().permitAll() // 🔥 인증 필요 없음
|
auth -> auth.anyRequest().permitAll() // 🔥 인증 필요 없음
|
||||||
);
|
);
|
||||||
;
|
;
|
||||||
|
|
||||||
return http.build();
|
return http.build();
|
||||||
@@ -66,10 +68,15 @@ public class SecurityConfig {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration)
|
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
return configuration.getAuthenticationManager();
|
return configuration.getAuthenticationManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CORS 설정
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public CorsConfigurationSource corsConfigurationSource() {
|
public CorsConfigurationSource corsConfigurationSource() {
|
||||||
CorsConfiguration config = new CorsConfiguration(); // CORS 객체 생성
|
CorsConfiguration config = new CorsConfiguration(); // CORS 객체 생성
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.kamco.cd.kamcoback.config;
|
package com.kamco.cd.kamcoback.config;
|
||||||
|
|
||||||
// @Configuration
|
//@Configuration
|
||||||
// @SecurityScheme(
|
//@SecurityScheme(
|
||||||
// name = "BearerAuth",
|
// name = "BearerAuth",
|
||||||
// type = SecuritySchemeType.HTTP,
|
// type = SecuritySchemeType.HTTP,
|
||||||
// scheme = "bearer",
|
// scheme = "bearer",
|
||||||
// bearerFormat = "JWT"
|
// bearerFormat = "JWT"
|
||||||
// )
|
//)
|
||||||
public class SwaggerConfig {}
|
public class SwaggerConfig {
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ public class ApiLogFunction {
|
|||||||
// 사용자 ID 추출 예시 (Spring Security 기준)
|
// 사용자 ID 추출 예시 (Spring Security 기준)
|
||||||
public static String getUserId(HttpServletRequest request) {
|
public static String getUserId(HttpServletRequest request) {
|
||||||
try {
|
try {
|
||||||
Object userId = request.getUserPrincipal();
|
|
||||||
return request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : null;
|
return request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
@@ -65,22 +64,22 @@ public class ApiLogFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String getRequestBody(
|
public static String getRequestBody(
|
||||||
HttpServletRequest servletRequest, ContentCachingRequestWrapper contentWrapper) {
|
HttpServletRequest servletRequest, ContentCachingRequestWrapper contentWrapper) {
|
||||||
StringBuilder resultBody = new StringBuilder();
|
StringBuilder resultBody = new StringBuilder();
|
||||||
// GET, form-urlencoded POST 파라미터
|
// GET, form-urlencoded POST 파라미터
|
||||||
Map<String, String[]> paramMap = servletRequest.getParameterMap();
|
Map<String, String[]> paramMap = servletRequest.getParameterMap();
|
||||||
|
|
||||||
String queryParams =
|
String queryParams =
|
||||||
paramMap.entrySet().stream()
|
paramMap.entrySet().stream()
|
||||||
.map(e -> e.getKey() + "=" + String.join(",", e.getValue()))
|
.map(e -> e.getKey() + "=" + String.join(",", e.getValue()))
|
||||||
.collect(Collectors.joining("&"));
|
.collect(Collectors.joining("&"));
|
||||||
|
|
||||||
resultBody.append(queryParams.isEmpty() ? "" : queryParams);
|
resultBody.append(queryParams.isEmpty() ? "" : queryParams);
|
||||||
|
|
||||||
// JSON Body
|
// JSON Body
|
||||||
if ("POST".equalsIgnoreCase(servletRequest.getMethod())
|
if ("POST".equalsIgnoreCase(servletRequest.getMethod())
|
||||||
&& servletRequest.getContentType() != null
|
&& servletRequest.getContentType() != null
|
||||||
&& servletRequest.getContentType().contains("application/json")) {
|
&& servletRequest.getContentType().contains("application/json")) {
|
||||||
try {
|
try {
|
||||||
// json인 경우는 Wrapper를 통해 가져오기
|
// json인 경우는 Wrapper를 통해 가져오기
|
||||||
resultBody.append(getBodyData(contentWrapper));
|
resultBody.append(getBodyData(contentWrapper));
|
||||||
@@ -92,8 +91,8 @@ public class ApiLogFunction {
|
|||||||
|
|
||||||
// Multipart form-data
|
// Multipart form-data
|
||||||
if ("POST".equalsIgnoreCase(servletRequest.getMethod())
|
if ("POST".equalsIgnoreCase(servletRequest.getMethod())
|
||||||
&& servletRequest.getContentType() != null
|
&& servletRequest.getContentType() != null
|
||||||
&& servletRequest.getContentType().startsWith("multipart/form-data")) {
|
&& servletRequest.getContentType().startsWith("multipart/form-data")) {
|
||||||
resultBody.append("multipart/form-data request");
|
resultBody.append("multipart/form-data request");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
package com.kamco.cd.kamcoback.config.api;
|
package com.kamco.cd.kamcoback.config.api;
|
||||||
|
|
||||||
|
import com.kamco.cd.kamcoback.auth.CustomUserDetails;
|
||||||
import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity;
|
import com.kamco.cd.kamcoback.postgres.entity.AuditLogEntity;
|
||||||
import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository;
|
import com.kamco.cd.kamcoback.postgres.repository.log.AuditLogRepository;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.util.Optional;
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.server.ServerHttpRequest;
|
import org.springframework.http.server.ServerHttpRequest;
|
||||||
import org.springframework.http.server.ServerHttpResponse;
|
import org.springframework.http.server.ServerHttpResponse;
|
||||||
import org.springframework.http.server.ServletServerHttpRequest;
|
import org.springframework.http.server.ServletServerHttpRequest;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||||
import org.springframework.web.util.ContentCachingRequestWrapper;
|
import org.springframework.web.util.ContentCachingRequestWrapper;
|
||||||
@@ -30,19 +31,19 @@ public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(
|
public boolean supports(
|
||||||
MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||||
// ApiResponseDto를 반환하는 경우에만 적용
|
// ApiResponseDto를 반환하는 경우에만 적용
|
||||||
return returnType.getParameterType().equals(ApiResponseDto.class);
|
return returnType.getParameterType().equals(ApiResponseDto.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object beforeBodyWrite(
|
public Object beforeBodyWrite(
|
||||||
Object body,
|
Object body,
|
||||||
MethodParameter returnType,
|
MethodParameter returnType,
|
||||||
MediaType selectedContentType,
|
MediaType selectedContentType,
|
||||||
Class<? extends HttpMessageConverter<?>> selectedConverterType,
|
Class<? extends HttpMessageConverter<?>> selectedConverterType,
|
||||||
ServerHttpRequest request,
|
ServerHttpRequest request,
|
||||||
ServerHttpResponse response) {
|
ServerHttpResponse response) {
|
||||||
|
|
||||||
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
|
HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
|
||||||
ContentCachingRequestWrapper contentWrapper = (ContentCachingRequestWrapper) servletRequest;
|
ContentCachingRequestWrapper contentWrapper = (ContentCachingRequestWrapper) servletRequest;
|
||||||
@@ -52,21 +53,34 @@ public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
|
|||||||
response.setStatusCode(apiResponse.getHttpStatus());
|
response.setStatusCode(apiResponse.getHttpStatus());
|
||||||
|
|
||||||
String ip = ApiLogFunction.getClientIp(servletRequest);
|
String ip = ApiLogFunction.getClientIp(servletRequest);
|
||||||
// TODO : userid 가 계정명인지, uid 인지 확인 후 로직 수정 필요함
|
|
||||||
Long userid =
|
|
||||||
Long.valueOf(Optional.ofNullable(ApiLogFunction.getUserId(servletRequest)).orElse("1"));
|
|
||||||
|
|
||||||
|
Long userid = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* servletRequest.getUserPrincipal() instanceof UsernamePasswordAuthenticationToken auth
|
||||||
|
* 이 요청이 JWT 인증을 통과한 요청인가? 그리고 Spring Security Authentication 객체가 UsernamePasswordAuthenticationToken 타입인가? 체크
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* auth.getPrincipal() instanceof CustomUserDetails customUserDetails
|
||||||
|
* principal 안에 들어있는 객체가 내가 만든 CustomUserDetails 타입인가? 체크
|
||||||
|
*/
|
||||||
|
if (servletRequest.getUserPrincipal() instanceof UsernamePasswordAuthenticationToken auth
|
||||||
|
&& auth.getPrincipal() instanceof CustomUserDetails customUserDetails) {
|
||||||
|
|
||||||
|
// audit 에는 long 타입 user_id가 들어가지만 토큰 sub은 uuid여서 user_id 가져오기
|
||||||
|
userid = customUserDetails.getMember().getId();
|
||||||
|
}
|
||||||
// TODO: menuUid 를 동적으로 가져오게끔 해야함
|
// TODO: menuUid 를 동적으로 가져오게끔 해야함
|
||||||
AuditLogEntity log =
|
AuditLogEntity log =
|
||||||
new AuditLogEntity(
|
new AuditLogEntity(
|
||||||
userid,
|
userid,
|
||||||
ApiLogFunction.getEventType(servletRequest),
|
ApiLogFunction.getEventType(servletRequest),
|
||||||
ApiLogFunction.isSuccessFail(apiResponse),
|
ApiLogFunction.isSuccessFail(apiResponse),
|
||||||
"MU_01_01",
|
"MU_01_01",
|
||||||
ip,
|
ip,
|
||||||
servletRequest.getRequestURI(),
|
servletRequest.getRequestURI(),
|
||||||
ApiLogFunction.getRequestBody(servletRequest, contentWrapper),
|
ApiLogFunction.getRequestBody(servletRequest, contentWrapper),
|
||||||
apiResponse.getErrorLogUid());
|
apiResponse.getErrorLogUid());
|
||||||
|
|
||||||
// tb_audit_log 테이블 저장
|
// tb_audit_log 테이블 저장
|
||||||
auditLogRepository.save(log);
|
auditLogRepository.save(log);
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import io.swagger.v3.oas.annotations.tags.Tag;
|
|||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import lombok.RequiredArgsConstructor;
|
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.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
@@ -28,159 +30,160 @@ public class AdminApiController {
|
|||||||
|
|
||||||
@Operation(summary = "회원가입", description = "회원가입")
|
@Operation(summary = "회원가입", description = "회원가입")
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "201",
|
responseCode = "201",
|
||||||
description = "회원가입 성공",
|
description = "회원가입 성공",
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = Long.class))),
|
schema = @Schema(implementation = Long.class))),
|
||||||
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
||||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
})
|
||||||
@PostMapping("/join")
|
@PostMapping("/join")
|
||||||
public ApiResponseDto<Long> saveMember(
|
public ApiResponseDto<Long> saveMember(
|
||||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||||
description = "회원가입",
|
description = "회원가입",
|
||||||
required = true,
|
required = true,
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = MembersDto.AddReq.class)))
|
schema = @Schema(implementation = MembersDto.AddReq.class)))
|
||||||
@RequestBody
|
@RequestBody
|
||||||
@Valid
|
@Valid
|
||||||
MembersDto.AddReq addReq) {
|
MembersDto.AddReq addReq) {
|
||||||
|
|
||||||
return ApiResponseDto.createOK(adminService.saveMember(addReq));
|
return ApiResponseDto.createOK(adminService.saveMember(addReq));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "역할 추가", description = "uuid 기준으로 역할 추가")
|
@Operation(summary = "역할 추가", description = "uuid 기준으로 역할 추가")
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "201",
|
responseCode = "201",
|
||||||
description = "역할 추가",
|
description = "역할 추가",
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = UUID.class))),
|
schema = @Schema(implementation = UUID.class))),
|
||||||
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
||||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
})
|
||||||
@PostMapping("/roles/add")
|
@PostMapping("/roles/add")
|
||||||
public ApiResponseDto<UUID> saveRoles(
|
public ApiResponseDto<UUID> saveRoles(
|
||||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||||
description = "역할 추가",
|
description = "역할 추가",
|
||||||
required = true,
|
required = true,
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = MembersDto.RolesDto.class)))
|
schema = @Schema(implementation = MembersDto.RolesDto.class)))
|
||||||
@RequestBody
|
@RequestBody
|
||||||
@Valid
|
@Valid
|
||||||
MembersDto.RolesDto rolesDto) {
|
MembersDto.RolesDto rolesDto) {
|
||||||
adminService.saveRoles(rolesDto);
|
adminService.saveRoles(rolesDto);
|
||||||
return ApiResponseDto.createOK(rolesDto.getUuid());
|
return ApiResponseDto.createOK(rolesDto.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "역할 삭제", description = "uuid 기준으로 역할 삭제")
|
@Operation(summary = "역할 삭제", description = "uuid 기준으로 역할 삭제")
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "201",
|
responseCode = "201",
|
||||||
description = "역할 삭제",
|
description = "역할 삭제",
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = UUID.class))),
|
schema = @Schema(implementation = UUID.class))),
|
||||||
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
||||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
})
|
||||||
@PostMapping("/roles/rm")
|
@DeleteMapping("/roles/rm")
|
||||||
public ApiResponseDto<UUID> deleteRoles(
|
public ApiResponseDto<UUID> deleteRoles(
|
||||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||||
description = "역할 삭제",
|
description = "역할 삭제",
|
||||||
required = true,
|
required = true,
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = MembersDto.RolesDto.class)))
|
schema = @Schema(implementation = MembersDto.RolesDto.class)))
|
||||||
@RequestBody
|
@RequestBody
|
||||||
@Valid
|
@Valid
|
||||||
MembersDto.RolesDto rolesDto) {
|
MembersDto.RolesDto rolesDto) {
|
||||||
adminService.deleteRoles(rolesDto);
|
adminService.deleteRoles(rolesDto);
|
||||||
return ApiResponseDto.createOK(rolesDto.getUuid());
|
return ApiResponseDto.createOK(rolesDto.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "상태 수정", description = "상태 수정")
|
@Operation(summary = "상태 수정", description = "상태 수정")
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "201",
|
responseCode = "201",
|
||||||
description = "상태 수정",
|
description = "상태 수정",
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = UUID.class))),
|
schema = @Schema(implementation = UUID.class))),
|
||||||
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
||||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
})
|
||||||
@PostMapping("/status/update")
|
@PatchMapping("{uuid}/status")
|
||||||
public ApiResponseDto<UUID> updateStatus(
|
public ApiResponseDto<UUID> updateStatus(
|
||||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||||
description = "상태 수정",
|
description = "상태 수정",
|
||||||
required = true,
|
required = true,
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = MembersDto.StatusDto.class)))
|
schema = @Schema(implementation = MembersDto.StatusDto.class)))
|
||||||
@RequestBody
|
@PathVariable UUID uuid,
|
||||||
@Valid
|
@RequestBody
|
||||||
MembersDto.StatusDto statusDto) {
|
@Valid
|
||||||
adminService.updateStatus(statusDto);
|
MembersDto.StatusDto statusDto) {
|
||||||
return ApiResponseDto.createOK(statusDto.getUuid());
|
adminService.updateStatus(uuid, statusDto);
|
||||||
|
return ApiResponseDto.createOK(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "회원 탈퇴", description = "회원 탈퇴")
|
@Operation(summary = "회원 탈퇴", description = "회원 탈퇴")
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "201",
|
responseCode = "201",
|
||||||
description = "회원 탈퇴",
|
description = "회원 탈퇴",
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = UUID.class))),
|
schema = @Schema(implementation = UUID.class))),
|
||||||
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
||||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
})
|
||||||
@PostMapping("/delete-account")
|
@DeleteMapping("/delete/{uuid}")
|
||||||
public ApiResponseDto<UUID> deleteAccount(MembersDto.StatusDto statusDto) {
|
public ApiResponseDto<UUID> deleteAccount(@PathVariable UUID uuid) {
|
||||||
adminService.deleteAccount(statusDto);
|
adminService.deleteAccount(uuid);
|
||||||
return ApiResponseDto.createOK(statusDto.getUuid());
|
return ApiResponseDto.createOK(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "패스워드 초기화", description = "패스워드 초기화")
|
@Operation(summary = "비밀번호 초기화", description = "비밀번호 초기화")
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "201",
|
responseCode = "201",
|
||||||
description = "패스워드 초기화",
|
description = "비밀번호 초기화",
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = Long.class))),
|
schema = @Schema(implementation = Long.class))),
|
||||||
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
||||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
})
|
||||||
@PostMapping("/{memberId}/password")
|
@PatchMapping("/{memberId}/password")
|
||||||
public ApiResponseDto<Long> resetPassword(@PathVariable Long memberId) {
|
public ApiResponseDto<Long> resetPassword(@PathVariable Long memberId) {
|
||||||
adminService.resetPassword(memberId);
|
adminService.resetPassword(memberId);
|
||||||
return ApiResponseDto.createOK(memberId);
|
return ApiResponseDto.createOK(memberId);
|
||||||
|
|||||||
@@ -41,27 +41,27 @@ public class AuthController {
|
|||||||
private boolean refreshCookieSecure;
|
private boolean refreshCookieSecure;
|
||||||
|
|
||||||
@PostMapping("/signin")
|
@PostMapping("/signin")
|
||||||
@Operation(summary = "로그인", description = "사번 또는 이메일과 비밀번호로 로그인하여 액세스/리프레시 토큰을 발급합니다.")
|
@Operation(summary = "로그인", description = "사번으로 로그인하여 액세스/리프레시 토큰을 발급.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "200",
|
responseCode = "200",
|
||||||
description = "로그인 성공",
|
description = "로그인 성공",
|
||||||
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
|
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "401",
|
responseCode = "401",
|
||||||
description = "ID 또는 비밀번호 불일치",
|
description = "ID 또는 비밀번호 불일치",
|
||||||
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
||||||
})
|
})
|
||||||
public ResponseEntity<TokenResponse> signin(
|
public ResponseEntity<TokenResponse> signin(
|
||||||
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
@io.swagger.v3.oas.annotations.parameters.RequestBody(
|
||||||
description = "로그인 요청 정보",
|
description = "로그인 요청 정보",
|
||||||
required = true)
|
required = true)
|
||||||
@RequestBody
|
@RequestBody
|
||||||
SignInRequest request,
|
SignInRequest request,
|
||||||
HttpServletResponse response) {
|
HttpServletResponse response) {
|
||||||
Authentication authentication =
|
Authentication authentication =
|
||||||
authenticationManager.authenticate(
|
authenticationManager.authenticate(
|
||||||
new UsernamePasswordAuthenticationToken(request.username(), request.password()));
|
new UsernamePasswordAuthenticationToken(request.username(), request.password()));
|
||||||
|
|
||||||
String username = authentication.getName(); // UserDetailsService 에서 사용한 username
|
String username = authentication.getName(); // UserDetailsService 에서 사용한 username
|
||||||
|
|
||||||
@@ -70,17 +70,17 @@ public class AuthController {
|
|||||||
|
|
||||||
// Redis에 RefreshToken 저장 (TTL = 7일)
|
// Redis에 RefreshToken 저장 (TTL = 7일)
|
||||||
refreshTokenService.save(
|
refreshTokenService.save(
|
||||||
username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
|
username, refreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
|
||||||
|
|
||||||
// HttpOnly + Secure 쿠키에 RefreshToken 저장
|
// HttpOnly + Secure 쿠키에 RefreshToken 저장
|
||||||
ResponseCookie cookie =
|
ResponseCookie cookie =
|
||||||
ResponseCookie.from(refreshCookieName, refreshToken)
|
ResponseCookie.from(refreshCookieName, refreshToken)
|
||||||
.httpOnly(true)
|
.httpOnly(true)
|
||||||
.secure(refreshCookieSecure) // 로컬 개발에서 http만 쓰면 false 로 바꿔야 할 수도 있음
|
.secure(refreshCookieSecure)
|
||||||
.path("/")
|
.path("/")
|
||||||
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
|
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
|
||||||
.sameSite("Strict")
|
.sameSite("Strict")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
||||||
|
|
||||||
@@ -91,13 +91,13 @@ public class AuthController {
|
|||||||
@Operation(summary = "토큰 재발급", description = "리프레시 토큰으로 새로운 액세스/리프레시 토큰을 재발급합니다.")
|
@Operation(summary = "토큰 재발급", description = "리프레시 토큰으로 새로운 액세스/리프레시 토큰을 재발급합니다.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "200",
|
responseCode = "200",
|
||||||
description = "재발급 성공",
|
description = "재발급 성공",
|
||||||
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
|
content = @Content(schema = @Schema(implementation = TokenResponse.class))),
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "401",
|
responseCode = "401",
|
||||||
description = "만료되었거나 유효하지 않은 리프레시 토큰",
|
description = "만료되었거나 유효하지 않은 리프레시 토큰",
|
||||||
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
content = @Content(schema = @Schema(implementation = ErrorResponse.class)))
|
||||||
})
|
})
|
||||||
public ResponseEntity<TokenResponse> refresh(String refreshToken, HttpServletResponse response) {
|
public ResponseEntity<TokenResponse> refresh(String refreshToken, HttpServletResponse response) {
|
||||||
if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) {
|
if (refreshToken == null || !jwtTokenProvider.isValidToken(refreshToken)) {
|
||||||
@@ -117,29 +117,29 @@ public class AuthController {
|
|||||||
|
|
||||||
// Redis 갱신
|
// Redis 갱신
|
||||||
refreshTokenService.save(
|
refreshTokenService.save(
|
||||||
username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
|
username, newRefreshToken, jwtTokenProvider.getRefreshTokenValidityInMs());
|
||||||
|
|
||||||
// 쿠키 갱신
|
// 쿠키 갱신
|
||||||
ResponseCookie cookie =
|
ResponseCookie cookie =
|
||||||
ResponseCookie.from(refreshCookieName, newRefreshToken)
|
ResponseCookie.from(refreshCookieName, newRefreshToken)
|
||||||
.httpOnly(true)
|
.httpOnly(true)
|
||||||
.secure(refreshCookieSecure)
|
.secure(refreshCookieSecure)
|
||||||
.path("/")
|
.path("/")
|
||||||
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
|
.maxAge(Duration.ofMillis(jwtTokenProvider.getRefreshTokenValidityInMs()))
|
||||||
.sameSite("Strict")
|
.sameSite("Strict")
|
||||||
.build();
|
.build();
|
||||||
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
||||||
|
|
||||||
return ResponseEntity.ok(new TokenResponse(newAccessToken));
|
return ResponseEntity.ok(new TokenResponse(newAccessToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/logout")
|
@PostMapping("/logout")
|
||||||
@Operation(summary = "로그아웃", description = "현재 사용자의 토큰을 무효화(블랙리스트 처리 또는 리프레시 토큰 삭제)합니다.")
|
@Operation(summary = "로그아웃", description = "현재 사용자의 토큰을 무효화(리프레시 토큰 삭제)합니다.")
|
||||||
@ApiResponses({
|
@ApiResponses({
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "200",
|
responseCode = "200",
|
||||||
description = "로그아웃 성공",
|
description = "로그아웃 성공",
|
||||||
content = @Content(schema = @Schema(implementation = Void.class)))
|
content = @Content(schema = @Schema(implementation = Void.class)))
|
||||||
})
|
})
|
||||||
public ResponseEntity<Void> logout(Authentication authentication, HttpServletResponse response) {
|
public ResponseEntity<Void> logout(Authentication authentication, HttpServletResponse response) {
|
||||||
if (authentication != null) {
|
if (authentication != null) {
|
||||||
@@ -150,13 +150,13 @@ public class AuthController {
|
|||||||
|
|
||||||
// 쿠키 삭제 (Max-Age=0)
|
// 쿠키 삭제 (Max-Age=0)
|
||||||
ResponseCookie cookie =
|
ResponseCookie cookie =
|
||||||
ResponseCookie.from(refreshCookieName, "")
|
ResponseCookie.from(refreshCookieName, "")
|
||||||
.httpOnly(true)
|
.httpOnly(true)
|
||||||
.secure(refreshCookieSecure)
|
.secure(refreshCookieSecure)
|
||||||
.path("/")
|
.path("/")
|
||||||
.maxAge(0)
|
.maxAge(0)
|
||||||
.sameSite("Strict")
|
.sameSite("Strict")
|
||||||
.build();
|
.build();
|
||||||
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
|
||||||
|
|
||||||
return ResponseEntity.noContent().build();
|
return ResponseEntity.noContent().build();
|
||||||
@@ -164,8 +164,12 @@ public class AuthController {
|
|||||||
|
|
||||||
@Schema(description = "로그인 요청 DTO")
|
@Schema(description = "로그인 요청 DTO")
|
||||||
public record SignInRequest(
|
public record SignInRequest(
|
||||||
@Schema(description = "사번", example = "11111") String username,
|
@Schema(description = "사번", example = "11111") String username,
|
||||||
@Schema(description = "비밀번호", example = "kamco1234!") String password) {}
|
@Schema(description = "비밀번호", example = "kamco1234!") String password) {
|
||||||
|
|
||||||
public record TokenResponse(String accessToken) {}
|
}
|
||||||
|
|
||||||
|
public record TokenResponse(String accessToken) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import org.springdoc.core.annotations.ParameterObject;
|
|||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
@@ -31,40 +31,40 @@ public class MembersApiController {
|
|||||||
|
|
||||||
@Operation(summary = "회원정보 목록", description = "회원정보 조회")
|
@Operation(summary = "회원정보 목록", description = "회원정보 조회")
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "200",
|
responseCode = "200",
|
||||||
description = "검색 성공",
|
description = "검색 성공",
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = Page.class))),
|
schema = @Schema(implementation = Page.class))),
|
||||||
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
|
@ApiResponse(responseCode = "400", description = "잘못된 검색 조건", content = @Content),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
})
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public ApiResponseDto<Page<Basic>> getMemberList(
|
public ApiResponseDto<Page<Basic>> getMemberList(
|
||||||
@ParameterObject MembersDto.SearchReq searchReq) {
|
@ParameterObject MembersDto.SearchReq searchReq) {
|
||||||
return ApiResponseDto.ok(membersService.findByMembers(searchReq));
|
return ApiResponseDto.ok(membersService.findByMembers(searchReq));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "회원정보 수정", description = "회원정보 수정")
|
@Operation(summary = "회원정보 수정", description = "회원정보 수정")
|
||||||
@ApiResponses(
|
@ApiResponses(
|
||||||
value = {
|
value = {
|
||||||
@ApiResponse(
|
@ApiResponse(
|
||||||
responseCode = "201",
|
responseCode = "201",
|
||||||
description = "회원정보 수정",
|
description = "회원정보 수정",
|
||||||
content =
|
content =
|
||||||
@Content(
|
@Content(
|
||||||
mediaType = "application/json",
|
mediaType = "application/json",
|
||||||
schema = @Schema(implementation = UUID.class))),
|
schema = @Schema(implementation = UUID.class))),
|
||||||
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
@ApiResponse(responseCode = "400", description = "잘못된 요청 데이터", content = @Content),
|
||||||
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
@ApiResponse(responseCode = "404", description = "코드를 찾을 수 없음", content = @Content),
|
||||||
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
@ApiResponse(responseCode = "500", description = "서버 오류", content = @Content)
|
||||||
})
|
})
|
||||||
@PostMapping("/{uuid}")
|
@PutMapping("/{uuid}")
|
||||||
public ApiResponseDto<UUID> updateMember(
|
public ApiResponseDto<UUID> updateMember(
|
||||||
@PathVariable UUID uuid, @RequestBody MembersDto.UpdateReq updateReq) {
|
@PathVariable UUID uuid, @RequestBody MembersDto.UpdateReq updateReq) {
|
||||||
membersService.updateMember(uuid, updateReq);
|
membersService.updateMember(uuid, updateReq);
|
||||||
return ApiResponseDto.createOK(uuid);
|
return ApiResponseDto.createOK(uuid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,19 +28,21 @@ public class MembersDto {
|
|||||||
private String email;
|
private String email;
|
||||||
private String status;
|
private String status;
|
||||||
private String roleName;
|
private String roleName;
|
||||||
@JsonFormatDttm private ZonedDateTime createdDttm;
|
@JsonFormatDttm
|
||||||
@JsonFormatDttm private ZonedDateTime updatedDttm;
|
private ZonedDateTime createdDttm;
|
||||||
|
@JsonFormatDttm
|
||||||
|
private ZonedDateTime updatedDttm;
|
||||||
|
|
||||||
public Basic(
|
public Basic(
|
||||||
Long id,
|
Long id,
|
||||||
UUID uuid,
|
UUID uuid,
|
||||||
String employeeNo,
|
String employeeNo,
|
||||||
String name,
|
String name,
|
||||||
String email,
|
String email,
|
||||||
String status,
|
String status,
|
||||||
String roleName,
|
String roleName,
|
||||||
ZonedDateTime createdDttm,
|
ZonedDateTime createdDttm,
|
||||||
ZonedDateTime updatedDttm) {
|
ZonedDateTime updatedDttm) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.employeeNo = employeeNo;
|
this.employeeNo = employeeNo;
|
||||||
@@ -166,10 +168,6 @@ public class MembersDto {
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public static class StatusDto {
|
public static class StatusDto {
|
||||||
|
|
||||||
@Schema(description = "UUID", example = "4e89e487-c828-4a34-a7fc-0d5b0e3b53b5")
|
|
||||||
@NotBlank
|
|
||||||
private UUID uuid;
|
|
||||||
|
|
||||||
@Schema(description = "변경할 상태값 ACTIVE, INACTIVE, ARCHIVED", example = "ACTIVE")
|
@Schema(description = "변경할 상태값 ACTIVE, INACTIVE, ARCHIVED", example = "ACTIVE")
|
||||||
@NotBlank
|
@NotBlank
|
||||||
private String status;
|
private String status;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.kamco.cd.kamcoback.members.service;
|
|||||||
import com.kamco.cd.kamcoback.auth.BCryptSaltGenerator;
|
import com.kamco.cd.kamcoback.auth.BCryptSaltGenerator;
|
||||||
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
import com.kamco.cd.kamcoback.members.dto.MembersDto;
|
||||||
import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
|
import com.kamco.cd.kamcoback.postgres.core.MembersCoreService;
|
||||||
|
import java.util.UUID;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.mindrot.jbcrypt.BCrypt;
|
import org.mindrot.jbcrypt.BCrypt;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@@ -60,17 +61,17 @@ public class AdminService {
|
|||||||
*
|
*
|
||||||
* @param statusDto
|
* @param statusDto
|
||||||
*/
|
*/
|
||||||
public void updateStatus(MembersDto.StatusDto statusDto) {
|
public void updateStatus(UUID uuid, MembersDto.StatusDto statusDto) {
|
||||||
membersCoreService.updateStatus(statusDto);
|
membersCoreService.updateStatus(uuid, statusDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 회원 탈퇴
|
* 회원 탈퇴
|
||||||
*
|
*
|
||||||
* @param statusDto
|
* @param uuid
|
||||||
*/
|
*/
|
||||||
public void deleteAccount(MembersDto.StatusDto statusDto) {
|
public void deleteAccount(UUID uuid) {
|
||||||
membersCoreService.deleteAccount(statusDto);
|
membersCoreService.deleteAccount(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ public class MembersCoreService {
|
|||||||
public Long saveMembers(MembersDto.AddReq addReq) {
|
public Long saveMembers(MembersDto.AddReq addReq) {
|
||||||
if (membersRepository.existsByEmployeeNo(addReq.getEmployeeNo())) {
|
if (membersRepository.existsByEmployeeNo(addReq.getEmployeeNo())) {
|
||||||
throw new MemberException.DuplicateMemberException(
|
throw new MemberException.DuplicateMemberException(
|
||||||
MemberException.DuplicateMemberException.Field.EMPLOYEE_NO, addReq.getEmployeeNo());
|
MemberException.DuplicateMemberException.Field.EMPLOYEE_NO, addReq.getEmployeeNo());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (membersRepository.existsByEmail(addReq.getEmail())) {
|
if (membersRepository.existsByEmail(addReq.getEmail())) {
|
||||||
throw new MemberException.DuplicateMemberException(
|
throw new MemberException.DuplicateMemberException(
|
||||||
MemberException.DuplicateMemberException.Field.EMAIL, addReq.getEmail());
|
MemberException.DuplicateMemberException.Field.EMAIL, addReq.getEmail());
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberEntity memberEntity = new MemberEntity();
|
MemberEntity memberEntity = new MemberEntity();
|
||||||
@@ -66,7 +66,7 @@ public class MembersCoreService {
|
|||||||
*/
|
*/
|
||||||
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
|
public void updateMembers(UUID uuid, MembersDto.UpdateReq updateReq) {
|
||||||
MemberEntity memberEntity =
|
MemberEntity memberEntity =
|
||||||
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
|
membersRepository.findByUUID(uuid).orElseThrow(() -> new MemberNotFoundException());
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(memberEntity.getEmployeeNo())) {
|
if (StringUtils.isNotBlank(memberEntity.getEmployeeNo())) {
|
||||||
memberEntity.setEmployeeNo(updateReq.getEmployeeNo());
|
memberEntity.setEmployeeNo(updateReq.getEmployeeNo());
|
||||||
@@ -93,13 +93,13 @@ public class MembersCoreService {
|
|||||||
public void saveRoles(MembersDto.RolesDto rolesDto) {
|
public void saveRoles(MembersDto.RolesDto rolesDto) {
|
||||||
|
|
||||||
MemberEntity memberEntity =
|
MemberEntity memberEntity =
|
||||||
membersRepository
|
membersRepository
|
||||||
.findByUUID(rolesDto.getUuid())
|
.findByUUID(rolesDto.getUuid())
|
||||||
.orElseThrow(() -> new MemberNotFoundException());
|
.orElseThrow(() -> new MemberNotFoundException());
|
||||||
|
|
||||||
if (memberRoleRepository.findByUuidAndRoleName(rolesDto)) {
|
if (memberRoleRepository.findByUuidAndRoleName(rolesDto)) {
|
||||||
throw new MemberException.DuplicateMemberException(
|
throw new MemberException.DuplicateMemberException(
|
||||||
MemberException.DuplicateMemberException.Field.DEFAULT, "중복된 역할이 있습니다.");
|
MemberException.DuplicateMemberException.Field.DEFAULT, "중복된 역할이 있습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
|
MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
|
||||||
@@ -120,9 +120,9 @@ public class MembersCoreService {
|
|||||||
*/
|
*/
|
||||||
public void deleteRoles(MembersDto.RolesDto rolesDto) {
|
public void deleteRoles(MembersDto.RolesDto rolesDto) {
|
||||||
MemberEntity memberEntity =
|
MemberEntity memberEntity =
|
||||||
membersRepository
|
membersRepository
|
||||||
.findByUUID(rolesDto.getUuid())
|
.findByUUID(rolesDto.getUuid())
|
||||||
.orElseThrow(() -> new MemberNotFoundException());
|
.orElseThrow(() -> new MemberNotFoundException());
|
||||||
|
|
||||||
MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
|
MemberRoleEntityId memberRoleEntityId = new MemberRoleEntityId();
|
||||||
memberRoleEntityId.setMemberUuid(rolesDto.getUuid());
|
memberRoleEntityId.setMemberUuid(rolesDto.getUuid());
|
||||||
@@ -140,11 +140,11 @@ public class MembersCoreService {
|
|||||||
*
|
*
|
||||||
* @param statusDto
|
* @param statusDto
|
||||||
*/
|
*/
|
||||||
public void updateStatus(MembersDto.StatusDto statusDto) {
|
public void updateStatus(UUID uuid, MembersDto.StatusDto statusDto) {
|
||||||
MemberEntity memberEntity =
|
MemberEntity memberEntity =
|
||||||
membersRepository
|
membersRepository
|
||||||
.findByUUID(statusDto.getUuid())
|
.findByUUID(uuid)
|
||||||
.orElseThrow(() -> new MemberNotFoundException());
|
.orElseThrow(() -> new MemberNotFoundException());
|
||||||
|
|
||||||
memberEntity.setStatus(statusDto.getStatus());
|
memberEntity.setStatus(statusDto.getStatus());
|
||||||
memberEntity.setUpdatedDttm(ZonedDateTime.now());
|
memberEntity.setUpdatedDttm(ZonedDateTime.now());
|
||||||
@@ -154,13 +154,13 @@ public class MembersCoreService {
|
|||||||
/**
|
/**
|
||||||
* 회원 탈퇴
|
* 회원 탈퇴
|
||||||
*
|
*
|
||||||
* @param statusDto
|
* @param uuid
|
||||||
*/
|
*/
|
||||||
public void deleteAccount(MembersDto.StatusDto statusDto) {
|
public void deleteAccount(UUID uuid) {
|
||||||
MemberEntity memberEntity =
|
MemberEntity memberEntity =
|
||||||
membersRepository
|
membersRepository
|
||||||
.findByUUID(statusDto.getUuid())
|
.findByUUID(uuid)
|
||||||
.orElseThrow(() -> new MemberNotFoundException());
|
.orElseThrow(() -> new MemberNotFoundException());
|
||||||
|
|
||||||
MemberArchivedEntityId memberArchivedEntityId = new MemberArchivedEntityId();
|
MemberArchivedEntityId memberArchivedEntityId = new MemberArchivedEntityId();
|
||||||
memberArchivedEntityId.setUserId(memberEntity.getId());
|
memberArchivedEntityId.setUserId(memberEntity.getId());
|
||||||
@@ -193,10 +193,10 @@ public class MembersCoreService {
|
|||||||
*/
|
*/
|
||||||
public void resetPassword(Long id) {
|
public void resetPassword(Long id) {
|
||||||
MemberEntity memberEntity =
|
MemberEntity memberEntity =
|
||||||
membersRepository.findById(id).orElseThrow(() -> new MemberNotFoundException());
|
membersRepository.findById(id).orElseThrow(() -> new MemberNotFoundException());
|
||||||
|
|
||||||
String salt =
|
String salt =
|
||||||
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
|
BCryptSaltGenerator.generateSaltWithEmployeeNo(memberEntity.getEmployeeNo().trim());
|
||||||
// 패스워드 암호화, 초기 패스워드 고정
|
// 패스워드 암호화, 초기 패스워드 고정
|
||||||
String hashedPassword = BCrypt.hashpw(password, salt);
|
String hashedPassword = BCrypt.hashpw(password, salt);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user