changeset 981:64b5816390f9 Indore-2017.2.x

TW-50054 support hg path whitelist Use hg path from VCS root only if it in whitelist
author Dmitry Neverov <dmitry.neverov@gmail.com>
date Wed, 24 Jan 2018 21:19:56 +0100
parents 2b1bd4bca6ad
children 4a0ea921c214
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-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgPathProvider.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootTest.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgPathProviderTest.java
diffstat 6 files changed, 50 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java	Wed Jan 24 13:49:01 2018 +0100
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java	Wed Jan 24 21:19:56 2018 +0100
@@ -45,4 +45,5 @@
   String CUSTOM_CLONE_PATH_ENABLED = "teamcity.hg.customClonePathEnabled";
   String CUSTOM_CLONE_PATH_WHITELIST = "teamcity.hg.customClonePathWhitelist";
   String CUSTOM_CACHES_DIR = "teamcity.hg.customCachesDir";
+  String HG_PATH_WHITELIST = "teamcity.hg.hgPathWhitelist";
 }
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java	Wed Jan 24 13:49:01 2018 +0100
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java	Wed Jan 24 21:19:56 2018 +0100
@@ -265,4 +265,18 @@
     }
     return false;
   }
+
+  public static boolean isAllowedHgPath(@Nullable String path) {
+    if (StringUtil.isEmptyOrSpaces(path))
+      return false;
+    String whitelist = TeamCityProperties.getProperty(Constants.HG_PATH_WHITELIST);
+    if (StringUtil.isEmpty(whitelist))
+      return false;
+    List<String> paths = StringUtil.split(whitelist, ";");
+    for (String p : paths) {
+      if (p.equals(path))
+        return true;
+    }
+    return false;
+  }
 }
--- a/mercurial-server/resources/buildServerResources/mercurialSettings.jsp	Wed Jan 24 13:49:01 2018 +0100
+++ b/mercurial-server/resources/buildServerResources/mercurialSettings.jsp	Wed Jan 24 21:19:56 2018 +0100
@@ -92,6 +92,7 @@
     <td>
       <props:textProperty name="hgCommandPath" className="longField" />
       <span class="error" id="error_hgCommandPath"></span>
+      <div class="smallNote" style="margin: 0;">The path will be used on TeamCity server only if it is included into whitelist.<bs:help file="Mercurial" anchor="Pathtohgexecutabledetection"/></div>
     </td>
   </tr>
   <tr class="advancedSetting">
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgPathProvider.java	Wed Jan 24 13:49:01 2018 +0100
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgPathProvider.java	Wed Jan 24 21:19:56 2018 +0100
@@ -33,17 +33,12 @@
 
 
   public String getHgPath(@NotNull final HgVcsRoot root) {
-    String serverWideHgPath = myConfig.getHgPath();
-    if (serverWideHgPath != null) {
-      return serverWideHgPath;
+    String pathFromRoot = root.getHgPath();
+    if (HgVcsRoot.isAllowedHgPath(pathFromRoot)) {
+      return pathFromRoot;
     } else {
-      String pathFromRoot = root.getHgPath();
-      if (pathFromRoot.equals(unresolvedAgentHgPath())) {
-        //try to use hg from the PATH:
-        return "hg";
-      } else {
-        return pathFromRoot;
-      }
+      String serverWideHgPath = myConfig.getHgPath();
+      return serverWideHgPath != null ? serverWideHgPath : "hg";
     }
   }
 
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootTest.java	Wed Jan 24 13:49:01 2018 +0100
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/HgVcsRootTest.java	Wed Jan 24 21:19:56 2018 +0100
@@ -141,6 +141,30 @@
     assertEquals(hgRoot.getCustomClonePath(), tempDir.getCanonicalPath());
   }
 
+  public void hg_path_whitelist() throws Exception {
+    assertFalse(HgVcsRoot.isAllowedHgPath(null));
+    assertFalse(HgVcsRoot.isAllowedHgPath("/some/path"));
+    setInternalProperty(Constants.HG_PATH_WHITELIST, "/some/path1;/some/path2");
+    assertTrue(HgVcsRoot.isAllowedHgPath("/some/path1"));
+    assertTrue(HgVcsRoot.isAllowedHgPath("/some/path2"));
+    assertFalse(HgVcsRoot.isAllowedHgPath("/some/other/path"));
+    assertFalse(HgVcsRoot.isAllowedHgPath("/some/path11"));
+    assertFalse(HgVcsRoot.isAllowedHgPath("/some/path1/hg"));
+
+    ServerHgPathProvider serverHgPathProvider = new ServerHgPathProvider(new ServerPluginConfigBuilder().build());
+    HgVcsRoot root = new HgVcsRoot(vcsRoot().withHgPath("/some/other/path").withUrl("http://some.org/repo").build());
+    assertEquals("hg", serverHgPathProvider.getHgPath(root));
+
+    serverHgPathProvider = new ServerHgPathProvider(new ServerPluginConfigBuilder().hgPath("/server/hg/path").build());
+    root = new HgVcsRoot(vcsRoot().withHgPath("/some/other/path").withUrl("http://some.org/repo").build());
+    assertEquals("/server/hg/path", serverHgPathProvider.getHgPath(root));
+
+    root = new HgVcsRoot(vcsRoot().withHgPath("/some/path1").withUrl("http://some.org/repo").build());
+    assertEquals("/some/path1", serverHgPathProvider.getHgPath(root));
+    root = new HgVcsRoot(vcsRoot().withHgPath("/some/path2").withUrl("http://some.org/repo").build());
+    assertEquals("/some/path2", serverHgPathProvider.getHgPath(root));
+  }
+
   private VcsRootImpl createVcsRoot(String url) {
     return createVcsRoot(url, "user", "pwd");
   }
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgPathProviderTest.java	Wed Jan 24 13:49:01 2018 +0100
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/ServerHgPathProviderTest.java	Wed Jan 24 21:19:56 2018 +0100
@@ -26,20 +26,22 @@
  * @author dmitry.neverov
  */
 @Test
-public class ServerHgPathProviderTest {
+public class ServerHgPathProviderTest extends BaseMercurialTestCase {
 
   private String myServerWideHgPath;
   private String myVcsRootHgPath;
 
 
   @BeforeMethod
-  public void setUp() {
+  public void setUp() throws Exception {
+    super.setUp();
     myServerWideHgPath = null;
     myVcsRootHgPath = "/vcs/root/hg/path";
   }
 
 
-  public void server_should_use_settings_from_vcs_root_if_server_wide_path_is_not_set() throws Exception {
+  public void server_should_use_settings_from_vcs_root_if_server_wide_path_is_not_set_and_path_is_in_whitelist() throws Exception {
+    setInternalProperty(Constants.HG_PATH_WHITELIST, myVcsRootHgPath);
     myServerWideHgPath = null;
     HgPathProvider provider = createHgPathProvider();
     HgVcsRoot root = createHgRoot();