From df162cdbdfeb5fbf5500546c9783e1685be6980f Mon Sep 17 00:00:00 2001 From: James Moger Date: Wed, 4 Jan 2012 08:42:54 -0500 Subject: Federation pull_scripts request. Documentation. --- src/com/gitblit/Constants.java | 2 +- src/com/gitblit/FederationPullExecutor.java | 47 ++++++++++++++++++++++++++++- src/com/gitblit/FederationServlet.java | 39 ++++++++++++++++++++++++ src/com/gitblit/GitBlit.java | 1 + src/com/gitblit/utils/FederationUtils.java | 16 +++++++++- src/com/gitblit/utils/JsonUtils.java | 13 ++++++++ 6 files changed, 115 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/com/gitblit/Constants.java b/src/com/gitblit/Constants.java index 8171d667..602a6aef 100644 --- a/src/com/gitblit/Constants.java +++ b/src/com/gitblit/Constants.java @@ -117,7 +117,7 @@ public class Constants { * Enumeration representing the types of federation requests. */ public static enum FederationRequest { - POKE, PROPOSAL, PULL_REPOSITORIES, PULL_USERS, PULL_TEAMS, PULL_SETTINGS, STATUS; + POKE, PROPOSAL, PULL_REPOSITORIES, PULL_USERS, PULL_TEAMS, PULL_SETTINGS, PULL_SCRIPTS, STATUS; public static FederationRequest fromName(String name) { for (FederationRequest type : values()) { diff --git a/src/com/gitblit/FederationPullExecutor.java b/src/com/gitblit/FederationPullExecutor.java index 2976c402..d54395e4 100644 --- a/src/com/gitblit/FederationPullExecutor.java +++ b/src/com/gitblit/FederationPullExecutor.java @@ -50,6 +50,7 @@ import com.gitblit.models.RepositoryModel; import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; import com.gitblit.utils.FederationUtils; +import com.gitblit.utils.FileUtils; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.JGitUtils.CloneResult; import com.gitblit.utils.StringUtils; @@ -281,6 +282,8 @@ public class FederationPullExecutor implements Runnable { r.close(); } + IUserService userService = null; + try { // Pull USERS // TeamModels are automatically pulled because they are contained @@ -290,7 +293,7 @@ public class FederationPullExecutor implements Runnable { if (users != null && users.size() > 0) { File realmFile = new File(registrationFolderFile, registration.name + "_users.conf"); realmFile.delete(); - ConfigUserService userService = new ConfigUserService(realmFile); + userService = new ConfigUserService(realmFile); for (UserModel user : users) { userService.updateUserModel(user.username, user); @@ -357,6 +360,27 @@ public class FederationPullExecutor implements Runnable { registration.name, registration.url), e); } + try { + // Pull TEAMS + // We explicitly pull these even though they are embedded in + // UserModels because it is possible to use teams to specify + // mailing lists or push scripts without specifying users. + if (userService != null) { + Collection teams = FederationUtils.getTeams(registration); + if (teams != null && teams.size() > 0) { + for (TeamModel team : teams) { + userService.updateTeamModel(team); + } + } + } + } catch (ForbiddenException e) { + // ignore forbidden exceptions + } catch (IOException e) { + logger.warn(MessageFormat.format( + "Failed to retrieve TEAMS from federated gitblit ({0} @ {1})", + registration.name, registration.url), e); + } + try { // Pull SETTINGS Map settings = FederationUtils.getSettings(registration); @@ -375,6 +399,27 @@ public class FederationPullExecutor implements Runnable { "Failed to retrieve SETTINGS from federated gitblit ({0} @ {1})", registration.name, registration.url), e); } + + try { + // Pull SCRIPTS + Map scripts = FederationUtils.getScripts(registration); + if (scripts != null && scripts.size() > 0) { + for (Map.Entry script : scripts.entrySet()) { + String scriptName = script.getKey(); + if (scriptName.endsWith(".groovy")) { + scriptName = scriptName.substring(0, scriptName.indexOf(".groovy")); + } + File file = new File(registrationFolderFile, registration.name + "_" + scriptName + ".groovy"); + FileUtils.writeContent(file, script.getValue()); + } + } + } catch (ForbiddenException e) { + // ignore forbidden exceptions + } catch (IOException e) { + logger.warn(MessageFormat.format( + "Failed to retrieve SCRIPTS from federated gitblit ({0} @ {1})", + registration.name, registration.url), e); + } } /** diff --git a/src/com/gitblit/FederationServlet.java b/src/com/gitblit/FederationServlet.java index f2ed903c..e7720508 100644 --- a/src/com/gitblit/FederationServlet.java +++ b/src/com/gitblit/FederationServlet.java @@ -15,12 +15,15 @@ */ package com.gitblit; +import java.io.File; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import javax.servlet.http.HttpServletResponse; @@ -30,6 +33,7 @@ import com.gitblit.models.FederationProposal; import com.gitblit.models.TeamModel; import com.gitblit.models.UserModel; import com.gitblit.utils.FederationUtils; +import com.gitblit.utils.FileUtils; import com.gitblit.utils.HttpUtils; import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; @@ -216,6 +220,41 @@ public class FederationServlet extends JsonServlet { teams.add(user); } result = teams; + } else if (FederationRequest.PULL_SCRIPTS.equals(reqType)) { + // pull scripts + if (!GitBlit.self().validateFederationRequest(reqType, token)) { + // invalid token to pull script + logger.warn(MessageFormat.format( + "Federation token from {0} not authorized to pull SCRIPTS", + request.getRemoteAddr())); + response.sendError(HttpServletResponse.SC_FORBIDDEN); + return; + } + Map scripts = new HashMap(); + + Set names = new HashSet(); + names.addAll(GitBlit.getStrings(Keys.groovy.preReceiveScripts)); + names.addAll(GitBlit.getStrings(Keys.groovy.postReceiveScripts)); + for (TeamModel team : GitBlit.self().getAllTeams()) { + names.addAll(team.preReceiveScripts); + names.addAll(team.postReceiveScripts); + } + File scriptsFolder = GitBlit.getFileOrFolder(Keys.groovy.scriptsFolder, "groovy"); + for (String name : names) { + File file = new File(scriptsFolder, name); + if (!file.exists() && !file.getName().endsWith(".groovy")) { + file = new File(scriptsFolder, name + ".groovy"); + } + if (file.exists()) { + // read the script + String content = FileUtils.readContent(file, "\n"); + scripts.put(name, content); + } else { + // missing script?! + logger.warn(MessageFormat.format("Failed to find push script \"{0}\"", name)); + } + } + result = scripts; } } diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java index 6271a0d6..89dcbf1a 100644 --- a/src/com/gitblit/GitBlit.java +++ b/src/com/gitblit/GitBlit.java @@ -1253,6 +1253,7 @@ public class GitBlit implements ServletContextListener { case PULL_TEAMS: return token.equals(all) || token.equals(unr); case PULL_SETTINGS: + case PULL_SCRIPTS: return token.equals(all); } return false; diff --git a/src/com/gitblit/utils/FederationUtils.java b/src/com/gitblit/utils/FederationUtils.java index 8207962a..4d6060dd 100644 --- a/src/com/gitblit/utils/FederationUtils.java +++ b/src/com/gitblit/utils/FederationUtils.java @@ -285,7 +285,8 @@ public class FederationUtils { } /** - * Tries to pull the gitblit team definitions from the remote gitblit instance. + * Tries to pull the gitblit team definitions from the remote gitblit + * instance. * * @param registration * @return a collection of TeamModel objects @@ -312,6 +313,19 @@ public class FederationUtils { return settings; } + /** + * Tries to pull the referenced scripts from the remote gitblit instance. + * + * @param registration + * @return a map of the remote gitblit scripts by script name + * @throws Exception + */ + public static Map getScripts(FederationModel registration) throws Exception { + String url = asLink(registration.url, registration.token, FederationRequest.PULL_SCRIPTS); + Map scripts = JsonUtils.retrieveJson(url, SETTINGS_TYPE); + return scripts; + } + /** * Send an status acknowledgment to the remote Gitblit server. * diff --git a/src/com/gitblit/utils/JsonUtils.java b/src/com/gitblit/utils/JsonUtils.java index 3cb43eb1..da9c99d2 100644 --- a/src/com/gitblit/utils/JsonUtils.java +++ b/src/com/gitblit/utils/JsonUtils.java @@ -108,6 +108,19 @@ public class JsonUtils { UnauthorizedException { return retrieveJson(url, type, null, null); } + + /** + * Reads a gson object from the specified url. + * + * @param url + * @param type + * @return the deserialized object + * @throws {@link IOException} + */ + public static X retrieveJson(String url, Class clazz) throws IOException, + UnauthorizedException { + return retrieveJson(url, clazz, null, null); + } /** * Reads a gson object from the specified url. -- cgit v1.2.3