/* * 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. * * Contributions from 2013-2017 where performed either by US government * employees, or under US Veterans Health Administration contracts. * * US Veterans Health Administration contributions by government employees * are work of the U.S. Government and are not subject to copyright * protection in the United States. Portions contributed by government * employees are USGovWork (17USC ยง105). Not subject to copyright. * * Contribution by contractors to the US Veterans Health Administration * during this period are contractually contributed under the * Apache License, Version 2.0. * * See: https://www.usa.gov/government-works * * Contributions prior to 2013: * * Copyright (C) International Health Terminology Standards Development Organisation. * Licensed under the Apache License, Version 2.0. * */ package sh.isaac.provider.sync.git.gitblit; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; import java.util.Date; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; //~--- non-JDK imports -------------------------------------------------------- import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sh.isaac.provider.sync.git.gitblit.models.RepositoryModel; import sh.isaac.provider.sync.git.gitblit.utils.RpcUtils; import sh.isaac.provider.sync.git.gitblit.utils.RpcUtils.AccessRestrictionType; //~--- classes ---------------------------------------------------------------- /** * {@link GitBlitUtils} * * This entire package exists because the GitBlit client API is a bit painful to use, and the client libraries they produce * aren't available in maven central, and they have a dependency chain we may not want to drag in. * * The code in this package, and below, are extracted from http://gitblit.github.io/gitblit-maven * within the com.gitblit:gbapi:1.8.0 module. * * @author <a href="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</a> */ public class GitBlitUtils { /** The log. */ private static Logger log = LoggerFactory.getLogger(GitBlitUtils.class); //~--- methods ------------------------------------------------------------- /** * This hackery is being done because of a code-sync issue between PRISME and ISAAC-Rest, where PRISME is putting a bare URL into the props file. * It will be fixed on the PRISME side, eventually, making this method a noop - but for now, handle either the old or new style. * * Essentially, if we see a bare URL like https://vaauscttdbs80.aac.va.gov:8080 we add /git to the end of it. * If we see a URL that includes a location - like https://vaauscttdbs80.aac.va.gov:8080/gitServer - we do nothing more than add a trailing forward slash * * @param url the url * @return the string */ public static String adjustBareUrlForGitBlit(String url) { String temp = url; if (!temp.endsWith("/")) { temp += "/"; } if (temp.matches("(?i)https?:\\/\\/[a-zA-Z0-9\\.\\-_]+:?\\d*\\/$")) { temp += "git/"; } return temp; } /** * Create a repository on a remote gitblit server. * * @param baseRemoteAddress - should be a url like https://git.isaac.sh/git/ (though {@link #adjustBareUrlForGitBlit(String)} is utilized * @param repoName a name such a foo or foo.git * @param repoDesc the description * @param username the username * @param password the password * @param allowRead true to allow unauthenticated users to read / clone the repository. False to lock down the repository * @throws IOException Signals that an I/O exception has occurred. */ public static void createRepository(String baseRemoteAddress, String repoName, String repoDesc, String username, char[] password, boolean allowRead) throws IOException { try { final RepositoryModel rm = new RepositoryModel(repoName, repoDesc, username, new Date()); if (allowRead) { rm.accessRestriction = AccessRestrictionType.PUSH.toString(); } final boolean status = RpcUtils.createRepository(rm, adjustBareUrlForGitBlit(baseRemoteAddress), username, password); log.info("Repository: " + repoName + ", create successfully: " + status); if (!status) { throw new IOException("Create of repo '" + repoName + "' failed"); } } catch (final Exception e) { log.error("Failed to create repository: " + repoName + ", Unexpected Error: ", e); throw new IOException("Failed to create repository: " + repoName + ", Internal error", e); } } /** * Take in a URL like https://git.isaac.sh/git/r/db_test.git * and turn it into https://git.isaac.sh/git * * @param url the url * @return the string * @throws IOException Signals that an I/O exception has occurred. */ public static String parseBaseRemoteAddress(String url) throws IOException { final Pattern p = Pattern.compile("(?i)(https?:\\/\\/[a-zA-Z0-9\\.\\-_]+:?\\d*\\/[a-zA-Z0-9\\-_]+\\/)r\\/[a-zA-Z0-9\\-_]+.git$"); final Matcher m = p.matcher(url); if (m.find()) { return m.group(1); } throw new IOException("Not a known giblit url pattern!"); } /** * Read repositories. * * @param baseRemoteAddress the base remote address * @param username the username * @param password the password * @return the set * @throws IOException Signals that an I/O exception has occurred. */ public static Set<String> readRepositories(String baseRemoteAddress, String username, char[] password) throws IOException { final HashSet<String> results = new HashSet<>(); RpcUtils.getRepositories(adjustBareUrlForGitBlit(baseRemoteAddress), username, password) .forEach((name, value) -> results.add((String) value.get("name"))); return results; } }