Browse Source

fix input validator for app namespace name (#2634)

Jason Song 5 years ago
parent
commit
15714ac9e7

+ 1 - 1
apollo-common/src/main/java/com/ctrip/framework/apollo/common/entity/AppNamespace.java

@@ -19,7 +19,7 @@ import javax.persistence.Table;
 @Where(clause = "isDeleted = 0")
 public class AppNamespace extends BaseEntity {
 
-  @NotBlank(message = "App Name cannot be blank")
+  @NotBlank(message = "AppNamespace Name cannot be blank")
   @Pattern(
       regexp = InputValidator.CLUSTER_NAMESPACE_VALIDATOR,
       message = "Namespace格式错误: " + InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE + " & " + InputValidator.INVALID_NAMESPACE_NAMESPACE_MESSAGE

+ 3 - 5
apollo-common/src/main/java/com/ctrip/framework/apollo/common/utils/InputValidator.java

@@ -12,10 +12,8 @@ public class InputValidator {
   public static final String INVALID_NAMESPACE_NAMESPACE_MESSAGE = "不允许以.json, .yml, .yaml, .xml, .properties结尾";
   public static final String CLUSTER_NAMESPACE_VALIDATOR = "[0-9a-zA-Z_.-]+";
   private static final String APP_NAMESPACE_VALIDATOR = "[a-zA-Z0-9._-]+(?<!\\.(json|yml|yaml|xml|properties))$";
-  private static final Pattern CLUSTER_NAMESPACE_PATTERN =
-      Pattern.compile(CLUSTER_NAMESPACE_VALIDATOR);
-  private static final Pattern APP_NAMESPACE_PATTERN =
-      Pattern.compile(APP_NAMESPACE_VALIDATOR);
+  private static final Pattern CLUSTER_NAMESPACE_PATTERN = Pattern.compile(CLUSTER_NAMESPACE_VALIDATOR);
+  private static final Pattern APP_NAMESPACE_PATTERN = Pattern.compile(APP_NAMESPACE_VALIDATOR);
 
   public static boolean isValidClusterNamespace(String name) {
     if (StringUtils.isEmpty(name)){
@@ -28,6 +26,6 @@ public class InputValidator {
     if (StringUtils.isEmpty(name)){
       return false;
     }
-    return CLUSTER_NAMESPACE_PATTERN.matcher(name).matches() && APP_NAMESPACE_PATTERN.matcher(name).matches();
+    return APP_NAMESPACE_PATTERN.matcher(name).matches();
   }
 }

+ 38 - 0
apollo-common/src/test/java/com/ctrip/framework/apollo/common/utils/InputValidatorTest.java

@@ -0,0 +1,38 @@
+package com.ctrip.framework.apollo.common.utils;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class InputValidatorTest {
+
+  @Test
+  public void testValidClusterName() throws Exception {
+    checkClusterName("some.cluster-_name.123", true);
+    checkClusterName("some.cluster-_name.123.yml", true);
+    checkClusterName("some.&.name", false);
+    checkClusterName("", false);
+    checkClusterName(null, false);
+  }
+
+  @Test
+  public void testValidAppNamespaceName() throws Exception {
+    checkAppNamespaceName("some.cluster-_name.123", true);
+    checkAppNamespaceName("some.&.name", false);
+    checkAppNamespaceName("", false);
+    checkAppNamespaceName(null, false);
+    checkAppNamespaceName("some.name.json", false);
+    checkAppNamespaceName("some.name.yml", false);
+    checkAppNamespaceName("some.name.yaml", false);
+    checkAppNamespaceName("some.name.xml", false);
+    checkAppNamespaceName("some.name.properties", false);
+  }
+
+  private void checkClusterName(String name, boolean valid) {
+    assertEquals(valid, InputValidator.isValidClusterNamespace(name));
+  }
+
+  private void checkAppNamespaceName(String name, boolean valid) {
+    assertEquals(valid, InputValidator.isValidAppNamespace(name));
+  }
+}

+ 6 - 0
apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/controller/NamespaceController.java

@@ -7,6 +7,7 @@ import com.ctrip.framework.apollo.common.exception.BadRequestException;
 import com.ctrip.framework.apollo.common.http.MultiResponseEntity;
 import com.ctrip.framework.apollo.common.http.RichResponseEntity;
 import com.ctrip.framework.apollo.common.utils.BeanUtils;
+import com.ctrip.framework.apollo.common.utils.InputValidator;
 import com.ctrip.framework.apollo.common.utils.RequestPrecondition;
 import com.ctrip.framework.apollo.core.enums.Env;
 import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
@@ -191,6 +192,11 @@ public class NamespaceController {
   public AppNamespace createAppNamespace(@PathVariable String appId,
       @RequestParam(defaultValue = "true") boolean appendNamespacePrefix,
       @Valid @RequestBody AppNamespace appNamespace) {
+    if (!InputValidator.isValidAppNamespace(appNamespace.getName())) {
+      throw new BadRequestException(String.format("Namespace格式错误: %s",
+          InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE + " & " + InputValidator.INVALID_NAMESPACE_NAMESPACE_MESSAGE));
+    }
+
     AppNamespace createdAppNamespace = appNamespaceService.createAppNamespaceInLocal(appNamespace, appendNamespacePrefix);
 
     if (portalConfig.canAppAdminCreatePrivateNamespace() || createdAppNamespace.isPublic()) {

+ 10 - 10
apollo-portal/src/test/java/com/ctrip/framework/apollo/portal/service/AppNamespaceServiceTest.java

@@ -69,7 +69,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
   @Sql(scripts = "/sql/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
   @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
   public void testCreatePublicAppNamespaceExisted() {
-    AppNamespace appNamespace = assmbleBaseAppNamespace();
+    AppNamespace appNamespace = assembleBaseAppNamespace();
     appNamespace.setPublic(true);
     appNamespace.setName("old");
 
@@ -80,7 +80,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
   @Sql(scripts = "/sql/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
   @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
   public void testCreatePublicAppNamespaceExistedAsPrivateAppNamespace() {
-    AppNamespace appNamespace = assmbleBaseAppNamespace();
+    AppNamespace appNamespace = assembleBaseAppNamespace();
     appNamespace.setPublic(true);
     appNamespace.setName("private-01");
     appNamespace.setFormat(ConfigFileFormat.Properties.getValue());
@@ -92,7 +92,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
   @Sql(scripts = "/sql/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
   @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
   public void testCreatePublicAppNamespaceNotExistedWithNoAppendnamespacePrefix() {
-    AppNamespace appNamespace = assmbleBaseAppNamespace();
+    AppNamespace appNamespace = assembleBaseAppNamespace();
     appNamespace.setPublic(true);
     appNamespace.setName("old");
 
@@ -106,7 +106,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
   @Sql(scripts = "/sql/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
   @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
   public void testCreatePublicAppNamespaceExistedWithNoAppendnamespacePrefix() {
-    AppNamespace appNamespace = assmbleBaseAppNamespace();
+    AppNamespace appNamespace = assembleBaseAppNamespace();
     appNamespace.setPublic(true);
     appNamespace.setName("datasource");
 
@@ -117,7 +117,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
   @Sql(scripts = "/sql/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
   @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
   public void testCreatePublicAppNamespaceNotExisted() {
-    AppNamespace appNamespace = assmbleBaseAppNamespace();
+    AppNamespace appNamespace = assembleBaseAppNamespace();
     appNamespace.setPublic(true);
 
     appNamespaceService.createAppNamespaceInLocal(appNamespace);
@@ -132,7 +132,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
   @Sql(scripts = "/sql/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
   @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
   public void testCreatePrivateAppNamespaceExisted() {
-    AppNamespace appNamespace = assmbleBaseAppNamespace();
+    AppNamespace appNamespace = assembleBaseAppNamespace();
     appNamespace.setPublic(false);
     appNamespace.setName("datasource");
     appNamespace.setAppId("100003173");
@@ -144,7 +144,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
   @Sql(scripts = "/sql/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
   @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
   public void testCreatePrivateAppNamespaceExistedInAnotherAppId() {
-    AppNamespace appNamespace = assmbleBaseAppNamespace();
+    AppNamespace appNamespace = assembleBaseAppNamespace();
     appNamespace.setPublic(false);
     appNamespace.setName("datasource");
     appNamespace.setAppId("song0711-01");
@@ -162,7 +162,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
   @Sql(scripts = "/sql/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
   @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
   public void testCreatePrivateAppNamespaceExistedInAnotherAppIdAsPublic() {
-    AppNamespace appNamespace = assmbleBaseAppNamespace();
+    AppNamespace appNamespace = assembleBaseAppNamespace();
     appNamespace.setPublic(false);
     appNamespace.setName("SCC.song0711-03");
     appNamespace.setAppId("100003173");
@@ -175,7 +175,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
   @Sql(scripts = "/sql/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
   @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
   public void testCreatePrivateAppNamespaceNotExisted() {
-    AppNamespace appNamespace = assmbleBaseAppNamespace();
+    AppNamespace appNamespace = assembleBaseAppNamespace();
     appNamespace.setPublic(false);
 
     appNamespaceService.createAppNamespaceInLocal(appNamespace);
@@ -187,7 +187,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
     Assert.assertEquals(appNamespace.getName(), createdAppNamespace.getName());
   }
 
-  private AppNamespace assmbleBaseAppNamespace() {
+  private AppNamespace assembleBaseAppNamespace() {
     AppNamespace appNamespace = new AppNamespace();
     appNamespace.setName("appNamespace");
     appNamespace.setAppId("1000");