changeset 979:2b1bd4bca6ad Indore-2017.2.x

TW-50054 support custom clone path whitelist
author Dmitry Neverov <dmitry.neverov@gmail.com>
date Wed, 24 Jan 2018 13:49:01 +0100
parents 38e96101a6ef
children 1168c4c64d49 64b5816390f9
files mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java mercurial-server/resources/buildServerResources/mercurialSettings.jsp mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootTest.java
diffstat 4 files changed, 55 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java	Wed Jan 24 11:34:45 2018 +0100
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java	Wed Jan 24 13:49:01 2018 +0100
@@ -43,5 +43,6 @@
 
   String SHOW_CUSTOM_CLONE_PATH = "teamcity.hg.showCustomClonePath";
   String CUSTOM_CLONE_PATH_ENABLED = "teamcity.hg.customClonePathEnabled";
+  String CUSTOM_CLONE_PATH_WHITELIST = "teamcity.hg.customClonePathWhitelist";
   String CUSTOM_CACHES_DIR = "teamcity.hg.customCachesDir";
 }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java	Wed Jan 24 11:34:45 2018 +0100
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java	Wed Jan 24 13:49:01 2018 +0100
@@ -25,6 +25,7 @@
 
 import java.io.File;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -197,8 +198,11 @@
   }
 
   private String readCustomClonePath() {
+    String clonePath = getProperty(Constants.SERVER_CLONE_PATH_PROP);
     if (TeamCityProperties.getBoolean(Constants.CUSTOM_CLONE_PATH_ENABLED))
-      return getProperty(Constants.SERVER_CLONE_PATH_PROP);
+      return clonePath;
+    if (isAllowedCustomClonePath(clonePath))
+      return clonePath;
     return null;
   }
 
@@ -239,4 +243,26 @@
     PURGE_UNKNOWN,
     PURGE_ALL
   }
+
+
+  public static boolean hasCustomClonePathWhitelist() {
+    return StringUtil.isNotEmpty(TeamCityProperties.getProperty(Constants.CUSTOM_CLONE_PATH_WHITELIST));
+  }
+
+  public static boolean isAllowedCustomClonePath(@Nullable String path) {
+    if (StringUtil.isEmptyOrSpaces(path))
+      return false;
+    String whitelist = TeamCityProperties.getProperty(Constants.CUSTOM_CLONE_PATH_WHITELIST);
+    if (StringUtil.isEmpty(whitelist))
+      return false;
+    List<String> paths = StringUtil.split(whitelist, ";");
+    for (String p : paths) {
+      if (p.endsWith("/*")) {
+        return new File(path).getParentFile().equals(new File(p.substring(0, p.length() - 2)));
+      } else if (p.equals(path)) {
+        return true;
+      }
+    }
+    return false;
+  }
 }
--- a/mercurial-server/resources/buildServerResources/mercurialSettings.jsp	Wed Jan 24 11:34:45 2018 +0100
+++ b/mercurial-server/resources/buildServerResources/mercurialSettings.jsp	Wed Jan 24 13:49:01 2018 +0100
@@ -1,6 +1,8 @@
 <%@ page import="jetbrains.buildServer.serverSide.TeamCityProperties" %>
 <%@ page import="jetbrains.buildServer.buildTriggers.vcs.mercurial.Constants" %>
 <%@ page import="jetbrains.buildServer.util.StringUtil" %>
+<%@ page import="jetbrains.buildServer.buildTriggers.vcs.mercurial.ServerPluginConfigImpl" %>
+<%@ page import="jetbrains.buildServer.buildTriggers.vcs.mercurial.command.HgVcsRoot" %>
 <%@include file="/include.jsp"%>
 <%@ taglib prefix="props" tagdir="/WEB-INF/tags/props" %>
 <%--
@@ -28,9 +30,10 @@
 }
 </script>
 <c:set var="subreposGloballyDisabled" value="<%= !TeamCityProperties.getBooleanOrTrue(Constants.GLOBAL_DETECT_SUBREPO_CHANGES) %>"/>
-<c:set var="showCustomClonePath" value="<%= TeamCityProperties.getBoolean(Constants.CUSTOM_CLONE_PATH_ENABLED) &&
-                                            (TeamCityProperties.getBoolean(Constants.SHOW_CUSTOM_CLONE_PATH)
-                                            || !StringUtil.isEmpty(propertiesBean.getProperties().get(Constants.SERVER_CLONE_PATH_PROP))) %>"/>
+<c:set var="showCustomClonePath" value="<%=
+  TeamCityProperties.getBoolean(Constants.CUSTOM_CLONE_PATH_ENABLED) &&
+  (TeamCityProperties.getBoolean(Constants.SHOW_CUSTOM_CLONE_PATH) || !StringUtil.isEmpty(propertiesBean.getProperties().get(Constants.SERVER_CLONE_PATH_PROP))) ||
+  HgVcsRoot.hasCustomClonePathWhitelist() %>"/>
 <table class="runnerFormTable">
 
   <l:settingsGroup title="General Settings">
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootTest.java	Wed Jan 24 11:34:45 2018 +0100
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootTest.java	Wed Jan 24 13:49:01 2018 +0100
@@ -24,8 +24,7 @@
 import java.io.File;
 
 import static jetbrains.buildServer.buildTriggers.vcs.mercurial.VcsRootBuilder.vcsRoot;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.*;
 import static org.testng.AssertJUnit.assertEquals;
 
 /**
@@ -122,6 +121,26 @@
     assertEquals(cloneDir.getAbsolutePath(), hgRoot2.getCustomClonePath());
   }
 
+  @TestFor(issues = {"TW-36401", "TW-50054"})
+  public void custom_clone_path_whitelist() throws Exception {
+    assertFalse(HgVcsRoot.isAllowedCustomClonePath(null));
+    assertFalse(HgVcsRoot.isAllowedCustomClonePath("/some/path"));
+    setInternalProperty(Constants.CUSTOM_CLONE_PATH_WHITELIST, "/some/path1;/some/path2/*");
+    assertTrue(HgVcsRoot.isAllowedCustomClonePath("/some/path1"));
+    assertTrue(HgVcsRoot.isAllowedCustomClonePath("/some/path2/repo1"));
+    assertFalse(HgVcsRoot.isAllowedCustomClonePath("/some/path2/a/b/c"));
+    assertFalse(HgVcsRoot.isAllowedCustomClonePath("/other/path"));
+    assertFalse(HgVcsRoot.isAllowedCustomClonePath("/some/path21"));
+
+    File tempDir = myTempFiles.createTempDir();
+    VcsRoot root = vcsRoot().withCloneRepositoryTo(tempDir).withUrl("http://some.org/repo").build();
+    HgVcsRoot hgRoot = new HgVcsRoot(root);
+    assertNull(hgRoot.getCustomClonePath());
+    setInternalProperty(Constants.CUSTOM_CLONE_PATH_WHITELIST, tempDir.getCanonicalPath());
+    hgRoot = new HgVcsRoot(root);
+    assertEquals(hgRoot.getCustomClonePath(), tempDir.getCanonicalPath());
+  }
+
   private VcsRootImpl createVcsRoot(String url) {
     return createVcsRoot(url, "user", "pwd");
   }