This is an automated email from the ASF dual-hosted git repository.
Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 1b3f0f7898 fix: validate namespace before config import (#7634)
1b3f0f7898 is described below
commit 1b3f0f78985e0b63a1a049fc2511491b136fa9f5
Author: Southern <[email protected]>
AuthorDate: Thu Oct 15 13:40:39 2026 +0800
fix: validate namespace before config import (#7634)
Validate that the target namespace exists before dispatching configuration
import data.
Reject imports for unknown namespaces to prevent orphaned
namespace-scoped records.
Add controller tests covering successful imports and rejected unknown
namespaces.
---
.../controller/ConfigsExportImportController.java | 10 +++++++++-
.../ConfigsExportImportControllerTest.java | 23 ++++++++++++++++++++++
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigsExportImportController.java
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigsExportImportController.java
index 1354b09248..6392ae436e 100644
---
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigsExportImportController.java
+++
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/controller/ConfigsExportImportController.java
@@ -22,6 +22,7 @@ import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.shenyu.admin.aspect.annotation.RestApi;
import org.apache.shenyu.admin.model.result.ShenyuAdminResult;
import org.apache.shenyu.admin.service.ConfigsService;
+import org.apache.shenyu.admin.service.NamespaceService;
import org.apache.shenyu.admin.service.SyncDataService;
import org.apache.shenyu.admin.utils.ShenyuResultMessage;
import org.apache.shenyu.common.constant.ExportImportConstants;
@@ -58,10 +59,14 @@ public class ConfigsExportImportController {
private final SyncDataService syncDataService;
+ private final NamespaceService namespaceService;
+
public ConfigsExportImportController(final ConfigsService configsService,
- final SyncDataService
syncDataService) {
+ final SyncDataService syncDataService,
+ final NamespaceService
namespaceService) {
this.configsService = configsService;
this.syncDataService = syncDataService;
+ this.namespaceService = namespaceService;
}
/**
@@ -134,6 +139,9 @@ public class ConfigsExportImportController {
if (StringUtils.isBlank(namespace) || Objects.isNull(file)) {
return
ShenyuAdminResult.error(ShenyuResultMessage.PARAMETER_ERROR);
}
+ if (Objects.isNull(namespaceService.findByNamespaceId(namespace))) {
+ return ShenyuAdminResult.error("namespace is not exist");
+ }
try {
ShenyuAdminResult importResult =
configsService.configsImport(namespace, file.getBytes());
if (Objects.equals(CommonErrorCode.SUCCESSFUL,
importResult.getCode())) {
diff --git
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ConfigsExportImportControllerTest.java
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ConfigsExportImportControllerTest.java
index f14d42173a..3a629906ce 100644
---
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ConfigsExportImportControllerTest.java
+++
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/controller/ConfigsExportImportControllerTest.java
@@ -19,7 +19,9 @@ package org.apache.shenyu.admin.controller;
import org.apache.shenyu.admin.exception.ExceptionHandlers;
import org.apache.shenyu.admin.model.result.ShenyuAdminResult;
+import org.apache.shenyu.admin.model.vo.NamespaceVO;
import org.apache.shenyu.admin.service.ConfigsService;
+import org.apache.shenyu.admin.service.NamespaceService;
import org.apache.shenyu.admin.service.SyncDataService;
import org.apache.shenyu.admin.utils.ShenyuResultMessage;
import org.apache.shenyu.admin.utils.ZipUtil;
@@ -43,6 +45,8 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.core.Is.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static
org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static
org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
@@ -72,6 +76,9 @@ public class ConfigsExportImportControllerTest {
@Mock
private SyncDataService syncDataService;
+ @Mock
+ private NamespaceService namespaceService;
+
@BeforeEach
public void setUp() {
this.mockMvc = MockMvcBuilders
@@ -106,6 +113,7 @@ public class ConfigsExportImportControllerTest {
when(this.configsService.configsImport(anyString(), any())).thenReturn(
ShenyuAdminResult.success(ShenyuResultMessage.SUCCESS));
+ when(this.namespaceService.findByNamespaceId("test")).thenReturn(new
NamespaceVO());
// mock file
MockMultipartFile file = new MockMultipartFile("file", "test.zip",
MediaType.TEXT_PLAIN_VALUE, ZipUtil.zip(zipItemList));
@@ -122,4 +130,19 @@ public class ConfigsExportImportControllerTest {
assertThat(response.getStatus()).isEqualTo(HttpStatus.OK.value());
}
+ @Test
+ public void testImportConfigsWithUnknownNamespace() throws Exception {
+ MockMultipartFile file = new MockMultipartFile("file", "test.zip",
MediaType.TEXT_PLAIN_VALUE, new byte[]{1});
+
when(this.namespaceService.findByNamespaceId("ghost-ns")).thenReturn(null);
+
+ mockMvc.perform(multipart("/configs/import")
+ .file(file)
+ .param("namespace", "ghost-ns")
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(jsonPath("$.message", is("namespace is not exist")))
+ .andExpect(status().isOk());
+
+ verify(this.configsService, never()).configsImport(anyString(), any());
+ }
+
}