EventType 화면 고정 제외 코드 필터링 로직 추가
- 제외 코드(CHECK_NOTICE 등) 구독 방지 위한 유효성 검사 강화 - 선택 가능한 EventType만 검증/표시하도록 로직 수정
This commit is contained in:
@@ -113,3 +113,4 @@ diff
|
||||
*gf63*
|
||||
*obsidian*
|
||||
design-backup
|
||||
/.envrc
|
||||
|
||||
@@ -210,8 +210,11 @@ public class WebhookController {
|
||||
modification.setId(webhook.getId());
|
||||
modification.setRequestType("MODIFY");
|
||||
modification.setTargetUrl(webhook.getTargetUrl());
|
||||
// 화면 고정 제외 코드(CHECK_NOTICE 등)는 체크박스가 렌더링되지 않으므로 세션 값에서도 제외한다.
|
||||
modification.setEventTypes(webhook.getEventTypes().stream()
|
||||
.map(e -> e.getCode()).collect(java.util.stream.Collectors.toList()));
|
||||
.map(e -> e.getCode())
|
||||
.filter(code -> !eventTypeProvider.isHidden(code))
|
||||
.collect(java.util.stream.Collectors.toList()));
|
||||
modification.setSelectedApis(new java.util.ArrayList<>(webhook.getApiIds()));
|
||||
model.addAttribute("webhookModification", modification);
|
||||
}
|
||||
@@ -374,7 +377,9 @@ public class WebhookController {
|
||||
bindingResult.rejectValue("targetUrl", "invalid.url",
|
||||
"올바른 URL 형식이 아닙니다. http:// 또는 https:// 로 시작하는 전체 주소를 입력해주세요.");
|
||||
}
|
||||
if (dto.getEventTypes() == null || dto.getEventTypes().isEmpty()) {
|
||||
boolean hasSelectableEventType = dto.getEventTypes() != null && dto.getEventTypes().stream()
|
||||
.anyMatch(code -> !eventTypeProvider.isHidden(code));
|
||||
if (!hasSelectableEventType) {
|
||||
bindingResult.rejectValue("eventTypes", "empty.eventTypes",
|
||||
"EventType을 1개 이상 선택해주세요.");
|
||||
}
|
||||
|
||||
+24
-1
@@ -2,9 +2,13 @@ package com.eactive.apim.portal.djb.webhook.service;
|
||||
|
||||
import com.eactive.apim.portal.djb.webhook.dto.WebhookEventTypeDTO;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -20,6 +24,14 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
@Component
|
||||
public class WebhookEventTypeProvider {
|
||||
|
||||
/**
|
||||
* 신청/수정 화면의 선택 목록에서 고정으로 제외하는 EventType 코드.
|
||||
* DB(TSEAIRM28)에 USEYN='Y' 로 남아 있어도 포털 사용자가 직접 구독할 수 없는 코드다.
|
||||
* 기존 데이터 표시(이름 조회)에는 영향이 없다.
|
||||
*/
|
||||
private static final Set<String> HIDDEN_CODES =
|
||||
Collections.unmodifiableSet(new HashSet<>(Arrays.asList("CHECK_NOTICE")));
|
||||
|
||||
private static final String EVENT_TYPE_SQL =
|
||||
"SELECT CODE, CODENAME FROM TSEAIRM28 "
|
||||
+ "WHERE CODEGROUP = 'EVENT_TYPE' AND USEYN = 'Y' "
|
||||
@@ -29,15 +41,25 @@ public class WebhookEventTypeProvider {
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
/** 신청/수정 화면에 노출할 선택 가능한 EventType 목록({@link #HIDDEN_CODES} 제외). */
|
||||
@Transactional(readOnly = true)
|
||||
public List<WebhookEventTypeDTO> getAll() {
|
||||
List<WebhookEventTypeDTO> list = new ArrayList<>();
|
||||
for (Object[] row : rows()) {
|
||||
list.add(new WebhookEventTypeDTO(asString(row[0]), asString(row[1])));
|
||||
String code = asString(row[0]);
|
||||
if (isHidden(code)) {
|
||||
continue;
|
||||
}
|
||||
list.add(new WebhookEventTypeDTO(code, asString(row[1])));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/** 화면 노출/구독 대상에서 고정 제외되는 코드인지 여부. */
|
||||
public boolean isHidden(String code) {
|
||||
return code != null && HIDDEN_CODES.contains(code);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Map<String, String> asMap() {
|
||||
Map<String, String> map = new LinkedHashMap<>();
|
||||
@@ -47,6 +69,7 @@ public class WebhookEventTypeProvider {
|
||||
return map;
|
||||
}
|
||||
|
||||
/** 코드 자체의 유효성(제외 코드 포함). 구독 가능 여부는 {@link #isHidden(String)} 로 별도 판단한다. */
|
||||
@Transactional(readOnly = true)
|
||||
public boolean isValid(String code) {
|
||||
if (code == null) {
|
||||
|
||||
@@ -161,7 +161,7 @@ public class WebhookService {
|
||||
for (String apiId : dedup(dto.getSelectedApis())) {
|
||||
apiRepository.save(new WebhookRequestApi(reqId, apiId));
|
||||
}
|
||||
for (String eventType : dedup(dto.getEventTypes())) {
|
||||
for (String eventType : selectableEventTypes(dto)) {
|
||||
if (!eventTypeProvider.isValid(eventType)) {
|
||||
throw new IllegalArgumentException("유효하지 않은 EventType 코드입니다: " + eventType);
|
||||
}
|
||||
@@ -169,11 +169,22 @@ public class WebhookService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 중복 제거 + 화면 고정 제외 코드(예: CHECK_NOTICE) 제거.
|
||||
* 제외 코드는 신청/수정 화면에 체크박스가 렌더링되지 않으므로 정상 경로로는 들어오지 않지만,
|
||||
* 세션에 남은 값이나 직접 조작한 요청으로 구독되지 않도록 저장 직전에 한 번 더 걸러낸다.
|
||||
*/
|
||||
private List<String> selectableEventTypes(WebhookRegistrationDTO dto) {
|
||||
return dedup(dto.getEventTypes()).stream()
|
||||
.filter(code -> !eventTypeProvider.isHidden(code))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void validate(WebhookRegistrationDTO dto) {
|
||||
if (!WebhookUrlValidator.isValid(dto.getTargetUrl())) {
|
||||
throw new IllegalArgumentException("올바른 URL 형식이 아닙니다. http:// 또는 https:// 로 시작하는 전체 주소를 입력해주세요.");
|
||||
}
|
||||
if (dto.getEventTypes() == null || dto.getEventTypes().isEmpty()) {
|
||||
if (selectableEventTypes(dto).isEmpty()) {
|
||||
throw new IllegalArgumentException("EventType을 1개 이상 선택해주세요.");
|
||||
}
|
||||
if (dto.getSelectedApis() == null || dto.getSelectedApis().isEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user