Mercurial > hg > mercurial
view mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/HgVcsRoot.java @ 1067:5bc9d4871754 Lakhnau-2020.2.x
made the check case insensitive
(grafted from d52989000edd01eedb870e71520a7ec5f1aeec17)
author | victory.bedrosova |
---|---|
date | Fri, 12 Mar 2021 13:58:38 +0100 |
parents | 4b6661db8a8a |
children |
line wrap: on
line source
/* * Copyright 2000-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.buildServer.buildTriggers.vcs.mercurial.command; import jetbrains.buildServer.buildTriggers.vcs.mercurial.Constants; import jetbrains.buildServer.buildTriggers.vcs.mercurial.PathUtil; import jetbrains.buildServer.serverSide.TeamCityProperties; import jetbrains.buildServer.util.StringUtil; import jetbrains.buildServer.vcs.VcsRoot; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Represents mercurial VCS root */ public class HgVcsRoot { public static final String DEFAULT_BRANCH_NAME = "default"; // prevent RCE, see TW-70054, TW-70541 public static final String[] PROHIBITED_OPTIONS = {"--config", "--debug", "--cwd"}; private final Map<String, String> myVcsRootProperties; private final String myRepository; private final String myHgCommandPath; private final String myBranchName; private final String myCustomClonePath; private final String myUserForTag; private final AuthSettings myAuthSettings; private File myCustomWorkingDir; private final boolean myDetectSubrepoChanges; private final boolean myUseTagsAsBranches; private final boolean myIncludeSubreposInPatch; private final boolean myUseArchiveForPatch; private final PurgePolicy myPurgePolicy; private final boolean myIgnoreMissingDefaultBranch; private final String myCustomHgConfig; private final Boolean myUseAgentMirrors; public HgVcsRoot(@NotNull final VcsRoot vcsRoot) { this(vcsRoot.getProperties()); } public HgVcsRoot(@NotNull Map<String, String> vcsRootProperties) { myVcsRootProperties = vcsRootProperties; myRepository = getValidatedProperty(Constants.REPOSITORY_PROP); myHgCommandPath = getProperty(Constants.HG_COMMAND_PATH_PROP); myBranchName = getValidatedProperty(Constants.BRANCH_NAME_PROP); myCustomClonePath = readCustomClonePath(); myUserForTag = getProperty(Constants.USER_FOR_TAG); myAuthSettings = new AuthSettings(getProperty(Constants.USERNAME), getProperty(Constants.PASSWORD)); myDetectSubrepoChanges = Boolean.parseBoolean(getProperty(Constants.DETECT_SUBREPO_CHANGES)); myUseTagsAsBranches = Boolean.parseBoolean(getProperty(Constants.USE_TAGS_AS_BRANCHES)); myIncludeSubreposInPatch = Boolean.parseBoolean(getProperty(Constants.INCLUDE_SUBREPOS_IN_PATCH, "true")); myUseArchiveForPatch = Boolean.parseBoolean(getProperty(Constants.USE_ARCHIVE_FOR_PATCH)); myPurgePolicy = readPurgePolicy(vcsRootProperties); myIgnoreMissingDefaultBranch = Boolean.parseBoolean(getProperty(Constants.IGNORE_MISSING_DEFAULT_BRANCH, "false")); myCustomHgConfig = getProperty(Constants.CUSTOM_HG_CONFIG_PROP, ""); myUseAgentMirrors = readUseSharedMirrors(); } @Nullable private Boolean readUseSharedMirrors() { String prop = getProperty(Constants.USE_AGENT_MIRRORS); if (StringUtil.isEmpty(prop)) return null; return Boolean.parseBoolean(prop); } @NotNull private PurgePolicy readPurgePolicy(@NotNull Map<String, String> properties) { String policy = properties.get(Constants.PURGE_POLICY); if (StringUtil.isEmpty(policy)) return PurgePolicy.DONT_RUN; return PurgePolicy.valueOf(policy); } public HgVcsRoot withUrl(@NotNull String repositoryUrl) { Map<String, String> customUrlProperties = new HashMap<>(getProperties()); customUrlProperties.put(Constants.REPOSITORY_PROP, repositoryUrl); return new HgVcsRoot(customUrlProperties); } public String getCustomClonePath() { return myCustomClonePath; } public String getRepository() { return myRepository; } public boolean includeSubreposInPatch() { return myIncludeSubreposInPatch; } public boolean useArchiveForPatch() { if (TeamCityProperties.getBoolean("teamcity.hg.useArchiveForPatch")) return true; return myUseArchiveForPatch; } /** * Returns name of the branch to use (returns 'default' if no branch specified) * @return see above */ @NotNull public String getBranchName() { return StringUtil.isEmpty(myBranchName) ? DEFAULT_BRANCH_NAME : myBranchName; } /** * @return path to hg command as it is set in VCS root settings */ public String getHgPath() { return myHgCommandPath; } @Nullable public String getUserForTag() { return myUserForTag; } public String getRepositoryUrlWithCredentials() { return myAuthSettings.getRepositoryUrlWithCredentials(myRepository); } /** * Set custom working dir for vcs root. This option make sence only for server-side checkout * @param customWorkingDir custom working dir */ public void setCustomWorkingDir(@NotNull final File customWorkingDir) { myCustomWorkingDir = PathUtil.getCanonicalFile(customWorkingDir); } /** * Returns custom working dir for root or null if default working dir should be used. * This options make sence only with server-side checkout. * @return see above */ @Nullable public File getCustomWorkingDir() { return myCustomWorkingDir; } public AuthSettings getAuthSettings() { return myAuthSettings; } public boolean detectSubrepoChanges() { return myDetectSubrepoChanges; } public boolean useTagsAsBranches() { return myUseTagsAsBranches; } public boolean isSubrepo() { return Boolean.parseBoolean(getProperty("teamcity.internal.subrepo")); } public String getSubrepoPath() { return getProperty("teamcity.internal.subrepo.path"); } public String expandSubrepoPath(@NotNull String subrepoPath) { if (!isSubrepo()) return subrepoPath; String mySubrepoPath = getSubrepoPath(); if (mySubrepoPath == null) return subrepoPath; if (!mySubrepoPath.endsWith("/")) mySubrepoPath += "/"; return mySubrepoPath + subrepoPath; } public String getProperty(@NotNull String propertyName) { return myVcsRootProperties.get(propertyName); } private String readCustomClonePath() { String clonePath = getProperty(Constants.SERVER_CLONE_PATH_PROP); if (TeamCityProperties.getBoolean(Constants.CUSTOM_CLONE_PATH_ENABLED)) return clonePath; if (isAllowedCustomClonePath(clonePath)) return clonePath; return null; } @NotNull public String getProperty(@NotNull String propertyName, @NotNull String defaultValue) { String value = myVcsRootProperties.get(propertyName); if (value != null) return value; return defaultValue; } @NotNull public PurgePolicy getPurgePolicy() { return myPurgePolicy; } @NotNull public Map<String, String> getProperties() { return myVcsRootProperties; } public boolean isIgnoreMissingDefaultBranch() { return myIgnoreMissingDefaultBranch; } @NotNull public String getCustomHgConfig() { return myCustomHgConfig; } @NotNull public String getCustomHgConfigServer() { return TeamCityProperties.getBoolean(Constants.CUSTOM_HG_CONFIG_ENABLED) ? myCustomHgConfig : ""; } @Nullable public Boolean getUseAgentMirrors() { return myUseAgentMirrors; } public enum PurgePolicy { DONT_RUN, 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; } public static boolean isAllowedHgPath(@Nullable String path) { if (StringUtil.isEmptyOrSpaces(path)) return false; String whitelist = TeamCityProperties.getProperty(Constants.CUSTOM_SERVER_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; } @Nullable public String getValidatedProperty(@NotNull String name) { return validateProperty(name, getProperty(name)); } public static String validateProperty(@NotNull String name, @Nullable String param) { if (StringUtil.isEmpty(param)) return null; for (String s : PROHIBITED_OPTIONS) { if (StringUtil.containsIgnoreCase(param, s)) { throw new IllegalArgumentException(String.format("Parameter \"" + name + "\" is not allowed to contain \"%s\" substring for security reasons", s)); } } return param; } }