From 2474002bb1c1365dbf57b8d88e1448e7fe8f73f5 Mon Sep 17 00:00:00 2001 From: RonnyChan Date: Thu, 7 Aug 2025 19:55:58 +0800 Subject: [PATCH 1/6] [app-platform] Add black list endpoints config --- .../aipp/http/call/AippHttpCallService.java | 31 ++++++++++++++++- .../src/main/resources/application.yml | 5 ++- .../http/call/AippHttpCallServiceTest.java | 33 +++++++++++++++---- 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java index d6fcf9ac6a..bd939de078 100644 --- a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java +++ b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java @@ -14,6 +14,10 @@ import modelengine.fit.jade.aipp.http.call.command.HttpCallResult; import modelengine.fitframework.annotation.Component; import modelengine.fitframework.annotation.Fitable; +import modelengine.fitframework.annotation.Value; +import modelengine.fitframework.log.Logger; + +import java.util.List; /** * 表示 {@link HttpCallService} 的 aipp 实现。 @@ -23,16 +27,32 @@ */ @Component public class AippHttpCallService implements HttpCallService { + private static final Logger log = Logger.get(AippHttpCallService.class); + private final HttpCallCommandHandler handler; - public AippHttpCallService(HttpCallCommandHandler handler) { + private List blacklistHttpEndpoints; + + public AippHttpCallService(HttpCallCommandHandler handler, + @Value("${blacklist.httpEndpoints:[]}") List blacklistHttpEndpoints) { this.handler = handler; + this.blacklistHttpEndpoints = blacklistHttpEndpoints; } @Override @Fitable("aipp") public HttpResult httpCall(HttpRequest request) throws HttpClientException { notNull(request, "Http request cannot be null."); + + String url = request.getUrl(); + if (isInBlacklist(url)) { + log.error("The URL is in the blacklist."); + HttpResult result = new HttpResult(); + result.setStatus(-1); + result.setErrorMsg("The URL is in the blacklist."); + return result; + } + HttpCallCommand command = new HttpCallCommand(); command.setMethod(request.getHttpMethod()); command.setUrl(request.getUrl()); @@ -49,4 +69,13 @@ public HttpResult httpCall(HttpRequest request) throws HttpClientException { result.setData(httpCallResult.getData()); return result; } + + private boolean isInBlacklist(String url) { + for (String endpoint : blacklistHttpEndpoints) { + if (url.contains(endpoint)) { + return true; + } + } + return false; + } } diff --git a/app-builder/plugins/aipp-http-call/src/main/resources/application.yml b/app-builder/plugins/aipp-http-call/src/main/resources/application.yml index da4634c599..b4e3d0e94f 100644 --- a/app-builder/plugins/aipp-http-call/src/main/resources/application.yml +++ b/app-builder/plugins/aipp-http-call/src/main/resources/application.yml @@ -1,4 +1,7 @@ fit: beans: packages: - - 'modelengine.fit.jade.aipp.http.call' \ No newline at end of file + - 'modelengine.fit.jade.aipp.http.call' + +blacklist: + httpEndpoints: ${BLACKLIST_ENDPOINTS:} \ No newline at end of file diff --git a/app-builder/plugins/aipp-http-call/src/test/java/modelengine/fit/jade/aipp/http/call/AippHttpCallServiceTest.java b/app-builder/plugins/aipp-http-call/src/test/java/modelengine/fit/jade/aipp/http/call/AippHttpCallServiceTest.java index 47df044522..7903a52a17 100644 --- a/app-builder/plugins/aipp-http-call/src/test/java/modelengine/fit/jade/aipp/http/call/AippHttpCallServiceTest.java +++ b/app-builder/plugins/aipp-http-call/src/test/java/modelengine/fit/jade/aipp/http/call/AippHttpCallServiceTest.java @@ -19,6 +19,8 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.List; + /** * {@link AippHttpCallService}测试集。 * @@ -33,7 +35,7 @@ public class AippHttpCallServiceTest { @BeforeEach void setUp() { this.handler = mock(HttpCallCommandHandler.class); - this.httpCallService = new AippHttpCallService(this.handler); + this.httpCallService = new AippHttpCallService(this.handler, List.of("blacklist.com")); } @Test @@ -44,11 +46,7 @@ void shouldOk() { when(this.handler.handle(any())).thenReturn(httpResult); when(httpResult.getStatus()).thenReturn(200); - HttpRequest request = new HttpRequest(); - request.setHttpMethod("GET"); - request.setUrl("http://examples.com"); - request.setTimeout(1000); - request.setArgs(MapBuilder.get().put("111", "2222").build()); + HttpRequest request = constructHttpRequest("http://examples.com"); // when HttpResult result = this.httpCallService.httpCall(request); @@ -56,4 +54,27 @@ void shouldOk() { // then Assertions.assertEquals(200, result.getStatus()); } + + @Test + @DisplayName("黑名单网站调用失败") + void blackListShouldBeBlocked() { + // given + HttpRequest request = constructHttpRequest("http://blacklist.com"); + + // when + HttpResult result = this.httpCallService.httpCall(request); + + // then + Assertions.assertEquals(-1, result.getStatus()); + Assertions.assertEquals("The URL is in the blacklist.", result.getErrorMsg()); + } + + private static HttpRequest constructHttpRequest(String url) { + HttpRequest request = new HttpRequest(); + request.setHttpMethod("GET"); + request.setUrl(url); + request.setTimeout(1000); + request.setArgs(MapBuilder.get().put("111", "2222").build()); + return request; + } } From b4835941c6549629c91713fe69b5ba9189c27e7c Mon Sep 17 00:00:00 2001 From: RonnyChan Date: Fri, 8 Aug 2025 09:35:51 +0800 Subject: [PATCH 2/6] [app-platform] Modify httpEndpoints default value --- .../plugins/aipp-http-call/src/main/resources/application.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app-builder/plugins/aipp-http-call/src/main/resources/application.yml b/app-builder/plugins/aipp-http-call/src/main/resources/application.yml index b4e3d0e94f..513a9c8c65 100644 --- a/app-builder/plugins/aipp-http-call/src/main/resources/application.yml +++ b/app-builder/plugins/aipp-http-call/src/main/resources/application.yml @@ -4,4 +4,4 @@ fit: - 'modelengine.fit.jade.aipp.http.call' blacklist: - httpEndpoints: ${BLACKLIST_ENDPOINTS:} \ No newline at end of file + httpEndpoints: [] \ No newline at end of file From 3d3676b6a7c76ae65c54e1f944512b30a92d5fc5 Mon Sep 17 00:00:00 2001 From: RonnyChan Date: Fri, 8 Aug 2025 10:06:24 +0800 Subject: [PATCH 3/6] [app-platform] Follow review opinions. --- .../aipp/http/call/AippHttpCallService.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java index bd939de078..677f251a61 100644 --- a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java +++ b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java @@ -17,6 +17,7 @@ import modelengine.fitframework.annotation.Value; import modelengine.fitframework.log.Logger; +import java.net.URI; import java.util.List; /** @@ -45,11 +46,12 @@ public HttpResult httpCall(HttpRequest request) throws HttpClientException { notNull(request, "Http request cannot be null."); String url = request.getUrl(); - if (isInBlacklist(url)) { - log.error("The URL is in the blacklist."); + if (this.isInBlacklist(url)) { + String sanitizedUrl = this.sanitizeUrlForLog(url); + log.error("Blocked: URL is in the blacklist. Requested URL: {}", sanitizedUrl); HttpResult result = new HttpResult(); result.setStatus(-1); - result.setErrorMsg("The URL is in the blacklist."); + result.setErrorMsg("Invalid request."); return result; } @@ -70,6 +72,17 @@ public HttpResult httpCall(HttpRequest request) throws HttpClientException { return result; } + private String sanitizeUrlForLog(String url) { + try { + URI uri = new URI(url); + return uri.getScheme() + "://" + uri.getHost() + + (uri.getPort() != -1 ? ":" + uri.getPort() : "") + + uri.getPath(); + } catch (Exception e) { + return "redacted"; + } + } + private boolean isInBlacklist(String url) { for (String endpoint : blacklistHttpEndpoints) { if (url.contains(endpoint)) { From e0e3a00f939f558ec10bf2c9288c2c4897246337 Mon Sep 17 00:00:00 2001 From: RonnyChan Date: Fri, 8 Aug 2025 11:36:35 +0800 Subject: [PATCH 4/6] [app-platform] Follow review opinions. --- .../aipp/http/call/AippHttpCallService.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java index 677f251a61..04998c0a9a 100644 --- a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java +++ b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java @@ -47,8 +47,8 @@ public HttpResult httpCall(HttpRequest request) throws HttpClientException { String url = request.getUrl(); if (this.isInBlacklist(url)) { - String sanitizedUrl = this.sanitizeUrlForLog(url); - log.error("Blocked: URL is in the blacklist. Requested URL: {}", sanitizedUrl); + String baseOnly = this.getBaseUrlSafely(url); + log.error("Blocked: URL is in the blacklist. Base URL: {}", baseOnly); HttpResult result = new HttpResult(); result.setStatus(-1); result.setErrorMsg("Invalid request."); @@ -72,15 +72,17 @@ public HttpResult httpCall(HttpRequest request) throws HttpClientException { return result; } - private String sanitizeUrlForLog(String url) { - try { - URI uri = new URI(url); - return uri.getScheme() + "://" + uri.getHost() + - (uri.getPort() != -1 ? ":" + uri.getPort() : "") + - uri.getPath(); - } catch (Exception e) { - return "redacted"; + private String getBaseUrlSafely(String url) { + if (url == null || url.trim().isEmpty()) { + return "null_or_empty"; } + url = url.trim(); + int queryOrFragmentIndex = url.length(); + int q = url.indexOf('?'); + int f = url.indexOf('#'); + if (q != -1) queryOrFragmentIndex = Math.min(queryOrFragmentIndex, q); + if (f != -1) queryOrFragmentIndex = Math.min(queryOrFragmentIndex, f); + return url.substring(0, queryOrFragmentIndex); } private boolean isInBlacklist(String url) { From 9e859d6b9df299b5cf80546a93408dcc0dda606f Mon Sep 17 00:00:00 2001 From: RonnyChan Date: Fri, 8 Aug 2025 14:24:55 +0800 Subject: [PATCH 5/6] [app-platform] Follow review opinions. --- .../aipp/http/call/AippHttpCallService.java | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java index 04998c0a9a..3a7eba8fdb 100644 --- a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java +++ b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java @@ -17,7 +17,6 @@ import modelengine.fitframework.annotation.Value; import modelengine.fitframework.log.Logger; -import java.net.URI; import java.util.List; /** @@ -46,13 +45,14 @@ public HttpResult httpCall(HttpRequest request) throws HttpClientException { notNull(request, "Http request cannot be null."); String url = request.getUrl(); + if (url == null || url.trim().isEmpty()) { + log.error("Blocked: URL is null or empty."); + return createErrorResponse(); + } if (this.isInBlacklist(url)) { String baseOnly = this.getBaseUrlSafely(url); log.error("Blocked: URL is in the blacklist. Base URL: {}", baseOnly); - HttpResult result = new HttpResult(); - result.setStatus(-1); - result.setErrorMsg("Invalid request."); - return result; + return createErrorResponse(); } HttpCallCommand command = new HttpCallCommand(); @@ -73,24 +73,21 @@ public HttpResult httpCall(HttpRequest request) throws HttpClientException { } private String getBaseUrlSafely(String url) { - if (url == null || url.trim().isEmpty()) { - return "null_or_empty"; + int queryOrFragmentIndex = Math.min(url.indexOf('?'), url.indexOf('#')); + if (queryOrFragmentIndex < 0) { + queryOrFragmentIndex = url.length(); } - url = url.trim(); - int queryOrFragmentIndex = url.length(); - int q = url.indexOf('?'); - int f = url.indexOf('#'); - if (q != -1) queryOrFragmentIndex = Math.min(queryOrFragmentIndex, q); - if (f != -1) queryOrFragmentIndex = Math.min(queryOrFragmentIndex, f); return url.substring(0, queryOrFragmentIndex); } private boolean isInBlacklist(String url) { - for (String endpoint : blacklistHttpEndpoints) { - if (url.contains(endpoint)) { - return true; - } - } - return false; + return blacklistHttpEndpoints.stream().anyMatch(url::contains); + } + + private HttpResult createErrorResponse() { + HttpResult result = new HttpResult(); + result.setStatus(-1); + result.setErrorMsg("Invalid request."); + return result; } } From 3cfff1ac846281bec6d5e10f70137329ebebe5ec Mon Sep 17 00:00:00 2001 From: RonnyChan Date: Fri, 8 Aug 2025 14:31:59 +0800 Subject: [PATCH 6/6] [app-platform] Follow review opinions. --- .../fit/jade/aipp/http/call/AippHttpCallService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java index 3a7eba8fdb..9ad5d68ff9 100644 --- a/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java +++ b/app-builder/plugins/aipp-http-call/src/main/java/modelengine/fit/jade/aipp/http/call/AippHttpCallService.java @@ -16,6 +16,7 @@ import modelengine.fitframework.annotation.Fitable; import modelengine.fitframework.annotation.Value; import modelengine.fitframework.log.Logger; +import modelengine.fitframework.util.StringUtils; import java.util.List; @@ -45,7 +46,7 @@ public HttpResult httpCall(HttpRequest request) throws HttpClientException { notNull(request, "Http request cannot be null."); String url = request.getUrl(); - if (url == null || url.trim().isEmpty()) { + if (StringUtils.isBlank(url)) { log.error("Blocked: URL is null or empty."); return createErrorResponse(); }