From 026da5fdcff851724013673a8da26666e8b4570a Mon Sep 17 00:00:00 2001 From: Hyojin Ahn Date: Tue, 25 Nov 2025 08:42:26 -0500 Subject: [PATCH] =?UTF-8?q?[Common]=20-=20CORS=20=EC=A0=81=EC=9A=A9=20[Cus?= =?UTF-8?q?tomer]=20-=20Customer=20No=20=EC=82=AC=EC=9A=A9=20(MIS=20?= =?UTF-8?q?=EC=9A=A9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/goi/erp/config/SecurityConfig.java | 51 ++++++++++++------- .../erp/controller/CustomerController.java | 42 ++++++++++++++- .../erp/repository/CustomerRepository.java | 4 ++ .../com/goi/erp/service/CustomerService.java | 35 ++++++++++--- 4 files changed, 107 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/goi/erp/config/SecurityConfig.java b/src/main/java/com/goi/erp/config/SecurityConfig.java index 7c32b88..3dfe4ad 100644 --- a/src/main/java/com/goi/erp/config/SecurityConfig.java +++ b/src/main/java/com/goi/erp/config/SecurityConfig.java @@ -1,6 +1,9 @@ package com.goi.erp.config; import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; @@ -8,6 +11,10 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; @Configuration @EnableMethodSecurity // @PreAuthorize 등 사용 가능 @@ -18,25 +25,35 @@ public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - http - // CSRF 비활성화 (API 서버라면 stateless) - .csrf(csrf -> csrf.disable()) - - // 세션 사용 안함 - .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) - - // 요청 권한 설정 + http + .csrf(csrf -> csrf.disable()) // CSRF 비활성화 (API 서버라면 stateless) + .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) // 세션 사용 안함 .authorizeHttpRequests(auth -> auth - .requestMatchers( - "/swagger-ui/**", - "/v3/api-docs/**" - ).permitAll() // 인증 없이 접근 허용 - .anyRequest().authenticated() // 나머지는 JWT 인증 필요 - ) - - // JWT 필터 등록 - .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class); + .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll() + .anyRequest().authenticated() + ) // 요청 권한 설정 + .addFilterBefore(new CorsFilter(corsConfigurationSource()), UsernamePasswordAuthenticationFilter.class) // JWT 필터 전에 CorsFilter 등록 + .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class); // JWT 필터 return http.build(); } + + @Bean + public CorsConfigurationSource corsConfigurationSource() { + CorsConfiguration configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(Arrays.asList( + "http://192.168.2.172:8000", + "http://localhost:8000", + "http://127.0.0.1:8000", + "https://homotypical-bowen-unlanguid.ngrok-free.dev" + )); + configuration.setAllowedMethods(Arrays.asList("GET","POST","PUT","DELETE","OPTIONS")); + configuration.setAllowedHeaders(Arrays.asList("Authorization","Content-Type")); + configuration.setAllowCredentials(true); + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } + } diff --git a/src/main/java/com/goi/erp/controller/CustomerController.java b/src/main/java/com/goi/erp/controller/CustomerController.java index 205506b..e90d5d4 100644 --- a/src/main/java/com/goi/erp/controller/CustomerController.java +++ b/src/main/java/com/goi/erp/controller/CustomerController.java @@ -99,7 +99,7 @@ public class CustomerController { } // UPDATE - @PutMapping("/{uuid}") + @PatchMapping("/{uuid}") public ResponseEntity updateCustomer( @PathVariable UUID uuid, @RequestBody CustomerRequestDto requestDto) { @@ -136,4 +136,44 @@ public class CustomerController { customerService.deleteCustomer(uuid); return ResponseEntity.noContent().build(); } + + // from MIS + @GetMapping("/{cusNo}") + public ResponseEntity getCustomer(@PathVariable String cusNo) { + // 권한 체크 + PermissionAuthenticationToken auth = (PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + + if (auth == null || auth.getPermissionSet() == null) { + throw new AccessDeniedException("Permission information is missing"); + } + + PermissionSet permissionSet = auth.getPermissionSet(); + if (!PermissionChecker.canDeleteCRM(permissionSet)) { + throw new AccessDeniedException("You do not have permission to read all CRM data"); + } + + // + CustomerResponseDto customer = customerService.getCustomerByNo(cusNo); + return ResponseEntity.ok(customer); + } + + @PutMapping("/{cusNo}") + public ResponseEntity updateCustomer(@PathVariable String cusNo, + @RequestBody CustomerRequestDto dto) { + // 권한 체크 + PermissionAuthenticationToken auth = (PermissionAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); + + if (auth == null || auth.getPermissionSet() == null) { + throw new AccessDeniedException("Permission information is missing"); + } + + PermissionSet permissionSet = auth.getPermissionSet(); + if (!PermissionChecker.canDeleteCRM(permissionSet)) { + throw new AccessDeniedException("You do not have permission to read all CRM data"); + } + + // + CustomerResponseDto updated = customerService.updateCustomerByNo(cusNo, dto); + return ResponseEntity.ok(updated); + } } diff --git a/src/main/java/com/goi/erp/repository/CustomerRepository.java b/src/main/java/com/goi/erp/repository/CustomerRepository.java index 8d07dc4..453a3cf 100644 --- a/src/main/java/com/goi/erp/repository/CustomerRepository.java +++ b/src/main/java/com/goi/erp/repository/CustomerRepository.java @@ -31,4 +31,8 @@ public interface CustomerRepository extends JpaRepository { Page findAllCustomerDtos(Pageable pageable); Optional findByCusUuid(UUID cusUuid); + + // from MIS + Optional findByCusNo(String cusNo); + boolean existsByCusNo(String cusNo); } diff --git a/src/main/java/com/goi/erp/service/CustomerService.java b/src/main/java/com/goi/erp/service/CustomerService.java index 15b64df..844f1da 100644 --- a/src/main/java/com/goi/erp/service/CustomerService.java +++ b/src/main/java/com/goi/erp/service/CustomerService.java @@ -48,13 +48,12 @@ public class CustomerService { Customer customer = customerRepository.findByCusUuid(uuid) .orElseThrow(() -> new RuntimeException("Customer not found")); - customer.setCusName(dto.getCusName()); - customer.setCusNo(dto.getCusNo()); - customer.setCusStatus(dto.getCusStatus()); - customer.setCusAddress1(dto.getCusAddress1()); - customer.setCusAddress2(dto.getCusAddress2()); - customer.setCusCity(dto.getCusCity()); - customer.setCusProvince(dto.getCusProvince()); + if (dto.getCusName() != null) customer.setCusName(dto.getCusName()); + if (dto.getCusStatus() != null) customer.setCusStatus(dto.getCusStatus()); + if (dto.getCusAddress1() != null) customer.setCusAddress1(dto.getCusAddress1()); + if (dto.getCusAddress2() != null) customer.setCusAddress2(dto.getCusAddress2()); + if (dto.getCusCity() != null) customer.setCusCity(dto.getCusCity()); + if (dto.getCusProvince() != null) customer.setCusProvince(dto.getCusProvince()); customerRepository.save(customer); return mapToDto(customer); @@ -74,4 +73,26 @@ public class CustomerService { .cusStatus(customer.getCusStatus()) .build(); } + + // from MIS + public CustomerResponseDto getCustomerByNo(String cusNo) { + Customer customer = customerRepository.findByCusNo(cusNo) + .orElseThrow(() -> new RuntimeException("Customer not found")); + return mapToDto(customer); + } + + public CustomerResponseDto updateCustomerByNo(String cusNo, CustomerRequestDto dto) { + Customer customer = customerRepository.findByCusNo(cusNo) + .orElseThrow(() -> new RuntimeException("Customer not found")); + + customer.setCusName(dto.getCusName()); + customer.setCusStatus(dto.getCusStatus()); + customer.setCusAddress1(dto.getCusAddress1()); + customer.setCusAddress2(dto.getCusAddress2()); + customer.setCusCity(dto.getCusCity()); + customer.setCusProvince(dto.getCusProvince()); + + customerRepository.save(customer); + return mapToDto(customer); + } }