Commit 15714ac9 authored by Jason Song's avatar Jason Song Committed by GitHub

fix input validator for app namespace name (#2634)

parent 1d12658a
...@@ -19,7 +19,7 @@ import javax.persistence.Table; ...@@ -19,7 +19,7 @@ import javax.persistence.Table;
@Where(clause = "isDeleted = 0") @Where(clause = "isDeleted = 0")
public class AppNamespace extends BaseEntity { public class AppNamespace extends BaseEntity {
@NotBlank(message = "App Name cannot be blank") @NotBlank(message = "AppNamespace Name cannot be blank")
@Pattern( @Pattern(
regexp = InputValidator.CLUSTER_NAMESPACE_VALIDATOR, regexp = InputValidator.CLUSTER_NAMESPACE_VALIDATOR,
message = "Namespace格式错误: " + InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE + " & " + InputValidator.INVALID_NAMESPACE_NAMESPACE_MESSAGE message = "Namespace格式错误: " + InputValidator.INVALID_CLUSTER_NAMESPACE_MESSAGE + " & " + InputValidator.INVALID_NAMESPACE_NAMESPACE_MESSAGE
......
...@@ -12,10 +12,8 @@ public class InputValidator { ...@@ -12,10 +12,8 @@ public class InputValidator {
public static final String INVALID_NAMESPACE_NAMESPACE_MESSAGE = "不允许以.json, .yml, .yaml, .xml, .properties结尾"; public static final String INVALID_NAMESPACE_NAMESPACE_MESSAGE = "不允许以.json, .yml, .yaml, .xml, .properties结尾";
public static final String CLUSTER_NAMESPACE_VALIDATOR = "[0-9a-zA-Z_.-]+"; 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 String APP_NAMESPACE_VALIDATOR = "[a-zA-Z0-9._-]+(?<!\\.(json|yml|yaml|xml|properties))$";
private static final Pattern CLUSTER_NAMESPACE_PATTERN = private static final Pattern CLUSTER_NAMESPACE_PATTERN = Pattern.compile(CLUSTER_NAMESPACE_VALIDATOR);
Pattern.compile(CLUSTER_NAMESPACE_VALIDATOR); private static final Pattern APP_NAMESPACE_PATTERN = Pattern.compile(APP_NAMESPACE_VALIDATOR);
private static final Pattern APP_NAMESPACE_PATTERN =
Pattern.compile(APP_NAMESPACE_VALIDATOR);
public static boolean isValidClusterNamespace(String name) { public static boolean isValidClusterNamespace(String name) {
if (StringUtils.isEmpty(name)){ if (StringUtils.isEmpty(name)){
...@@ -28,6 +26,6 @@ public class InputValidator { ...@@ -28,6 +26,6 @@ public class InputValidator {
if (StringUtils.isEmpty(name)){ if (StringUtils.isEmpty(name)){
return false; return false;
} }
return CLUSTER_NAMESPACE_PATTERN.matcher(name).matches() && APP_NAMESPACE_PATTERN.matcher(name).matches(); return APP_NAMESPACE_PATTERN.matcher(name).matches();
} }
} }
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));
}
}
...@@ -7,6 +7,7 @@ import com.ctrip.framework.apollo.common.exception.BadRequestException; ...@@ -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.MultiResponseEntity;
import com.ctrip.framework.apollo.common.http.RichResponseEntity; import com.ctrip.framework.apollo.common.http.RichResponseEntity;
import com.ctrip.framework.apollo.common.utils.BeanUtils; 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.common.utils.RequestPrecondition;
import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.enums.Env;
import com.ctrip.framework.apollo.portal.api.AdminServiceAPI; import com.ctrip.framework.apollo.portal.api.AdminServiceAPI;
...@@ -191,6 +192,11 @@ public class NamespaceController { ...@@ -191,6 +192,11 @@ public class NamespaceController {
public AppNamespace createAppNamespace(@PathVariable String appId, public AppNamespace createAppNamespace(@PathVariable String appId,
@RequestParam(defaultValue = "true") boolean appendNamespacePrefix, @RequestParam(defaultValue = "true") boolean appendNamespacePrefix,
@Valid @RequestBody AppNamespace appNamespace) { @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); AppNamespace createdAppNamespace = appNamespaceService.createAppNamespaceInLocal(appNamespace, appendNamespacePrefix);
if (portalConfig.canAppAdminCreatePrivateNamespace() || createdAppNamespace.isPublic()) { if (portalConfig.canAppAdminCreatePrivateNamespace() || createdAppNamespace.isPublic()) {
......
...@@ -69,7 +69,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -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/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testCreatePublicAppNamespaceExisted() { public void testCreatePublicAppNamespaceExisted() {
AppNamespace appNamespace = assmbleBaseAppNamespace(); AppNamespace appNamespace = assembleBaseAppNamespace();
appNamespace.setPublic(true); appNamespace.setPublic(true);
appNamespace.setName("old"); appNamespace.setName("old");
...@@ -80,7 +80,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -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/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testCreatePublicAppNamespaceExistedAsPrivateAppNamespace() { public void testCreatePublicAppNamespaceExistedAsPrivateAppNamespace() {
AppNamespace appNamespace = assmbleBaseAppNamespace(); AppNamespace appNamespace = assembleBaseAppNamespace();
appNamespace.setPublic(true); appNamespace.setPublic(true);
appNamespace.setName("private-01"); appNamespace.setName("private-01");
appNamespace.setFormat(ConfigFileFormat.Properties.getValue()); appNamespace.setFormat(ConfigFileFormat.Properties.getValue());
...@@ -92,7 +92,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -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/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testCreatePublicAppNamespaceNotExistedWithNoAppendnamespacePrefix() { public void testCreatePublicAppNamespaceNotExistedWithNoAppendnamespacePrefix() {
AppNamespace appNamespace = assmbleBaseAppNamespace(); AppNamespace appNamespace = assembleBaseAppNamespace();
appNamespace.setPublic(true); appNamespace.setPublic(true);
appNamespace.setName("old"); appNamespace.setName("old");
...@@ -106,7 +106,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -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/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testCreatePublicAppNamespaceExistedWithNoAppendnamespacePrefix() { public void testCreatePublicAppNamespaceExistedWithNoAppendnamespacePrefix() {
AppNamespace appNamespace = assmbleBaseAppNamespace(); AppNamespace appNamespace = assembleBaseAppNamespace();
appNamespace.setPublic(true); appNamespace.setPublic(true);
appNamespace.setName("datasource"); appNamespace.setName("datasource");
...@@ -117,7 +117,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -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/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testCreatePublicAppNamespaceNotExisted() { public void testCreatePublicAppNamespaceNotExisted() {
AppNamespace appNamespace = assmbleBaseAppNamespace(); AppNamespace appNamespace = assembleBaseAppNamespace();
appNamespace.setPublic(true); appNamespace.setPublic(true);
appNamespaceService.createAppNamespaceInLocal(appNamespace); appNamespaceService.createAppNamespaceInLocal(appNamespace);
...@@ -132,7 +132,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -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/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testCreatePrivateAppNamespaceExisted() { public void testCreatePrivateAppNamespaceExisted() {
AppNamespace appNamespace = assmbleBaseAppNamespace(); AppNamespace appNamespace = assembleBaseAppNamespace();
appNamespace.setPublic(false); appNamespace.setPublic(false);
appNamespace.setName("datasource"); appNamespace.setName("datasource");
appNamespace.setAppId("100003173"); appNamespace.setAppId("100003173");
...@@ -144,7 +144,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -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/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testCreatePrivateAppNamespaceExistedInAnotherAppId() { public void testCreatePrivateAppNamespaceExistedInAnotherAppId() {
AppNamespace appNamespace = assmbleBaseAppNamespace(); AppNamespace appNamespace = assembleBaseAppNamespace();
appNamespace.setPublic(false); appNamespace.setPublic(false);
appNamespace.setName("datasource"); appNamespace.setName("datasource");
appNamespace.setAppId("song0711-01"); appNamespace.setAppId("song0711-01");
...@@ -162,7 +162,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -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/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testCreatePrivateAppNamespaceExistedInAnotherAppIdAsPublic() { public void testCreatePrivateAppNamespaceExistedInAnotherAppIdAsPublic() {
AppNamespace appNamespace = assmbleBaseAppNamespace(); AppNamespace appNamespace = assembleBaseAppNamespace();
appNamespace.setPublic(false); appNamespace.setPublic(false);
appNamespace.setName("SCC.song0711-03"); appNamespace.setName("SCC.song0711-03");
appNamespace.setAppId("100003173"); appNamespace.setAppId("100003173");
...@@ -175,7 +175,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -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/appnamespaceservice/init-appnamespace.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
@Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD) @Sql(scripts = "/sql/cleanup.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)
public void testCreatePrivateAppNamespaceNotExisted() { public void testCreatePrivateAppNamespaceNotExisted() {
AppNamespace appNamespace = assmbleBaseAppNamespace(); AppNamespace appNamespace = assembleBaseAppNamespace();
appNamespace.setPublic(false); appNamespace.setPublic(false);
appNamespaceService.createAppNamespaceInLocal(appNamespace); appNamespaceService.createAppNamespaceInLocal(appNamespace);
...@@ -187,7 +187,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest { ...@@ -187,7 +187,7 @@ public class AppNamespaceServiceTest extends AbstractIntegrationTest {
Assert.assertEquals(appNamespace.getName(), createdAppNamespace.getName()); Assert.assertEquals(appNamespace.getName(), createdAppNamespace.getName());
} }
private AppNamespace assmbleBaseAppNamespace() { private AppNamespace assembleBaseAppNamespace() {
AppNamespace appNamespace = new AppNamespace(); AppNamespace appNamespace = new AppNamespace();
appNamespace.setName("appNamespace"); appNamespace.setName("appNamespace");
appNamespace.setAppId("1000"); appNamespace.setAppId("1000");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment